Browse Source

Init first freedom-u-sdk for starlight

yiming.li 3 years ago
commit
45a7b8e2cb
100 changed files with 15794 additions and 0 deletions
  1. 1 0
      README.md
  2. 17 0
      codaj12/Android.mk
  3. 169 0
      codaj12/Makefile
  4. BIN
      codaj12/Nieuport_JpgDec
  5. BIN
      codaj12/Nieuport_JpgEnc
  6. 15 0
      codaj12/README.md
  7. 546 0
      codaj12/TestRunnerCodaJ12Dec.sh
  8. 459 0
      codaj12/TestRunnerCodaJ12Enc.sh
  9. 556 0
      codaj12/TestRunnerCodaJ12Multi.sh
  10. 639 0
      codaj12/TestRunnerCommon.sh
  11. 0 0
      codaj12/TestRunnerParamCodaJ12Dec.txt
  12. 0 0
      codaj12/TestRunnerParamCodaJ12Enc.txt
  13. 21 0
      codaj12/build_ffmpeg.sh
  14. 50 0
      codaj12/build_for_riscv.sh
  15. 62 0
      codaj12/cfg/HuffmanTable01.cfg
  16. 84 0
      codaj12/cfg/HuffmanTable01_ES.cfg
  17. 18 0
      codaj12/cfg/QuantTable00.cfg
  18. 18 0
      codaj12/cfg/QuantTable01.cfg
  19. 18 0
      codaj12/cfg/QuantTable02.cfg
  20. 18 0
      codaj12/cfg/QuantTableEX_23.cfg
  21. 32 0
      codaj12/cfg/outI400_qcif_inI400.cfg
  22. 34 0
      codaj12/cfg/outI400_qcif_inI400_12b.cfg
  23. 32 0
      codaj12/cfg/outI400_qcif_inUYVY.cfg
  24. 32 0
      codaj12/cfg/outI400_qcif_inVYUY.cfg
  25. 32 0
      codaj12/cfg/outI400_qcif_inYUYV.cfg
  26. 32 0
      codaj12/cfg/outI400_qcif_inYVYU.cfg
  27. 32 0
      codaj12/cfg/outI420_cif_inNV12.cfg
  28. 32 0
      codaj12/cfg/outI420_cif_inNV12_tiled.cfg
  29. 32 0
      codaj12/cfg/outI420_qcif_inI420.cfg
  30. 34 0
      codaj12/cfg/outI420_qcif_inI420_12b.cfg
  31. 32 0
      codaj12/cfg/outI420_qcif_inNV12.cfg
  32. 32 0
      codaj12/cfg/outI420_qcif_inNV21.cfg
  33. 32 0
      codaj12/cfg/outI420_qcif_inUYVY.cfg
  34. 32 0
      codaj12/cfg/outI420_qcif_inVYUY.cfg
  35. 32 0
      codaj12/cfg/outI420_qcif_inYUYV.cfg
  36. 32 0
      codaj12/cfg/outI420_qcif_inYVYU.cfg
  37. 32 0
      codaj12/cfg/outI422_qcif_inI422.cfg
  38. 34 0
      codaj12/cfg/outI422_qcif_inI422_12b.cfg
  39. 32 0
      codaj12/cfg/outI422_qcif_inNV16.cfg
  40. 32 0
      codaj12/cfg/outI422_qcif_inNV16_tiled.cfg
  41. 32 0
      codaj12/cfg/outI422_qcif_inNV61.cfg
  42. 32 0
      codaj12/cfg/outI422_qcif_inUYVY.cfg
  43. 32 0
      codaj12/cfg/outI422_qcif_inVYUY.cfg
  44. 32 0
      codaj12/cfg/outI422_qcif_inYUYV.cfg
  45. 32 0
      codaj12/cfg/outI422_qcif_inYVYU.cfg
  46. 32 0
      codaj12/cfg/outI440_qcif_in16NV.cfg
  47. 32 0
      codaj12/cfg/outI440_qcif_in61NV.cfg
  48. 32 0
      codaj12/cfg/outI440_qcif_inI440.cfg
  49. 34 0
      codaj12/cfg/outI440_qcif_inI440_12b.cfg
  50. 32 0
      codaj12/cfg/outI440_qcif_inUYVY.cfg
  51. 32 0
      codaj12/cfg/outI440_qcif_inVYUY.cfg
  52. 32 0
      codaj12/cfg/outI440_qcif_inYUYV.cfg
  53. 32 0
      codaj12/cfg/outI440_qcif_inYVYU.cfg
  54. 32 0
      codaj12/cfg/outI444_3840_2160_inI444.cfg
  55. 32 0
      codaj12/cfg/outI444_4608_3456_inI444.cfg
  56. 32 0
      codaj12/cfg/outI444_cif_inNV24.cfg
  57. 32 0
      codaj12/cfg/outI444_cif_inNV24_tiled.cfg
  58. 32 0
      codaj12/cfg/outI444_qcif_inI444.cfg
  59. 32 0
      codaj12/cfg/outI444_qcif_inNV24.cfg
  60. 32 0
      codaj12/cfg/outI444_qcif_inNV42.cfg
  61. 32 0
      codaj12/cfg/outI444_qcif_inUYVY.cfg
  62. 32 0
      codaj12/cfg/outI444_qcif_inVYUY.cfg
  63. 32 0
      codaj12/cfg/outI444_qcif_inYUVP.cfg
  64. 32 0
      codaj12/cfg/outI444_qcif_inYUYV.cfg
  65. 32 0
      codaj12/cfg/outI444_qcif_inYVYU.cfg
  66. 34 0
      codaj12/cfg/outI444_vga_inI444_12b.cfg
  67. 8 0
      codaj12/cmd/jpg_dec_test_12b.cmd
  68. 6 0
      codaj12/cmd/jpg_dec_test_8b.cmd
  69. 5 0
      codaj12/cmd/jpg_enc_test_12b.cmd
  70. 42 0
      codaj12/cmd/jpg_enc_test_8b.cmd
  71. 27 0
      codaj12/config.h
  72. 123 0
      codaj12/jdi/jdi.h
  73. 49 0
      codaj12/jdi/linux/driver/Makefile
  74. 51 0
      codaj12/jdi/linux/driver/Makefile.usb
  75. 0 0
      codaj12/jdi/linux/driver/Module.symvers
  76. 4 0
      codaj12/jdi/linux/driver/build_env_setup_android.sh
  77. 8 0
      codaj12/jdi/linux/driver/build_env_setup_riscv.sh
  78. 109 0
      codaj12/jdi/linux/driver/driver.dsp
  79. 29 0
      codaj12/jdi/linux/driver/driver.dsw
  80. 646 0
      codaj12/jdi/linux/driver/jmm.h
  81. 1039 0
      codaj12/jdi/linux/driver/jpu.c
  82. 49 0
      codaj12/jdi/linux/driver/jpu.h
  83. 2 0
      codaj12/jdi/linux/driver/jpu.mod
  84. 26 0
      codaj12/jdi/linux/driver/load
  85. 25 0
      codaj12/jdi/linux/driver/load.sh
  86. 24 0
      codaj12/jdi/linux/driver/load_android.sh
  87. 14 0
      codaj12/jdi/linux/driver/unload
  88. 14 0
      codaj12/jdi/linux/driver/unload.sh
  89. 13 0
      codaj12/jdi/linux/driver/unload_android.sh
  90. 834 0
      codaj12/jdi/linux/jdi.c
  91. 660 0
      codaj12/jdi/mm.c
  92. 123 0
      codaj12/jdi/mm.h
  93. 853 0
      codaj12/jdi/nonos/jdi.c
  94. 39 0
      codaj12/jpuapi/Android.mk
  95. 1731 0
      codaj12/jpuapi/jpuapi.c
  96. 1426 0
      codaj12/jpuapi/jpuapi.h
  97. 2993 0
      codaj12/jpuapi/jpuapifunc.c
  98. 332 0
      codaj12/jpuapi/jpuapifunc.h
  99. 59 0
      codaj12/jpuapi/jpuconfig.h
  100. 258 0
      codaj12/jpuapi/jputable.h

+ 1 - 0
README.md

@@ -0,0 +1 @@
+This directory add for soft of 3rd party. such as: WAVE511, WAVE521, JPEG, VP6

+ 17 - 0
codaj12/Android.mk

@@ -0,0 +1,17 @@
+#
+# Copyright (C) 2009 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+	  include $(all-subdir-makefiles)
+

+ 169 - 0
codaj12/Makefile

@@ -0,0 +1,169 @@
+# ----------------------------------------------------------------------
+#
+# Project: C&M Video decoder sample
+#
+# ----------------------------------------------------------------------
+.PHONY: CREATE_DIR
+
+USE_PTHREAD = yes
+USE_RTL_SIM = no
+BUILD_CONFIGURATION = EmbeddedLinux
+MAKECMDGOALS ?=
+
+ifeq ($(RTL_SIM), 1)
+USE_RTL_SIM = yes
+endif
+
+PLATFORM = nativelinux_64bit
+
+CROSS_CC_PREFIX =
+JDI_C           = jdi/linux/jdi.c
+MM_C            =
+PLATFORM_FLAGS  =
+VPATH           = jdi/linux:
+USE_FFMPEG      = yes
+USE_ALLOCATOR   = no
+
+INCLUDES = -I./jpuapi -I./include -I./jdi -I./sample -I./sample/helper
+ifeq ("$(BUILD_CONFIGURATION)", "NonOS")
+    CROSS_CC_PREFIX = arm-none-eabi-
+    JDI_C           = jdi/nonos/jdi.c
+    USE_FFMPEG      = no
+    USE_PTHREAD     = no
+    PLATFORM        = none
+    DEFINES         = -DLIB_C_STUB
+    PLATFORM_FLAGS  =
+    VPATH           = jdi/nonos:
+    USE_FFMPEG      = no
+    USE_ALLOCATOR   = yes
+endif
+ifeq ("$(BUILD_CONFIGURATION)", "EmbeddedLinux")
+    CROSS_CC_PREFIX = riscv64-buildroot-linux-gnu-
+    PLATFORM        = riscvlinux
+    USE_FFMPEG      ?= yes
+endif
+
+CC  = $(CROSS_CC_PREFIX)gcc
+CXX = $(CROSS_CC_PREFIX)g++
+AR  = $(CROSS_CC_PREFIX)ar
+
+ifeq ($(USE_FFMPEG), yes)
+DEFINES += -DSUPPORT_FFMPEG
+INCLUDES += -I./ffmpeg/include
+LDLIBS  += -lavformat -lavcodec -lavutil -lz
+LDFLAGS += -L./ffmpeg/$(PLATFORM)
+LDFLAGS += -L./ffmpeg/lib
+endif
+
+ifeq ($(USE_RTL_SIM), yes)
+DEFINES += -DCNM_SIM_PLATFORM -DCNM_SIM_DPI_INTERFACE
+else
+endif
+
+CFLAGS  += -g -I. -Wno-implicit-function-declaration -Wno-int-to-pointer-cast -Wno-format -Wl,--fatal-warning $(INCLUDES) $(DEFINES) $(PLATFORM_FLAGS) -Wall -Werror
+ifeq ($(MAKECMDGOALS), multi)
+CFLAGS  +=  -DSUPPORT_MULTI_INSTANCE_TEST
+endif
+ifeq ($(USE_RTL_SIM), yes)
+ifeq ($(IUS), 1)
+#CFLAGS  += -m32 # ncverilog is 32bit version
+CFLAGS  += -fPIC # ncverilog is 64bit version
+endif
+USE_ALLOCATOR = yes
+endif
+ARFLAGS += cru
+ifeq ($(USE_PTHREAD), yes)
+LDLIBS  += -lpthread
+endif
+LDLIBS  += -lm
+
+OBJDIR=obj
+ALLOBJS=*.o
+ALLDEPS=*.dep
+ALLLIBS=*.a
+RM=rm -f
+MKDIR=mkdir -p
+
+ENC_SOURCES = $(JDI_C) jpuapi.c jpuapifunc.c jpuhelper.c jpulog.c cnm_fpga.c main_jpg_enc_test.c \
+              yuv_feeder.c platform.c datastructure.c bitstreamwriter.c
+DEC_SOURCES = $(JDI_C) jpuapi.c jpuapifunc.c jpuhelper.c jpulog.c cnm_fpga.c main_jpg_dec_test.c \
+              platform.c datastructure.c bitstreamfeeder.c bsfeeder_fixedsize_impl.c
+MUL_SOURCES = $(JDI_C) jpuapi.c jpuapifunc.c jpuhelper.c jpulog.c cnm_fpga.c main_multi_instance_test.c \
+              platform.c datastructure.c yuv_feeder.c
+MUL_SOURCES += bitstreamfeeder.c bsfeeder_fixedsize_impl.c main_jpg_dec_test.c
+MUL_SOURCES += bitstreamwriter.c main_jpg_enc_test.c
+
+ifeq ($(USE_RTL_SIM), yes)
+ENC_SOURCES += main_sim.c
+DEC_SOURCES += main_sim.c
+MUL_SOURCES += main_sim.c
+endif
+ifeq ($(USE_ALLOCATOR), yes)
+ENC_SOURCES += mm.c
+DEC_SOURCES += mm.c
+MUL_SOURCES += mm.c
+endif
+ifeq ($(USE_FFMPEG), yes)
+ENC_SOURCES += bswriter_container_impl.c
+DEC_SOURCES += bsfeeder_framesize_impl.c
+MUL_SOURCES += bsfeeder_framesize_impl.c
+MUL_SOURCES += bswriter_container_impl.c
+endif
+
+
+
+VPATH += jdi:
+VPATH += jdi/nonos:
+VPATH += jpuapi:
+VPATH += sample:sample/helper:
+
+
+DEC_OBJECTNAMES=$(patsubst %.c,%.o,$(DEC_SOURCES))
+DEC_OBJECTPATHS=$(addprefix $(OBJDIR)/,$(notdir $(DEC_OBJECTNAMES)))
+ENC_OBJECTNAMES=$(patsubst %.c,%.o,$(ENC_SOURCES))
+ENC_OBJECTPATHS=$(addprefix $(OBJDIR)/,$(notdir $(ENC_OBJECTNAMES)))
+MUL_OBJECTNAMES=$(patsubst %.c,%.o,$(MUL_SOURCES))
+MUL_OBJECTPATHS=$(addprefix $(OBJDIR)/,$(notdir $(MUL_OBJECTNAMES)))
+
+ifeq ($(MAKECMDGOALS), multi)
+	TARGET = multi
+else
+	TARGET = decoder
+	TARGET += encoder
+endif
+
+all: $(TARGET)
+
+
+encoder: CREATE_DIR $(ENC_OBJECTPATHS)
+ifeq ($(USE_RTL_SIM), yes)
+	# do not need to make excutable
+else
+	$(CC) -o jpg_enc_test $(LDFLAGS) -Wl,-gc-section -Wl,--start-group $(ENC_OBJECTPATHS) $(LDLIBS) -Wl,--end-group
+endif
+
+decoder: CREATE_DIR $(DEC_OBJECTPATHS)
+ifeq ($(USE_RTL_SIM), yes)
+	# do not need to make excutable
+else
+	$(CC) -o jpg_dec_test $(LDFLAGS) -Wl,-gc-section -Wl,--start-group $(DEC_OBJECTPATHS) $(LDLIBS) -Wl,--end-group
+endif
+
+multi: CREATE_DIR $(MUL_OBJECTPATHS)
+ifeq ($(USE_RTL_SIM), yes)
+	# do not need to make excutable
+else
+	$(CC) -o multi_instance_test $(LDFLAGS) -Wl,-gc-section -Wl,--start-group $(MUL_OBJECTPATHS) $(LDLIBS) -Wl,--end-group
+endif
+
+-include $(OBJECTPATHS:.o=.dep)
+
+clean:
+	$(RM) $(TARGET) jpg_enc_test jpg_dec_test multi_instance_test
+	$(RM) $(OBJDIR)/$(ALLOBJS)
+	$(RM) $(OBJDIR)/$(ALLDEPS)
+
+CREATE_DIR:
+	-mkdir -p $(OBJDIR)
+obj/%.o: %.c Makefile
+	$(CC) $(CFLAGS) -c $< -o $@ -MD -MF $(@:.o=.dep)

BIN
codaj12/Nieuport_JpgDec


BIN
codaj12/Nieuport_JpgEnc


File diff suppressed because it is too large
+ 15 - 0
codaj12/README.md


+ 546 - 0
codaj12/TestRunnerCodaJ12Dec.sh

@@ -0,0 +1,546 @@
+#!/bin/bash
+
+source TestRunnerCommon.sh
+
+# Global varaibles for decoder option
+fail_stop=0
+refc_exec="Nieuport_JpgDec"
+bin_dir="./"
+stream_dir="./stream"
+wiki_log_file="./log/dec_confluence.log"
+g_random_test="false";
+jenkins=""
+txt_param_switch=0
+output_path="output_fpga.yuv"
+default_yuv_fmt=""
+default_subsample="none"
+default_ordering="none"
+simulation="false"
+default_bssize=5242880      # 5MB
+MAX_BS_SIZE=10485760        # 10MB, You can allocate more memory.
+MIN_BS_SIZE=8192            # 8KB
+g_random_test="false"
+g_slice_height=0
+g_enable_slice_intr=0
+default_read_delay=
+default_write_delay=
+
+fmt_test_400_list=("none" "420p" "422p" "444p" "nv12" "nv21" "nv16" "nv61" "nv24" "nv42" "yuyv" "yvyu" "uyvy" "vyuy")
+fmt_test_420_list=("none" "420p" "422p" "444p" "nv12" "nv21" "nv16" "nv61" "nv24" "nv42" "yuyv" "yvyu" "uyvy" "vyuy")
+fmt_test_422_list=("none" "420p" "422p" "444p" "nv12" "nv21" "nv16" "nv61" "nv24" "nv42" "yuyv" "yvyu" "uyvy" "vyuy")
+fmt_test_440_list=("none" "420p" "422p" "444p" "nv12" "nv21" "nv16" "nv61" "nv16v" "nv61v" "nv24" "nv42" "yuyv" "yvyu" "uyvy" "vyuy")
+fmt_test_444_list=("none" "420p" "422p" "444p" "nv12" "nv21" "nv16" "nv61" "nv24" "nv42" "yuyv" "yvyu" "uyvy" "vyuy" "ayuv")
+
+fmt_test_400_num=${#fmt_test_400_list[@]}
+fmt_test_420_num=${#fmt_test_420_list[@]}
+fmt_test_422_num=${#fmt_test_422_list[@]}
+fmt_test_440_num=${#fmt_test_440_list[@]}
+fmt_test_444_num=${#fmt_test_444_list[@]}
+
+MAX_OUTPUT_FMT=$((${#SUPPORTED_YUV_FMT[@]} -1))
+
+function help {
+    echo ""
+    echo "-------------------------------------------------------------------------------"
+    echo "Chips&Media conformance Tool v2.0"
+    echo "All copyright reserved by Chips&Media"
+    echo "-------------------------------------------------------------------------------"
+    echo "$0 OPTION streamlist_file"
+    echo "-h                        help"
+    echo "-n num                    number of frames."
+    echo "--enable-random           generate random option."
+    echo "--bin-dir                 ref-c directory, default: ./"
+    echo "--stream-dir              stream directory"
+    echo "--12bit                   input stream is an extended sequential jpeg"
+    echo "--stream-endian           ENDIAN  bitstream endianness. refer to datasheet Chapter 4."
+    echo "--frame-endian            ENDIAN   pixel endianness of 16bit input source. refer to datasheet Chapter 4."
+    echo "--pixelj                  16bit-pixel justification. 0(default) - msb justified, 1 - lsb justified in little-endianness"
+    echo "--subsample               conversion sub-sample(ignore case: NONE, 420, 422, 444";
+    echo "--ordering                conversion ordering(ingore-case: NONE, NV12, NV21, YUYV, YVYU, UYVY, VYUY, AYUV";
+    echo "                          NONE - planar format";
+    echo "                          NV12, NV21 - semi-planar format for all the subsamples.";
+    echo "                                       If subsample isn't defined or is none, the sub-sample depends on jpeg information";
+    echo "                                       The subsample 440 can be converted to the semi-planar format. It means that the encoded sub-sample should be 440.";
+    echo "                          YUVV..VYUY - packed format. subsample be ignored.";
+    echo "                          AYUV       - 444 packed format. subsample be ignored.";
+    echo "--scaleH                  Horizontal downscale: 0(none), 1(1/2), 2(1/4), 3(1/8)";
+    echo "--scaleV                  Vertical downscale  : 0(none), 1(1/2), 2(1/4), 3(1/8)";
+    echo "--rotation                0, 90, 180, 270 CCW"
+    echo "--mirror                  0, 1(vertical), 2(horizontal), 3(both)"
+}
+
+function generate_parameters {
+    local val=0
+    local list
+
+    g_stream_endian=$(gen_val 0 3 $default_stream_endian)
+    if [ "$g_jpeg_12bit" == "true" ]; then
+        g_frame_endian=$(gen_val 0 7 $default_frame_endian)
+    else
+        g_frame_endian=$(gen_val 0 3 $default_frame_endian)
+    fi
+
+    # PPU AND SCALER
+    if [ "$g_random_test" == "true" ]; then
+        ppu_random=$(gen_val 0 1) # 0 - rotation/mirror, 1 - scaler
+        if [ "$ppu_random" == "0" ]; then
+            g_rotation=$(gen_val_angle $default_rotation)
+            g_mirror=$(gen_val 0 3 $default_mirror)
+            g_scale_h=0
+            g_scale_v=0
+        elif [ "$ppu_random" == "1" ]; then
+            g_rotation=0
+            g_mirror=0
+            g_scale_h=$(gen_val 0 3 $default_scaleH)
+            g_scale_v=$(gen_val 0 3 $default_scaleV)
+        fi
+    else
+        g_rotation=$(gen_val_angle $default_rotation)
+        g_mirror=$(gen_val 0 3 $default_mirror)
+        g_scale_h=$(gen_val 0 3 $default_scaleH)
+        g_scale_v=$(gen_val 0 3 $default_scaleV)
+        if [ "$g_rotation" != "0" ] || [ "$g_mirror" != "0" ]; then
+            if [ "$g_scale_h" != "0" ] || [ "$g_scale_h" != "0" ]; then
+                echo "The PPU(rotator and mirror) doesn't work with the down-scaler"
+                echo "rotation: $g_rotation, mirror: $mirror, scale-H: $g_scale_h, scale-V: $g_scale_v"
+                exit 1
+            fi
+        fi
+    fi
+
+    # SUBSAMPLE AND ORDERING
+    if [ "$g_random_test" == "true" ]; then
+        default_yuv_fmt="-99"
+    fi
+    if [ "$default_yuv_fmt" == "-99" ]; then
+        case $g_orig_fmt in
+        400) list=(${fmt_test_400_list[@]});;
+        420) list=(${fmt_test_420_list[@]});;
+        422) list=(${fmt_test_422_list[@]});;
+        440) list=(${fmt_test_440_list[@]});;
+        444) list=(${fmt_test_444_list[@]});;
+        esac
+        max_fmt_num=${#list[@]}
+        val=$(gen_val 0 $((max_fmt_num-1)))
+        output_format="${list[$val]}"
+        # generate subsample and ordering parameter for ref-sw
+        convert_fmt_val_for_refsw $output_format $g_orig_fmt
+    else
+        g_subsample="$default_subsample"
+        g_ordering="$default_ordering"
+    fi
+
+    if [ "$g_rotation" != "0" ] || [ "$g_mirror" != "0" ]; then
+        # color format converter and rotator cannot work together.
+        if [ "$g_subsample" != "none" ]; then
+            g_subsample="none"
+        fi
+        if [ "$g_ordering" != "nv12" ] && [ "$g_ordering" != "nv21" ]; then
+            g_ordering="none"
+        fi
+    fi
+
+    g_bs_size=$(gen_val $MIN_BS_SIZE $MAX_BS_SIZE $default_bssize)
+    g_bs_size=$((($g_bs_size + 4095) & ~4095))
+
+    g_pixel_just=$(gen_val 0 1 $default_pixelj)
+
+    # generate -pn -pk and -v options for c-model
+    convert_fmt_val_for_cmodel $g_subsample $g_orig_fmt $g_ordering
+}
+
+function build_test_param {
+    local param=""
+
+    param="$param --rotation=$g_rotation"
+    param="$param --mirror=$g_mirror"
+    param="$param --stream-endian=$g_stream_endian --frame-endian=$g_frame_endian"
+    param="$param --subsample=$g_subsample --ordering=$g_ordering"
+    param="$param --scaleH=$g_scale_h"
+    param="$param --scaleV=$g_scale_v"
+    param="$param --bs-size=$g_bs_size"
+    param="$param --pixelj=$g_pixel_just"
+    if [ "$simulation" == "true" ]; then
+        param="$param $g_fsdb_param --TestRunner=1"
+    fi
+
+    g_func_ret_str="$param"
+}
+
+function get_yuv_format {
+    local format=""
+    local cmd="${bin_dir}/${refc_exec} -i $1 -m 1"
+
+    if [ "$g_jpeg_12bit" == "true" ]; then
+        cmd="$cmd -u"
+    fi
+    $cmd > result.txt
+    while read line; do
+        line=$(echo $line | tr -d '\n')
+        line=$(echo $line | tr -d '\r')
+        line="${line%%\#*}"
+        attr=$(echo $line | cut -d':' -f1)
+        attr=$(echo $attr | tr -d ' ')
+        value=$(echo $line | cut -d':' -f2-)
+        value=$(echo $value | tr -d ' ')
+        value="${value//:/}"
+        if [ "$attr" == "OutputYUVformat" ]; then
+            format="$value"
+            break;
+        fi
+    done < result.txt
+
+    echo "$format"
+}
+
+################################################################################
+# Parse arguments                                                              #
+################################################################################
+OPTSTRING="-o hw: -l enable-random,stream-dir:,bin-dir:"
+OPTSTRING="${OPTSTRING},stream-endian:,frame-endian:"
+OPTSTRING="${OPTSTRING},slice-height:,enable-slice-intr:,subsample:,ordering:,output:,input:,bs-size:"
+OPTSTRING="${OPTSTRING},scaleH:,scaleV:,rotation:,mirror:"
+OPTSTRING="${OPTSTRING},12bit,pixelj:"
+
+OPTS=`getopt $OPTSTRING -- "$@"`
+
+if [ $? -ne 0 ]; then
+    exit 1
+fi
+
+eval set -- "$OPTS"
+
+while true; do
+    case "$1" in
+        -h)
+            help
+            exit 1
+            shift;;
+        --bin-dir)
+            bin_dir=$2
+            shift 2;;
+        --enable-random)
+            g_random_test="true"
+            shift;;
+        --stream-dir)
+            echo "stream-dir"
+            stream_dir=$2
+            shift 2;;
+        --stream-endian)
+            default_stream_endian=$2
+            shift 2;;
+        --frame-endian)
+            default_frame_endian="$2"
+            shift 2;;
+        --12bit)
+            g_jpeg_12bit="true"
+            shift;;
+        --pixelj)
+            default_pixelj="$2"
+            shift 2;;
+        --input)
+            streamset_path="$2"
+            shift 2;;
+        --output)
+            output_path="$2"
+            shift 2;;
+        --subsample)
+            default_subsample="$2"
+            shift 2;;
+        --ordering)
+            default_ordering="$2"
+            shift 2;;
+        --scaleH)
+            default_scaleH="$2"
+            shift 2;;
+        --scaleV)
+            default_scaleV="$2"
+            shift 2;;
+        --rotation)
+            default_rotation="$2"
+            shift 2;;
+        --mirror)
+            default_mirror="$2"
+            shift 2;;
+        --bs-size)
+            default_bssize="$2"
+            shift 2;;
+        --)
+            shift
+            break;;
+    esac
+done
+
+shift $(($OPTIND - 1))
+
+if [ "$simulation" == "true" ]; then
+    ACLK_MIN=160
+    ACLK_MAX=300
+    CCLK_MIN=160
+    CCLK_MAX=300
+    DEFAULT_ACLK=200
+    DEFAULT_CCLK=200
+    test_exec="./runit"
+else
+    DEFAULT_ACLK=20
+    DEFAULT_CCLK=20
+    test_exec="./jpg_dec_test"
+fi
+
+
+
+################################################################################
+# Get param from target text file                                              #
+################################################################################
+name_value=()
+input_param_name="TestRunnerParamCodaJ12Dec.txt"
+if [ -f $input_param_name ]; then
+    while read line; do
+        # remove right comment
+        line="${line%%\#*}"
+        if [ "$line" = "" ]; then continue; fi
+
+        OIFS=$IFS
+        IFS='='
+        count=0
+        for word in $line; do
+            word=${word// /}
+            name_value[$count]="$word"
+            count=$(($count+1))
+        done
+        IFS=$OIFS
+        attr="${name_value[0]}"
+        value="${name_value[1]}"
+
+        case "$attr" in
+            default)            default_opt="$value";;
+            aclk)               [ ! -z $default_aclk ]          || default_aclk="$value";;
+            cclk)               [ ! -z $default_cclk ]          || default_cclk="$value";;
+            n)                  g_frame_num="-n $value";;
+            fake_test)          fake_test="$value";;
+            stream-endian)      [ ! -z $default_stream_endian ] || default_stream_endian="$value";;
+            frame-endian)       [ ! -z $default_frame_endian ]  || default_frame_endian="$value";;
+            scaleH)             [ ! -z $default_scaleH ]        || default_scaleH="$value";;
+            scaleV)             [ ! -z $default_scaleV ]        || default_scaleV="$value";;
+            rotation)           [ ! -z $default_rotation ]      || default_rotation="$value";;
+            mirror)             [ ! -z $default_mirror ]        || default_mirror="$value";;
+            pixelj)             [ ! -z $default_pixelj ]        || default_pixelj="$value";;
+            slice-height)       [ ! -z $default_slice_height ]  || default_slice_height="$value";;
+            enable-slice-intr)  [ ! -z $default_slice_int ]     || default_slice_int="$value";;
+            txt-param)      txt_param_switch=1;;
+            *) ;;
+        esac
+    done < $input_param_name
+else
+    if [ ! -f $input_param_name ]; then
+        echo "$input_param_name file doesn't exist";
+    fi
+fi
+
+# SET DEFAULT VALUES
+if [ "$g_random_test" != "true" ]; then
+    [ ! -z $default_aclk ]          || default_aclk=$DEFAULT_ACLK
+    [ ! -z $default_cclk ]          || default_cclk=$DEFAULT_CCLK
+    [ ! -z $default_stream_endian ] || default_stream_endian=0
+    [ ! -z $default_frame_endian ]  || default_frame_endian=0
+    [ ! -z $default_scaleH ]        || default_scaleH=0
+    [ ! -z $default_scaleV ]        || default_scaleV=0
+    [ ! -z $default_rotation ]      || default_rotation=0
+    [ ! -z $default_mirror ]        || default_mirror=0
+    [ ! -z $default_slice_int ]     || default_slice_int=0
+    [ ! -z $default_slice_height ]  || default_slice_height=0
+    [ ! -z $default_pixelj ]        || default_pixelj=0
+else
+    default_slice_int=0
+    default_slice_height=0
+fi
+
+if [ -z $streamset_path ]; then
+    streamset_path=$1
+fi
+streamset_file=`basename ${streamset_path}`
+
+################################################################################
+# count stream number                                                          #
+################################################################################
+stream_file_array=()
+ext="${streamset_file##*.}"
+ext=$(tr '[:upper:]' '[:lower:]' <<< $ext)
+single_file="false"
+if [ "$ext" == "jpg" ] || [ "$ext" == "jpeg" ]; then
+    stream_file_array[0]="$streamset_path"
+    single_file="true"
+else
+    if [ ! -e "${streamset_path}" ]; then
+        echo "No such file: ${streamset_path}"
+        exit 1
+    fi
+    parse_streamset_file $streamset_path stream_file_array
+fi
+
+num_of_streams=${#stream_file_array[@]}
+
+count=1
+success_count=0
+failure_count=0
+remain_count=${num_of_streams}
+basedir=${basedir//\/}  # remove last delimeter
+
+mkdir -p temp
+mkdir -p output
+mkdir -p log/decoder_conformance
+conf_log_path="log/decoder_conformance/${streamset_file}.log"
+conf_err_log_path="log/decoder_conformance/${streamset_file}_error.log"
+temp_log_path="./temp/temp.log"
+# truncate contents of log file
+echo "" > $conf_log_path
+echo "" > $conf_err_log_path
+echo "" > $temp_log_path
+beginTime=$(date +%s%N)
+
+################################################################################
+# read cmd file.                                                               #
+################################################################################
+for (( c=0; c< $num_of_streams ; c++ )) do
+    line=${stream_file_array[$c]}
+    if [ "$single_file" == "true" ]; then
+        stream="${line}"
+    else
+        stream="${stream_dir}/${line}"
+    fi
+    log_conf "--------------------------------------------------------------------------------" ${temp_log_path}
+    log_conf "[${count}/${num_of_streams}] ${stream}" ${temp_log_path}
+    log_conf "--------------------------------------------------------------------------------" ${temp_log_path}
+
+    if [ ! -f $stream ]; then
+        log_conf "Not found $stream" $temp_log_path
+        log_conf "[RESULT] FAILURE" $temp_log_path
+        echo "Not found $stream" >> $conf_err_log_path
+        echo "[RESULT] FAILURE" >> $conf_err_log_path
+        cat $temp_log_path >> $conf_log_path
+        failure_count=$(($failure_count + 1))
+        remain_count=$(($remain_count - 1))
+        count=$(($count + 1))
+        continue
+    fi
+
+    result=0
+    target_stream=$stream
+
+################################################################################
+# make argc & argv parameter                                                   #
+################################################################################
+    if [ $result -eq 0 ]; then
+        g_orig_fmt=$(get_yuv_format $target_stream)
+        generate_parameters
+        build_test_param
+        test_param="$g_func_ret_str"
+
+################################################################################
+# Golden YUV                                                                   #
+################################################################################
+        golden_yuv_path="output_refc.yuv"
+        generate_golden_yuv $stream $golden_yuv_path
+        result=$?
+
+################################################################################
+# print information                                                            #
+################################################################################
+
+        if [ $result -eq 0 ]; then
+            log_conf "RANDOM TEST    : $g_random_test" $temp_log_path
+            log_conf "ENDIAN         : STREAM($g_stream_endian) FRAME($g_frame_endian)" $temp_log_path
+            log_conf "SUBSAMPLE      : $g_subsample" $temp_log_path
+            log_conf "ORDERING       : $g_ordering" $temp_log_path
+            log_conf "ROTATE         : $g_rotation" $temp_log_path
+            log_conf "MIRROR         : ${MIRROR_NAME[$g_mirror]}" $temp_log_path
+            log_conf "SCALE DOWN     : H: ${SCALEDOWN_NAME[$g_scale_h]} V: ${SCALEDOWN_NAME[$g_scale_v]}" $temp_log_path
+            log_conf "PIXEL_JUST.    : ${JUSTIFY_NAME[$g_pixel_just]}" $temp_log_path
+
+            rm -f output_fpga.yuv
+            cmd="$test_exec $test_param --output=$output_path --input=$target_stream"
+            cmd_log="$test_exec $test_param --output=$output_path --input=$stream"
+            log_conf "$cmd_log" $temp_log_path
+            cat $temp_log_path >> $conf_log_path
+
+            if [ "$fake_test" == "1" ]; then
+                echo "<< Testing just script >>"
+            else
+				exit
+                $cmd
+                result=$?
+                if [ "$result" == "0" ]; then
+                    cmp $output_path output_refc.yuv
+                    if [ "$?" != "0" ]; then
+                        result=1
+                    fi
+                fi
+            fi
+        fi
+    else
+        cat $temp_log_path >> $conf_log_path
+    fi
+
+    if [ $result -eq 0 ]; then
+        log_conf "[RESULT] SUCCESS" $conf_log_path
+        success_count=$(($success_count + 1))
+    else
+        cat ./ErrorLog.txt >> $conf_log_path
+        log_conf "[RESULT] FAILURE" $conf_log_path
+        failure_count=$(($failure_count + 1))
+        cat $temp_log_path >> $conf_err_log_path
+        cat ./ErrorLog.txt >> $conf_err_log_path
+        echo "cmp $stream $target_stream"
+        cmp $stream $target_stream
+        echo "[RESULT] FAILURE" >> $conf_err_log_path
+        if [ $result -eq 10 ]; then
+            echo "Abnormal exit!!!"
+            break
+        fi
+    fi
+    remain_count=$(($remain_count - 1))
+    count=$(($count + 1))
+    # clear temp log
+    echo "" > $temp_log_path
+    # delete temporal input file
+    if [ $fail_stop -eq 1 ] && [ $result -ne 0 ]; then
+        break;
+    fi
+done
+
+endTime=$(date +%s%N)
+elapsed=$((($endTime - $beginTime) / 1000000000))
+elapsedH=$(($elapsed / 3600))
+elapsedS=$(($elapsed % 60))
+elapsedM=$(((($elapsed - $elapsedS) / 60) % 60))
+if [ "$((elapsedS / 10))" == "0" ]; then elapsedS="0${elapsedS}" ;fi
+if [ "$((elapsedM / 10))" == "0" ]; then elapsedM="0${elapsedM}" ;fi
+if [ "$((elapsedH / 10))" == "0" ]; then elapsedH="0${elapsedH}" ;fi
+
+if [ $elapsed -le 60 ]; then
+    time_hms="{color:red}*${elapsedH}:${elapsedM}:${elapsedS}*{color}"
+else
+    time_hms="${elapsedH}:${elapsedM}:${elapsedS}"
+fi
+
+log_filename=$(basename $conf_log_path)
+log_err_filename=$(basename $conf_err_log_path)
+if [ $failure_count == 0 ] && [ $num_of_streams != 0 ]; then
+    pass=${PASS}
+    rm $conf_err_log_path
+    log_err_filename=""
+else
+    pass=${FAIL}
+fi
+
+wiki_log="| $streamset_file | $num_of_streams | $success_count | $failure_count | $remain_count | $log_filename | ${log_err_filename} | $pass | $time_hms | | | |"
+
+echo $wiki_log
+echo $wiki_log >> $wiki_log_file
+
+if [ "$num_of_streams" == "0" ]; then
+    echo "num_of_streams: $num_of_streams = exit 1"
+    exit 1
+fi
+
+exit $failure_count

+ 459 - 0
codaj12/TestRunnerCodaJ12Enc.sh

@@ -0,0 +1,459 @@
+#!/bin/bash
+
+source TestRunnerCommon.sh
+
+# Global varaibles for encoder options
+wiki_log_file="./log/enc_confluence.log"
+jenkins=""
+txt_param_switch=0
+output_path="output_fpga.jpg"
+DEFAULT_BS_SIZE=5242880    # 5MB
+MIN_BS_SIZE=8192           # 8KB
+default_read_delay=
+default_write_delay=
+
+g_random_test=0
+simulation="false"
+
+yuv_dir="./yuv"
+bin_dir="./"
+cfg_dir="./cfg"
+g_aclk=$DEFAULT_ACLK
+g_cclk=$DEFAULT_CCLK
+refc_exec="Nieuport_JpgEnc"
+tiled_exec="./tiled_mode"
+
+
+################################################################################
+# Initialize parameter variables                                               #
+################################################################################
+
+function help {
+    echo ""
+    echo "-------------------------------------------------------------------------------"
+    echo "Chips&Media conformance Tool v2.0"
+    echo "All copyright reserved by Chips&Media"
+    echo "-------------------------------------------------------------------------------"
+    echo "$0 OPTION streamlist_file"
+    echo "-h                        help"
+    echo "--enable-random           It generates random parameters"
+    echo "--bin-dir                 ref-c directory, default: ./"
+    echo "--cfg-dir                 base directory of encoder configuration files. default: ./cfg"
+    echo "--yuv-dir                 base directory storing YUV. default: ./yuv"
+    echo "--stream-endian           ENDIAN  bitstream endianness. refer to datasheet Chapter 4."
+    echo "--frame-endian            ENDIAN   pixel endianness of 16bit input source. refer to datasheet Chapter 4."
+    echo "--slice-height            the vertical hieght of a slice. multiple of 16 for 420, multiple of 8 for others"
+    echo "--enable-slice-intr=ONOFF enable get the interrupt at every slice encoded. ONOFF - 0 for disable, 1 for enable. default OFF"
+    echo "--bs-size                 itstream buffer size in byte"
+    echo "--output                  output path"
+    echo "--input                   input path"
+    echo "--rotation=angle          0, 90, 180, 270"
+    echo "--mirror=value            0, 1(Vertical), 2(Horizontal), 3(both)"
+}
+
+function generate_parameters {
+    local cfg=$1
+
+    g_stream_endian=$(gen_val 0 3 $default_stream_endian)
+    if [ "$jpeg_12bit" == "1" ]; then
+        g_frame_endian=$(gen_val 0 7 $default_frame_endian)
+    else
+        g_frame_endian=$(gen_val 0 3 $default_frame_endian)
+    fi
+
+    g_pixel_just=$(gen_val 0 1 $default_pixelj)
+    g_rotation=$(gen_val_angle $default_rotation)
+    g_mirror=$(gen_val 0 3 $default_mirror)
+
+    if [ "$g_random_test" == "1" ]; then
+        slice_random=$(gen_val 0 1) # 0: disable slice done, 1: enable slice_done
+    else
+        slice_random=0
+    fi
+    if [ "$slice_random" == "1" ] || [ "$default_slice_height" != "0" ]; then
+        read_cfg $cfg
+        if [ "$g_rotation" == "90" ] || [ "$g_rotation" == "270" ]; then
+            local temp=$cfg_width
+            cfg_width=$cfg_height
+            cfg_height=$temp
+            if [ "$cfg_img_format" == "2" ]; then
+                # 422 to 440
+                cfg_img_format=3
+            elif [ "$cfg_img_format" == "3" ]; then
+                # 440 to 422
+                cfg_img_format=2
+            fi
+        fi
+        if [ "$g_rotation" != "0" ] || [ "$g_mirror" != "0" ]; then
+            # disable the slice-encoding mode
+            g_slice_height=0
+            g_enable_slice_intr=0
+        else
+            g_slice_height=$(gen_valid_slice_height $cfg_width $cfg_height $cfg_img_format $default_slice_height)
+            if [ "$g_slice_height" != "0" ]; then
+                g_enable_slice_intr=$(gen_val 0 1 $default_slice_int)
+            else
+                g_enable_slice_intr=0
+            fi
+        fi
+    else
+        g_slice_height=0
+        g_enable_slice_intr=0
+    fi
+
+    g_bs_size=$(gen_val $MIN_BS_SIZE $DEFAULT_BS_SIZE $default_bs_size)
+    g_bs_size=$((($g_bs_size + 4095) & ~4095))
+
+    g_tiled_mode=$default_tiled_mode
+}
+
+function build_test_param {
+    local param=""
+
+    if [ "$jpeg_12bit" == "1" ]; then
+        param="$param --12bit"
+    fi
+    param="$param --stream-endian=$g_stream_endian --frame-endian=$g_frame_endian"
+    param="$param --pixelj=$g_pixel_just"
+    param="$param --slice-height=$g_slice_height"
+    param="$param --enable-slice-intr=$g_enable_slice_intr"
+    param="$param --enable-tiledMode=$g_tiled_mode"
+    param="$param --bs-size=$g_bs_size"
+    param="$param --rotation=$g_rotation"
+    param="$param --mirror=$g_mirror"
+    g_func_ret_str="$param"
+}
+
+################################################################################
+# Parse arguments                                                              #
+################################################################################
+OPTSTRING="-o hw: -l enable-random,bin-dir:,cfg-dir:,yuv-dir:"
+OPTSTRING="${OPTSTRING},stream-endian:,frame-endian:"
+OPTSTRING="${OPTSTRING},slice-height:,enable-slice-intr:,bs-size:,output:,input:"
+OPTSTRING="${OPTSTRING},enable-tiledMode:"
+OPTSTRING="${OPTSTRING},12bit,pixelj:"
+OPTSTRING="${OPTSTRING},rotation:,mirror:"
+
+OPTS=`getopt $OPTSTRING -- "$@"`
+
+if [ $? -ne 0 ]; then
+    exit 1
+fi
+
+eval set -- "$OPTS"
+
+while true; do
+    case "$1" in
+        -h)
+            help
+            exit 1
+            shift;;
+        --bin-dir)
+            bin_dir_user=$2
+            shift 2;;
+        --enable-random)
+            g_random_test=1
+            shift;;
+        --cfg-dir)
+            cfg_dir_user=$2
+            shift 2;;
+        --yuv-dir)
+            yuv_dir_user=$2
+            shift 2;;
+        --12bit)
+            jpeg_12bit=1
+            shift;;
+        --pixelj)
+            default_pixelj="$2"
+            shift 2;;
+        --enable-tiledMode)
+            g_tiled_mode=$2
+            shift 2;;
+        --stream-endian)
+            default_stream_endian="$2"
+            shift 2;;
+        --frame-endian)
+            default_frame_endian="$2"
+            shift 2;;
+        --slice-height)
+            default_slice_height="$2"
+            shift 2;;
+        --enable-slice-intr)
+            default_slice_int="$2"
+            shift 2;;
+        --rotation)
+            default_rotation="$2"
+            shift 2;;
+        --mirror)
+            default_mirror="$2"
+            shift 2;;
+        --bs-size)
+            default_bs_size="$2"
+            shift 2;;
+        --output)
+            output_path="$2"
+            shift 2;;
+        --input)
+            streamset_path="$2"
+            shift 2;;
+        --)
+            shift
+            break;;
+    esac
+done
+
+shift $(($OPTIND - 1))
+
+if [ "$simulation" == "true" ]; then
+    ACLK_MIN=160
+    ACLK_MAX=300
+    CCLK_MIN=160
+    CCLK_MAX=300
+    DEFAULT_ACLK=200
+    DEFAULT_CCLK=200
+    test_exec="./runit"
+else
+    DEFAULT_ACLK=20
+    DEFAULT_CCLK=20
+    test_exec="./jpg_enc_test"
+fi
+
+if [ ! -f ./$test_exec ] ; then
+    echo " $test_exec file doesn't exist";
+    exit 1
+fi
+
+if [ ! -z $yuv_dir_user ]; then
+    yuv_dir="$yuv_dir_user"
+fi
+if [ ! -z $cfg_dir_user ]; then
+    cfg_dir="$cfg_dir_user"
+fi
+if [ ! -z $bin_dir_user ]; then
+    bin_dir="$bin_dir_user"
+fi
+
+
+
+# SET DEFAULT VALUES
+if [ "$g_random_test" != "1" ]; then
+    [ ! -z $default_aclk ]          || default_aclk=$DEFAULT_ACLK
+    [ ! -z $default_cclk ]          || default_cclk=$DEFAULT_CCLK
+    [ ! -z $default_stream_endian ] || default_stream_endian=0
+    [ ! -z $default_frame_endian ]  || default_frame_endian=0
+    [ ! -z $default_pixelj ]        || default_pixelj=0
+    [ ! -z $default_rotation ]      || default_rotation=0
+    [ ! -z $default_mirror ]        || default_mirror=0
+    [ ! -z $default_slice_int ]     || default_slice_int=0
+    [ ! -z $default_slice_height ]  || default_slice_height=0
+    [ ! -z $default_bs_size ]       || default_bs_size=$DEFAULT_BS_SIZE
+    [ ! -z $default_tiled_mode ]    || default_tiled_mode=0
+else
+    # tiled option is not random value. It depends on a cfg name.
+    default_tiled_mode=0
+fi
+
+if [ -z $streamset_path ]; then
+    streamset_path=$1
+fi
+streamset_file=`basename ${streamset_path}`
+
+################################################################################
+# count stream number                                                          #
+################################################################################
+cfg_file_array=()
+ext="${streamset_file##*.}"
+if [ "$ext" == "cfg" ]; then
+    cfg_file_array[0]="$streamset_path"
+else
+    if [ ! -e "${streamset_path}" ]; then
+        echo "No such file: ${streamset_path}"
+        exit 1
+    fi
+    parse_streamset_file $streamset_path cfg_file_array
+fi
+
+num_of_cfgs=${#cfg_file_array[@]}
+
+count=1
+success_count=0
+failure_count=0
+remain_count=${num_of_cfgs}
+basedir=${basedir//\/}  # remove last delimeter
+
+################################################################################
+# make log info
+################################################################################
+mkdir -p temp
+mkdir -p output
+mkdir -p log/encoder_conformance
+conf_log_path="log/encoder_conformance/${streamset_file}.log"
+conf_err_log_path="log/encoder_conformance/${streamset_file}_error.log"
+temp_log_path="./temp/temp.log"
+# truncate contents of log file
+echo "" > $conf_log_path
+echo "" > $conf_err_log_path
+echo "" > $temp_log_path
+beginTime=$(date +%s%N)
+
+################################################################################
+# read cmd file.                                                               #
+################################################################################
+for (( c=0; c< $num_of_cfgs ; c++ )) do
+    line=${cfg_file_array[$c]}
+    cfg="${line}"
+    cfg_path="${cfg_dir}/${line}"
+    log_conf "--------------------------------------------------------------------------------" ${temp_log_path}
+    log_conf "[${count}/${num_of_cfgs}] ${cfg_path}" ${temp_log_path}
+    log_conf "--------------------------------------------------------------------------------" ${temp_log_path}
+
+    if [ ! -f $cfg_path ]; then
+        log_conf "Not found $cfg_path" $conf_log_path
+        log_conf "[RESULT] FAILURE" $conf_log_path
+        echo "Not found $stream" >> $conf_err_log_path
+        echo "[RESULT] FAILURE" >> $conf_err_log_path
+        cat $temp_log_path >> $conf_log_path
+        failure_count=$(($failure_count + 1))
+        remain_count=$(($remain_count - 1))
+        count=$(($count + 1))
+        continue
+    fi
+
+    ################################################################################
+    # read from cfg file name                                                      #
+    ################################################################################
+    if [[ $cfg == *"12b"* ]]; then
+        echo "set jpeg_12bit from cfg file name"
+        jpeg_12bit=1
+    fi
+    if [[ $cfg == *"tiled"* ]]; then
+        echo "set g_tiled_mode from cfg file name"
+        default_tiled_mode=1
+    fi
+
+    result=0
+################################################################################
+# make argc & argv parameter                                                   #
+################################################################################
+    if [ $result -eq 0 ]; then
+        generate_parameters $cfg_path
+        build_test_param
+        test_param="$g_func_ret_str"
+
+################################################################################
+# Golden Data                                                                  #
+################################################################################
+        golden_path="output_refc.jpg"
+        generate_golden_stream $line $golden_path
+        result=$?
+
+################################################################################
+# print information                                                            #
+################################################################################
+        if [ $result -eq 0 ]; then
+            log_conf "--------------------------------------------------------------------------------" ${temp_log_path}
+            log_conf "RANDOM TEST    : ${ON_OFF[$g_random_test]}" $temp_log_path
+            log_conf "ENDIAN         : STREAM($g_stream_endian) FRAME($g_frame_endian)" $temp_log_path
+            log_conf "STANDARD       : JPEG" $temp_log_path
+            log_conf "PIXEL JUST.    : ${JUSTIFY_NAME[$g_pixel_just]}" $temp_log_path
+            log_conf "TILED MODE     : ${ON_OFF[$g_tiled_mode]}" $temp_log_path
+            log_conf "WIDTH          : $cfg_width" $temp_log_path
+            log_conf "HEIGHT         : $cfg_height" $temp_log_path
+            log_conf "SLICE_HEIGHT   : $g_slice_height" $temp_log_path
+            log_conf "EN_SLICE_INTR  : $g_enable_slice_intr" $temp_log_path
+            log_conf "BS SIZE        : $g_bs_size" $temp_log_path
+            log_conf "--------------------------------------------------------------------------------" ${temp_log_path}
+            if [ -e $output_path ]; then
+                rm -f $output_path
+            fi
+            cmd="$test_exec --output=$output_path --cfg-dir=$cfg_dir --yuv-dir=$yuv_dir $test_param --input=$cfg"
+            if [ "$simulation" == "true" ]; then
+                cmd="$cmd $g_w_param $g_fsdb_param --TestRunner=1"
+            fi
+            log_conf "$cmd" $temp_log_path
+            cat $temp_log_path >> $conf_log_path
+
+            if [ "$simulation" == "true" ]; then
+                $cmd 2>&1 | tee -a $conf_log_path
+            else
+				exit
+                $cmd
+            fi
+            log_conf "---------------- COMPARE ------------------" $conf_log_path
+            log_conf "cmp $output_path output_refc.jpg" $conf_log_path
+            if [ "$simulation" == "true" ]; then
+                # For log messages.
+                cmp $output_path output_refc.jpg 2>&1 | tee -a $conf_log_path > /dev/null #save the log
+            fi
+            cmp $output_path output_refc.jpg                                          #get the result & show log
+            if [ "$?" != "0" ]; then
+                log_conf "------- COMPARE FAIL--------------" $conf_log_path
+                result=1
+            else
+                log_conf "------- COMPARE SUCCESS-----------" $conf_log_path
+            fi
+        fi
+    else
+        cat $temp_log_path >> $conf_log_path
+    fi
+
+    if [ $result -eq 0 ]; then
+        log_conf "[RESULT] SUCCESS" $conf_log_path
+        success_count=$(($success_count + 1))
+    else
+        cat ./ErrorLog.txt >> $conf_log_path
+        log_conf "[RESULT] FAILURE" $conf_log_path
+        failure_count=$(($failure_count + 1))
+        cat $temp_log_path >> $conf_err_log_path
+        cat ./ErrorLog.txt >> $conf_err_log_path
+        echo "[RESULT] FAILURE" >> $conf_err_log_path
+        if [ $result -eq 10 ]; then
+            echo "Abnormal exit!!!"
+            break
+        fi
+    fi
+    remain_count=$(($remain_count - 1))
+    count=$(($count + 1))
+    # clear temp log
+    echo "" > $temp_log_path
+done
+
+################################################################################
+# Create Test Log                                                              #
+################################################################################
+endTime=$(date +%s%N)
+elapsed=$((($endTime - $beginTime) / 1000000000))
+elapsedH=$(($elapsed / 3600))
+elapsedS=$(($elapsed % 60))
+elapsedM=$(((($elapsed - $elapsedS) / 60) % 60))
+if [ "$((elapsedS / 10))" == "0" ]; then elapsedS="0${elapsedS}" ;fi
+if [ "$((elapsedM / 10))" == "0" ]; then elapsedM="0${elapsedM}" ;fi
+if [ "$((elapsedH / 10))" == "0" ]; then elapsedH="0${elapsedH}" ;fi
+
+if [ $elapsed -le 60 ]; then
+    time_hms="{color:red}*${elapsedH}:${elapsedM}:${elapsedS}*{color}"
+else
+    time_hms="${elapsedH}:${elapsedM}:${elapsedS}"
+fi
+
+log_filename=$(basename $conf_log_path)
+log_err_filename=$(basename $conf_err_log_path)
+if [ "$failure_count" == "0" ] && [ $num_of_cfgs != 0 ]; then
+    pass=${PASS}
+    rm $conf_err_log_path
+    log_err_filename=""
+else
+    pass=${FAIL}
+fi
+
+wiki_log="| $streamset_file | $num_of_cfgs | $success_count | $failure_count | $remain_count | $log_filename | ${log_err_filename} | $pass | $time_hms | | | |"
+
+echo $wiki_log
+echo $wiki_log >> $wiki_log_file
+
+if [ "$num_of_cfgs" == "0" ]; then
+    echo "num_of_cfgs: $num_of_cfgs = exit 1"
+    exit 1
+fi
+
+exit $failure_count

+ 556 - 0
codaj12/TestRunnerCodaJ12Multi.sh

@@ -0,0 +1,556 @@
+#!/bin/bash
+
+source TestRunnerCommon.sh
+
+# Global varaibles for encoder options
+
+enable_sync=0
+wiki_log_file="./log/confluence.log"
+instance_num=0
+
+DEFAULT_BS_SIZE=5242880    # 5MB
+MIN_BS_SIZE=8192           # 8KB
+
+simulation="false"
+
+################################################################################
+# Initialize parameter variables                                               #
+################################################################################
+
+function help {
+    echo ""
+    echo "-------------------------------------------------------------------------------"
+    echo "Chips&Media conformance Tool v2.0"
+    echo "All copyright reserved by Chips&Media"
+    echo "-------------------------------------------------------------------------------"
+    echo "$0 OPTION --input=cfg1,cfg2,... --instance-num=n"
+    echo "-h                        help"
+    echo "--enable-random           It generates random parameters"
+    echo "--bin-dir                 ref-c directory, default: ../../../design/ref_c/bin/Linux"
+    echo "--cfg-dir                 base directory of encoder configuration files. default: ../../../fpga/board/jpgcfg_v20"
+    echo "--yuv-dir                 base directory storing YUV. default: ./yuv"
+    echo "--enable-tiledMode        enable tiled mode"
+    echo "--stream-endian           ENDIAN  bitstream endianness. refer to datasheet Chapter 4."
+    echo "--frame-endian            ENDIAN   pixel endianness of 16bit input source. refer to datasheet Chapter 4."
+    echo "--slice-height            the vertical height of a slice. multiple of 16 for 420, multiple of 8 for others"
+    echo "--enable-slice-intr       enable get the interrupt at every slice encoded"
+    echo "--pixelj                  16bit-pixel justification. 0(default) - msb justified, 1 - lsb justified in little-endianness"
+    echo "--bs-size                 bitstream buffer size in byte"
+    echo "--instance-num            The number of instances"
+}
+
+function generate_parameters {
+    local input_file=$1
+    local is_encoder=$2
+    local ext="${input_file##%.}"
+
+    if [ "$is_encoder" == "true" ]; then
+        read_cfg $input_file
+    else
+        get_jpeg_info $input_file $jpeg_12bit
+    fi
+
+    if [ "$g_random_test" == "1" ] || [ "$txt_param_switch" == "1" ]; then
+        g_stream_endian=$(gen_val 0 3 $stream_endian_temp)
+        if [ "$jpeg_12bit" == "1" ]; then
+            g_frame_endian=$(gen_val 0 7 $frame_endian_temp)
+        else
+            g_frame_endian=$(gen_val 0 3 $frame_endian_temp)
+        fi
+        slice_random=$(gen_val 0 1) # 0: disable slice done, 1: enable slice_done
+        if [ "$slice_random" == "1" ] || [ "$slice_height_temp" != "0" ]; then
+            if [ "$is_encoder" == "true" ]; then
+                g_slice_height=$(gen_valid_slice_height $cfg_width $cfg_height $cfg_img_format $slice_height_temp)
+            else
+                pic_height_in_8=$(($jpg_height/8))
+                if [ -z $slice_height_temp ]; then
+                    g_slice_height=$(gen_val 0 $pic_height_in_8 $slice_height_temp)
+                    g_slice_height=$(($g_slice_height * 8))
+                else
+                    g_slice_height=$slice_height_temp
+                fi
+            fi
+            if [ "$g_slice_height" != "0" ]; then
+                g_enable_slice_intr=$(gen_val 0 1 $g_enable_slice_intr_temp)
+            else
+                g_enable_slice_intr=0
+            fi
+        else
+            g_slice_height=0
+            g_enable_slice_intr=0
+        fi
+
+        g_pixel_just=$(gen_val 0 1 $pixel_just_temp)
+        g_bs_size=$(gen_val $MIN_BS_SIZE $DEFAULT_BS_SIZE $bs_size_temp)
+        g_bs_size=$((($g_bs_size + 4095) & ~4095))
+        g_tiled_mode=$(gen_val 0 0 $g_tiled_mode_temp)
+    else
+        g_stream_endian=$(gen_val 0 0 $stream_endian_temp)
+        g_frame_endian=$(gen_val 0 0 $frame_endian_temp)
+        if [ "$is_encoder" == "true" ]; then
+            g_slice_height=$(gen_valid_slice_height $cfg_width $cfg_height $cfg_img_format $slice_height_temp)
+        else
+            pic_height_in_8=$(($jpg_height/8))
+            if [ -z $slice_height_temp ]; then
+                g_slice_height=$(gen_val 0 $pic_height_in_8 $slice_height_temp)
+                g_slice_height=$(($g_slice_height * 8))
+            else
+                g_slice_height=$slice_height_temp
+            fi
+        fi
+        g_enable_slice_intr=$(gen_val 0 0 $g_enable_slice_intr_temp)
+        g_pixel_just=$(gen_val 0 0 $pixel_just_temp)
+        g_bs_size=$(gen_val $DEFAULT_BS_SIZE $DEFAULT_BS_SIZE $bs_size_temp)
+        g_bs_size=$((($g_bs_size + 4095) & ~4095))
+        g_tiled_mode=$(gen_val 0 0 $g_tiled_mode_temp)
+    fi
+}
+
+################################################################################
+# Parse arguments                                                              #
+################################################################################
+OPTSTRING="-o e:hw: -l input:"
+OPTSTRING="${OPTSTRING},enable-random,bin-dir:,cfg-dir:,yuv-dir:"
+OPTSTRING="${OPTSTRING},instance-num:,12bit:"
+OPTSTRING="${OPTSTRING},stream-endian:,frame-endian:,output:"
+OPTSTRING="${OPTSTRING},slice-height:,enable-slice-intr:,pixelj:,bs-size:,enable-tiledMode:"
+
+OPTS=`getopt $OPTSTRING -- "$@"`
+
+if [ $? -ne 0 ]; then
+    exit 1
+fi
+
+eval set -- "$OPTS"
+
+while true; do
+    case "$1" in
+        -h)
+            help
+            exit 1
+            shift;;
+        -e)
+            in_comp_param="$2"
+            shift 2;;
+        --bin-dir)
+            bin_dir_user=$2
+            shift 2;;
+        --enable-random)
+            g_random_test=1
+            shift;;
+        --cfg-dir)
+            cfg_dir_user=$2
+            shift 2;;
+        --input)
+            input_param=$2
+            shift 2;;
+        --yuv-dir)
+            yuv_dir_user=$2
+            shift 2;;
+            #shift 2;;
+        --instance-num)
+            instance_num="$2"
+            shift 2;;
+        --12bit)
+            jpeg_12bit_multi=$2
+            shift 2;;
+        --enable-tiledMode)
+            g_tiled_mode_multi=$2
+            shift 2;;
+        --stream-endian)
+            stream_endian_multi="$2"
+            shift 2;;
+        --frame-endian)
+            frame_endian_multi="$2"
+            shift 2;;
+        --slice-height)
+            slice_height_multi="$2"
+            shift 2;;
+        --enable-slice-intr)
+            g_enable_slice_intr_multi="$2"
+            shift 2;;
+        --pixelj)
+            pixel_just_multi="$2"
+            shift 2;;
+        --bs-size)
+            bs_size_multi="$2"
+            shift 2;;
+        --output)
+            output_multi="$2"
+            shift 2;;
+        --)
+            shift
+            break;;
+    esac
+done
+
+shift $(($OPTIND - 1))
+
+yuv_dir="./yuv"
+#bin_dir="../../../design/ref_c/bin/Linux"
+bin_dir="./"
+#cfg_dir="../../../fpga/board/jpgcfg_v20"
+cfg_dir="./cfg"
+if [ "$simulation" == "true" ]; then
+    ACLK_MIN=160
+    ACLK_MAX=300
+    CCLK_MIN=160
+    CCLK_MAX=300
+    DEFAULT_ACLK=200
+    DEFAULT_CCLK=200
+    test_exec="./runit"
+    g_random_test=0
+else
+    DEFAULT_ACLK=20
+    DEFAULT_CCLK=20
+    test_exec="./multi_instance_test"
+fi
+if [ -z $aclk_freq_temp ]; then
+    g_aclk=$DEFAULT_ACLK
+else
+    g_aclk=$aclk_freq_temp
+fi
+if [ -z $cclk_freq_temp ]; then
+    g_cclk=$DEFAULT_CCLK
+else
+    g_cclk=$cclk_freq_temp
+fi
+if [ ! -z $yuv_dir_user ]; then
+    yuv_dir="$yuv_dir_user"
+fi
+if [ ! -z $cfg_dir_user ]; then
+    cfg_dir="$cfg_dir_user"
+fi
+if [ ! -z $bin_dir_user ]; then
+    bin_dir="$bin_dir_user"
+fi
+tiled_exec="./tiled_mode"
+
+if [ ! -f ./$test_exec ] ; then
+    echo " $test_exec file doesn't exist";
+    exit 1
+fi
+
+################################################################################
+# make log info
+################################################################################
+mkdir -p temp
+mkdir -p output
+mkdir -p log/multi_conformance
+if [ $simulation == "true" ]; then
+    conf_log_path="simv.log"
+    conf_err_log_path="simv_error.log"
+else
+    conf_log_path="log/multi_conformance/${streamset_file}.log"
+    conf_err_log_path="log/multi_conformance/${streamset_file}_error.log"
+fi
+temp_log_path="./temp/temp.log"
+echo "" > $conf_log_path
+echo "" > $conf_err_log_path
+echo "" > $temp_log_path
+beginTime=$(date +%s%N)
+
+output=()
+golden=()
+
+################################################################################
+# Add test param                                                               #
+# Options of the each instance are seperated by ","                            #
+################################################################################
+test_param=""
+comp_param=""
+for ((i=0;i<$instance_num;i++)); do
+    #######################
+    # separate parameters #
+    #######################
+    g_tiled_mode_temp=0
+    jpeg_12bit=0
+    if [ -n "$input_param" ]; then
+        filename=$(echo ${input_param} | cut -d',' -f$(($i+1)))
+        ext=${filename##*.}
+        ext=$(tr '[:upper:]' '[:lower:]' <<< $ext)
+        if [ "$ext" == "cfg" ]; then
+            is_encoder="true"
+            input_path=${cfg_dir}/${filename}
+            refc_exec="Nieuport_JpgEnc"
+            output[$i]="instance_${i}_output.jpg"
+            golden[$i]="output_refc_${i}.jpg"
+        else
+            is_encoder="false"
+            input_path="$filename"
+            refc_exec="Nieuport_JpgDec"
+            output[$i]="instance_${i}_output.yuv"
+            golden[$i]="output_refc_${i}.yuv"
+        fi
+        rm -f ${output[$i]}
+        rm -f ${golden[$i]}
+        stream[$i]=$filename
+
+        if [ "$comp_param" != "" ]; then
+            comp_param="${comp_param},"
+        fi
+        if [ "$is_encoder" == "true" ]; then
+            comp_param="${comp_param}0"
+        else
+            comp_param="${comp_param}1"
+        fi
+    fi
+    if [ -n "$output_multi" ]; then
+        output[$i]=$(echo ${output_multi} | cut -d',' -f$(($i+1)))
+    fi
+    if [ -n "$stream_endian_multi" ]; then
+        stream_endian_temp=$(echo ${stream_endian_multi} | cut -d',' -f$(($i+1)))
+    fi
+    if [ -n "$frame_endian_multi" ]; then
+        frame_endian_temp=$(echo ${frame_endian_multi} | cut -d',' -f$(($i+1)))
+    fi
+    if [ -n "$slice_height_multi" ]; then
+        slice_height_temp=$(echo ${slice_height_multi} | cut -d',' -f$(($i+1)))
+    fi
+    if [ -n "$g_enable_slice_intr_multi" ]; then
+        g_enable_slice_intr_temp=$(echo ${g_enable_slice_intr_multi} | cut -d',' -f$(($i+1)))
+    fi
+    if [ -n "$pixel_just_multi" ]; then
+        pixel_just_temp=$(echo ${pixel_just_multi} | cut -d',' -f$(($i+1)))
+    fi
+    if [ -n "$bs_size_multi" ]; then
+        bs_size_temp=$(echo ${bs_size_multi} | cut -d',' -f$(($i+1)))
+    fi
+    if [ -n "$g_tiled_mode_multi" ]; then
+        g_tiled_mode_temp=$(echo ${g_tiled_mode_multi} | cut -d',' -f$(($i+1)))
+    fi
+    if [ -n "$jpeg_12bit_multi" ]; then
+        jpeg_12bit=$(echo ${jpeg_12bit_multi} | cut -d',' -f$(($i+1)))
+    fi
+
+    ################################################################################
+    # read from cfg file name                                                      #
+    ################################################################################
+    if [[ $filename == *"12b"* ]]; then
+        echo "set jpeg_12bit from cfg file name"
+        jpeg_12bit=1
+    fi
+    if [[ $filename == *"tiled"* ]]; then
+        echo "set g_tiled_mode from cfg file name"
+        g_tiled_mode_temp=1
+    fi
+
+    ################################################################################
+    # make argc & argv parameter                                                   #
+    ################################################################################
+    generate_parameters $input_path $is_encoder
+
+    if [ "$is_encoder" == "true" ]; then
+        ################################################################################
+        # Create Input YUV data for tiledMode                                          #
+        ################################################################################
+        if [ "$g_tiled_mode" == "1" ]; then
+           generate_input_yuv ${input_path}
+           result=$?
+
+           if [ "$result" != "0" ]; then
+               log_conf "failed to create yuv file $input_path" $conf_log_path
+               log_conf "[RESULT] FAILURE" $conf_log_path
+               echo "failed to create yuv file $input_path" >> $conf_err_log_path
+               echo "[RESULT] FAILURE" >> $conf_err_log_path
+               continue
+           fi
+        fi
+    fi
+
+    ################################################################################
+    # Golden Data                                                                  #
+    ################################################################################
+    log_conf "--------------------------------------------------------------------------------" ${temp_log_path}
+    if [ "$is_encoder" == "true" ]; then
+        generate_golden_stream $filename ${golden[$i]}
+    else
+        if [ "$jpeg_12bit" == "1" ]; then
+            g_jpeg_12bit="true"
+        else
+            g_jpeg_12bit="false"
+        fi
+        generate_golden_yuv $input_path ${golden[$i]}
+    fi
+    result=$?
+    log_conf "--------------------------------------------------------------------------------" ${temp_log_path}
+    if [ $result -ne 0 ]; then
+        exit $result
+    fi
+
+    ################################################################################
+    # make test param
+    ################################################################################
+    is_encoder[$i]=0 #encoder
+    if [ "$i" = "0" ]; then
+        codec_std_test_param="${is_encoder[$i]}"
+        stream_test_param="${filename}"
+        if [ -n ${output[$i]} ]; then
+            output_test_param="${output[$i]}"
+        fi
+        stream_endian_test_param="${g_stream_endian}"
+        frame_endian_test_param="${g_frame_endian}"
+        bs_size_test_param="${g_bs_size}"
+        slice_height_test_param="${g_slice_height}"
+        slice_intr_test_param="${g_enable_slice_intr}"
+        tiled_mode_test_param="${g_tiled_mode}"
+        jpeg_12bit_test_param="${jpeg_12bit}"
+        pixelj_test_param="${g_pixel_just}"
+    else
+        codec_std_test_param="${codec_std_test_param},${is_encoder[$i]}"
+        stream_test_param="${stream_test_param},${filename}"
+        if [ -n ${output[$i]} ]; then
+            output_test_param="${output_test_param},${output[$i]}"
+        fi
+        stream_endian_test_param="${stream_endian_test_param},${g_stream_endian}"
+        frame_endian_test_param="${frame_endian_test_param},${g_frame_endian}"
+        bs_size_test_param="${bs_size_test_param},${g_bs_size}"
+        slice_height_test_param="${slice_height_test_param},${g_slice_height}"
+        slice_intr_test_param="${slice_intr_test_param},${g_enable_slice_intr}"
+        tiled_mode_test_param="${tiled_mode_test_param},${g_tiled_mode}"
+        jpeg_12bit_test_param="${jpeg_12bit_test_param},${jpeg_12bit}"
+        pixelj_test_param="${pixelj_test_param},${g_pixel_just}"
+    fi
+
+################################################################################
+# print information                                                            #
+################################################################################
+    log_conf "--------------------------------------------------------------------------------" ${temp_log_path}
+    log_conf "RANDOM TEST    : ${ON_OFF[$g_random_test]}" $temp_log_path
+    log_conf "INSTANCE NUM   : $i" $temp_log_path
+    log_conf "CFG            : $filename " $temp_log_path
+    log_conf "ENDIAN         : STREAM($g_stream_endian) FRAME($g_frame_endian)" $temp_log_path
+    log_conf "STANDARD       : JPEG" $temp_log_path
+    log_conf "CBCR interleave: ${ON_OFF[$g_cbcr_interleave]}" $temp_log_path
+    log_conf "PIXEL JUST.    : ${JUSTIFY_NAME[$g_pixel_just]}" $temp_log_path
+    log_conf "TILED MODE     : ${ON_OFF[$g_tiled_mode]}" $temp_log_path
+    log_conf "WIDTH          : $cfg_width" $temp_log_path
+    log_conf "HEIGHT         : $cfg_height" $temp_log_path
+    log_conf "SLICE_HEIGHT   : $g_slice_height" $temp_log_path
+    log_conf "EN_SLICE_INTR  : $g_enable_slice_intr" $temp_log_path
+    log_conf "BS SIZE        : $g_bs_size" $temp_log_path
+    log_conf "--------------------------------------------------------------------------------" ${temp_log_path}
+done
+
+if [ "$in_comp_param" != "" ]; then
+    comp_param="$in_comp_param"
+fi
+
+test_param="-e ${comp_param} $g_w_param $g_fsdb_param $g_ius_param"
+test_param="${test_param} --instance-num=${instance_num} --cfg-dir=$cfg_dir --yuv-dir=$yuv_dir"
+test_param="${test_param} --stream-endian=${stream_endian_test_param}"
+test_param="${test_param} --frame-endian=${frame_endian_test_param} --bs-size=${bs_size_test_param}"
+test_param="${test_param} --pixelj=${pixelj_test_param}"
+test_param="${test_param} --slice-height=${slice_height_test_param}"
+test_param="${test_param} --enable-slice-intr=${slice_intr_test_param}"
+test_param="${test_param} --enable-tiledMode=${tiled_mode_test_param}"
+test_param="${test_param} --input=${stream_test_param} --output=${output_test_param}"
+if [ "$simulation" == "true" ]; then
+    test_param="${test_param} --TestRunner=1"
+fi
+
+success_count=0
+failure_count=0
+################################################################################
+################################################################################
+# Test Mode Thread                                                             #
+################################################################################
+################################################################################
+result=0
+log_conf "--------------------------------------------------------------------------------" ${temp_log_path}
+log_conf "MultiInstance test : Thread" ${temp_log_path}
+log_conf "--------------------------------------------------------------------------------" ${temp_log_path}
+for ((i=0;i<$instance_num;i++)); do
+    log_conf "[${i}/${instance_num}] ${stream[$i]}" ${temp_log_path}
+    if [ -e ${output[$i]} ]; then
+        rm -rf ${output[$i]}
+    fi
+done
+log_conf "--------------------------------------------------------------------------------" ${temp_log_path}
+cat $temp_log_path >> $conf_log_path
+
+echo "$test_exec $test_param"
+
+if [ "$simulation" == "true" ]; then
+    $test_exec $test_param 2>&1 | tee -a $conf_log_path
+else
+    echo "$test_exec $test_param"
+	exit #samin
+    #$test_exec $test_param
+fi
+
+if [ $result -eq 0 ]; then
+    log_conf "---------------- COMPARE ------------------" $conf_log_path
+    for ((i=0;i<$instance_num;i++)); do
+        log_conf "cmp ${output[$i]} ${golden[$i]}"  $conf_log_path
+        cmp ${output[$i]} ${golden[$i]} 2>&1 | tee -a $conf_log_path > /dev/null #save the log
+        cmp ${output[$i]} ${golden[$i]} #get the result & show log
+        if [ "$?" != "0" ]; then
+            log_conf "[RESULT] COMPARE FAIL" $conf_log_path
+            result=1
+        fi
+    done
+    if [ $result -eq 0 ]; then
+        log_conf "[RESULT] SUCCESS" $conf_log_path
+        success_count=$(($success_count + 1))
+    fi
+fi
+if [ $result -eq 1 ]; then
+    log_conf "[RESULT] FAILURE" $conf_log_path
+    failure_count=$(($failure_count + 1))
+    cat $temp_log_path >> $conf_err_log_path
+    cat ./ErrorLog.txt >> $conf_err_log_path
+    echo "[RESULT] FAILURE" >> $conf_err_log_path
+    if [ $result -eq 10 ]; then
+        echo "Abnormal exit!!!"
+        break
+    fi
+fi
+
+echo "TEST_CONDITION: $0 $test_param"
+
+# clear temp log
+echo "" > $temp_log_path
+
+
+
+################################################################################
+# Create Test Log                                                              #
+################################################################################
+endTime=$(date +%s%N)
+elapsed=$((($endTime - $beginTime) / 1000000000))
+elapsedH=$(($elapsed / 3600))
+elapsedS=$(($elapsed % 60))
+elapsedM=$(((($elapsed - $elapsedS) / 60) % 60))
+if [ "$((elapsedS / 10))" == "0" ]; then elapsedS="0${elapsedS}" ;fi
+if [ "$((elapsedM / 10))" == "0" ]; then elapsedM="0${elapsedM}" ;fi
+if [ "$((elapsedH / 10))" == "0" ]; then elapsedH="0${elapsedH}" ;fi
+
+if [ $elapsed -le 60 ]; then
+    time_hms="{color:red}*${elapsedH}:${elapsedM}:${elapsedS}*{color}"
+else
+time_hms="${elapsedH}:${elapsedM}:${elapsedS}"
+fi
+
+log_filename=$(basename $conf_log_path)
+log_err_filename=$(basename $conf_err_log_path)
+if [ "$failure_count" == "0" ] && [ "$instance_num" != "0" ]; then
+    pass=${PASS}
+    rm $conf_err_log_path
+    log_err_filename=""
+else
+    pass=${FAIL}
+fi
+
+wiki_log="| $streamset_file | 1 | $success_count | $failure_count | 0 | $log_filename | ${log_err_filename} | $pass | $time_hms | | | Inst Num = $instance_num |"
+
+echo $wiki_log
+echo $wiki_log >> $wiki_log_file
+
+if [ "$instance_num" == "0" ]; then
+    echo "instance_num: $instance_num = exit 1"
+    exit 1
+fi
+
+exit $failure_count
+

+ 639 - 0
codaj12/TestRunnerCommon.sh

@@ -0,0 +1,639 @@
+###############################################################################
+# COMMON DATA
+###############################################################################
+ON_OFF=(
+    "OFF"
+    "ON"
+)
+
+YUV_FORMAT_NAME=(
+    "AUTO"
+    "YUV420"
+    "YUV422"
+    "YUV444"
+    "YUV400"
+)
+
+ENDIAN_NAME=(
+    "VDI_64BIT_LE"
+    "VDI_64BIT_BE"
+    "VDI_32BIT_LE"
+    "VDI_32BIT_BE"
+)
+
+MIRROR_NAME=(
+    "NONE"
+    "VERTICAL"
+    "HORIZONTAL"
+    "BOTH"
+)
+
+JUSTIFY_NAME=(
+    "MSB_JUSTFIED"
+    "LSB_JUSTFIED"
+)
+
+YUV_PACKING_NAME=(
+    "PLANAR"
+    "SEMI-PLANAR(CbCr)"
+    "SEMI-PLANAR(CrCb)"
+    "YUYV"
+    "UYVY"
+    "YVYU"
+    "VYUY"
+    "444 PACK(8BIT)"
+    "PPM(12BIT)"
+)
+
+SCALEDOWN_NAME=(
+    "NONE"
+    "1/2"
+    "1/4"
+    "1/8"
+)
+
+
+PASS="PASS"
+FAIL="FAIL"
+PASS="{color:green}*PASS*{color}"
+FAIL="{color:red}*FAIL*{color}"
+
+###############################################################################
+# GLOBAL VARIABLES
+###############################################################################
+g_fpga_reset=0                       # 1 : reset fpga every time
+g_jpeg_12bit="false"
+
+######################## COMMON VARAIABLES FOR DECODER ########################
+g_yuv_fmt_list=("${YUV_FORMAT_LIST[@]}")
+g_match_mode=1                        # 0 - nomatch, 1 - yuv
+g_aclk=20
+g_cclk=20
+g_secondary_axi=0
+g_stream_endian=0
+g_frame_endian=0
+g_tiled_mode=0
+g_cbcr_format=0                         # 0 - none, 1 - NV12, 2 - NV21
+g_fake_test=0
+
+########################## VARAIABLES FOR PPU #################################
+g_rotation=0
+g_mirror=0
+
+
+###############################################################################
+cmodel_pn_val="" # planar format
+cmodel_pk_val="" # packed format
+cmodel_nv_val="" # semi-planar
+
+###############################################################################
+# GLOBAL FUNCTIONS
+###############################################################################
+# get_random start end
+# generate constraint random value with @start end @end.
+#
+function get_random {
+    start=$1
+    end=$2
+    size=$(($end - $start + 1))
+    val2=$RANDOM
+    val1=$(($val2 % size))
+    val=$(($start + $val1%$size))
+    echo "$val"
+}
+
+function gen_val {
+    local min_val=$1
+    local max_val=$2
+    local default_val=$3
+    local val
+
+    if [ -z $default_val ] || [ "$default_val" == "-99" ]; then
+        # Generate random value
+        val=$(get_random $min_val $max_val)
+    else
+        val=$default_val
+    fi
+    
+    echo "$val"
+}
+
+function gen_val_angle {
+    local default_val=$1
+    local val
+
+    if [ -z $default_val ] || [ "$default_val" == "-99" ]; then
+        val=$(($(get_random 0 3)*90))
+    else
+        val=$default_val
+    fi
+
+    echo "$val"
+}
+
+function gen_yuv_pack_12bit {
+    local yuv_format=$1
+    local default=$2
+    local val
+
+    case $yuv_format in
+    0)  # No conversion
+        val=0;;
+    1)  # YUV420, 3 for ppm format
+        val=$(gen_val 1 3 $default)
+        if [ "$val" == "3" ]; then
+            val=8 # PPM
+        fi
+        ;;
+    2)  # YUV422
+        val=$(gen_val 1 8 $default)
+        if [ "$val" == "7" ]; then
+            # 7 - YUV444 pack mode for 8bit yuv
+            val=8
+        fi
+        ;;
+    3)  # YUV444, 3 for ppm format
+        val=$(gen_val 1 3 $default)
+        if [ "$val" == "3" ]; then
+            val=8
+        fi
+        ;;
+    4)  # YUV400, 1 for ppm format
+        val=$(gen_val 0 1 $default)
+        if [ "$val" == "1" ]; then
+            val=8
+        fi
+        ;;
+    *)  echo "Unknown yuv_format: $yuv_format"
+        exit;;
+    esac
+
+    echo "$val"
+}
+
+function gen_yuv_pack_8bit {
+    local yuv_format=$1
+    local default=$2
+    local val
+
+    case $yuv_format in
+    0)  # No conversion
+        val=0;;
+    1)  # YUV420 
+        val=$(gen_val 1 2 $default)
+        ;;
+    2)  # YUV422
+        val=$(gen_val 1 6 $default)
+        ;;
+    3)  # YUV444, 3 for YUV444 pack
+        val=$(gen_val 1 3 $default)
+        if [ "$val" == "3" ]; then
+            val="7"
+        fi
+        ;;
+    4)  # YUV400
+        val=0
+        ;;
+    *)  echo "Unknown yuv_format: $yuv_format"
+        exit 1;;
+    esac
+
+    echo "$val"
+}
+
+function gen_yuv_pack {
+    local yuv_12bit=$1
+    local yuv_format=$2
+    local default=$3
+    local val
+
+    if [ "$yuv_12bit" == "1" ]; then
+        val=$(gen_yuv_pack_12bit $yuv_format $default)
+    else
+        val=$(gen_yuv_pack_8bit $yuv_format $default)
+    fi
+
+    echo "$val"
+}
+
+
+# log_conf log_message log_file
+# write @log_message to @log_file
+#
+function log_conf {
+    echo "$1" | tee -a "$2"
+}
+
+# parse_streamset_file streamset_path *array
+# - parse streamset file and store data into @g_stream_file_array
+# 
+function parse_streamset_file {
+    local f="$1"
+    local index=0
+    local line=""
+    while read -r line || [ -n "$line" ]; do
+        line="${line#*( )}"         # remove front whitespace
+        line="${line%%[ $'\t']*}"   # remove start of whitespace
+        line="${line//\\//}"        # replace backslash to slash
+        line="${line/$'\r'/}"       # remove carriage return
+        firstchar=${line:0:1}
+        case "$firstchar" in
+            "@") break;;        # exit flag
+            "#") continue;;     # comment
+            ";") continue;;     # comment
+            "")  continue;;     # comment
+            *)
+        esac
+        eval $2[$index]="$line"
+        index=$(($index + 1))
+    done < $f
+}
+
+function convert_fmt_val_for_cmodel {
+    local subsample=$1
+    local orig_subsample=$2
+    local ordering=$3
+
+    ordering=$(tr '[:upper:]' '[:lower:]' <<< $ordering)
+    cmodel_pn_val=0
+    cmodel_pk_val=0
+    cmodel_nv_val=0
+
+    if [ "$ordering" == "none" ]; then
+        case $subsample in
+        420)   cmodel_pn_val=0;;
+        422)   cmodel_pn_val=1;;
+        444)   cmodel_pn_val=3;;
+        *)     cmodel_pn_val=5;;
+        esac
+    else
+        if [ "$ordering" == "nv12" ] || [ "$ordering" == "nv21" ]; then
+            if [ "$subsample" == "none" ]; then
+                cmodel_pn_val=5
+
+                if [ "$ordering" == "nv12" ]; then
+                    cmodel_pk_val=1
+                else
+                    cmodel_pk_val=2
+                fi
+            else
+                case $subsample in
+                400)   cmodel_pn_val=4;;
+                420)   cmodel_pn_val=0;;
+                422)   cmodel_pn_val=1;;
+                440)   cmodel_pn_val=2;;
+                444)   cmodel_pn_val=3;;
+                esac
+
+                if [ "$ordering" == "nv12" ]; then
+                    cmodel_nv_val=1
+                else
+                    cmodel_nv_val=2
+                fi
+            fi
+        else
+            case $ordering in
+            yuyv)   cmodel_pn_val=1
+                    cmodel_pk_val=3;;
+            uyvy)   cmodel_pn_val=1
+                    cmodel_pk_val=4;;
+            yvyu)   cmodel_pn_val=1
+                    cmodel_pk_val=5;;
+            vyuy)   cmodel_pn_val=1
+                    cmodel_pk_val=6;;
+            ayuv)   cmodel_pn_val=3
+                    cmodel_pk_val=7;;
+            esac
+        fi
+    fi
+
+    if [ "$g_tiled_mode" == "1" ]; then
+        if [ "$cmodel_pn_val" == "5" ]; then
+            # no conversion
+            cmodel_nv_val=0
+            cmodel_pk_val=1
+        fi
+    fi
+}
+
+function convert_fmt_val_for_refsw {
+    local fmt=$1
+    local srcsample=$2
+    g_subsample="none"
+    g_ordering="none"
+    case $fmt in
+    420p)   g_subsample="420";;
+    422p)   g_subsample="422";;
+    444p)   g_subsample="444";;
+    nv12)   if [ "$srcsample" != "420" ]; then
+                g_subsample="420"
+            fi
+            g_ordering="nv12";;
+    nv21)   if [ "$srcsample" != "420" ]; then
+                g_subsample="420"
+            fi
+            g_ordering="nv21";;
+    nv16)   if [ "$srcsample" != "422" ]; then
+                g_subsample="422"
+            fi
+            g_ordering="nv12";;
+    nv61)   if [ "$srcsample" != "422" ]; then
+                g_subsample="422"
+            fi
+            g_ordering="nv21";;
+    nv16v)  g_ordering="nv12";;
+    nv61v)  g_ordering="nv21";;
+    nv24)   if [ "$srcsample" != "444" ]; then
+                g_subsample="444"
+            fi
+            g_ordering="nv12";;
+    nv42)   if [ "$srcsample" != "444" ]; then
+                g_subsample="444"
+            fi
+            g_ordering="nv21";;
+    yuyv)   g_ordering="yuyv";;
+    uyvy)   g_ordering="uyvy";;
+    yvyu)   g_ordering="yvyu";;
+    vyuy)   g_ordering="vyuy";;
+    ayuv)   g_ordering="ayuv";;
+    esac
+}
+
+function generate_golden_stream {
+    local input=$1
+    local output=$2
+    local exec_path="${bin_dir}/${refc_exec}"
+    local param=""
+    local cmd=""
+
+    if [ "$jpeg_12bit" == "1" ]; then
+        param="-u"
+    fi
+
+    # ref_c do not support tiled mode.
+    # In case of tiled mode, ref_c output data is same with linear mode.
+    if [ "$g_tiled_mode" == "1" ]; then
+        input=$(echo $input | sed 's/_tiled//g')
+    fi
+
+    param="$param -i $input -o ${output}"
+    param="$param -g $(($g_mirror<<2 | $g_rotation/90))"
+    param="$param -m 1 -ps $yuv_dir -pc $cfg_dir"
+    if [ "$g_slice_height" ]; then
+        param="$param -sh $g_slice_height"
+    fi
+    cmd="$exec_path $param"
+    echo "$cmd"
+
+    $cmd
+
+    return $?
+}
+
+function generate_golden_yuv {
+    local input=$1
+    local output=$2
+    local exec_path="${bin_dir}/${refc_exec}"
+    local param=""
+    local cmd=""
+
+    if [ "$g_jpeg_12bit" == "true" ]; then
+        param="-u"
+    fi
+    if [ "$cmodel_pn_val" != "" ]; then
+        param="$param -pn $cmodel_pn_val" 
+    fi
+    if [ "$cmodel_pk_val" != "" ]; then
+        param="$param -pk $cmodel_pk_val"
+    fi
+    if [ "$cmodel_nv_val" != "" ]; then
+        param="$param -v $cmodel_nv_val"
+    fi
+    param="$param -i $input -o $output"
+    param="$param -g $(($g_mirror<<2 | $g_rotation/90))"
+    if [ "$g_scale_h" != "" ]; then
+        param="$param -sx $g_scale_h"
+    fi
+    if [ "$g_scale_v" != "" ]; then
+        param="$param -sy $g_scale_v"
+    fi
+    if [ "$g_pixel_just" == "1" ]; then
+        param="$param -z"
+    fi
+
+    cmd="$exec_path $param -c"
+    echo "$cmd"
+    $cmd
+
+    return $?
+}
+
+function generate_input_yuv {
+    local input_cfg=$1
+    local param=""
+    local cmd=""
+    local bit_depth=0
+    local input_yuv=""
+    local _srcyuv=""
+    local _width=0
+    local _height=0
+    local _format=0
+    local _name=""
+    local _firstchar=""
+    
+    # Parse input cfg file.
+    while read cfg_line; do
+        _firstchar=${cfg_line:0:1}
+        case "$_firstchar" in
+            "#") continue;;     # comment
+            ";") continue;;     # comment
+            "")  continue;;
+        esac
+        _name=$(echo ${cfg_line} | cut -d' ' -f1)
+        if [ "$_name" = "YUV_SRC_IMG" ]; then
+            _srcyuv=$(echo ${cfg_line} | cut -d' ' -f2)
+        elif [ "$_name" = "PICTURE_WIDTH" ]; then
+            _width=$(echo ${cfg_line} | cut -d' ' -f2)
+        elif [ "$_name" = "PICTURE_HEIGHT" ]; then
+            _height=$(echo ${cfg_line} | cut -d' ' -f2)
+        elif [ "$_name" = "IMG_FORMAT" ]; then
+            _format=$(echo ${cfg_line} | cut -d' ' -f2)
+        fi
+    done < $input_cfg
+
+    # Check the file exist
+    echo "${yuv_dir}/${_srcyuv}"
+    if [ -f "${yuv_dir}/${_srcyuv}" ]; then
+        echo "File exist : ${yuv_dir}/${_srcyuv}"
+        return 0
+    fi
+
+    # Copy lenear yuv
+    input_yuv=$(echo $_srcyuv | sed 's/_tiled//g')
+    cp "${yuv_dir}/${input_yuv}" ./
+
+    if [ "$jpeg_12bit" == "1" ]; then
+        bit_depth="16"
+    else
+        bit_depth="8"
+    fi
+
+    param="-i ${input_yuv} -o ${_srcyuv} --width=${_width} --height=${_height} --bit-depth=${bit_depth} --format=${_format} --map-type=1"
+
+    # Execute tiled_mode program
+    if [ "$simulation" == "true" ]; then
+        gcc -o $tiled_exec ../../../fpga/board/ref-sw/tools/tiled_mode.c
+    else
+        gcc -o $tiled_exec tools/tiled_mode.c
+    fi
+    cmd="$tiled_exec $param"
+    echo "$cmd"
+
+    $cmd
+    result=$?
+
+    if [ "$result" != "0" ]; then
+        return 1
+    fi
+
+    cp "${_srcyuv}" "${yuv_dir}/${_srcyuv}"
+    return 0
+}
+
+# string get_stream_path(cfgfile)
+function generate_golden_stream_path {
+    local cfgfile=$1
+
+    streamset_name=$(basename $streamset_path)
+    temp=`expr match "$streamset_name" '.*\(_[0-9]*\.cmd\)'`
+    if [ "$temp" != "" ]; then
+        streamset_name="${streamset_name%_[0-9]*\.cmd}.cmd"
+    fi
+    echo "streamset_name: $streamset_name"
+    path="${stream_dir}/$codec_dir/$streamset_name"
+    cfgname=$(basename $cfgfile)
+    if [ ! -d "$path" ]; then
+        mkdir -p "$path"
+    fi
+
+    path="$path/${cfgname}_0.$ext"
+
+    g_func_ret_str=$path
+}
+
+function read_cfg {
+    local cfg=$1
+    if [ -f ${cfg} ]; then
+        while read line2; do
+            # remove right comment
+            line2=$(echo $line2 | tr -d '\n')
+            line2=$(echo $line2 | tr -d '\r')
+            line2="${line2%%\#*}"
+    
+            attr=$(echo $line2 | cut -d' ' -f1)
+            attr=$(echo $attr | tr -d ' ')
+    
+            value=$(echo $line2 | cut -d' ' -f2)
+            #echo "attr=$attr, value=$value"
+    
+            case "$attr" in
+                PICTURE_WIDTH)  cfg_width="$value";;
+                PICTURE_HEIGHT) cfg_height="$value";;
+                IMG_FORMAT)     cfg_img_format="$value";;
+                *) ;;
+            esac
+        done < $cfg
+    else
+        echo "File is not exist ($cfg)"
+        exit 1
+    fi
+}
+
+function get_jpeg_info {
+    local format=""
+    local cmd="${bin_dir}/${refc_exec} -i $1 -m 1" 
+
+    if [ "$2" == "1" ]; then
+        cmd="$cmd -u"
+    fi
+    $cmd > result.txt
+    while read line; do
+        line=$(echo $line | tr -d '\n')
+        line=$(echo $line | tr -d '\r')
+        line="${line%%\#*}"
+        attr=$(echo $line | cut -d':' -f1)
+        attr=$(echo $attr | tr -d ' ')
+        value=$(echo $line | cut -d':' -f2-)
+        value=$(echo $value | tr -d ' ')
+        value="${value//:/}"
+        if [ "$attr" == "OutputYUVformat" ]; then
+            jpg_format="$value"
+            break
+        elif [ "$attr" == "Pictureconfig" ]; then
+            value=${value%@*}    
+            jpg_width=$(echo $value | cut -d'x' -f1)
+            jpg_height=$(echo $value | cut -d'x' -f2)
+        fi
+    done < result.txt
+
+    echo "$format"
+}
+
+
+function gen_valid_slice_height {
+    local pic_width=$1
+    local pic_height=$2
+    local fmt=$3
+    local default=$4
+    local temp=0
+    local sample_factor_x=1
+    local sample_factor_y=1
+    local mcu_height=8
+    local slice_height=0
+    local num_mcu_h=0
+
+    if [ ! -z $default ] && [ "$default" != "-99" ]; then
+        echo "$default"
+        return
+    fi
+
+    case $fmt in
+    0) # YUV420
+       sample_factor_x=2
+       sample_factor_y=2
+       mcu_height=16;;
+    1) # YUV422
+       sample_factor_x=2
+       mcu_height=8;;
+    2) # YUV440
+       sample_factor_y=2
+       mcu_height=16;;
+    4) # YUV400
+       mcu_height=32;;
+    *) ;;
+    esac
+    num_mcu_h=$(($pic_height/$mcu_height))
+
+    mcu_num_x_fac=$(($sample_factor_x * 8))
+    mcu_num_y_fac=$(($sample_factor_y * 8))
+    mcu_num_w=$((($pic_width+($mcu_num_x_fac-1))/$mcu_num_x_fac))
+
+    temp=$(gen_val 1 $(($pic_height / $mcu_height)) $default)
+    while [ $temp -gt 0 ] ; do
+        slice_height=$(($temp * $mcu_height))
+        s_mcu_num_h=$((($slice_height+($mcu_num_y_fac-1))/$mcu_num_y_fac))
+        total_mcu_in_slice=$(($mcu_num_w * $s_mcu_num_h))
+        if [ $total_mcu_in_slice -lt 65536 ]; then
+            # A value of restart interval should be less than 65536
+            break
+        fi
+        temp=$(gen_val 1 $(($pic_height / $mcu_height)) $default)
+    done
+
+    if [ "$slice_height" == "$pic_height" ]; then
+        slice_height=$(($slice_height - $mcu_height))
+    fi
+
+    echo "$slice_height"
+}
+

+ 0 - 0
codaj12/TestRunnerParamCodaJ12Dec.txt


+ 0 - 0
codaj12/TestRunnerParamCodaJ12Enc.txt


+ 21 - 0
codaj12/build_ffmpeg.sh

@@ -0,0 +1,21 @@
+#!/bin/sh
+cmd=$1
+PWD=`pwd`
+FFMPEG=${PWD}/ffmpeg
+FFMPEG_SRC=${FFMPEG}/src
+FFMPEG_INC=${FFMPEG}/include
+FFMPEG_LIB=${FFMPEG}/lib
+FFMPEG_BIN=${FFMPEG}/bin
+FFMPEG_SHARE=${FFMPEG}/share
+FFMPEG_VERSION="2.1.8"
+CPU_CORE=`cat /proc/cpuinfo |grep "processor"|wc -l`
+
+if [ $1 == "clean" ];then   #clean
+	rm -rf $FFMPEG_INC $FFMPEG_LIB $FFMPEG_BIN $FFMPEG_SHARE $FFMPEG_SRC/ffmpeg-${FFMPEG_VERSION}
+else     					#build
+	cd $FFMPEG_SRC
+	tar -xvf ffmpeg-${FFMPEG_VERSION}.tar.gz
+	cd ffmpeg-${FFMPEG_VERSION}
+	./config_ffmpeg_riscv.sh
+	make -j${CPU_CORE} && make install
+fi

+ 50 - 0
codaj12/build_for_riscv.sh

@@ -0,0 +1,50 @@
+#!/bin/bash
+jpu_path=`pwd`
+#output="../../work/buildroot_initramfs_sysroot"
+output="./jpu_driver"
+jpu_driver=${jpu_path}/jdi/linux/driver
+jpu_env=${jpu_driver}/build_env_setup_riscv.sh
+obj_jpu=$output
+obj_jpu_driver=${obj_jpu}/driver
+
+#set env
+#source $jpu_env
+
+#mkdir
+if [ ! -d $obj_jpu ];then
+	mkdir -p $obj_jpu
+fi
+if [ ! -d $obj_jpu_driver ];then
+	mkdir -p $obj_jpu_driver
+fi
+
+#cp test files
+cp -rdvp ${jpu_path}/script/* ${obj_jpu}/
+cp -rdvp ${jpu_path}/cfg $obj_jpu
+cp -rdvp ${jpu_path}/yuv $obj_jpu
+cp -rdvp ${jpu_path}/stream $obj_jpu
+cp -dvp ${jpu_driver}/load.sh $obj_jpu_driver
+cp -dvp ${jpu_driver}/unload.sh $obj_jpu_driver
+
+#make linux driver
+cd $jpu_driver
+source build_env_setup_riscv.sh
+make clean
+make
+
+#make multi_instance
+cd $jpu_path
+make clean
+make MAKECMDGOALS=multi USE_FFMPEG=no
+cp ${jpu_path}/multi_instance_test $obj_jpu
+
+#make decoder/encoder
+make clean
+make USE_FFMPEG=no
+cp ${jpu_path}/jpg_enc_test ${jpu_path}/jpg_dec_test $obj_jpu
+
+#cp driver
+cp ${jpu_driver}/jpu.ko $obj_jpu_driver
+cp -rdvp jpu_driver ../../../freedom-u-sdk/work/buildroot_initramfs_sysroot/root/
+
+

+ 62 - 0
codaj12/cfg/HuffmanTable01.cfg

@@ -0,0 +1,62 @@
+// DC index 0 (Luminance DC) Bits
+00 01 05 01 01 01 01 01
+01 00 00 00 00 00 00 00
+// DC index 0 (Luminance DC) HuffValue
+00 01 02 03 04 05 06 07
+08 09 0A 0B
+// AC index 0 (Luminance AC) Bits
+00 02 01 03 03 02 04 03
+05 05 04 04 00 00 01 7D
+// AC index 0 (Luminance AC) HuffValue
+01 02 03 00 04 11 05 12
+21 31 41 06 13 51 61 07
+22 71 14 32 81 91 A1 08
+23 42 B1 C1 15 52 D1 F0
+24 33 62 72 82 09 0A 16
+17 18 19 1A 25 26 27 28
+29 2A 34 35 36 37 38 39
+3A 43 44 45 46 47 48 49
+4A 53 54 55 56 57 58 59
+5A 63 64 65 66 67 68 69
+6A 73 74 75 76 77 78 79
+7A 83 84 85 86 87 88 89
+8A 92 93 94 95 96 97 98
+99 9A A2 A3 A4 A5 A6 A7
+A8 A9 AA B2 B3 B4 B5 B6
+B7 B8 B9 BA C2 C3 C4 C5
+C6 C7 C8 C9 CA D2 D3 D4
+D5 D6 D7 D8 D9 DA E1 E2
+E3 E4 E5 E6 E7 E8 E9 EA
+F1 F2 F3 F4 F5 F6 F7 F8
+F9 FA
+// DC index 1 (Chrominance DC) Bits
+00 03 01 01 01 01 01 01
+01 01 01 00 00 00 00 00
+// DC index 1 (Chrominance DC) HuffValue
+00 01 02 03 04 05 06 07
+08 09 0A 0B
+// AC index 1 (Chrominance AC) Bits
+00 02 01 02 04 04 03 04
+07 05 04 04 00 01 02 77
+// AC index 1 (Chrominance AC)) HuffValue
+00 01 02 03 11 04 05 21
+31 06 12 41 51 07 61 71
+13 22 32 81 08 14 42 91
+A1 B1 C1 09 23 33 52 F0
+15 62 72 D1 0A 16 24 34
+E1 25 F1 17 18 19 1A 26
+27 28 29 2A 35 36 37 38
+39 3A 43 44 45 46 47 48
+49 4A 53 54 55 56 57 58
+59 5A 63 64 65 66 67 68
+69 6A 73 74 75 76 77 78
+79 7A 82 83 84 85 86 87
+88 89 8A 92 93 94 95 96
+97 98 99 9A A2 A3 A4 A5
+A6 A7 A8 A9 AA B2 B3 B4
+B5 B6 B7 B8 B9 BA C2 C3
+C4 C5 C6 C7 C8 C9 CA D2
+D3 D4 D5 D6 D7 D8 D9 DA
+E2 E3 E4 E5 E6 E7 E8 E9
+EA F2 F3 F4 F5 F6 F7 F8
+F9 FA

+ 84 - 0
codaj12/cfg/HuffmanTable01_ES.cfg

@@ -0,0 +1,84 @@
+// DC index 0 (Luminance DC) Bits
+00 02 03 01 00 03 01 01
+01 01 00 00 00 00 00 00
+// DC index 0 (Luminance DC) HuffValue
+08 09 06 07 0A 05 03 04
+0B 02 00 01 0C
+// AC index 0 (Luminance AC) Bits
+00 01 04 02 02 02 01 04
+01 02 00 01 00 01 00 EB
+// AC index 0 (Luminance AC) HuffValue
+02 01 03 04 05 06 07 08
+12 09 11 13 00 14 21 22
+15 0a 23 31 16 32 17 24
+33 41 18 25 42 51 0b 26
+19 43 52 61 35 62 71 0c
+0d 0e 0f 10 1a 1b 1c 1d
+1e 1f 20 27 28 29 2a 2b
+2c 2d 2e 2f 30 34 36 37
+38 39 3a 3b 3c 3d 3e 3f
+40 44 45 46 47 48 49 4a
+4b 4c 4d 4e 4f 50 53 54
+55 56 57 58 59 5a 5b 5c
+5d 5e 5f 60 63 64 65 66
+67 68 69 6a 6b 6c 6d 6e
+6f 70 72 73 74 75 76 77
+78 79 7a 7b 7c 7d 7e 7f
+80 81 82 83 84 85 86 87
+88 89 8a 8b 8c 8d 8e 8f
+90 91 92 93 94 95 96 97
+98 99 9a 9b 9c 9d 9e 9f
+a0 a1 a2 a3 a4 a5 a6 a7
+a8 a9 aa ab ac ad ae af
+b0 b1 b2 b3 b4 b5 b6 b7
+b8 b9 ba bb bc bd be bf
+c0 c1 c2 c3 c4 c5 c6 c7
+c8 c9 ca cb cc cd ce cf
+d0 d1 d2 d3 d4 d5 d6 d7
+d8 d9 da db dc dd de df
+e0 e1 e2 e3 e4 e5 e6 e7
+e8 e9 ea eb ec ed ee ef
+f0 f1 f2 f3 f4 f5 f6 f7
+f8 f9 fa fb fc fd fe ff
+// DC index 1 (Chrominance DC) Bits
+00 02 02 02 03 01 01 01
+01 00 00 00 00 00 00 00
+// DC index 1 (Chrominance DC) HuffValue
+06 07 05 08 04 09 02 03
+0A 01 0B 00 0C
+// AC index 1 (Chrominance AC) Bits
+00 01 03 02 05 01 05 05
+03 07 04 04 03 04 06 CB
+// AC index 1 (Chrominance AC)) HuffValue
+01 02 03 11 04 21 00 05
+06 12 31 41 07 13 22 51
+61 08 14 32 71 81 42 91
+a1 09 15 23 52 b1 c1 f0
+16 62 d1 e1 0a 24 72 f1
+17 82 92 33 43 53 b2 0b
+0c 18 35 a2 c2 0d 0e 0f
+10 19 1a 1b 1c 1d 1e 1f
+20 25 26 27 28 29 2a 2b
+2c 2d 2e 2f 30 34 36 37
+38 39 3a 3b 3c 3d 3e 3f
+40 44 45 46 47 48 49 4a
+4b 4c 4d 4e 4f 50 54 55
+56 57 58 59 5a 5b 5c 5d
+5e 5f 60 63 64 65 66 67
+68 69 6a 6b 6c 6d 6e 6f
+70 73 74 75 76 77 78 79
+7a 7b 7c 7d 7e 7f 80 83
+84 85 86 87 88 89 8a 8b
+8c 8d 8e 8f 90 93 94 95
+96 97 98 99 9a 9b 9c 9d
+9e 9f a0 a3 a4 a5 a6 a7
+a8 a9 aa ab ac ad ae af
+b0 b3 b4 b5 b6 b7 b8 b9
+ba bb bc bd be bf c0 c3
+c4 c5 c6 c7 c8 c9 ca cb
+cc cd ce cf d0 d2 d3 d4
+d5 d6 d7 d8 d9 da db dc
+dd de df e0 e2 e3 e4 e5
+e6 e7 e8 e9 ea eb ec ed
+ee ef f2 f3 f4 f5 f6 f7
+f8 f9 fa fb fc fd fe ff

+ 18 - 0
codaj12/cfg/QuantTable00.cfg

@@ -0,0 +1,18 @@
+; Quality 0 Luma
+14 11 11 1A 12 1A 29 18
+18 29 33 27 20 27 33 27
+1C 1C 1C 1C 27 22 17 17
+17 17 17 22 11 0C 0C 0C
+0C 0C 0C 11 0C 0C 0C 0C
+0C 0C 0C 0C 0C 0C 0C 0C
+0C 0C 0C 0C 0C 0C 0C 0C
+0C 0C 0C 0C 0C 0C 0C 0C
+; Quality 0 Chroma
+15 1A 1A 21 1D 21 22 18
+18 22 14 0E 0E 0E 14 14
+0E 0E 0E 0E 14 11 0C 0C
+0C 0C 0C 11 11 0C 0C 0C
+0C 0C 0C 11 0C 0C 0C 0C
+0C 0C 0C 0C 0C 0C 0C 0C
+0C 0C 0C 0C 0C 0C 0C 0C
+0C 0C 0C 0C 0C 0C 0C 0C

+ 18 - 0
codaj12/cfg/QuantTable01.cfg

@@ -0,0 +1,18 @@
+; Quality 1 Luma
+0C 08 08 08 09 08 0C 09
+09 0C 11 0B 0A 0B 11 15
+0F 0C 0C 0F 15 18 13 13
+15 13 13 18 11 0C 0C 0C
+0C 0C 0C 11 0C 0C 0C 0C
+0C 0C 0C 0C 0C 0C 0C 0C
+0C 0C 0C 0C 0C 0C 0C 0C
+0C 0C 0C 0C 0C 0C 0C 0C
+; Quality 1 Chroma
+0D 0B 0B 0D 0E 0D 10 0E
+0E 10 14 0E 0E 0E 14 14
+0E 0E 0E 0E 14 11 0C 0C
+0C 0C 0C 11 11 0C 0C 0C
+0C 0C 0C 11 0C 0C 0C 0C
+0C 0C 0C 0C 0C 0C 0C 0C
+0C 0C 0C 0C 0C 0C 0C 0C
+0C 0C 0C 0C 0C 0C 0C 0C

+ 18 - 0
codaj12/cfg/QuantTable02.cfg

@@ -0,0 +1,18 @@
+; Quality 3 Luma
+06 04 04 04 05 04 06 05
+05 06 09 06 05 06 09 0B
+08 06 06 08 0B 0C 0A 0A
+0B 0A 0A 0C 10 0C 0C 0C
+0C 0C 0C 10 0C 0C 0C 0C
+0C 0C 0C 0C 0C 0C 0C 0C
+0C 0C 0C 0C 0C 0C 0C 0C
+0C 0C 0C 0C 0C 0C 0C 0C
+; Quality 3 Chroma
+07 07 07 0D 0C 0D 18 10
+10 18 14 0E 0E 0E 14 14
+0E 0E 0E 0E 14 11 0C 0C
+0C 0C 0C 11 11 0C 0C 0C
+0C 0C 0C 11 0C 0C 0C 0C
+0C 0C 0C 0C 0C 0C 0C 0C
+0C 0C 0C 0C 0C 0C 0C 0C
+0C 0C 0C 0C 0C 0C 0C 0C

+ 18 - 0
codaj12/cfg/QuantTableEX_23.cfg

@@ -0,0 +1,18 @@
+; Quality 23 Luma
+0023 0018 0016 0023 0034 0057 006f 0084
+001a 001a 001e 0029 0038 007e 0082 0077
+001e 001c 0023 0034 0057 007c 0096 007a
+001e 0025 0030 003f 006f 00bd 00ae 0087
+0027 0030 0050 007a 0094 00ed 00e0 00a7
+0034 004c 0077 008b 00b0 00e2 00f5 00c8
+006a 008b 00a9 00bd 00e0 0107 0104 00db
+009c 00c8 00ce 00d5 00f3 00d9 00e0 00d7
+; Quality 23 Chroma
+0025 0027 0034 0066 00d7 00d7 00d7 00d7
+0027 002e 0038 008f 00d7 00d7 00d7 00d7
+0034 0038 007a 00d7 00d7 00d7 00d7 00d7
+0066 008f 00d7 00d7 00d7 00d7 00d7 00d7
+00d7 00d7 00d7 00d7 00d7 00d7 00d7 00d7
+00d7 00d7 00d7 00d7 00d7 00d7 00d7 00d7
+00d7 00d7 00d7 00d7 00d7 00d7 00d7 00d7
+00d7 00d7 00d7 00d7 00d7 00d7 00d7 00d7

+ 32 - 0
codaj12/cfg/outI400_qcif_inI400.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_I400.yuv
+FRAME_FORMAT                 0
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  4
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 34 - 0
codaj12/cfg/outI400_qcif_inI400_12b.cfg

@@ -0,0 +1,34 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_I400_12b.yuv
+FRAME_FORMAT                 0
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  4
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTableEX_23.cfg
+QMATRIX_PREC0               1
+QMATRIX_PREC1               1
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01_ES.cfg

+ 32 - 0
codaj12/cfg/outI400_qcif_inUYVY.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_UYVY.yuv
+FRAME_FORMAT                 4
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  4
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI400_qcif_inVYUY.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_VYUY.yuv
+FRAME_FORMAT                 6
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  4
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI400_qcif_inYUYV.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_YUYV.yuv
+FRAME_FORMAT                 3
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  4
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI400_qcif_inYVYU.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_YVYU.yuv
+FRAME_FORMAT                 5
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  4
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI420_cif_inNV12.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  mobile_cif_NV12.yuv
+FRAME_FORMAT                 1
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                352
+PICTURE_HEIGHT               288
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  0
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI420_cif_inNV12_tiled.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  mobile_cif_NV12_tiled.yuv
+FRAME_FORMAT                 1
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                352
+PICTURE_HEIGHT               288
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  0
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI420_qcif_inI420.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_I420.yuv
+FRAME_FORMAT                 0
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  0
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 34 - 0
codaj12/cfg/outI420_qcif_inI420_12b.cfg

@@ -0,0 +1,34 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_I420_12b.yuv
+FRAME_FORMAT                 0
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  0
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTableEX_23.cfg
+QMATRIX_PREC0               1
+QMATRIX_PREC1               1
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01_ES.cfg

+ 32 - 0
codaj12/cfg/outI420_qcif_inNV12.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_NV12.yuv
+FRAME_FORMAT                 1
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  0
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI420_qcif_inNV21.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_NV21.yuv
+FRAME_FORMAT                 2
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  0
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI420_qcif_inUYVY.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_UYVY.yuv
+FRAME_FORMAT                 4
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  1
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI420_qcif_inVYUY.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_VYUY.yuv
+FRAME_FORMAT                 6
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  1
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI420_qcif_inYUYV.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_YUYV.yuv
+FRAME_FORMAT                 3
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  1
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI420_qcif_inYVYU.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_YVYU.yuv
+FRAME_FORMAT                 5
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  1
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI422_qcif_inI422.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_I422.yuv
+FRAME_FORMAT                 0
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  1
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 34 - 0
codaj12/cfg/outI422_qcif_inI422_12b.cfg

@@ -0,0 +1,34 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_I422_12b.yuv
+FRAME_FORMAT                 0
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  1
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTableEX_23.cfg
+QMATRIX_PREC0               1
+QMATRIX_PREC1               1
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01_ES.cfg

+ 32 - 0
codaj12/cfg/outI422_qcif_inNV16.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_NV16.yuv
+FRAME_FORMAT                 1
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  1
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI422_qcif_inNV16_tiled.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_NV16_tiled.yuv
+FRAME_FORMAT                 1
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  1
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI422_qcif_inNV61.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_NV61.yuv
+FRAME_FORMAT                 2
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  1
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI422_qcif_inUYVY.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_UYVY.yuv
+FRAME_FORMAT                 4
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  1
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI422_qcif_inVYUY.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_VYUY.yuv
+FRAME_FORMAT                 6
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  1
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI422_qcif_inYUYV.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_YUYV.yuv
+FRAME_FORMAT                 3
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  1
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI422_qcif_inYVYU.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_YVYU.yuv
+FRAME_FORMAT                 5
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  1
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI440_qcif_in16NV.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_16NV.yuv
+FRAME_FORMAT                 1
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  2
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI440_qcif_in61NV.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_61NV.yuv
+FRAME_FORMAT                 2
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  2
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI440_qcif_inI440.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_I440.yuv
+FRAME_FORMAT                 0
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  2
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 34 - 0
codaj12/cfg/outI440_qcif_inI440_12b.cfg

@@ -0,0 +1,34 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_I440_12b.yuv
+FRAME_FORMAT                 0
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  2
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTableEX_23.cfg
+QMATRIX_PREC0               1
+QMATRIX_PREC1               1
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01_ES.cfg

+ 32 - 0
codaj12/cfg/outI440_qcif_inUYVY.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_UYVY.yuv
+FRAME_FORMAT                 4
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  2
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI440_qcif_inVYUY.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_VYUY.yuv
+FRAME_FORMAT                 6
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  2
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI440_qcif_inYUYV.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_YUYV.yuv
+FRAME_FORMAT                 3
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  2
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI440_qcif_inYVYU.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_YVYU.yuv
+FRAME_FORMAT                 5
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  2
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI444_3840_2160_inI444.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  pic_3840_2160_I444.yuv
+FRAME_FORMAT                 0
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                3840
+PICTURE_HEIGHT               2160
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  3
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI444_4608_3456_inI444.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  pic_4608_3456_I444.yuv
+FRAME_FORMAT                 0
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                4608
+PICTURE_HEIGHT               3456
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  3
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI444_cif_inNV24.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  mobile_cif_NV24.yuv
+FRAME_FORMAT                 1
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                352
+PICTURE_HEIGHT               288
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  3
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI444_cif_inNV24_tiled.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  mobile_cif_NV24_tiled.yuv
+FRAME_FORMAT                 1
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                352
+PICTURE_HEIGHT               288
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  3
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI444_qcif_inI444.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_I444.yuv
+FRAME_FORMAT                 0
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  3
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI444_qcif_inNV24.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_NV24.yuv
+FRAME_FORMAT                 1
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  3
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI444_qcif_inNV42.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_NV42.yuv
+FRAME_FORMAT                 2
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  3
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI444_qcif_inUYVY.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_UYVY.yuv
+FRAME_FORMAT                 4
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  3
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI444_qcif_inVYUY.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_VYUY.yuv
+FRAME_FORMAT                 6
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  3
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI444_qcif_inYUVP.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_YUVP.yuv
+FRAME_FORMAT                 7
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  3
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI444_qcif_inYUYV.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_YUYV.yuv
+FRAME_FORMAT                 3
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  3
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 32 - 0
codaj12/cfg/outI444_qcif_inYVYU.cfg

@@ -0,0 +1,32 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  stefan_qcif_YVYU.yuv
+FRAME_FORMAT                 5
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                176
+PICTURE_HEIGHT               144
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  3
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTable02.cfg
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01.cfg

+ 34 - 0
codaj12/cfg/outI444_vga_inI444_12b.cfg

@@ -0,0 +1,34 @@
+;-----------------------------------------------------------------
+; Configuration File for MJPEG BP @ Encoder
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+;----------------------------
+; Sequence PARAMETERs
+;----------------------------
+; source YUV image file
+YUV_SRC_IMG                  foreman_vga_I444_12b.yuv
+FRAME_FORMAT                 0
+                            ; 0-planar, 1-NV12,NV16(CbCr interleave) 2-NV21,NV61(CbCr alternative)
+                            ; 3-YUYV, 4-UYVY, 5-YVYU, 6-VYUY, 7-YUV packed (444 only)
+PICTURE_WIDTH                640
+PICTURE_HEIGHT               480
+FRAME_RATE					30
+FRAME_NUMBER_ENCODED         1
+                            ; number of frames to be encoded (#>0)
+;---------------------------------------
+; MJPEG Encodeing PARAMETERs
+;---------------------------------------
+VERSION_ID					3
+RESTART_INTERVAL			0
+IMG_FORMAT                  3
+                            ; Source Format (0 : 4:2:0, 1 : 4:2:2, 2 : 4:4:0, 3 : 4:4:4, 4 : 4:0:0)
+; Component Information Table
+COMPINFO_TABLE				CinfoTable420.cfg
+; QMatrix Table
+QMATRIX_TABLE				QuantTableEX_23.cfg
+QMATRIX_PREC0               1
+QMATRIX_PREC1               1
+; Huffman Table
+HUFFMAN_TABLE				HuffmanTable01_ES.cfg

+ 8 - 0
codaj12/cmd/jpg_dec_test_12b.cmd

@@ -0,0 +1,8 @@
+enc_0_1280_720_420_ref_12b.jpg
+enc_0_176_144_400_ref_12b.jpg
+enc_0_176_144_420_ref_12b.jpg
+enc_0_176_144_422_ref_12b.jpg
+enc_0_176_144_440_ref_12b.jpg
+enc_0_176_144_444_ref_12b.jpg
+enc_0_352_288_420_ref_12b.jpg
+enc_0_640_480_420_ref_12b.jpg

+ 6 - 0
codaj12/cmd/jpg_dec_test_8b.cmd

@@ -0,0 +1,6 @@
+enc_0_176_144_400_ref.jpg
+enc_0_176_144_420_ref.jpg
+enc_0_176_144_422_ref.jpg
+enc_0_176_144_440_ref.jpg
+enc_0_176_144_444_ref.jpg
+

+ 5 - 0
codaj12/cmd/jpg_enc_test_12b.cmd

@@ -0,0 +1,5 @@
+outI400_qcif_inI400_12b.cfg
+outI420_qcif_inI420_12b.cfg
+outI422_qcif_inI422_12b.cfg
+outI440_qcif_inI440_12b.cfg
+outI444_vga_inI444_12b.cfg

+ 42 - 0
codaj12/cmd/jpg_enc_test_8b.cmd

@@ -0,0 +1,42 @@
+;-----------------------------------------------------------------
+; List filenames of bitstreams to be tested.
+;
+; NOTE.
+; If a line begins with ;, the line is treated as a comment-line.
+;-----------------------------------------------------------------
+; YUV files not exist
+;-----------------------------------------------------------------
+outI400_qcif_inI400.cfg
+outI400_qcif_inUYVY.cfg
+outI400_qcif_inVYUY.cfg
+outI400_qcif_inYUYV.cfg
+outI400_qcif_inYVYU.cfg
+outI420_qcif_inI420.cfg
+outI420_qcif_inNV12.cfg
+outI420_qcif_inNV21.cfg
+outI420_qcif_inUYVY.cfg
+outI420_qcif_inVYUY.cfg
+outI420_qcif_inYUYV.cfg
+outI420_qcif_inYVYU.cfg
+outI422_qcif_inI422.cfg
+outI422_qcif_inNV16.cfg
+outI422_qcif_inNV61.cfg
+outI422_qcif_inUYVY.cfg
+outI422_qcif_inVYUY.cfg
+outI422_qcif_inYUYV.cfg
+outI422_qcif_inYVYU.cfg
+outI440_qcif_in16NV.cfg
+outI440_qcif_in61NV.cfg
+outI440_qcif_inI440.cfg
+outI440_qcif_inUYVY.cfg
+outI440_qcif_inVYUY.cfg
+outI440_qcif_inYUYV.cfg
+outI440_qcif_inYVYU.cfg
+outI444_qcif_inI444.cfg
+outI444_qcif_inNV24.cfg
+outI444_qcif_inNV42.cfg
+outI444_qcif_inUYVY.cfg
+outI444_qcif_inVYUY.cfg
+outI444_qcif_inYUVP.cfg
+outI444_qcif_inYUYV.cfg
+outI444_qcif_inYVYU.cfg

+ 27 - 0
codaj12/config.h

@@ -0,0 +1,27 @@
+//------------------------------------------------------------------------------
+// File: config.h
+//
+// Copyright (c) 2006, Chips & Media.  All rights reserved.
+// This file should be modified by some developers of C&M according to product version.
+//------------------------------------------------------------------------------
+
+
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+
+#if defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(WIN32) || defined(__MINGW32__)
+#	define PLATFORM_WIN32
+#elif defined(linux) || defined(__linux) || defined(ANDROID)
+#	define PLATFORM_LINUX
+#else
+#	define PLATFORM_NON_OS
+#endif
+
+
+#define API_VERSION 0x125
+
+
+
+#endif	/* __CONFIG_H__ */
+

+ 123 - 0
codaj12/jdi/jdi.h

@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2018, Chips&Media
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _JDI_HPI_H_
+#define _JDI_HPI_H_
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include "../jpuapi/jpuconfig.h"
+#include "mm.h"
+#include "jputypes.h"
+
+#define MAX_JPU_BUFFER_POOL 32
+#define JpuWriteInstReg( INST_IDX, ADDR, DATA )		jdi_write_register( ((unsigned long)INST_IDX*NPT_REG_SIZE)+ADDR, DATA ) // system register write 	with instance index
+#define JpuReadInstReg( INST_IDX, ADDR )		jdi_read_register( ((unsigned long)INST_IDX*NPT_REG_SIZE)+ADDR ) // system register write 	with instance index
+#define JpuWriteReg( ADDR, DATA )                   jdi_write_register( ADDR, DATA ) // system register write
+#define JpuReadReg( ADDR )                          jdi_read_register( ADDR )           // system register write
+#define JpuWriteMem( ADDR, DATA, LEN, ENDIAN )      jdi_write_memory( ADDR, DATA, LEN, ENDIAN ) // system memory write
+#define JpuReadMem( ADDR, DATA, LEN, ENDIAN )       jdi_read_memory( ADDR, DATA, LEN, ENDIAN ) // system memory write
+
+
+typedef struct jpu_buffer_t {
+    unsigned int  size;
+    unsigned long phys_addr;
+    unsigned long base;
+    unsigned long virt_addr;
+} jpu_buffer_t;
+
+typedef struct jpu_instance_pool_t {
+    unsigned char   jpgInstPool[MAX_NUM_INSTANCE][MAX_INST_HANDLE_SIZE];
+    Int32           jpu_instance_num;
+    BOOL            instance_pool_inited;
+	void*           instPendingInst[MAX_NUM_INSTANCE];
+    jpeg_mm_t       vmem;
+} jpu_instance_pool_t;
+
+
+typedef enum {
+    JDI_LITTLE_ENDIAN = 0,
+    JDI_BIG_ENDIAN,
+    JDI_32BIT_LITTLE_ENDIAN,
+    JDI_32BIT_BIG_ENDIAN,
+} EndianMode;
+
+
+typedef enum {
+    JDI_LOG_CMD_PICRUN  = 0,
+    JDI_LOG_CMD_INIT  = 1,
+    JDI_LOG_CMD_RESET  = 2,
+    JDI_LOG_CMD_PAUSE_INST_CTRL = 3,
+    JDI_LOG_CMD_MAX
+} jdi_log_cmd;
+
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+    int jdi_probe();
+    /* @brief It returns the number of task using JDI.
+     */
+    int jdi_get_task_num();
+    int jdi_init();
+    int jdi_release();    //this function may be called only at system off.
+    jpu_instance_pool_t *jdi_get_instance_pool();
+    int jdi_allocate_dma_memory(jpu_buffer_t *vb);
+    void jdi_free_dma_memory(jpu_buffer_t *vb);
+
+    int jdi_wait_interrupt(int timeout, unsigned int addr_int_reason, unsigned long instIdx);
+    int jdi_hw_reset();
+    int jdi_wait_inst_ctrl_busy(int timeout, unsigned int addr_flag_reg, unsigned int flag);
+    int jdi_set_clock_gate(int enable);
+    int jdi_get_clock_gate();
+
+    int jdi_open_instance(unsigned long instIdx);
+    int jdi_close_instance(unsigned long instIdx);
+    int jdi_get_instance_num();
+
+
+    void jdi_write_register(unsigned long addr, unsigned long data);
+    unsigned long jdi_read_register(unsigned long addr);
+
+    int jdi_write_memory(unsigned long addr, unsigned char *data, int len, int endian);
+    int jdi_read_memory(unsigned long addr, unsigned char *data, int len, int endian);
+
+    int jdi_lock();
+    void jdi_unlock();
+    void jdi_log(int cmd, int step, int inst);
+    void jdi_flush_ddr(unsigned long start,unsigned long size,unsigned char flag);
+#define ACLK_MAX                    300
+#define ACLK_MIN                    16
+#define CCLK_MAX                    300
+#define CCLK_MIN                    16
+
+
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif //#ifndef _JDI_HPI_H_

+ 49 - 0
codaj12/jdi/linux/driver/Makefile

@@ -0,0 +1,49 @@
+# Comment/uncomment the	following line to disable/enable debugging
+#DEBUG = y
+
+# Add your debugging flag (or not) to CFLAGS
+ifeq ($(DEBUG),y)
+  DEBFLAGS = -O	-g # "-O" is needed to expand inlines
+else
+  DEBFLAGS = -O2
+endif
+
+export CC="$(CROSS_COMPILE)gcc"
+export AR="$(CROSS_COMPILE)ar"
+export CXX="${CROSS_COMPILE}g++"
+export AS="${CROSS_COMPILE}as"
+export LD="${CROSS_COMPILE}ld"
+export RANLIB="${CROSS_COMPILE}ranlib"
+export READELF="${CROSS_COMPILE}readelf"
+export STRIP="${CROSS_COMPILE}strip"
+
+
+EXTRA_CFLAGS +=	$(DEBFLAGS) -I$(LDDINCDIR)
+
+ifneq ($(KERNELRELEASE),)
+# call from kernel build system
+
+obj-m	:= jpu.o
+
+else
+
+KERNELDIR := ../../../../../work/linux/
+PWD	  := $(shell pwd)
+
+default:
+	$(MAKE)	-C $(KERNELDIR)	M=$(PWD) LDDINCDIR=$(PWD)/../include modules
+
+endif
+
+
+
+clean:
+	rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
+
+depend .depend dep:
+	$(CC) $(CFLAGS)	-M *.c > .depend
+
+
+ifeq (.depend,$(wildcard .depend))
+include	.depend
+endif

+ 51 - 0
codaj12/jdi/linux/driver/Makefile.usb

@@ -0,0 +1,51 @@
+# Comment/uncomment the	following line to disable/enable debugging
+#DEBUG = y
+
+# Add your debugging flag (or not) to CFLAGS
+ifeq ($(DEBUG),y)
+  DEBFLAGS = -O	-g # "-O" is needed to expand inlines
+else
+  DEBFLAGS = -O2
+endif
+
+export CC="$(CROSS_COMPILE)gcc"
+export AR="$(CROSS_COMPILE)ar"
+export CXX="${CROSS_COMPILE}g++"
+export AS="${CROSS_COMPILE}as"
+export LD="${CROSS_COMPILE}ld"
+export RANLIB="${CROSS_COMPILE}ranlib"
+export READELF="${CROSS_COMPILE}readelf"
+export STRIP="${CROSS_COMPILE}strip"
+
+
+//EXTRA_CFLAGS +=	$(DEBFLAGS) -I$(LDDINCDIR) 
+EXTRA_CFLAGS +=	$(DEBFLAGS) -I$(LDDINCDIR)  -DCNM_FPGA_PLATFORM -DCNM_FPGA_USB_INTERFACE -DCONFIG_PM
+
+ifneq ($(KERNELRELEASE),)
+# call from kernel build system
+
+obj-m	:= jpu.o
+
+else
+
+KERNELDIR ?= ../../../../../work/linux/
+
+PWD	  := $(shell pwd)
+
+default:
+	$(MAKE)	-C $(KERNELDIR)	M=$(PWD) LDDINCDIR=$(PWD)/../include modules
+
+endif
+
+
+
+clean:
+	rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
+
+depend .depend dep:
+	$(CC) $(CFLAGS)	-M *.c > .depend
+
+
+ifeq (.depend,$(wildcard .depend))
+include	.depend
+endif

+ 0 - 0
codaj12/jdi/linux/driver/Module.symvers


+ 4 - 0
codaj12/jdi/linux/driver/build_env_setup_android.sh

@@ -0,0 +1,4 @@
+export PATH=/home/ta/work/android_tcc-4.2.2/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin:$PATH
+export ARCH=arm
+export SUBARCH=arm
+export CROSS_COMPILE=arm-eabi-

+ 8 - 0
codaj12/jdi/linux/driver/build_env_setup_riscv.sh

@@ -0,0 +1,8 @@
+PWD=`pwd`
+RISCV_TOOLCHAIN_BASE=${PWD}/../../../../../work/buildroot_initramfs/host
+echo $RISCV_TOOLCHAIN_BASE
+export PATH=${RISCV_TOOLCHAIN_BASE}/bin:$PATH
+export LD_LIBRARY_PATH=${RISCV_TOOLCHAIN_BASE}/lib:$LD_LIBRARY_PATH
+export ARCH=riscv
+export SUBARCH=riscv
+export CROSS_COMPILE=riscv64-buildroot-linux-gnu-

+ 109 - 0
codaj12/jdi/linux/driver/driver.dsp

@@ -0,0 +1,109 @@
+# Microsoft Developer Studio Project File - Name="driver" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) External Target" 0x0106
+
+CFG=driver - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "driver.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "driver.mak" CFG="driver - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "driver - Win32 Release" (based on "Win32 (x86) External Target")
+!MESSAGE "driver - Win32 Debug" (based on "Win32 (x86) External Target")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+
+!IF  "$(CFG)" == "driver - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Cmd_Line "NMAKE /f driver.mak"
+# PROP BASE Rebuild_Opt "/a"
+# PROP BASE Target_File "driver.exe"
+# PROP BASE Bsc_Name "driver.bsc"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Cmd_Line "nmake /f "driver.mak""
+# PROP Rebuild_Opt "/a"
+# PROP Target_File "driver.exe"
+# PROP Bsc_Name ""
+# PROP Target_Dir ""
+
+!ELSEIF  "$(CFG)" == "driver - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Cmd_Line "NMAKE /f driver.mak"
+# PROP BASE Rebuild_Opt "/a"
+# PROP BASE Target_File "driver.exe"
+# PROP BASE Bsc_Name "driver.bsc"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Cmd_Line "nmake /f "driver.mak""
+# PROP Rebuild_Opt "/a"
+# PROP Target_File "driver.exe"
+# PROP Bsc_Name ""
+# PROP Target_Dir ""
+
+!ENDIF 
+
+# Begin Target
+
+# Name "driver - Win32 Release"
+# Name "driver - Win32 Debug"
+
+!IF  "$(CFG)" == "driver - Win32 Release"
+
+!ELSEIF  "$(CFG)" == "driver - Win32 Debug"
+
+!ENDIF 
+
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\jpu.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\jpu.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# Begin Source File
+
+SOURCE=.\Makefile
+# End Source File
+# End Target
+# End Project

+ 29 - 0
codaj12/jdi/linux/driver/driver.dsw

@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "driver"=.\driver.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+

+ 646 - 0
codaj12/jdi/linux/driver/jmm.h

@@ -0,0 +1,646 @@
+#ifndef __CNM_JPU_MM_H__
+#define __CNM_JPU_MM_H__
+
+
+typedef unsigned long long  jmem_key_t;
+
+#define JMEM_PAGE_SIZE           (16*1024)
+#define MAKE_KEY(_a, _b)        (((jmem_key_t)_a)<<32 | _b)
+#define KEY_TO_VALUE(_key)      (_key>>32)
+
+typedef struct page_struct {
+	int             pageno;
+	unsigned long   addr;
+	int             used;
+	int             alloc_pages;
+	int             first_pageno;
+} page_t;
+
+
+typedef struct avl_node_struct {
+	jmem_key_t   key;
+	int     height;
+	page_t* page;
+	struct avl_node_struct* left;
+	struct avl_node_struct* right;
+} avl_node_t;
+
+
+typedef struct _jpu_mm_struct {
+	avl_node_t*     free_tree;
+	avl_node_t*     alloc_tree;
+	page_t*         page_list;
+	int             num_pages;
+	unsigned long   base_addr;
+	unsigned long   mem_size;
+	int             free_page_count;
+	int             alloc_page_count;
+} jpu_mm_t;
+
+
+
+#define VMEM_P_ALLOC(_x)         kmalloc(_x, GFP_KERNEL)
+#define VMEM_P_FREE(_x)          kfree(_x)
+
+#define VMEM_ASSERT(_exp)        if (!(_exp)) { printk(KERN_INFO "VMEM_ASSERT at %s:%d\n", __FILE__, __LINE__); /*while(1);*/ }
+#define VMEM_HEIGHT(_tree)       (_tree==NULL ? -1 : _tree->height)
+
+
+#define MAX(_a, _b)         (_a >= _b ? _a : _b)
+
+typedef enum {
+    LEFT,
+    RIGHT
+} rotation_dir_t;
+
+
+
+typedef struct avl_node_data_struct {
+    int     key;
+    page_t* page;
+} avl_node_data_t;
+
+static avl_node_t*
+make_avl_node(
+    jmem_key_t key,
+    page_t* page
+    )
+{
+    avl_node_t* node = (avl_node_t*)VMEM_P_ALLOC(sizeof(avl_node_t));
+    node->key     = key;
+    node->page    = page;
+    node->height  = 0;
+    node->left    = NULL;
+    node->right   = NULL;
+
+    return node;
+}
+
+
+static int
+get_balance_factor(
+    avl_node_t* tree
+    )
+{
+    int factor = 0;
+    if (tree) {
+        factor = VMEM_HEIGHT(tree->right) - VMEM_HEIGHT(tree->left);
+    }
+
+    return factor;
+}
+
+/*
+ * Left Rotation
+ *
+ *      A                      B
+ *       \                    / \
+ *        B         =>       A   C
+ *       /  \                 \
+ *      D    C                 D
+ *
+ */
+static avl_node_t*
+rotation_left(
+    avl_node_t* tree
+    )
+{
+    avl_node_t* rchild;
+    avl_node_t* lchild;
+
+    if (tree == NULL) return NULL;
+    
+    rchild = tree->right;
+    if (rchild == NULL) {
+        return tree;
+    }
+
+    lchild = rchild->left;
+    rchild->left = tree;
+    tree->right = lchild;
+
+    tree->height   = MAX(VMEM_HEIGHT(tree->left), VMEM_HEIGHT(tree->right)) + 1;
+    rchild->height = MAX(VMEM_HEIGHT(rchild->left), VMEM_HEIGHT(rchild->right)) + 1;
+
+    return rchild;
+}
+
+
+/*
+ * Reft Rotation
+ *
+ *         A                  B
+ *       \                  /  \
+ *      B         =>       D    A
+ *    /  \                     /
+ *   D    C                   C
+ *
+ */
+static avl_node_t*
+rotation_right(
+    avl_node_t* tree
+    )
+{
+    avl_node_t* rchild;
+    avl_node_t* lchild;
+
+    if (tree == NULL) return NULL;
+
+    lchild = tree->left;
+    if (lchild == NULL) return NULL;
+
+    rchild = lchild->right;
+    lchild->right = tree;
+    tree->left = rchild;
+
+    tree->height   = MAX(VMEM_HEIGHT(tree->left), VMEM_HEIGHT(tree->right)) + 1;
+    lchild->height = MAX(VMEM_HEIGHT(lchild->left), VMEM_HEIGHT(lchild->right)) + 1;
+
+    return lchild;
+}
+
+static avl_node_t*
+do_balance(
+    avl_node_t* tree
+    )
+{
+    int bfactor = 0, child_bfactor;       /* balancing factor */
+
+    bfactor = get_balance_factor(tree);
+
+    if (bfactor >= 2) {
+        child_bfactor = get_balance_factor(tree->right);
+        if (child_bfactor == 1 || child_bfactor == 0) {
+            tree = rotation_left(tree);
+        } else if (child_bfactor == -1) {
+            tree->right = rotation_right(tree->right);
+            tree        = rotation_left(tree);
+        } else {
+            printk(KERN_INFO "invalid balancing factor: %d\n", child_bfactor);
+            VMEM_ASSERT(0);
+            return NULL;
+        }
+    } else if (bfactor <= -2) {
+        child_bfactor = get_balance_factor(tree->left);
+        if (child_bfactor == -1 || child_bfactor == 0) {
+            tree = rotation_right(tree);
+        } else if (child_bfactor == 1) {
+            tree->left = rotation_left(tree->left);
+            tree       = rotation_right(tree);
+        } else {
+            printk(KERN_INFO "invalid balancing factor: %d\n", child_bfactor);
+            VMEM_ASSERT(0);
+            return NULL;
+        }
+    }
+    
+    return tree;
+}
+static avl_node_t*
+unlink_end_node(
+    avl_node_t* tree,
+    int dir,
+    avl_node_t** found_node
+    )
+{
+    avl_node_t* node;
+    *found_node = NULL;
+
+    if (tree == NULL) return NULL;
+
+    if (dir == LEFT) {
+        if (tree->left == NULL) {
+            *found_node = tree;
+            return NULL;
+        }
+    } else {
+        if (tree->right == NULL) {
+            *found_node = tree;
+            return NULL;
+        }
+    }
+
+    if (dir == LEFT) {
+        node = tree->left;
+        tree->left = unlink_end_node(tree->left, LEFT, found_node);
+        if (tree->left == NULL) {
+            tree->left = (*found_node)->right;
+            (*found_node)->left  = NULL;
+            (*found_node)->right = NULL;
+        }
+    } else {
+        node = tree->right;
+        tree->right = unlink_end_node(tree->right, RIGHT, found_node);
+        if (tree->right == NULL) {
+            tree->right = (*found_node)->left;
+            (*found_node)->left  = NULL;
+            (*found_node)->right = NULL;
+        }
+    }
+
+    tree->height = MAX(VMEM_HEIGHT(tree->left), VMEM_HEIGHT(tree->right)) + 1;
+
+    return do_balance(tree);
+}
+
+
+static avl_node_t*
+avltree_insert(
+    avl_node_t* tree,
+    jmem_key_t key,
+    page_t* page
+    )
+{
+    if (tree == NULL) {
+        tree = make_avl_node(key, page);
+    } else {
+        if (key >= tree->key) {
+            tree->right = avltree_insert(tree->right, key, page);
+        } else {
+            tree->left  = avltree_insert(tree->left, key, page);
+        }
+    }
+
+    tree = do_balance(tree);
+
+    tree->height = MAX(VMEM_HEIGHT(tree->left), VMEM_HEIGHT(tree->right)) + 1;
+
+    return tree;
+}
+
+static avl_node_t*
+do_unlink(
+    avl_node_t* tree
+    )
+{
+    avl_node_t* node;
+    avl_node_t* end_node;
+    node = unlink_end_node(tree->right, LEFT, &end_node);
+    if (node) {
+        tree->right = node;
+    } else {
+        node = unlink_end_node(tree->left, RIGHT, &end_node);
+        if (node) tree->left = node;
+    }
+
+    if (node == NULL) {
+        node = tree->right ? tree->right : tree->left;
+        end_node = node;
+    }
+
+    if (end_node) {
+        end_node->left  = (tree->left != end_node) ? tree->left : end_node->left;
+        end_node->right = (tree->right != end_node) ? tree->right : end_node->right;
+        end_node->height = MAX(VMEM_HEIGHT(end_node->left), VMEM_HEIGHT(end_node->right)) + 1;
+    } 
+
+    tree = end_node;
+
+    return tree;
+}
+
+static avl_node_t*
+avltree_remove(
+    avl_node_t* tree,
+    avl_node_t** found_node,
+    jmem_key_t key
+    )
+{
+    *found_node = NULL;
+    if (tree == NULL) {
+        printk(KERN_INFO "failed to find key %d\n", (int)key);
+        return NULL;
+    } 
+
+    if (key == tree->key) {
+        *found_node = tree;
+        tree = do_unlink(tree);
+    } else if (key > tree->key) {
+        tree->right = avltree_remove(tree->right, found_node, key);
+    } else {
+        tree->left  = avltree_remove(tree->left, found_node, key);
+    }
+
+    if (tree) tree->height = MAX(VMEM_HEIGHT(tree->left), VMEM_HEIGHT(tree->right)) + 1;
+
+    tree = do_balance(tree);
+
+    return tree;
+}
+
+void
+avltree_free(
+    avl_node_t* tree
+    )
+{
+    if (tree == NULL) return;
+    if (tree->left == NULL && tree->right == NULL) {
+        VMEM_P_FREE(tree);
+        return;
+    }
+
+    avltree_free(tree->left);
+    tree->left = NULL;
+    avltree_free(tree->right);
+    tree->right = NULL;
+}
+
+
+
+
+static avl_node_t*
+remove_approx_value(
+    avl_node_t* tree,
+    avl_node_t** found,
+    jmem_key_t key
+    )
+{
+    *found = NULL;
+    if (tree == NULL) {
+        return NULL;
+    }
+
+    if (key == tree->key) {
+        *found = tree;
+        tree = do_unlink(tree);
+    } else if (key > tree->key) {
+        tree->right = remove_approx_value(tree->right, found, key);
+    } else {
+        tree->left  = remove_approx_value(tree->left, found, key);
+        if (*found == NULL) {
+            *found = tree;
+            tree = do_unlink(tree);
+        }
+    }
+    if (tree) tree->height = MAX(VMEM_HEIGHT(tree->left), VMEM_HEIGHT(tree->right)) + 1;
+    tree = do_balance(tree);
+
+    return tree;
+}
+
+static void
+set_blocks_free(
+	jpu_mm_t *mm,
+    int pageno,
+    int npages
+    )
+{
+    int last_pageno     = pageno + npages - 1;
+    int i;
+    page_t* page;
+    page_t* last_page;
+
+    VMEM_ASSERT(npages);
+
+    if (last_pageno >= mm->num_pages) {
+        printk(KERN_INFO "set_blocks_free: invalid last page number: %d\n", last_pageno);
+        VMEM_ASSERT(0);
+        return;
+    }
+
+    for (i=pageno; i<=last_pageno; i++) {
+        mm->page_list[i].used         = 0;
+        mm->page_list[i].alloc_pages  = 0;
+        mm->page_list[i].first_pageno = -1;
+    }
+
+    page        = &mm->page_list[pageno];
+    page->alloc_pages = npages;
+    last_page   = &mm->page_list[last_pageno];    
+    last_page->first_pageno = pageno;
+
+    mm->free_tree = avltree_insert(mm->free_tree, MAKE_KEY(npages, pageno), page);
+}
+
+static void
+set_blocks_alloc(
+	jpu_mm_t *mm,
+    int pageno,
+    int npages
+    )
+{
+    int last_pageno     = pageno + npages - 1;
+    int i;
+    page_t* page;
+    page_t* last_page;
+
+    if (last_pageno >= mm->num_pages) {
+        printk(KERN_INFO "set_blocks_free: invalid last page number: %d\n", last_pageno);
+        VMEM_ASSERT(0);
+        return;
+    }
+
+    for (i=pageno; i<=last_pageno; i++) {
+        mm->page_list[i].used         = 1;
+        mm->page_list[i].alloc_pages  = 0;
+        mm->page_list[i].first_pageno = -1;
+    }
+
+    page        = &mm->page_list[pageno];
+    page->alloc_pages = npages;
+
+    last_page   = &mm->page_list[last_pageno];    
+    last_page->first_pageno = pageno;
+
+    mm->alloc_tree = avltree_insert(mm->alloc_tree, MAKE_KEY(page->addr, 0), page);
+}
+
+
+int
+jmem_init(
+	jpu_mm_t* mm, 
+	unsigned long addr,
+    unsigned long size
+    )
+{
+    int i;
+	
+	
+    mm->base_addr  = (addr+(JMEM_PAGE_SIZE-1))&~(JMEM_PAGE_SIZE-1);
+    mm->mem_size   = size&~JMEM_PAGE_SIZE;
+    mm->num_pages  = mm->mem_size/JMEM_PAGE_SIZE;
+    mm->page_list  = (page_t*)VMEM_P_ALLOC(mm->num_pages*sizeof(page_t));
+    mm->free_tree  = NULL;
+    mm->alloc_tree = NULL;
+    mm->free_page_count = mm->num_pages;
+    mm->alloc_page_count = 0;
+
+    for (i=0; i<mm->num_pages; i++) {
+        mm->page_list[i].pageno       = i;
+        mm->page_list[i].addr         = mm->base_addr + i*JMEM_PAGE_SIZE;
+        mm->page_list[i].alloc_pages  = 0;
+        mm->page_list[i].used         = 0;
+        mm->page_list[i].first_pageno = -1;
+    }
+
+    set_blocks_free(mm, 0, mm->num_pages);
+	
+    return 0;
+}
+
+int
+jmem_exit(
+	jpu_mm_t* mm
+    )
+{
+	if (mm == NULL) {
+        printk(KERN_INFO "vmem_exit: invalid handle\n");
+        return -1;
+    }
+
+    if (mm->free_tree) {
+        avltree_free(mm->free_tree);
+    }
+    if (mm->alloc_tree) {
+        avltree_free(mm->alloc_tree);
+    }
+
+    VMEM_P_FREE(mm->page_list);
+	
+	mm->base_addr  = 0;
+	mm->mem_size   = 0;
+	mm->num_pages  = 0;
+	mm->page_list  = NULL;
+	mm->free_tree  = NULL;
+	mm->alloc_tree = NULL;
+	mm->free_page_count = 0;
+	mm->alloc_page_count = 0;
+    return 0;
+}
+
+unsigned long
+jmem_alloc(
+	jpu_mm_t* mm,
+    int size,
+	unsigned long pid
+    )
+{
+    avl_node_t* node;
+    page_t*     free_page;
+    int         npages, free_size;
+    int         alloc_pageno;
+    unsigned long  ptr;
+	
+	if (mm == NULL) {
+		printk(KERN_INFO "vmem_alloc: invalid handle\n");
+		return -1;
+	}
+
+    if (size <= 0) return -1;
+
+	npages = (size + JMEM_PAGE_SIZE -1)/JMEM_PAGE_SIZE;
+
+    mm->free_tree = remove_approx_value(mm->free_tree, &node, MAKE_KEY(npages, 0));
+    if (node == NULL) {
+        return -1;
+    }
+    free_page = node->page;
+    free_size = KEY_TO_VALUE(node->key);
+
+    alloc_pageno = free_page->pageno;
+    set_blocks_alloc(mm, alloc_pageno, npages);
+    if (npages != free_size) {
+        int free_pageno = alloc_pageno + npages;
+        set_blocks_free(mm, free_pageno, (free_size-npages));
+    }
+
+    VMEM_P_FREE(node);
+
+    ptr = mm->page_list[alloc_pageno].addr;
+    mm->alloc_page_count += npages;
+    mm->free_page_count  -= npages;
+
+
+    return ptr;
+}
+
+int
+jmem_free(
+	jpu_mm_t* mm,
+    unsigned long ptr,
+	unsigned long pid
+    )
+{
+    unsigned long addr;
+    avl_node_t* found;
+    page_t* page;
+    int pageno, prev_free_pageno, next_free_pageno;
+    int prev_size, next_size;
+    int merge_page_no, merge_page_size, free_page_size;
+	
+
+	if (mm == NULL) {
+		printk(KERN_INFO "vmem_free: invalid handle\n");
+		return -1;
+	}
+
+    addr = ptr;
+
+    mm->alloc_tree = avltree_remove(mm->alloc_tree, &found, MAKE_KEY(addr, 0));
+    if (found == NULL) {
+        printk(KERN_INFO "vmem_free: 0x%08x not found\n", (int)addr);
+        VMEM_ASSERT(0);
+        return -1;
+    }
+
+    /* find previous free block */
+    page = found->page;
+    pageno = page->pageno;
+    free_page_size = page->alloc_pages;
+    prev_free_pageno = pageno-1;
+    prev_size = -1;
+    if (prev_free_pageno >= 0) {
+        if (mm->page_list[prev_free_pageno].used == 0) {
+            prev_free_pageno = mm->page_list[prev_free_pageno].first_pageno;
+            prev_size = mm->page_list[prev_free_pageno].alloc_pages;
+        }
+    }
+
+    /* find next free block */
+    next_free_pageno = pageno + page->alloc_pages;
+    next_free_pageno = (next_free_pageno == mm->num_pages) ? -1 : next_free_pageno;
+    next_size = -1;
+    if (next_free_pageno >= 0) {
+        if (mm->page_list[next_free_pageno].used == 0) {
+            next_size = mm->page_list[next_free_pageno].alloc_pages;
+        }
+    }
+    VMEM_P_FREE(found);
+
+    /* merge */
+    merge_page_no = page->pageno;
+    merge_page_size = page->alloc_pages;
+    if (prev_size >= 0) {
+        mm->free_tree = avltree_remove(mm->free_tree, &found, MAKE_KEY(prev_size, prev_free_pageno));
+        if (found == NULL) {
+            VMEM_ASSERT(0);
+            return -1;
+        }
+        merge_page_no = found->page->pageno;
+        merge_page_size += found->page->alloc_pages;
+        VMEM_P_FREE(found);
+    }
+    if (next_size >= 0) {
+        mm->free_tree = avltree_remove(mm->free_tree, &found, MAKE_KEY(next_size, next_free_pageno));
+        if (found == NULL) {
+            VMEM_ASSERT(0);
+            return -1;
+        }
+        merge_page_size += found->page->alloc_pages;
+        VMEM_P_FREE(found);
+    }
+
+    page->alloc_pages  = 0;
+    page->first_pageno = -1;
+
+    set_blocks_free(mm, merge_page_no, merge_page_size);
+
+    mm->alloc_page_count -= free_page_size;
+    mm->free_page_count  += free_page_size;
+
+    return 0;
+}
+
+
+
+#endif /* __CNM_JPU_MM_H__ */

+ 1039 - 0
codaj12/jdi/linux/driver/jpu.c

@@ -0,0 +1,1039 @@
+//--=========================================================================--
+//  This file is linux device driver for JPU.
+//-----------------------------------------------------------------------------
+//
+//       This confidential and proprietary software may be used only
+//     as authorized by a licensing agreement from Chips&Media Inc.
+//     In the event of publication, the following notice is applicable:
+//
+//            (C) COPYRIGHT 2006 - 2016  CHIPS&MEDIA INC.
+//                      ALL RIGHTS RESERVED
+//
+//       The entire notice above must be reproduced on all authorized
+//       copies.
+//
+//--=========================================================================-
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/wait.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/uaccess.h>
+#include <linux/cdev.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/sched/signal.h>
+#include <linux/version.h>
+#include <soc/starfive/vic7100.h>
+
+#include "../../../jpuapi/jpuconfig.h"
+#include "jpu.h"
+
+//#define ENABLE_DEBUG_MSG
+#ifdef ENABLE_DEBUG_MSG
+#define DPRINTK(args...)            printk(KERN_INFO args);
+#else
+#define DPRINTK(args...)
+#endif
+
+/* definitions to be changed as customer  configuration */
+/* if you want to have clock gating scheme frame by frame */
+#define JPU_SUPPORT_CLOCK_CONTROL
+#define JPU_SUPPORT_ISR
+//#define JPU_IRQ_CONTROL
+/* if the platform driver knows the name of this driver */
+/* JPU_PLATFORM_DEVICE_NAME */
+#define JPU_SUPPORT_PLATFORM_DRIVER_REGISTER
+
+/* if this driver knows the dedicated video memory address */
+
+//#define JPU_SUPPORT_RESERVED_VIDEO_MEMORY        //if this driver knows the dedicated video memory address
+
+
+#define JPU_PLATFORM_DEVICE_NAME    "cnm_jpu"
+#define JPU_CLK_NAME                "jpege"
+#define JPU_DEV_NAME                "jpu"
+
+#define JPU_REG_BASE_ADDR           0x11900000
+#define JPU_REG_SIZE                0x300
+
+
+#ifdef JPU_SUPPORT_ISR
+#define JPU_IRQ_NUM                 24
+/* if the driver want to disable and enable IRQ whenever interrupt asserted. */
+/*#define JPU_IRQ_CONTROL*/
+#endif
+
+
+#ifndef VM_RESERVED	/*for kernel up to 3.7.0 version*/
+#define VM_RESERVED   (VM_DONTEXPAND | VM_DONTDUMP)
+#endif
+
+struct device *jpu_dev;
+
+typedef struct jpu_drv_context_t {
+    struct fasync_struct *async_queue;
+    u32 open_count;                     /*!<< device reference count. Not instance count */
+    u32 interrupt_reason[MAX_NUM_INSTANCE];
+} jpu_drv_context_t;
+
+
+/* To track the allocated memory buffer */
+typedef struct jpudrv_buffer_pool_t {
+    struct list_head        list;
+    struct jpudrv_buffer_t  jb;
+    struct file*            filp;
+} jpudrv_buffer_pool_t;
+
+/* To track the instance index and buffer in instance pool */
+typedef struct jpudrv_instance_list_t {
+    struct list_head    list;
+    unsigned long       inst_idx;
+    struct file*        filp;
+} jpudrv_instance_list_t;
+
+typedef struct jpudrv_instance_pool_t {
+	unsigned char codecInstPool[MAX_NUM_INSTANCE][MAX_INST_HANDLE_SIZE];
+} jpudrv_instance_pool_t;
+
+#ifdef JPU_SUPPORT_RESERVED_VIDEO_MEMORY
+#include "jmm.h"
+static jpu_mm_t         s_jmem;
+static jpudrv_buffer_t  s_video_memory = {0};
+#endif /* JPU_SUPPORT_RESERVED_VIDEO_MEMORY */
+
+
+static int jpu_hw_reset(void);
+static void jpu_clk_disable(struct clk *clk);
+static int jpu_clk_enable(struct clk *clk);
+static struct clk *jpu_clk_get(struct device *dev);
+static void jpu_clk_put(struct clk *clk);
+// end customer definition
+
+static jpudrv_buffer_t s_instance_pool = {0};
+static jpu_drv_context_t s_jpu_drv_context;
+static int s_jpu_major;
+static struct cdev s_jpu_cdev;
+static struct clk *s_jpu_clk;
+static int s_jpu_open_ref_count;
+#ifdef JPU_SUPPORT_ISR
+static int s_jpu_irq = JPU_IRQ_NUM;
+#endif
+
+static jpudrv_buffer_t s_jpu_register = {0};
+
+static int s_interrupt_flag[MAX_NUM_INSTANCE];
+static wait_queue_head_t s_interrupt_wait_q[MAX_NUM_INSTANCE];
+
+
+static spinlock_t s_jpu_lock = __SPIN_LOCK_UNLOCKED(s_jpu_lock);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
+static DECLARE_MUTEX(s_jpu_sem);
+#else
+static DEFINE_SEMAPHORE(s_jpu_sem);
+#endif
+static struct list_head s_jbp_head = LIST_HEAD_INIT(s_jbp_head);
+static struct list_head s_inst_list_head = LIST_HEAD_INIT(s_inst_list_head);
+
+#ifdef CONFIG_PM
+/* implement to power management functions */
+#endif
+
+#define NPT_BASE                                0x0000
+#define NPT_REG_SIZE                            0x300
+#define MJPEG_PIC_STATUS_REG(_inst_no)          (NPT_BASE + (_inst_no*NPT_REG_SIZE) + 0x004)
+
+#define ReadJpuRegister(addr)           *(volatile unsigned int *)(s_jpu_register.virt_addr + addr)
+#define WriteJpuRegister(addr, val)     *(volatile unsigned int *)(s_jpu_register.virt_addr + addr) = (unsigned int)val
+#define WriteJpu(addr, val)             *(volatile unsigned int *)(addr) = (unsigned int)val;
+
+
+static int jpu_alloc_dma_buffer(jpudrv_buffer_t *jb)
+{
+    if (!jb)
+        return -1;
+#ifdef JPU_SUPPORT_RESERVED_VIDEO_MEMORY
+    jb->phys_addr = (unsigned long long)jmem_alloc(&s_jmem, jb->size, 0);
+    if ((unsigned long)jb->phys_addr  == (unsigned long)-1) {
+        printk(KERN_ERR "[JPUDRV] Physical memory allocation error size=%d\n", jb->size);
+        return -1;
+    }
+
+    jb->base = (unsigned long)(s_video_memory.base + (jb->phys_addr - s_video_memory.phys_addr));
+#else
+    jb->base = (unsigned long)dma_alloc_coherent(jpu_dev, PAGE_ALIGN(jb->size), (dma_addr_t *) (&jb->phys_addr), GFP_DMA | GFP_KERNEL);
+    if ((void *)(jb->base) == NULL) {
+        printk(KERN_ERR "[JPUDRV] Physical memory allocation error size=%d\n", jb->size);
+        return -1;
+    }
+	starfive_flush_dcache(jb->phys_addr,PAGE_ALIGN(jb->size));
+#endif /* JPU_SUPPORT_RESERVED_VIDEO_MEMORY */
+    return 0;
+}
+
+static void jpu_free_dma_buffer(jpudrv_buffer_t *jb)
+{
+    if (!jb) {
+        return;
+    }
+
+    if (jb->base)
+#ifdef JPU_SUPPORT_RESERVED_VIDEO_MEMORY
+        jmem_free(&s_jmem, jb->phys_addr, 0);
+#else
+        dma_free_coherent(jpu_dev, PAGE_ALIGN(jb->size), (void *)jb->base, jb->phys_addr);
+#endif /* JPUR_SUPPORT_RESERVED_VIDEO_MEMORY */
+}
+
+static int jpu_free_instances(struct file *filp)
+{
+    jpudrv_instance_list_t *vil, *n;
+    jpudrv_instance_pool_t *vip;
+    void *vip_base;
+    int instance_pool_size_per_core;
+    void *jdi_mutexes_base;
+    const int PTHREAD_MUTEX_T_DESTROY_VALUE = 0xdead10cc;
+
+    DPRINTK("[JPUDRV] jpu_free_instances\n");
+
+    instance_pool_size_per_core = (s_instance_pool.size/MAX_NUM_JPU_CORE); /* s_instance_pool.size  assigned to the size of all core once call JDI_IOCTL_GET_INSTANCE_POOL by user. */
+
+    list_for_each_entry_safe(vil, n, &s_inst_list_head, list)
+    {
+        if (vil->filp == filp) {
+            vip_base = (void *)(s_instance_pool.base + instance_pool_size_per_core);
+            DPRINTK("[JPUDRV] jpu_free_instances detect instance crash instIdx=%d, vip_base=%p, instance_pool_size_per_core=%d\n", (int)vil->inst_idx, vip_base, (int)instance_pool_size_per_core);
+            vip = (jpudrv_instance_pool_t *)vip_base;
+            if (vip) {
+                memset(&vip->codecInstPool[vil->inst_idx], 0x00, 4);    /* only first 4 byte is key point(inUse of CodecInst in jpuapi) to free the corresponding instance. */
+#define PTHREAD_MUTEX_T_HANDLE_SIZE 4
+                jdi_mutexes_base = (vip_base + (instance_pool_size_per_core - PTHREAD_MUTEX_T_HANDLE_SIZE*4));
+                DPRINTK("[JPUDRV] jpu_free_instances : force to destroy jdi_mutexes_base=%p in userspace \n", jdi_mutexes_base);
+                if (jdi_mutexes_base) {
+                    int i;
+                    for (i = 0; i < 4; i++) {
+                        memcpy(jdi_mutexes_base, &PTHREAD_MUTEX_T_DESTROY_VALUE, PTHREAD_MUTEX_T_HANDLE_SIZE);
+                        jdi_mutexes_base += PTHREAD_MUTEX_T_HANDLE_SIZE;
+                    }
+                }
+            }
+            s_jpu_open_ref_count--;
+            list_del(&vil->list);
+            kfree(vil);
+        }
+    }
+    return 1;
+}
+
+static int jpu_free_buffers(struct file *filp)
+{
+    jpudrv_buffer_pool_t *pool, *n;
+    jpudrv_buffer_t jb;
+
+    DPRINTK("[JPUDRV] jpu_free_buffers\n");
+
+    list_for_each_entry_safe(pool, n, &s_jbp_head, list)
+    {
+        if (pool->filp == filp) {
+            jb = pool->jb;
+            if (jb.base) {
+                jpu_free_dma_buffer(&jb);
+                list_del(&pool->list);
+                kfree(pool);
+            }
+        }
+    }
+
+    return 0;
+}
+
+
+static irqreturn_t jpu_irq_handler(int irq, void *dev_id)
+{
+    jpu_drv_context_t*  dev = (jpu_drv_context_t *)dev_id;
+    int i;
+    u32 flag;
+
+    DPRINTK("[JPUDRV][+]%s\n", __func__);
+
+#ifdef JPU_IRQ_CONTROL
+    disable_irq_nosync(s_jpu_irq);
+#endif
+
+    for (i=0; i<MAX_NUM_INSTANCE; i++) {
+        flag = ReadJpuRegister(MJPEG_PIC_STATUS_REG(i));
+        if (flag != 0) {
+            break;
+        }
+    }
+
+    dev->interrupt_reason[i] = flag;
+    s_interrupt_flag[i] = 1;
+    DPRINTK("[JPUDRV][%d] INTERRUPT FLAG: %08x, %08x\n", i, dev->interrupt_reason[i], MJPEG_PIC_STATUS_REG(i));
+
+    if (dev->async_queue)
+        kill_fasync(&dev->async_queue, SIGIO, POLL_IN);    // notify the interrupt to userspace
+
+#ifndef JPU_IRQ_CONTROL
+    WriteJpuRegister(MJPEG_PIC_STATUS_REG(i),flag);  	//clear interrut
+#endif
+
+    wake_up_interruptible(&s_interrupt_wait_q[i]);
+
+    DPRINTK("[JPUDRV][-]%s\n", __func__);
+
+    return IRQ_HANDLED;
+}
+
+static int jpu_open(struct inode *inode, struct file *filp)
+{
+    DPRINTK("[JPUDRV][+] %s\n", __func__);
+
+    spin_lock(&s_jpu_lock);
+
+    s_jpu_drv_context.open_count++;
+
+    filp->private_data = (void *)(&s_jpu_drv_context);
+    spin_unlock(&s_jpu_lock);
+
+    DPRINTK("[JPUDRV][-] %s\n", __func__);
+
+    return 0;
+}
+
+static long jpu_ioctl(struct file *filp, u_int cmd, u_long arg)
+{
+    int ret = 0;
+
+    switch (cmd)
+    {
+    case JDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY:
+        {
+            jpudrv_buffer_pool_t *jbp;
+
+            DPRINTK("[JPUDRV][+]JDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY\n");
+            if ((ret = down_interruptible(&s_jpu_sem)) == 0) {
+                jbp = kzalloc(sizeof(jpudrv_buffer_pool_t), GFP_KERNEL);
+                if (!jbp) {
+                    up(&s_jpu_sem);
+                    return -ENOMEM;
+                }
+
+                ret = copy_from_user(&(jbp->jb), (jpudrv_buffer_t *)arg, sizeof(jpudrv_buffer_t));
+                if (ret)
+                {
+                    kfree(jbp);
+                    up(&s_jpu_sem);
+                    return -EFAULT;
+                }
+
+                ret = jpu_alloc_dma_buffer(&(jbp->jb));
+                if (ret == -1)
+                {
+                    ret = -ENOMEM;
+                    kfree(jbp);
+                    up(&s_jpu_sem);
+                    break;
+                }
+                ret = copy_to_user((void __user *)arg, &(jbp->jb), sizeof(jpudrv_buffer_t));
+                if (ret)
+                {
+                    kfree(jbp);
+                    ret = -EFAULT;
+                    up(&s_jpu_sem);
+                    break;
+                }
+
+                jbp->filp = filp;
+                spin_lock(&s_jpu_lock);
+                list_add(&jbp->list, &s_jbp_head);
+                spin_unlock(&s_jpu_lock);
+
+                up(&s_jpu_sem);
+            }
+            DPRINTK("[JPUDRV][-]JDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY\n");
+        }
+        break;
+    case JDI_IOCTL_FREE_PHYSICALMEMORY:
+        {
+            jpudrv_buffer_pool_t *jbp, *n;
+            jpudrv_buffer_t jb;
+
+            DPRINTK("[JPUDRV][+]VDI_IOCTL_FREE_PHYSICALMEMORY\n");
+            if ((ret = down_interruptible(&s_jpu_sem)) == 0) {
+                ret = copy_from_user(&jb, (jpudrv_buffer_t *)arg, sizeof(jpudrv_buffer_t));
+                if (ret) {
+                    up(&s_jpu_sem);
+                    return -EACCES;
+                }
+
+                if (jb.base)
+                    jpu_free_dma_buffer(&jb);
+
+                spin_lock(&s_jpu_lock);
+                list_for_each_entry_safe(jbp, n, &s_jbp_head, list) {
+                    if (jbp->jb.base == jb.base) {
+                        list_del(&jbp->list);
+                        kfree(jbp);
+                        break;
+                    }
+                }
+                spin_unlock(&s_jpu_lock);
+
+                up(&s_jpu_sem);
+            }
+            DPRINTK("[JPUDRV][-]VDI_IOCTL_FREE_PHYSICALMEMORY\n");
+        }
+        break;
+    case JDI_IOCTL_GET_RESERVED_VIDEO_MEMORY_INFO:
+        {
+#ifdef JPU_SUPPORT_RESERVED_VIDEO_MEMORY
+            if (s_video_memory.base != 0) {
+                ret = copy_to_user((void __user *)arg, &s_video_memory, sizeof(jpudrv_buffer_t));
+                if (ret != 0)
+                    ret = -EFAULT;
+            } else {
+                ret = -EFAULT;
+            }
+#endif /* JPU_SUPPORT_RESERVED_VIDEO_MEMORY */
+        }
+        break;
+
+
+    case JDI_IOCTL_WAIT_INTERRUPT:
+        {
+            jpudrv_intr_info_t info;
+            struct jpu_drv_context_t *dev = (struct jpu_drv_context_t *)filp->private_data;
+            u32 instance_no;
+
+            DPRINTK("[JPUDRV][+]JDI_IOCTL_WAIT_INTERRUPT\n");
+            ret = copy_from_user(&info, (jpudrv_intr_info_t *)arg, sizeof(jpudrv_intr_info_t));
+            if (ret != 0)
+                return -EFAULT;
+
+            instance_no = info.inst_idx;
+            DPRINTK("[JPUDRV] INSTANCE NO: %d\n", instance_no);
+            ret = wait_event_interruptible_timeout(s_interrupt_wait_q[instance_no], s_interrupt_flag[instance_no] != 0, msecs_to_jiffies(info.timeout));
+            if (!ret) {
+                DPRINTK("[JPUDRV] INSTANCE NO: %d ETIME\n", instance_no);
+                ret = -ETIME;
+                break;
+            }
+
+            if (signal_pending(current)) {
+                ret = -ERESTARTSYS;
+                DPRINTK("[JPUDRV] INSTANCE NO: %d ERESTARTSYS\n", instance_no);
+                break;
+            }
+
+            DPRINTK("[JPUDRV] INST(%d) s_interrupt_flag(%d), reason(0x%08x)\n", instance_no, s_interrupt_flag[instance_no], dev->interrupt_reason[instance_no]);
+
+            info.intr_reason = dev->interrupt_reason[instance_no];
+            s_interrupt_flag[instance_no] = 0;
+            dev->interrupt_reason[instance_no] = 0;
+            ret = copy_to_user((void __user *)arg, &info, sizeof(jpudrv_intr_info_t));
+#ifdef JPU_IRQ_CONTROL
+            enable_irq(s_jpu_irq);
+#endif
+            DPRINTK("[VPUDRV][-]VDI_IOCTL_WAIT_INTERRUPT\n");
+            if (ret != 0)
+                return -EFAULT;
+        }
+        break;
+    case JDI_IOCTL_SET_CLOCK_GATE:
+        {
+            u32 clkgate;
+
+            if (get_user(clkgate, (u32 __user *) arg))
+                return -EFAULT;
+
+#ifdef JPU_SUPPORT_CLOCK_CONTROL
+            if (clkgate)
+                jpu_clk_enable(s_jpu_clk);
+            else
+                jpu_clk_disable(s_jpu_clk);
+#endif /* JPU_SUPPORT_CLOCK_CONTROL */
+        }
+        break;
+    case JDI_IOCTL_GET_INSTANCE_POOL:
+        DPRINTK("[JPUDRV][+]JDI_IOCTL_GET_INSTANCE_POOL\n");
+
+        if ((ret = down_interruptible(&s_jpu_sem)) == 0) {
+            if (s_instance_pool.base != 0) {
+                ret = copy_to_user((void __user *)arg, &s_instance_pool, sizeof(jpudrv_buffer_t));
+            } else {
+                ret = copy_from_user(&s_instance_pool, (jpudrv_buffer_t *)arg, sizeof(jpudrv_buffer_t));
+                if (ret == 0) {
+                    s_instance_pool.size      = PAGE_ALIGN(s_instance_pool.size);
+                    s_instance_pool.base      = (unsigned long)vmalloc(s_instance_pool.size);
+                    s_instance_pool.phys_addr = s_instance_pool.base;
+
+                    if (s_instance_pool.base != 0) {
+                        memset((void *)s_instance_pool.base, 0x0, s_instance_pool.size); /*clearing memory*/
+                        ret = copy_to_user((void __user *)arg, &s_instance_pool, sizeof(jpudrv_buffer_t));
+                        if (ret == 0) {
+                            /* success to get memory for instance pool */
+                            up(&s_jpu_sem);
+                            break;
+                        }
+                    }
+                    ret = -EFAULT;
+                }
+            }
+            up(&s_jpu_sem);
+        }
+
+        DPRINTK("[JPUDRV][-]JDI_IOCTL_GET_INSTANCE_POOL: %s base: %lx, size: %d\n",
+                (ret==0 ? "OK" : "NG"), s_instance_pool.base, s_instance_pool.size);
+        break;
+    case JDI_IOCTL_OPEN_INSTANCE:
+        {
+            jpudrv_inst_info_t inst_info;
+
+            if (copy_from_user(&inst_info, (jpudrv_inst_info_t *)arg, sizeof(jpudrv_inst_info_t)))
+                return -EFAULT;
+
+            spin_lock(&s_jpu_lock);
+            s_jpu_open_ref_count++; /* flag just for that jpu is in opened or closed */
+            inst_info.inst_open_count = s_jpu_open_ref_count;
+            spin_unlock(&s_jpu_lock);
+
+            if (copy_to_user((void __user *)arg, &inst_info, sizeof(jpudrv_inst_info_t))) {
+                return -EFAULT;
+            }
+
+            DPRINTK("[JPUDRV] JDI_IOCTL_OPEN_INSTANCE inst_idx=%d, s_jpu_open_ref_count=%d, inst_open_count=%d\n",
+                    (int)inst_info.inst_idx, s_jpu_open_ref_count, inst_info.inst_open_count);
+        }
+        break;
+    case JDI_IOCTL_CLOSE_INSTANCE:
+        {
+            jpudrv_inst_info_t inst_info;
+
+            DPRINTK("[JPUDRV][+]JDI_IOCTL_CLOSE_INSTANCE\n");
+            if (copy_from_user(&inst_info, (jpudrv_inst_info_t *)arg, sizeof(jpudrv_inst_info_t)))
+                return -EFAULT;
+
+            spin_lock(&s_jpu_lock);
+            s_jpu_open_ref_count--; /* flag just for that jpu is in opened or closed */
+            inst_info.inst_open_count = s_jpu_open_ref_count;
+            spin_unlock(&s_jpu_lock);
+
+            if (copy_to_user((void __user *)arg, &inst_info, sizeof(jpudrv_inst_info_t)))
+                return -EFAULT;
+
+            DPRINTK("[JPUDRV] JDI_IOCTL_CLOSE_INSTANCE inst_idx=%d, s_jpu_open_ref_count=%d, inst_open_count=%d\n",
+                    (int)inst_info.inst_idx, s_jpu_open_ref_count, inst_info.inst_open_count);
+        }
+        break;
+    case JDI_IOCTL_GET_INSTANCE_NUM:
+        {
+            jpudrv_inst_info_t inst_info;
+
+            DPRINTK("[JPUDRV][+]JDI_IOCTL_GET_INSTANCE_NUM\n");
+
+            ret = copy_from_user(&inst_info, (jpudrv_inst_info_t *)arg, sizeof(jpudrv_inst_info_t));
+            if (ret != 0)
+                break;
+
+            spin_lock(&s_jpu_lock);
+            inst_info.inst_open_count = s_jpu_open_ref_count;
+            spin_unlock(&s_jpu_lock);
+
+            ret = copy_to_user((void __user *)arg, &inst_info, sizeof(jpudrv_inst_info_t));
+
+            DPRINTK("[JPUDRV] JDI_IOCTL_GET_INSTANCE_NUM inst_idx=%d, open_count=%d\n", (int)inst_info.inst_idx, inst_info.inst_open_count);
+        }
+        break;
+    case JDI_IOCTL_RESET:
+        jpu_hw_reset();
+        break;
+
+    case JDI_IOCTL_GET_REGISTER_INFO:
+        DPRINTK("[JPUDRV][+]JDI_IOCTL_GET_REGISTER_INFO\n");
+        ret = copy_to_user((void __user *)arg, &s_jpu_register, sizeof(jpudrv_buffer_t));
+        if (ret != 0)
+            ret = -EFAULT;
+        DPRINTK("[JPUDRV][-]JDI_IOCTL_GET_REGISTER_INFO s_jpu_register.phys_addr=0x%lx, s_jpu_register.virt_addr=0x%lx, s_jpu_register.size=%d\n",
+                s_jpu_register.phys_addr , s_jpu_register.virt_addr, s_jpu_register.size);
+        break;
+    case JDI_IOCTL_FLUSH_DCACHE:
+        {
+            jpudrv_flush_cache_t cache_info;
+
+            //DPRINTK("[JPUDRV][+]JDI_IOCTL_FLUSH_DCACHE\n");
+            ret = copy_from_user(&cache_info, (jpudrv_flush_cache_t *)arg, sizeof(jpudrv_flush_cache_t));
+            if (ret != 0)
+                ret = -EFAULT;
+
+            if(cache_info.flag)
+                starfive_flush_dcache(cache_info.start,cache_info.size);
+
+            //DPRINTK("[JPUDRV][-]JDI_IOCTL_FLUSH_DCACHE\n");
+            break;
+        }
+    default:
+        {
+            printk(KERN_ERR "No such IOCTL, cmd is %d\n", cmd);
+        }
+        break;
+    }
+    return ret;
+}
+
+static ssize_t jpu_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
+{
+
+    return -1;
+}
+
+static ssize_t jpu_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
+{
+
+    /* DPRINTK("[VPUDRV] vpu_write len=%d\n", (int)len); */
+    if (!buf) {
+        printk(KERN_ERR "[VPUDRV] vpu_write buf = NULL error \n");
+        return -EFAULT;
+    }
+
+    return -1;
+}
+
+static int jpu_release(struct inode *inode, struct file *filp)
+{
+    int ret = 0;
+    u32 open_count;
+
+    DPRINTK("[JPUDRV][+] jpu_release\n");
+
+    if ((ret = down_interruptible(&s_jpu_sem)) == 0) {
+
+        /* found and free the not handled buffer by user applications */
+        jpu_free_buffers(filp);
+
+        /* found and free the not closed instance by user applications */
+        jpu_free_instances(filp);
+        DPRINTK("[JPUDRV] open_count: %d\n", s_jpu_drv_context.open_count);
+        spin_lock(&s_jpu_lock);
+        s_jpu_drv_context.open_count--;
+        open_count = s_jpu_drv_context.open_count;
+        spin_unlock(&s_jpu_lock);
+        if (open_count == 0) {
+            if (s_instance_pool.base) {
+                DPRINTK("[JPUDRV] free instance pool\n");
+                vfree((const void *)s_instance_pool.base);
+                s_instance_pool.base = 0;
+            }
+
+
+        }
+    }
+    up(&s_jpu_sem);
+
+    DPRINTK("[JPUDRV][-] jpu_release\n");
+
+    return 0;
+}
+
+
+static int jpu_fasync(int fd, struct file *filp, int mode)
+{
+    struct jpu_drv_context_t *dev = (struct jpu_drv_context_t *)filp->private_data;
+    return fasync_helper(fd, filp, mode, &dev->async_queue);
+}
+
+
+
+
+static int jpu_map_to_register(struct file *fp, struct vm_area_struct *vm)
+{
+    unsigned long pfn;
+
+    vm->vm_flags |= VM_IO | VM_RESERVED;
+    vm->vm_page_prot = pgprot_noncached(vm->vm_page_prot);
+    pfn = s_jpu_register.phys_addr >> PAGE_SHIFT;
+
+    return remap_pfn_range(vm, vm->vm_start, pfn, vm->vm_end-vm->vm_start, vm->vm_page_prot) ? -EAGAIN : 0;
+}
+
+static int jpu_map_to_physical_memory(struct file *fp, struct vm_area_struct *vm)
+{
+    vm->vm_flags |= VM_IO | VM_RESERVED;
+    vm->vm_page_prot = pgprot_noncached(vm->vm_page_prot);
+
+    return remap_pfn_range(vm, vm->vm_start, vm->vm_pgoff, vm->vm_end-vm->vm_start, vm->vm_page_prot) ? -EAGAIN : 0;
+}
+
+static int jpu_map_to_instance_pool_memory(struct file *fp, struct vm_area_struct *vm)
+{
+    int ret;
+    long length = vm->vm_end - vm->vm_start;
+    unsigned long start = vm->vm_start;
+    char *vmalloc_area_ptr = (char *)s_instance_pool.base;
+    unsigned long pfn;
+
+    vm->vm_flags |= VM_RESERVED;
+
+    /* loop over all pages, map it page individually */
+    while (length > 0) {
+        pfn = vmalloc_to_pfn(vmalloc_area_ptr);
+        if ((ret = remap_pfn_range(vm, start, pfn, PAGE_SIZE, PAGE_SHARED)) < 0) {
+            return ret;
+        }
+        start += PAGE_SIZE;
+        vmalloc_area_ptr += PAGE_SIZE;
+        length -= PAGE_SIZE;
+    }
+
+
+    return 0;
+}
+
+/*!
+* @brief memory map interface for jpu file operation
+* @return  0 on success or negative error code on error
+*/
+static int jpu_mmap(struct file *fp, struct vm_area_struct *vm)
+{
+    if (vm->vm_pgoff == 0)
+        return jpu_map_to_instance_pool_memory(fp, vm);
+
+    if (vm->vm_pgoff == (s_jpu_register.phys_addr>>PAGE_SHIFT))
+        return jpu_map_to_register(fp, vm);
+
+    return jpu_map_to_physical_memory(fp, vm);
+}
+
+struct file_operations jpu_fops = {
+    .owner = THIS_MODULE,
+    .open = jpu_open,
+    .read = jpu_read,
+    .write = jpu_write,
+    .unlocked_ioctl = jpu_ioctl,
+    .release = jpu_release,
+    .fasync = jpu_fasync,
+    .mmap = jpu_mmap,
+};
+
+
+
+static int jpu_probe(struct platform_device *pdev)
+{
+    int err = 0;
+    struct resource *res = NULL;
+#ifdef JPU_SUPPORT_RESERVED_VIDEO_MEMORY
+	struct resource res_cma;
+	struct device_node *node;
+#endif
+
+    DPRINTK("[JPUDRV] jpu_probe\n");
+    if (pdev) {
+        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+    }
+
+    if (res) {/* if platform driver is implemented */
+        s_jpu_register.phys_addr = res->start;
+        s_jpu_register.virt_addr = (unsigned long)ioremap(res->start, res->end - res->start);
+        s_jpu_register.size      = res->end - res->start;
+        DPRINTK("[JPUDRV] : jpu base address get from platform driver physical base addr==0x%lx, virtual base=0x%lx\n", s_jpu_register.phys_addr , s_jpu_register.virt_addr);
+    } else {
+        s_jpu_register.phys_addr = JPU_REG_BASE_ADDR;
+        s_jpu_register.virt_addr = (unsigned long)ioremap(s_jpu_register.phys_addr, JPU_REG_SIZE);
+        s_jpu_register.size      = JPU_REG_SIZE;
+        DPRINTK("[JPUDRV] : jpu base address get from defined value physical base addr==0x%lx, virtual base=0x%lx\n", s_jpu_register.phys_addr, s_jpu_register.virt_addr);
+    }
+    if (pdev) {
+        jpu_dev = &pdev->dev;
+		//jpu_dev->dma_ops = NULL;
+        dev_info(jpu_dev,"init device.\n");
+    }
+    /* get the major number of the character device */
+    if ((alloc_chrdev_region(&s_jpu_major, 0, 1, JPU_DEV_NAME)) < 0) {
+        err = -EBUSY;
+        printk(KERN_ERR "could not allocate major number\n");
+        goto ERROR_PROVE_DEVICE;
+    }
+
+    /* initialize the device structure and register the device with the kernel */
+    cdev_init(&s_jpu_cdev, &jpu_fops);
+    if ((cdev_add(&s_jpu_cdev, s_jpu_major, 1)) < 0) {
+        err = -EBUSY;
+        printk(KERN_ERR "could not allocate chrdev\n");
+
+        goto ERROR_PROVE_DEVICE;
+    }
+
+    if (pdev)
+        s_jpu_clk = jpu_clk_get(&pdev->dev);
+    else
+        s_jpu_clk = jpu_clk_get(NULL);
+
+    if (!s_jpu_clk) {
+        printk(KERN_ERR "[JPUDRV] : not support clock controller.\n");
+    }
+    else {
+        DPRINTK("[JPUDRV] : get clock controller s_jpu_clk=%p\n", s_jpu_clk);
+    }
+
+#ifdef JPU_SUPPORT_CLOCK_CONTROL
+#else
+    jpu_clk_enable(s_jpu_clk);
+#endif
+
+
+#ifdef JPU_SUPPORT_ISR
+#ifdef JPU_SUPPORT_PLATFORM_DRIVER_REGISTER
+    if(pdev)
+        res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+    if (res) {/* if platform driver is implemented */
+        s_jpu_irq = res->start;
+        DPRINTK("[JPUDRV] : jpu irq number get from platform driver irq=0x%x\n", s_jpu_irq );
+    } else {
+        DPRINTK("[JPUDRV] : jpu irq number get from defined value irq=0x%x\n", s_jpu_irq );
+    }
+#else
+    DPRINTK("[JPUDRV] : jpu irq number get from defined value irq=0x%x\n", s_jpu_irq);
+#endif
+
+
+    err = request_irq(s_jpu_irq, jpu_irq_handler, 0, "JPU_CODEC_IRQ", (void *)(&s_jpu_drv_context));
+    if (err) {
+        printk(KERN_ERR "[JPUDRV] :  fail to register interrupt handler\n");
+        goto ERROR_PROVE_DEVICE;
+    }
+#endif
+
+#ifdef JPU_SUPPORT_RESERVED_VIDEO_MEMORY
+	node = of_parse_phandle(jpu_dev->of_node, "memory-region", 0);
+	if(node){
+		dev_info(jpu_dev, "Get mem form memory-region\n");
+		of_address_to_resource(node, 0, &res_cma);
+		s_video_memory.size = resource_size(&res_cma);
+    	s_video_memory.phys_addr = res_cma.start;
+	}else{
+        dev_info(jpu_dev, "Get mem form reserved memory failed.please check the dts file.\n");
+		return 0;
+    }
+    s_video_memory.base = (unsigned long)ioremap(MEM2SYS(s_video_memory.phys_addr), PAGE_ALIGN(s_video_memory.size));
+	if (!s_video_memory.base) {
+        printk(KERN_ERR "[JPUDRV] :  fail to remap video memory physical phys_addr=0x%lx, base=0x%lx, size=%d\n", MEM2SYS(s_video_memory.phys_addr), s_video_memory.base, s_video_memory.size);
+        goto ERROR_PROVE_DEVICE;
+    }
+
+    if (jmem_init(&s_jmem, s_video_memory.phys_addr, s_video_memory.size) < 0) {
+        printk(KERN_ERR "[JPUDRV] :  fail to init vmem system\n");
+        goto ERROR_PROVE_DEVICE;
+    }
+    DPRINTK("[JPUDRV] success to probe jpu device with reserved video memory phys_addr=0x%lx, base=0x%lx\n", s_video_memory.phys_addr, s_video_memory.base);
+#else
+    DPRINTK("[JPUDRV] success to probe jpu device with non reserved video memory\n");
+#endif
+
+    return 0;
+
+
+ERROR_PROVE_DEVICE:
+
+    if (s_jpu_major)
+        unregister_chrdev_region(s_jpu_major, 1);
+
+    if (s_jpu_register.virt_addr)
+        iounmap((void *)s_jpu_register.virt_addr);
+
+    return err;
+}
+
+static int jpu_remove(struct platform_device *pdev)
+{
+    DPRINTK("[JPUDRV] jpu_remove\n");
+#ifdef JPU_SUPPORT_PLATFORM_DRIVER_REGISTER
+
+    if (s_instance_pool.base) {
+        vfree((const void *)s_instance_pool.base);
+        s_instance_pool.base = 0;
+    }
+#ifdef JPU_SUPPORT_RESERVED_VIDEO_MEMORY
+    if (s_video_memory.base) {
+        iounmap((void *)s_video_memory.base);
+        s_video_memory.base = 0;
+        jmem_exit(&s_jmem);
+    }
+#endif
+
+    if (s_jpu_major > 0) {
+        cdev_del(&s_jpu_cdev);
+        unregister_chrdev_region(s_jpu_major, 1);
+        s_jpu_major = 0;
+    }
+
+#ifdef JPU_SUPPORT_ISR
+    if (s_jpu_irq)
+        free_irq(s_jpu_irq, &s_jpu_drv_context);
+#endif
+
+    if (s_jpu_register.virt_addr)
+        iounmap((void*)s_jpu_register.virt_addr);
+
+    jpu_clk_put(s_jpu_clk);
+
+#endif /* JPU_SUPPORT_PLATFORM_DRIVER_REGISTER */
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int jpu_suspend(struct platform_device *pdev, pm_message_t state)
+{
+    jpu_clk_disable(s_jpu_clk);
+    return 0;
+
+}
+static int jpu_resume(struct platform_device *pdev)
+{
+    jpu_clk_enable(s_jpu_clk);
+
+    return 0;
+}
+#else
+#define    jpu_suspend    NULL
+#define    jpu_resume    NULL
+#endif /* !CONFIG_PM */
+
+#ifdef JPU_SUPPORT_PLATFORM_DRIVER_REGISTER
+static const struct of_device_id jpu_of_id_table[] = {
+	{ .compatible = "cm,codaj12-jpu-1" },
+	{}
+};
+
+static struct platform_driver jpu_driver = {
+    .driver = {
+        .name = JPU_PLATFORM_DEVICE_NAME,
+        .of_match_table = of_match_ptr(jpu_of_id_table),
+    },
+    .probe      = jpu_probe,
+    .remove     = jpu_remove,
+    .suspend    = jpu_suspend,
+    .resume     = jpu_resume,
+};
+#endif /* JPU_SUPPORT_PLATFORM_DRIVER_REGISTER */
+
+static int __init jpu_init(void)
+{
+    int res = 0;
+    u32 i;
+
+    DPRINTK("[JPUDRV] begin jpu_init\n");
+    for (i=0; i<MAX_NUM_INSTANCE; i++) {
+        init_waitqueue_head(&s_interrupt_wait_q[i]);
+    }
+    s_instance_pool.base = 0;
+#ifdef JPU_SUPPORT_PLATFORM_DRIVER_REGISTER
+    res = platform_driver_register(&jpu_driver);
+#else
+    res = jpu_probe(NULL);
+#endif /* JPU_SUPPORT_PLATFORM_DRIVER_REGISTER */
+
+    DPRINTK("[JPUDRV] end jpu_init result=0x%x\n", res);
+    return res;
+}
+
+static void __exit jpu_exit(void)
+{
+    DPRINTK("[JPUDRV] [+]jpu_exit\n");
+#ifdef JPU_SUPPORT_PLATFORM_DRIVER_REGISTER
+    platform_driver_unregister(&jpu_driver);
+#else /* JPU_SUPPORT_PLATFORM_DRIVER_REGISTER */
+#ifdef JPU_SUPPORT_CLOCK_CONTROL
+#else
+    jpu_clk_disable(s_jpu_clk);
+#endif /* JPU_SUPPORT_CLOCK_CONTROL */
+    jpu_clk_put(s_jpu_clk);
+    if (s_instance_pool.base) {
+        vfree((const void *)s_instance_pool.base);
+        s_instance_pool.base = 0;
+    }
+#ifdef JPU_SUPPORT_RESERVED_VIDEO_MEMORY
+    if (s_video_memory.base) {
+        iounmap((void *)s_video_memory.base);
+        s_video_memory.base = 0;
+
+        jmem_exit(&s_jmem);
+    }
+#endif /* JPU_SUPPORT_RESERVED_VIDEO_MEMORY */
+
+    if (s_jpu_major > 0) {
+        cdev_del(&s_jpu_cdev);
+        unregister_chrdev_region(s_jpu_major, 1);
+        s_jpu_major = 0;
+    }
+
+#ifdef JPU_SUPPORT_ISR
+    if (s_jpu_irq)
+        free_irq(s_jpu_irq, &s_jpu_drv_context);
+#endif /* JPU_SUPPORT_ISR */
+
+    if (s_jpu_register.virt_addr) {
+        iounmap((void *)s_jpu_register.virt_addr);
+        s_jpu_register.virt_addr = 0x00;
+    }
+
+#endif /* JPU_SUPPORT_PLATFORM_DRIVER_REGISTER */
+    DPRINTK("[JPUDRV] [-]jpu_exit\n");
+
+    return;
+}
+
+MODULE_AUTHOR("A customer using C&M JPU, Inc.");
+MODULE_DESCRIPTION("JPU linux driver");
+MODULE_LICENSE("GPL");
+
+module_init(jpu_init);
+module_exit(jpu_exit);
+
+static int jpu_hw_reset(void)
+{
+    DPRINTK("[JPUDRV] request jpu reset from application. \n");
+    return 0;
+}
+
+
+struct clk *jpu_clk_get(struct device *dev)
+{
+    return clk_get(dev, JPU_CLK_NAME);
+}
+void jpu_clk_put(struct clk *clk)
+{
+    if (!(clk == NULL || IS_ERR(clk)))
+        clk_put(clk);
+}
+int jpu_clk_enable(struct clk *clk)
+{
+
+    if (clk) {
+        DPRINTK("[JPUDRV] jpu_clk_enable\n");
+        // You need to implement it
+        return 1;
+    }
+    return 0;
+}
+
+void jpu_clk_disable(struct clk *clk)
+{
+    if (!(clk == NULL || IS_ERR(clk))) {
+        DPRINTK("[JPUDRV] jpu_clk_disable\n");
+        // You need to implement it
+    }
+}
+
+
+

+ 49 - 0
codaj12/jdi/linux/driver/jpu.h

@@ -0,0 +1,49 @@
+
+
+#ifndef __JPU_DRV_H__
+#define __JPU_DRV_H__
+
+#include <linux/fs.h>
+#include <linux/types.h>
+
+#define JDI_IOCTL_MAGIC  'J'
+
+#define JDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY          _IO(JDI_IOCTL_MAGIC, 0)
+#define JDI_IOCTL_FREE_PHYSICALMEMORY               _IO(JDI_IOCTL_MAGIC, 1)
+#define JDI_IOCTL_WAIT_INTERRUPT                    _IO(JDI_IOCTL_MAGIC, 2)
+#define JDI_IOCTL_SET_CLOCK_GATE                    _IO(JDI_IOCTL_MAGIC, 3)
+#define JDI_IOCTL_RESET                             _IO(JDI_IOCTL_MAGIC, 4)
+#define JDI_IOCTL_GET_INSTANCE_POOL                 _IO(JDI_IOCTL_MAGIC, 5)
+#define JDI_IOCTL_GET_RESERVED_VIDEO_MEMORY_INFO    _IO(JDI_IOCTL_MAGIC, 6)
+#define JDI_IOCTL_GET_REGISTER_INFO                 _IO(JDI_IOCTL_MAGIC, 7)
+#define JDI_IOCTL_OPEN_INSTANCE                     _IO(JDI_IOCTL_MAGIC, 8)
+#define JDI_IOCTL_CLOSE_INSTANCE                    _IO(JDI_IOCTL_MAGIC, 9)
+#define JDI_IOCTL_GET_INSTANCE_NUM                  _IO(JDI_IOCTL_MAGIC, 10)
+#define JDI_IOCTL_FLUSH_DCACHE                 		_IO(JDI_IOCTL_MAGIC, 11)
+
+#define MEM2SYS(addr) ((addr) > 0x80000000 && (addr) < 0x87FFFFFFF ? ((addr)+0xF80000000):(addr))
+
+typedef struct jpudrv_flush_cache_t {
+    unsigned long start;
+    unsigned long size;
+    unsigned char flag;
+} jpudrv_flush_cache_t;
+
+typedef struct jpudrv_buffer_t {
+    unsigned int size;
+    unsigned long phys_addr;
+    unsigned long base;                     /* kernel logical address in use kernel */
+    unsigned long virt_addr;                /* virtual user space address */
+} jpudrv_buffer_t;
+
+typedef struct jpudrv_inst_info_t {
+    unsigned int inst_idx;
+    int inst_open_count;    /* for output only*/
+} jpudrv_inst_info_t;
+
+typedef struct jpudrv_intr_info_t {
+    unsigned int    timeout;
+    int             intr_reason;
+    unsigned int    inst_idx;
+} jpudrv_intr_info_t;
+#endif

+ 2 - 0
codaj12/jdi/linux/driver/jpu.mod

@@ -0,0 +1,2 @@
+/home/samin/data/startlight/freedom-u-sdk/soft_3rdparty/codaj12/jdi/linux/driver/jpu.o
+

+ 26 - 0
codaj12/jdi/linux/driver/load

@@ -0,0 +1,26 @@
+#!/bin/sh
+
+module="jpu"
+device="jpu"
+mode="664"
+
+# Group: since distributions do	it differently,	look for wheel or use staff
+if grep	'^staff:' /etc/group > /dev/null; then
+    group="staff"
+else
+    group="wheel"
+fi
+
+# invoke insmod	with all arguments we got
+# and use a pathname, as newer modutils	don't look in .	by default
+/sbin/insmod -f	./$module.ko $*	|| exit	1
+
+major=`cat /proc/devices | awk "\\$2==\"$module\" {print \\$1}"`
+
+# Remove stale nodes and replace them, then give gid and perms
+# Usually the script is	shorter, it's simple that has several devices in it.
+
+rm -f /dev/${device}
+mknod /dev/${device} c $major 0
+chgrp $group /dev/${device}
+chmod $mode  /dev/${device}

+ 25 - 0
codaj12/jdi/linux/driver/load.sh

@@ -0,0 +1,25 @@
+#!/bin/sh
+
+module="jpu"
+device="jpu"
+mode="664"
+
+# Group: since distributions do	it differently,	look for wheel or use staff
+if grep	'^staff:' /etc/group > /dev/null; then
+    group="staff"
+else
+    group="wheel"
+fi
+
+# invoke insmod	with all arguments we got
+# and use a pathname, as newer modutils	don't look in .	by default
+/sbin/insmod ./$module.ko $*	|| exit	1
+
+major=`cat /proc/devices | grep "$device"|awk {'print $1'}`
+# Remove stale nodes and replace them, then give gid and perms
+# Usually the script is	shorter, it's simple that has several devices in it.
+
+rm -f /dev/${device}
+mknod /dev/${device} c $major 0
+chgrp $group /dev/${device}
+chmod $mode  /dev/${device}

+ 24 - 0
codaj12/jdi/linux/driver/load_android.sh

@@ -0,0 +1,24 @@
+module="jpu"
+device="jpu"
+mode="664"
+
+# invoke insmod	with all arguments we got
+# and use a pathname, as newer modutils	don't look in .	by default
+/system/bin/insmod /system/lib/modules/$module.ko $*	|| exit	1
+echo "module $module inserted"
+
+#remove old nod
+rm -f /dev/${device}
+
+#read the major asigned at loading time
+major=`cat /proc/devices | busybox awk "\\$2==\"$module\" {print \\$1}"`
+echo "$module major = $major"
+
+# Remove stale nodes and replace them, then give gid and perms
+# Usually the script is	shorter, it's simple that has several devices in it.
+
+busybox mknod /dev/${device} c $major 0
+echo "node $device created"
+
+chmod $mode  /dev/${device}
+echo "set node access to $mode"

+ 14 - 0
codaj12/jdi/linux/driver/unload

@@ -0,0 +1,14 @@
+#!/bin/sh
+module="jpu"
+device="jpu"
+
+# invoke rmmod with all	arguments we got
+/sbin/rmmod $module $* || exit 1
+
+# Remove stale nodes
+rm -f /dev/${device} 
+
+
+
+
+ 

+ 14 - 0
codaj12/jdi/linux/driver/unload.sh

@@ -0,0 +1,14 @@
+#!/bin/sh
+module="jpu"
+device="jpu"
+
+# invoke rmmod with all	arguments we got
+/sbin/rmmod $module $* || exit 1
+
+# Remove stale nodes
+rm -f /dev/${device} 
+
+
+
+
+ 

+ 13 - 0
codaj12/jdi/linux/driver/unload_android.sh

@@ -0,0 +1,13 @@
+module="jpu"
+device="jpu"
+
+# invoke rmmod with all	arguments we got
+/system/bin/rmmod $module $* || exit 1
+
+# Remove stale nodes
+rm -f /dev/${device} 
+
+
+
+
+ 

+ 834 - 0
codaj12/jdi/linux/jdi.c

@@ -0,0 +1,834 @@
+/*
+ * Copyright (c) 2018, Chips&Media
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#if defined(linux) || defined(__linux) || defined(ANDROID)
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#ifdef    _KERNEL_
+#include <linux/delay.h>
+#endif
+#include <signal.h>        /* SIGIO */
+#include <fcntl.h>        /* fcntl */
+#include <pthread.h>
+#include <sys/mman.h>        /* mmap */
+#include <sys/ioctl.h>        /* fopen/fread */
+#include <sys/errno.h>        /* fopen/fread */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <termios.h>
+
+#include "driver/jpu.h"
+#include "../jdi.h"
+#include "jpulog.h"
+#include "jputypes.h"
+#include "regdefine.h"
+
+
+#define JPU_DEVICE_NAME "/dev/jpu"
+#define JDI_INSTANCE_POOL_SIZE          sizeof(jpu_instance_pool_t)
+#define JDI_INSTANCE_POOL_TOTAL_SIZE    (JDI_INSTANCE_POOL_SIZE + sizeof(MUTEX_HANDLE)*JDI_NUM_LOCK_HANDLES)
+typedef pthread_mutex_t    MUTEX_HANDLE;
+
+#endif /* CNM_FPGA_PLATFORM */
+
+
+
+/***********************************************************************************
+*
+***********************************************************************************/
+
+#define JDI_DRAM_PHYSICAL_BASE          0x00
+#define JDI_DRAM_PHYSICAL_SIZE          (64*1024*1024)
+#define JDI_SYSTEM_ENDIAN               JDI_LITTLE_ENDIAN
+#define JPU_REG_SIZE                    0x300
+#define JDI_NUM_LOCK_HANDLES            4
+
+typedef struct jpudrv_buffer_pool_t
+{
+    jpudrv_buffer_t jdb;
+    BOOL            inuse;
+} jpudrv_buffer_pool_t;
+
+typedef struct  {
+    Int32                   jpu_fd;
+    jpu_instance_pool_t*    pjip;
+    Int32                   task_num;
+    Int32                   clock_state;
+    jpudrv_buffer_t         jdb_register;
+    jpudrv_buffer_pool_t    jpu_buffer_pool[MAX_JPU_BUFFER_POOL];
+    Int32                   jpu_buffer_pool_count;
+    void*                   jpu_mutex;
+} jdi_info_t;
+
+static jdi_info_t s_jdi_info;
+
+static Int32 swap_endian(BYTE* data, Uint32 len, Uint32 endian);
+
+void jdi_flush_ddr(unsigned long start,unsigned long size,unsigned char flag)
+{
+	jdi_info_t *jdi;
+	jpudrv_flush_cache_t cache_info;
+	
+	jdi = &s_jdi_info;
+	cache_info.start = start;
+	cache_info.size = size;
+	cache_info.flag = flag;
+
+	ioctl(jdi->jpu_fd, JDI_IOCTL_FLUSH_DCACHE, &cache_info);
+}
+
+int jdi_probe()
+{
+    int ret;
+
+    ret = jdi_init();
+    jdi_release();
+
+    return ret;
+}
+
+/* @return number of tasks.
+ */
+int jdi_get_task_num()
+{
+    jdi_info_t *jdi;
+
+    jdi = &s_jdi_info;
+
+    if (jdi->jpu_fd == -1 || jdi->jpu_fd == 0x00) {
+        return 0;
+    }
+
+    return jdi->task_num;
+}
+
+
+int jdi_init()
+{
+    jdi_info_t *jdi;
+    int i;
+
+    jdi = &s_jdi_info;
+
+    if (jdi->jpu_fd != -1 && jdi->jpu_fd != 0x00)
+    {
+        jdi_lock();
+        jdi->task_num++;
+        jdi_unlock();
+        return 0;
+    }
+
+#ifdef ANDROID
+    system("/system/lib/modules/load_android.sh");
+#endif /* ANDROID */
+
+    jdi->jpu_fd = open(JPU_DEVICE_NAME, O_RDWR);
+    if (jdi->jpu_fd < 0) {
+        JLOG(ERR, "[JDI] Can't open jpu driver. [error=%s]. try to run jdi/linux/driver/load.sh script \n", strerror(errno));
+        return -1;
+    }
+
+    memset(jdi->jpu_buffer_pool, 0x00, sizeof(jpudrv_buffer_pool_t)*MAX_JPU_BUFFER_POOL);
+
+    if (!jdi_get_instance_pool()) {
+        JLOG(ERR, "[JDI] fail to create instance pool for saving context \n");
+        goto ERR_JDI_INIT;
+    }
+
+    if (jdi->pjip->instance_pool_inited == FALSE) {
+        Uint32* pCodecInst;
+        pthread_mutexattr_t mutexattr;
+        pthread_mutexattr_init(&mutexattr);
+        pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED);
+#if defined(ANDROID) || !defined(PTHREAD_MUTEX_ROBUST_NP)
+#else
+         /* If a process or a thread is terminated abnormally,
+         * pthread_mutexattr_setrobust_np(attr, PTHREAD_MUTEX_ROBUST_NP) makes
+         * next onwer call pthread_mutex_lock() without deadlock.
+         */
+        pthread_mutexattr_setrobust_np(&mutexattr, PTHREAD_MUTEX_ROBUST_NP);
+#endif
+        pthread_mutex_init((MUTEX_HANDLE *)jdi->jpu_mutex, &mutexattr);
+
+        for( i = 0; i < MAX_NUM_INSTANCE; i++) {
+            pCodecInst    = (Uint32*)jdi->pjip->jpgInstPool[i];
+            pCodecInst[1] = i;    // indicate instIndex of CodecInst
+            pCodecInst[0] = 0;    // indicate inUse of CodecInst
+        }
+        jdi->pjip->instance_pool_inited = TRUE;
+    }
+    if (ioctl(jdi->jpu_fd, JDI_IOCTL_GET_REGISTER_INFO, &jdi->jdb_register) < 0)
+    {
+        JLOG(ERR, "[JDI] fail to get host interface register\n");
+        goto ERR_JDI_INIT;
+    }
+    jdi->jdb_register.virt_addr = (unsigned long)mmap(NULL, jdi->jdb_register.size, PROT_READ | PROT_WRITE, MAP_SHARED, jdi->jpu_fd, jdi->jdb_register.phys_addr);
+    if (jdi->jdb_register.virt_addr == (unsigned long)MAP_FAILED) {
+        JLOG(ERR, "[JDI] fail to map jpu registers \n");
+        goto ERR_JDI_INIT;
+    }
+    JLOG(INFO, "[JDI] map jdb_register virtaddr=0x%lx, size=%d\n", jdi->jdb_register.virt_addr, jdi->jdb_register.size);
+    jdi_set_clock_gate(1);
+
+
+
+    if (jdi_lock() < 0)
+    {
+        JLOG(ERR, "[JDI] fail to handle lock function\n");
+        goto ERR_JDI_INIT;
+    }
+
+    jdi->task_num++;
+    jdi_unlock();
+
+    JLOG(INFO, "[JDI] success to init driver \n");
+    return 0;
+
+ERR_JDI_INIT:
+    jdi_unlock();
+    jdi_release();
+    return -1;
+}
+
+int jdi_release()
+{
+    jdi_info_t *jdi;
+
+    jdi = &s_jdi_info;
+    if (!jdi || jdi->jpu_fd == -1 || jdi->jpu_fd == 0x00) {
+        return 0;
+    }
+
+    if (jdi_lock() < 0) {
+        JLOG(ERR, "[JDI] fail to handle lock function\n");
+        return -1;
+    }
+
+    if (jdi->task_num == 0) {
+        JLOG(ERR, "[JDI] %s:%d task_num is 0\n", __FUNCTION__, __LINE__);
+        jdi_unlock();
+        return 0;
+    }
+
+    jdi->task_num--;
+    if (jdi->task_num > 0) {// means that the opened instance remains
+        jdi_unlock();
+        return 0;
+    }
+    if (jdi->jdb_register.virt_addr) {
+        if (munmap((void *)jdi->jdb_register.virt_addr, jdi->jdb_register.size) < 0) { //lint !e511
+            JLOG(ERR, "%s:%d failed to munmap\n", __FUNCTION__, __LINE__);
+        }
+    }
+
+    memset(&jdi->jdb_register, 0x00, sizeof(jpudrv_buffer_t));
+    jdi_unlock();
+    if (jdi->jpu_fd != -1 && jdi->jpu_fd != 0x00) {
+        if (jdi->pjip != NULL) {
+            if (munmap((void*)jdi->pjip, JDI_INSTANCE_POOL_TOTAL_SIZE) < 0) {
+                JLOG(ERR, "%s:%d failed to munmap\n", __FUNCTION__, __LINE__);
+            }
+        }
+        close(jdi->jpu_fd);
+    }
+
+    memset(jdi, 0x00, sizeof(jdi_info_t));
+
+    return 0;
+}
+
+jpu_instance_pool_t *jdi_get_instance_pool()
+{
+    jdi_info_t *jdi;
+    jpudrv_buffer_t jdb;
+
+    jdi = &s_jdi_info;
+
+    if(!jdi || jdi->jpu_fd == -1 || jdi->jpu_fd == 0x00 )
+        return NULL;
+
+    memset(&jdb, 0x00, sizeof(jpudrv_buffer_t));
+    if (!jdi->pjip) {
+        jdb.size = JDI_INSTANCE_POOL_TOTAL_SIZE;
+        if (ioctl(jdi->jpu_fd, JDI_IOCTL_GET_INSTANCE_POOL, &jdb) < 0) {
+            JLOG(ERR, "[JDI] fail to allocate get instance pool physical space=%d\n", (int)jdb.size);
+            return NULL;
+        }
+
+        jdb.virt_addr = (unsigned long)mmap(NULL, jdb.size, PROT_READ | PROT_WRITE, MAP_SHARED, jdi->jpu_fd, 0);
+        if (jdb.virt_addr == (unsigned long)MAP_FAILED) {
+            JLOG(ERR, "[JDI] fail to map instance pool phyaddr=0x%lx, size = %d\n", (int)jdb.phys_addr, (int)jdb.size);
+            return NULL;
+        }
+        jdi->pjip      = (jpu_instance_pool_t *)jdb.virt_addr;//lint !e511
+        //change the pointer of jpu_mutex to at end pointer of jpu_instance_pool_t to assign at allocated position.
+        jdi->jpu_mutex = (void *)((unsigned long)jdi->pjip + JDI_INSTANCE_POOL_SIZE); //lint !e511
+
+        JLOG(INFO, "[JDI] instance pool physaddr=%p, virtaddr=%p, base=%p, size=%d\n", jdb.phys_addr, jdb.virt_addr, jdb.base, jdb.size);
+    }
+
+    return (jpu_instance_pool_t *)jdi->pjip;
+}
+
+int jdi_open_instance(unsigned long inst_idx)
+{
+    jdi_info_t *jdi;
+    jpudrv_inst_info_t inst_info;
+
+    jdi = &s_jdi_info;
+
+    if(!jdi || jdi->jpu_fd == -1 || jdi->jpu_fd == 0x00)
+        return -1;
+
+    inst_info.inst_idx = inst_idx;
+    if (ioctl(jdi->jpu_fd, JDI_IOCTL_OPEN_INSTANCE, &inst_info) < 0)
+    {
+        JLOG(ERR, "[JDI] fail to deliver open instance num inst_idx=%d\n", (int)inst_idx);
+        return -1;
+    }
+    jdi->pjip->jpu_instance_num = inst_info.inst_open_count;
+
+    return 0;
+}
+
+int jdi_close_instance(unsigned long inst_idx)
+{
+    jdi_info_t *jdi;
+    jpudrv_inst_info_t inst_info;
+
+    jdi = &s_jdi_info;
+
+    if(!jdi || jdi->jpu_fd == -1 || jdi->jpu_fd == 0x00)
+        return -1;
+
+    inst_info.inst_idx = inst_idx;
+    if (ioctl(jdi->jpu_fd, JDI_IOCTL_CLOSE_INSTANCE, &inst_info) < 0)
+    {
+        JLOG(ERR, "[JDI] fail to deliver open instance num inst_idx=%d\n", (int)inst_idx);
+        return -1;
+    }
+    jdi->pjip->jpu_instance_num = inst_info.inst_open_count;
+
+    return 0;
+}
+int jdi_get_instance_num()
+{
+    jdi_info_t *jdi;
+    jdi = &s_jdi_info;
+
+    if(!jdi || jdi->jpu_fd == -1 || jdi->jpu_fd == 0x00)
+        return -1;
+
+    return jdi->pjip->jpu_instance_num;
+}
+
+int jdi_hw_reset()
+{
+    jdi_info_t *jdi;
+    jdi = &s_jdi_info;
+
+    if(!jdi || jdi->jpu_fd == -1 || jdi->jpu_fd == 0x00)
+        return -1;
+
+    return ioctl(jdi->jpu_fd, JDI_IOCTL_RESET, 0);
+
+}
+
+static void restore_mutex_in_dead(MUTEX_HANDLE *mutex)
+{
+    int mutex_value;
+
+    if (!mutex)
+        return;
+#if defined(ANDROID)
+    mutex_value = mutex->value;
+#else
+    memcpy(&mutex_value, mutex, sizeof(mutex_value));
+#endif
+    if (mutex_value == (int)0xdead10cc) // destroy by device driver
+    {
+        pthread_mutexattr_t mutexattr;
+        pthread_mutexattr_init(&mutexattr);
+        pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED);
+        pthread_mutex_init(mutex, &mutexattr);
+    }
+}
+
+int jdi_lock()
+{
+    jdi_info_t *jdi = &s_jdi_info;
+
+    if(!jdi || jdi->jpu_fd == -1 || jdi->jpu_fd == 0x00) {
+        JLOG(ERR, "%s:%d JDI handle isn't initialized\n", __FUNCTION__, __LINE__);
+        return -1;
+    }
+
+
+#if defined(ANDROID) || !defined(PTHREAD_MUTEX_ROBUST_NP)
+    restore_mutex_in_dead((MUTEX_HANDLE *)jdi->jpu_mutex);
+    pthread_mutex_lock((MUTEX_HANDLE*)jdi->jpu_mutex);
+#else
+    if (pthread_mutex_lock(&jdi->jpu_mutex) != 0) {
+        JLOG(ERR, "%s:%d failed to pthread_mutex_locK\n", __FUNCTION__, __LINE__);
+        return -1;
+    }
+#endif
+
+    return 0;//lint !e454
+}
+
+void jdi_unlock()
+{
+    jdi_info_t *jdi;
+
+    jdi = &s_jdi_info;
+
+    if(!jdi || jdi->jpu_fd <= 0)
+        return;
+
+    pthread_mutex_unlock((MUTEX_HANDLE *)jdi->jpu_mutex);//lint !e455
+}
+void jdi_write_register(unsigned long addr, unsigned long data)
+{
+    jdi_info_t *jdi;
+    unsigned long *reg_addr;
+
+    jdi = &s_jdi_info;
+
+    if(!jdi || jdi->jpu_fd == -1 || jdi->jpu_fd == 0x00)
+        return;
+
+
+    reg_addr = (unsigned long *)(addr + (unsigned long)jdi->jdb_register.virt_addr);
+    *(volatile unsigned int *)reg_addr = data;
+}
+
+unsigned long jdi_read_register(unsigned long addr)
+{
+    jdi_info_t *jdi;
+    unsigned long *reg_addr;
+
+    jdi = &s_jdi_info;
+
+    if(!jdi || jdi->jpu_fd == -1 || jdi->jpu_fd == 0x00)
+        return (unsigned int)-1;
+
+
+    reg_addr = (unsigned long *)(addr + (unsigned long)jdi->jdb_register.virt_addr);
+    return *(volatile unsigned int *)reg_addr;
+}
+
+int jdi_write_memory(unsigned long addr, unsigned char *data, int len, int endian)
+{
+    jdi_info_t *jdi;
+    jpudrv_buffer_t jdb;
+    Uint32          offset;
+    Uint32          i;
+
+    jdi = &s_jdi_info;
+
+    if(!jdi || jdi->jpu_fd==-1 || jdi->jpu_fd == 0x00)
+        return -1;
+
+    memset(&jdb, 0x00, sizeof(jpudrv_buffer_t));
+
+    for (i=0; i<MAX_JPU_BUFFER_POOL; i++)
+    {
+        if (jdi->jpu_buffer_pool[i].inuse == 1)
+        {
+            jdb = jdi->jpu_buffer_pool[i].jdb;
+            if (addr >= jdb.phys_addr && addr < (jdb.phys_addr + jdb.size)) {
+                break;
+            }
+        }
+    }
+
+    if (i == MAX_JPU_BUFFER_POOL) {
+        JLOG(ERR, "%s NOT FOUND ADDRESS: %#lx\n", __FUNCTION__, addr);
+        return -1;
+    }
+
+    if (!jdb.size) {
+        JLOG(ERR, "address 0x%08x is not mapped address!!!\n", (int)addr);
+        return -1;
+    }
+
+    offset = addr - (unsigned long)jdb.phys_addr;
+    swap_endian(data, len, endian);
+    memcpy((void *)((unsigned long)jdb.virt_addr+offset), data, len);
+
+   jdi_flush_ddr((unsigned long )(jdb.phys_addr+offset),len,1);
+	
+    return len;
+}
+
+int jdi_read_memory(unsigned long addr, unsigned char *data, int len, int endian)
+{
+    jdi_info_t *jdi;
+    jpudrv_buffer_t jdb;
+    unsigned long offset;
+    int i;
+
+    jdi = &s_jdi_info;
+
+    if(!jdi || jdi->jpu_fd==-1 || jdi->jpu_fd == 0x00)
+        return -1;
+
+    memset(&jdb, 0x00, sizeof(jpudrv_buffer_t));
+
+    for (i=0; i<MAX_JPU_BUFFER_POOL; i++)
+    {
+        if (jdi->jpu_buffer_pool[i].inuse == 1)
+        {
+            jdb = jdi->jpu_buffer_pool[i].jdb;
+            if (addr >= jdb.phys_addr && addr < (jdb.phys_addr + jdb.size))
+                break;
+        }
+    }
+
+    if (len == 0) {
+        return 0;
+    }
+
+    if (!jdb.size)
+        return -1;
+
+
+
+    offset = addr - (unsigned long)jdb.phys_addr;
+
+    jdi_flush_ddr((unsigned long )(jdb.phys_addr+offset),len,1);
+    memcpy(data, (const void *)((unsigned long)jdb.virt_addr+offset), len);
+    swap_endian(data, len,  endian);
+
+    return len;
+}
+
+int jdi_allocate_dma_memory(jpu_buffer_t *vb)
+{
+    jdi_info_t *jdi;
+    int i;
+    jpudrv_buffer_t jdb;
+
+    jdi = &s_jdi_info;
+
+    if(!jdi || jdi->jpu_fd==-1 || jdi->jpu_fd == 0x00)
+        return -1;
+
+    memset(&jdb, 0x00, sizeof(jpudrv_buffer_t));
+
+    jdb.size = vb->size;
+    if (ioctl(jdi->jpu_fd, JDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY, &jdb) < 0)
+    {
+        JLOG(ERR, "[JDI] fail to jdi_allocate_dma_memory size=%d\n", vb->size);
+        return -1;
+    }
+
+    vb->phys_addr = (unsigned long)jdb.phys_addr;
+    vb->base = (unsigned long)jdb.base;
+
+    //map to virtual address
+    jdb.virt_addr = (unsigned long)mmap(NULL, jdb.size, PROT_READ | PROT_WRITE, MAP_SHARED, jdi->jpu_fd, MEM2SYS(jdb.phys_addr));
+    if (jdb.virt_addr == (unsigned long)MAP_FAILED) {
+        memset(vb, 0x00, sizeof(jpu_buffer_t));
+        return -1;
+    }
+    vb->virt_addr = jdb.virt_addr;
+
+    jdi_lock();
+    for (i=0; i<MAX_JPU_BUFFER_POOL; i++)
+    {
+        if (jdi->jpu_buffer_pool[i].inuse == 0)
+        {
+            jdi->jpu_buffer_pool[i].jdb = jdb;
+            jdi->jpu_buffer_pool_count++;
+            jdi->jpu_buffer_pool[i].inuse = 1;
+            break;
+        }
+    }
+    jdi_unlock();
+    JLOG(INFO, "[JDI] jdi_allocate_dma_memory, physaddr=%p, virtaddr=%p~%p, size=%d\n",
+         vb->phys_addr, vb->virt_addr, vb->virt_addr + vb->size, vb->size);
+    return 0;
+}
+
+void jdi_free_dma_memory(jpu_buffer_t *vb)
+{
+    jdi_info_t *jdi;
+    int i;
+    jpudrv_buffer_t jdb;
+
+
+    jdi = &s_jdi_info;
+
+    if(!vb || !jdi || jdi->jpu_fd==-1 || jdi->jpu_fd == 0x00)
+        return;
+
+    if (vb->size == 0)
+        return ;
+
+    memset(&jdb, 0x00, sizeof(jpudrv_buffer_t));
+
+    jdi_lock();
+    for (i=0; i<MAX_JPU_BUFFER_POOL; i++) {
+        if (jdi->jpu_buffer_pool[i].jdb.phys_addr == vb->phys_addr) {
+            jdi->jpu_buffer_pool[i].inuse = 0;
+            jdi->jpu_buffer_pool_count--;
+            jdb = jdi->jpu_buffer_pool[i].jdb;
+            break;
+        }
+    }
+	jdi_unlock();
+
+    if (!jdb.size)
+    {
+        JLOG(ERR, "[JDI] invalid buffer to free address = 0x%lx\n", (int)jdb.virt_addr);
+        return ;
+    }
+    ioctl(jdi->jpu_fd, JDI_IOCTL_FREE_PHYSICALMEMORY, &jdb);
+
+    if (munmap((void *)jdb.virt_addr, jdb.size) != 0) {
+        JLOG(ERR, "[JDI] fail to jdi_free_dma_memory virtial address = 0x%lx\n", (int)jdb.virt_addr);
+    }
+    memset(vb, 0, sizeof(jpu_buffer_t));
+}
+
+
+
+int jdi_set_clock_gate(int enable)
+{
+    jdi_info_t *jdi = NULL;
+    int ret;
+
+    jdi = &s_jdi_info;
+    if(!jdi || jdi->jpu_fd==-1 || jdi->jpu_fd == 0x00)
+        return -1;
+
+    jdi->clock_state = enable;
+    ret = ioctl(jdi->jpu_fd, JDI_IOCTL_SET_CLOCK_GATE, &enable);
+
+    return ret;
+}
+
+int jdi_get_clock_gate()
+{
+    jdi_info_t *jdi;
+    int ret;
+
+    jdi = &s_jdi_info;
+
+    if(!jdi || jdi->jpu_fd==-1 || jdi->jpu_fd == 0x00)
+        return -1;
+
+    ret = jdi->clock_state;
+
+    return ret;
+}
+
+
+
+
+int jdi_wait_inst_ctrl_busy(int timeout, unsigned int addr_flag_reg, unsigned int flag)
+{
+	Int64 elapse, cur;
+	unsigned int data_flag_reg;
+	struct timeval tv;
+	int retry_count;
+	tv.tv_sec = 0;
+	tv.tv_usec = 0;
+	gettimeofday(&tv, NULL);
+	elapse = tv.tv_sec*1000 + tv.tv_usec/1000;
+
+
+	while(1)
+	{
+		data_flag_reg = jdi_read_register(addr_flag_reg);
+
+		if (((data_flag_reg >> 4)&0xf) == flag)
+			break;
+
+		gettimeofday(&tv, NULL);
+		cur = tv.tv_sec * 1000 + tv.tv_usec / 1000;
+
+		if (timeout > 0 && (cur - elapse) > timeout)
+		{
+
+			for (retry_count=0; retry_count<10; retry_count++) {
+				JLOG(ERR, "[VDI] jdi_wait_inst_ctrl_busy timeout, 0x%x=0x%lx\n", addr_flag_reg, jdi_read_register(addr_flag_reg));
+			}
+			return -1;
+		}
+	}
+	return 0;
+
+}
+
+
+int jdi_wait_interrupt(int timeout, unsigned int addr_int_reason, unsigned long instIdx)
+{
+    int intr_reason = 0;
+    jdi_info_t *jdi;
+    int ret;
+    jpudrv_intr_info_t intr_info;
+
+
+    jdi = &s_jdi_info;
+
+    if(!jdi || jdi->jpu_fd <= 0)
+        return -1;
+
+
+    intr_info.timeout     = timeout;
+    intr_info.intr_reason = 0;
+    intr_info.inst_idx    = instIdx;
+    ret = ioctl(jdi->jpu_fd, JDI_IOCTL_WAIT_INTERRUPT, (void*)&intr_info);
+    if (ret != 0)
+        return -1;
+    intr_reason = intr_info.intr_reason;
+
+    return intr_reason;
+}
+
+void jdi_log(int cmd, int step, int inst)
+{
+    Int32   i;
+
+    switch(cmd)
+    {
+    case JDI_LOG_CMD_PICRUN:
+        if (step == 1)    //
+            JLOG(INFO, "\n**PIC_RUN INST=%d start\n", inst);
+        else
+            JLOG(INFO, "\n**PIC_RUN INST=%d  end \n", inst);
+        break;
+    case JDI_LOG_CMD_INIT:
+        if (step == 1)    //
+            JLOG(INFO, "\n**INIT INST=%d  start\n", inst);
+        else
+            JLOG(INFO, "\n**INIT INST=%d  end \n", inst);
+        break;
+    case JDI_LOG_CMD_RESET:
+        if (step == 1)    //
+            JLOG(INFO, "\n**RESET INST=%d  start\n", inst);
+        else
+            JLOG(INFO, "\n**RESET INST=%d  end \n", inst);
+        break;
+    case JDI_LOG_CMD_PAUSE_INST_CTRL:
+        if (step == 1)    //
+            JLOG(INFO, "\n**PAUSE INST_CTRL  INST=%d start\n", inst);
+        else
+            JLOG(INFO, "\n**PAUSE INST_CTRL  INST=%d end\n", inst);
+        break;
+    }
+
+    for (i=(inst*NPT_REG_SIZE); i<=((inst*NPT_REG_SIZE)+0x250); i=i+16)
+    {
+        JLOG(INFO, "0x%04xh: 0x%08x 0x%08x 0x%08x 0x%08x\n", i,
+            jdi_read_register(i), jdi_read_register(i+4),
+            jdi_read_register(i+8), jdi_read_register(i+0xc));
+    }
+
+    JLOG(INFO, "0x%04xh: 0x%08x 0x%08x 0x%08x 0x%08x\n", NPT_PROC_BASE,
+        jdi_read_register(NPT_PROC_BASE+0x00), jdi_read_register(NPT_PROC_BASE+4),
+        jdi_read_register(NPT_PROC_BASE+8), jdi_read_register(NPT_PROC_BASE+0xc));
+}
+
+
+static void SwapByte(Uint8* data, Uint32 len)
+{
+    Uint8   temp;
+    Uint32  i;
+
+    for (i=0; i<len; i+=2) {
+        temp      = data[i];
+        data[i]   = data[i+1];
+        data[i+1] = temp;
+    }
+}
+
+static void SwapWord(Uint8* data, Uint32 len)
+{
+    Uint16  temp;
+    Uint16* ptr = (Uint16*)data;
+    Int32   i, size = len/sizeof(Uint16);
+
+    for (i=0; i<size; i+=2) {
+        temp      = ptr[i];
+        ptr[i]   = ptr[i+1];
+        ptr[i+1] = temp;
+    }
+}
+
+static void SwapDword(Uint8* data, Uint32 len)
+{
+    Uint32  temp;
+    Uint32* ptr = (Uint32*)data;
+    Int32   i, size = len/sizeof(Uint32);
+
+    for (i=0; i<size; i+=2) {
+        temp      = ptr[i];
+        ptr[i]   = ptr[i+1];
+        ptr[i+1] = temp;
+    }
+}
+
+
+Int32 swap_endian(BYTE* data, Uint32 len, Uint32 endian)
+{
+    Uint8   endianMask[8] = {   // endianMask : [2] - 4byte unit swap
+        0x00, 0x07, 0x04, 0x03, //              [1] - 2byte unit swap
+        0x06, 0x05, 0x02, 0x01  //              [0] - 1byte unit swap
+    };
+    Uint8   targetEndian;
+    Uint8   systemEndian;
+    Uint8   changes;
+    BOOL    byteSwap=FALSE, wordSwap=FALSE, dwordSwap=FALSE;
+
+    if (endian > 7) {
+        JLOG(ERR, "Invalid endian mode: %d, expected value: 0~7\n", endian);
+        return -1;
+    }
+
+    targetEndian = endianMask[endian];
+    systemEndian = endianMask[JDI_SYSTEM_ENDIAN];
+    changes      = targetEndian ^ systemEndian;
+    byteSwap     = changes & 0x01 ? TRUE : FALSE;
+    wordSwap     = changes & 0x02 ? TRUE : FALSE;
+    dwordSwap    = changes & 0x04 ? TRUE : FALSE;
+
+    if (byteSwap == TRUE)  SwapByte(data, len);
+    if (wordSwap == TRUE)  SwapWord(data, len);
+    if (dwordSwap == TRUE) SwapDword(data, len);
+
+    return changes == 0 ? 0 : 1;
+}
+
+
+
+

+ 660 - 0
codaj12/jdi/mm.c

@@ -0,0 +1,660 @@
+/*
+ * Copyright (c) 2018, Chips&Media
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "mm.h"
+
+#ifdef MM_DEBUG
+#ifdef _MSC_VER
+#define DPRINT(_fmt, ...)       printf(_fmt, __VA_ARGS__)
+#else
+#define DPRINT(_fmt, ...)       printf(_fmt, args...)
+#endif
+#else
+#define DPRINT(_fmt, ...)
+#endif
+
+
+
+#define P_ALLOC(_x)         malloc(_x)
+#define P_FREE(_x)          free(_x)
+#define ASSERT(_exp)        if (!(_exp)) { printf("ASSERT at %s:%d\n", __FILE__, __LINE__); while(1); }
+#define HEIGHT(_tree)       (_tree==NULL ? -1 : _tree->height)
+#define MAX(_a, _b)         (_a >= _b ? _a : _b)
+
+typedef enum {
+    LEFT,
+    RIGHT
+} rotation_dir_t;
+
+
+
+typedef struct avl_node_data_struct {
+    int     key;
+    page_t* page;
+} avl_node_data_t;
+
+static avl_node_t*
+make_avl_node(
+    vmem_key_t key,
+    page_t* page
+    )
+{
+    avl_node_t* node = (avl_node_t*)P_ALLOC(sizeof(avl_node_t));
+    if (node != NULL)
+    {
+        node->key     = key;
+        node->page    = page;
+        node->height  = 0;
+        node->left    = NULL;
+        node->right   = NULL;
+    }
+
+    return node;
+}
+
+
+static int
+get_balance_factor(
+    avl_node_t* tree
+    )
+{
+    int factor = 0;
+    if (tree) {
+        factor = HEIGHT(tree->right) - HEIGHT(tree->left);
+    }
+
+    return factor;
+}
+
+/*
+ * Left Rotation
+ *
+ *      A                      B
+ *       \                    / \
+ *        B         =>       A   C
+ *       /  \                 \
+ *      D    C                 D
+ *
+ */
+static avl_node_t*
+rotation_left(
+    avl_node_t* tree
+    )
+{
+    avl_node_t* rchild;
+    avl_node_t* lchild;
+
+    if (tree == NULL) return NULL;
+
+    rchild = tree->right;
+    if (rchild == NULL) {
+        return tree;
+    }
+
+    lchild = rchild->left;
+    rchild->left = tree;
+    tree->right = lchild;
+
+    tree->height   = MAX(HEIGHT(tree->left), HEIGHT(tree->right)) + 1;
+    rchild->height = MAX(HEIGHT(rchild->left), HEIGHT(rchild->right)) + 1;
+
+    return rchild;
+}
+
+
+/*
+ * Reft Rotation
+ *
+ *         A                  B
+ *       \                  /  \
+ *      B         =>       D    A
+ *    /  \                     /
+ *   D    C                   C
+ *
+ */
+static avl_node_t*
+rotation_right(
+    avl_node_t* tree
+    )
+{
+    avl_node_t* rchild;
+    avl_node_t* lchild;
+
+    if (tree == NULL) return NULL;
+
+    lchild = tree->left;
+    if (lchild == NULL) return NULL;
+
+    rchild = lchild->right;
+    lchild->right = tree;
+    tree->left = rchild;
+
+    tree->height   = MAX(HEIGHT(tree->left), HEIGHT(tree->right)) + 1;
+    lchild->height = MAX(HEIGHT(lchild->left), HEIGHT(lchild->right)) + 1;
+
+    return lchild;
+}
+
+static avl_node_t*
+do_balance(
+    avl_node_t* tree
+    )
+{
+    int bfactor = 0, child_bfactor;       /* balancing factor */
+
+    bfactor = get_balance_factor(tree);
+
+    if (bfactor >= 2) {
+        child_bfactor = get_balance_factor(tree->right);
+        if (child_bfactor == 1 || child_bfactor == 0) {
+            tree = rotation_left(tree);
+        } else if (child_bfactor == -1) {
+            tree->right = rotation_right(tree->right);
+            tree        = rotation_left(tree);
+        } else {
+            fprintf(stderr, "invalid balancing factor: %d\n", child_bfactor);
+            ASSERT(0);
+            return NULL;
+        }
+    } else if (bfactor <= -2) {
+        child_bfactor = get_balance_factor(tree->left);
+        if (child_bfactor == -1 || child_bfactor == 0) {
+            tree = rotation_right(tree);
+        } else if (child_bfactor == 1) {
+            tree->left = rotation_left(tree->left);
+            tree       = rotation_right(tree);
+        } else {
+            fprintf(stderr, "invalid balancing factor: %d\n", child_bfactor);
+            ASSERT(0);
+            return NULL;
+        }
+    }
+
+    return tree;
+}
+static avl_node_t*
+unlink_end_node(
+    avl_node_t* tree,
+    int dir,
+    avl_node_t** found_node
+    )
+{
+    *found_node = NULL;
+    if (tree == NULL) return NULL;
+
+    if (dir == LEFT) {
+        if (tree->left == NULL) {
+            *found_node = tree;
+            return NULL;
+        }
+    } else {
+        if (tree->right == NULL) {
+            *found_node = tree;
+            return NULL;
+        }
+    }
+
+    if (dir == LEFT) {
+        tree->left = unlink_end_node(tree->left, LEFT, found_node);
+        if (tree->left == NULL) {
+            tree->left = (*found_node)->right;
+            (*found_node)->left  = NULL;
+            (*found_node)->right = NULL;
+        }
+    } else {
+        tree->right = unlink_end_node(tree->right, RIGHT, found_node);
+        if (tree->right == NULL) {
+            tree->right = (*found_node)->left;
+            (*found_node)->left  = NULL;
+            (*found_node)->right = NULL;
+        }
+    }
+
+    tree->height = MAX(HEIGHT(tree->left), HEIGHT(tree->right)) + 1;
+
+    return do_balance(tree);
+}
+
+static avl_node_t*
+avltree_insert(
+    avl_node_t* tree,
+    vmem_key_t key,
+    page_t* page
+    )
+{
+    if (tree == NULL) {
+        tree = make_avl_node(key, page);
+    } else {
+        if (key >= tree->key) {
+            tree->right = avltree_insert(tree->right, key, page);
+        } else {
+            tree->left  = avltree_insert(tree->left, key, page);
+        }
+    }
+
+    tree = do_balance(tree);
+
+    tree->height = MAX(HEIGHT(tree->left), HEIGHT(tree->right)) + 1;
+
+    return tree;
+}
+
+static avl_node_t*
+do_unlink(
+    avl_node_t* tree
+    )
+{
+    avl_node_t* node;
+    avl_node_t* end_node;
+    node = unlink_end_node(tree->right, LEFT, &end_node);
+    if (node) {
+        tree->right = node;
+    } else {
+        node = unlink_end_node(tree->left, RIGHT, &end_node);
+        if (node) tree->left = node;
+    }
+
+    if (node == NULL) {
+        node = tree->right ? tree->right : tree->left;
+        end_node = node;
+    }
+
+    if (end_node) {
+        end_node->left  = (tree->left != end_node) ? tree->left : end_node->left;
+        end_node->right = (tree->right != end_node) ? tree->right : end_node->right;
+        end_node->height = MAX(HEIGHT(end_node->left), HEIGHT(end_node->right)) + 1;
+    }
+
+    tree = end_node;
+
+    return tree;
+}
+
+static avl_node_t*
+avltree_remove(
+    avl_node_t* tree,
+    avl_node_t** found_node,
+    vmem_key_t key
+    )
+{
+    *found_node = NULL;
+    if (tree == NULL) {
+        DPRINT("failed to find key %d\n", (int)key);
+        return NULL;
+    }
+
+    if (key == tree->key) {
+        *found_node = tree;
+        tree = do_unlink(tree);
+    } else if (key > tree->key) {
+        tree->right = avltree_remove(tree->right, found_node, key);
+    } else {
+        tree->left  = avltree_remove(tree->left, found_node, key);
+    }
+
+    if (tree) tree->height = MAX(HEIGHT(tree->left), HEIGHT(tree->right)) + 1;
+
+    tree = do_balance(tree);
+
+    return tree;
+}
+
+void
+avltree_free(
+    avl_node_t* tree
+    )
+{
+    if (tree == NULL) return;
+    if (tree->left == NULL && tree->right == NULL) {
+        P_FREE(tree);
+        return;
+    }
+
+    avltree_free(tree->left);
+    tree->left = NULL;
+    avltree_free(tree->right);
+    tree->right = NULL;
+    P_FREE(tree);
+}
+
+static avl_node_t*
+remove_approx_value(
+    avl_node_t* tree,
+    avl_node_t** found,
+    vmem_key_t key
+    )
+{
+    *found = NULL;
+    if (tree == NULL) {
+        return NULL;
+    }
+
+    if (key == tree->key) {
+        *found = tree;
+        tree = do_unlink(tree);
+    } else if (key > tree->key) {
+        tree->right = remove_approx_value(tree->right, found, key);
+    } else {
+        tree->left  = remove_approx_value(tree->left, found, key);
+        if (*found == NULL) {
+            *found = tree;
+            tree = do_unlink(tree);
+        }
+    }
+    if (tree) tree->height = MAX(HEIGHT(tree->left), HEIGHT(tree->right)) + 1;
+    tree = do_balance(tree);
+
+    return tree;
+}
+
+static void
+set_blocks_free(
+	jpeg_mm_t *mm,
+    int pageno,
+    int npages
+    )
+{
+    int last_pageno     = pageno + npages - 1;
+    int i;
+    page_t* page;
+    page_t* last_page;
+
+    ASSERT(npages);
+
+    if (last_pageno >= mm->num_pages) {
+        DPRINT("set_blocks_free: invalid last page number: %d\n", last_pageno);
+        ASSERT(0);
+        return;
+    }
+
+    for (i=pageno; i<=last_pageno; i++) {
+        mm->page_list[i].used         = 0;
+        mm->page_list[i].alloc_pages  = 0;
+        mm->page_list[i].first_pageno = -1;
+    }
+
+    page        = &mm->page_list[pageno];
+    page->alloc_pages = npages;
+    last_page   = &mm->page_list[last_pageno];
+    last_page->first_pageno = pageno;
+
+    mm->free_tree = avltree_insert(mm->free_tree, MAKE_KEY(npages, pageno), page);
+}
+
+static void
+set_blocks_alloc(
+	jpeg_mm_t *mm,
+    int pageno,
+    int npages
+    )
+{
+    int last_pageno     = pageno + npages - 1;
+    int i;
+    page_t* page;
+    page_t* last_page;
+
+    if (last_pageno >= mm->num_pages) {
+        DPRINT("set_blocks_free: invalid last page number: %d\n", last_pageno);
+        ASSERT(0);
+        return;
+    }
+
+    for (i=pageno; i<=last_pageno; i++) {
+        mm->page_list[i].used         = 1;
+        mm->page_list[i].alloc_pages  = 0;
+        mm->page_list[i].first_pageno = -1;
+    }
+
+    page        = &mm->page_list[pageno];
+    page->alloc_pages = npages;
+
+    last_page   = &mm->page_list[last_pageno];
+    last_page->first_pageno = pageno;
+
+    mm->alloc_tree = avltree_insert(mm->alloc_tree, MAKE_KEY(page->addr, 0), page);
+}
+
+
+int
+jmem_init(
+	jpeg_mm_t* mm,
+	unsigned long addr,
+    unsigned long size
+    )
+{
+    int i;
+
+
+    mm->base_addr  = (addr+(VMEM_PAGE_SIZE-1))&~(VMEM_PAGE_SIZE-1);
+    mm->mem_size   = size&~VMEM_PAGE_SIZE;
+    mm->num_pages  = mm->mem_size/VMEM_PAGE_SIZE;
+    mm->page_list  = (page_t*)P_ALLOC(mm->num_pages*sizeof(page_t));
+    mm->free_tree  = NULL;
+    mm->alloc_tree = NULL;
+    mm->free_page_count = mm->num_pages;
+    mm->alloc_page_count = 0;
+
+    for (i=0; i<mm->num_pages; i++) {
+        mm->page_list[i].pageno       = i;
+        mm->page_list[i].addr         = mm->base_addr + i*VMEM_PAGE_SIZE;
+        mm->page_list[i].alloc_pages  = 0;
+        mm->page_list[i].used         = 0;
+        mm->page_list[i].first_pageno = -1;
+    }
+
+    set_blocks_free(mm, 0, mm->num_pages);
+
+    return 0;
+}
+
+int
+jmem_exit(
+	jpeg_mm_t* mm
+    )
+{
+	if (mm == NULL) {
+        DPRINT("vmem_exit: invalid handle\n");
+        return -1;
+    }
+
+    if (mm->free_tree) {
+        avltree_free(mm->free_tree);
+        mm->free_tree = NULL;
+    }
+    if (mm->alloc_tree) {
+        avltree_free(mm->alloc_tree);
+        mm->alloc_tree = NULL;
+    }
+
+    if (mm->page_list) {
+        P_FREE(mm->page_list);
+        mm->page_list = NULL;
+    }
+
+    return 0;
+}
+
+unsigned long
+jmem_alloc(
+	jpeg_mm_t* mm,
+    int size,
+	unsigned long pid
+    )
+{
+    avl_node_t* node;
+    page_t*     free_page;
+    int         npages, free_size;
+    int         alloc_pageno;
+    unsigned long  ptr;
+
+	if (mm == NULL) {
+		printf("%s:%d: invalid handle\n", __FUNCTION__, __LINE__);
+        return (unsigned long)-1;
+    }
+
+    if (size <= 0) return (unsigned long)-1;
+
+	npages = (size + VMEM_PAGE_SIZE -1)/VMEM_PAGE_SIZE;
+
+    mm->free_tree = remove_approx_value(mm->free_tree, &node, MAKE_KEY(npages, 0));
+    if (node == NULL) {
+        printf("%s:%d: Not found node?\n", __FUNCTION__, __LINE__);
+        return (unsigned long)-1;
+    }
+    free_page = node->page;
+    free_size = KEY_TO_VALUE(node->key);
+
+    alloc_pageno = free_page->pageno;
+    set_blocks_alloc(mm, alloc_pageno, npages);
+    if (npages != free_size) {
+        int free_pageno = alloc_pageno + npages;
+        set_blocks_free(mm, free_pageno, (free_size-npages));
+    }
+
+    P_FREE(node);
+
+    ptr = mm->page_list[alloc_pageno].addr;
+    mm->alloc_page_count += npages;
+    mm->free_page_count  -= npages;
+
+
+    return ptr;
+}
+
+int
+jmem_free(
+	jpeg_mm_t* mm,
+    unsigned long ptr,
+	unsigned long pid
+    )
+{
+    unsigned long addr;
+    avl_node_t* found;
+    page_t* page;
+    int pageno, prev_free_pageno, next_free_pageno;
+    int prev_size, next_size;
+    int merge_page_no, merge_page_size, free_page_size;
+
+
+	if (mm == NULL) {
+		DPRINT("vmem_free: invalid handle\n");
+		return -1;
+	}
+
+    addr = ptr;
+
+    mm->alloc_tree = avltree_remove(mm->alloc_tree, &found, MAKE_KEY(addr, 0));
+    if (found == NULL) {
+        DPRINT("vmem_free: 0x%08x not found\n", addr);
+        return -1;
+    }
+
+    /* find previous free block */
+    page = found->page;
+    pageno = page->pageno;
+    free_page_size = page->alloc_pages;
+    prev_free_pageno = pageno-1;
+    prev_size = -1;
+    if (prev_free_pageno >= 0) {
+        if (mm->page_list[prev_free_pageno].used == 0) {
+            prev_free_pageno = mm->page_list[prev_free_pageno].first_pageno;
+            prev_size = mm->page_list[prev_free_pageno].alloc_pages;
+        }
+    }
+
+    /* find next free block */
+    next_free_pageno = pageno + page->alloc_pages;
+    next_free_pageno = (next_free_pageno == mm->num_pages) ? -1 : next_free_pageno;
+    next_size = -1;
+    if (next_free_pageno >= 0) {
+        if (mm->page_list[next_free_pageno].used == 0) {
+            next_size = mm->page_list[next_free_pageno].alloc_pages;
+        }
+    }
+    P_FREE(found);
+
+    /* merge */
+    merge_page_no = page->pageno;
+    merge_page_size = page->alloc_pages;
+    if (prev_size >= 0) {
+        mm->free_tree = avltree_remove(mm->free_tree, &found, MAKE_KEY(prev_size, prev_free_pageno));
+        if (found == NULL) {
+            ASSERT(0);
+            return -1;
+        }
+        merge_page_no = found->page->pageno;
+        merge_page_size += found->page->alloc_pages;
+        P_FREE(found);
+    }
+    if (next_size >= 0) {
+        mm->free_tree = avltree_remove(mm->free_tree, &found, MAKE_KEY(next_size, next_free_pageno));
+        if (found == NULL) {
+            ASSERT(0);
+            return -1;
+        }
+        merge_page_size += found->page->alloc_pages;
+        P_FREE(found);
+    }
+
+    page->alloc_pages  = 0;
+    page->first_pageno = -1;
+
+    set_blocks_free(mm, merge_page_no, merge_page_size);
+
+    mm->alloc_page_count -= free_page_size;
+    mm->free_page_count  += free_page_size;
+
+    DPRINT("FREE: total(%d) alloc(%d) free(%d)\n", mm->num_pages, mm->alloc_page_count, mm->free_page_count);
+
+    return 0;
+}
+
+int
+jmem_get_info(
+	jpeg_mm_t* mm,
+    jmem_info_t* info
+    )
+{
+	if (mm == NULL) {
+		DPRINT("vmem_get_info: invalid handle\n");
+		return -1;
+	}
+
+    if (info == NULL) {
+        return -1;
+    }
+
+    info->total_pages = mm->num_pages;
+    info->alloc_pages = mm->alloc_page_count;
+    info->free_pages  = mm->free_page_count;
+    info->page_size   = VMEM_PAGE_SIZE;
+
+    return 0;
+}
+
+
+

+ 123 - 0
codaj12/jdi/mm.h

@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2018, Chips&Media
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __CNM_VIDEO_MEMORY_MANAGEMENT_H__
+#define __CNM_VIDEO_MEMORY_MANAGEMENT_H__
+
+
+typedef struct _jmem_info_struct {
+	unsigned long   total_pages;
+	unsigned long   alloc_pages;
+	unsigned long   free_pages;
+    unsigned long   page_size;
+} jmem_info_t;
+
+#if defined(WIN32) || defined(WIN64)
+#if (_MSC_VER == 1200)
+typedef _int64              vmem_key_t;
+#else
+typedef unsigned long long  vmem_key_t;
+#endif
+#else
+typedef unsigned long long  vmem_key_t;
+#endif
+
+#define VMEM_PAGE_SIZE           (16*1024UL)
+
+#define MAKE_KEY(_a, _b)        (((vmem_key_t)_a)<<32 | _b)
+#define KEY_TO_VALUE(_key)      (_key>>32)
+
+typedef struct page_struct {
+	int             pageno;
+	unsigned long   addr;
+	int             used;
+	int             alloc_pages;
+	int             first_pageno;
+} page_t;
+
+
+typedef struct avl_node_struct {
+	vmem_key_t   key;
+	int     height;
+	page_t* page;
+	struct avl_node_struct* left;
+	struct avl_node_struct* right;
+} avl_node_t;
+
+
+typedef struct _jpeg_mm_struct {
+	avl_node_t*     free_tree;
+	avl_node_t*     alloc_tree;
+	page_t*         page_list;
+	int             num_pages;
+	unsigned long   base_addr;
+	unsigned long   mem_size;
+	void*           mutex;
+	int             free_page_count;
+	int             alloc_page_count;
+} jpeg_mm_t;
+
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+extern int
+jmem_init(
+	jpeg_mm_t* mm,
+	unsigned long addr,
+	unsigned long size
+	);
+
+extern int
+jmem_exit(
+	jpeg_mm_t* mm
+	);
+
+extern unsigned long
+jmem_alloc(
+	jpeg_mm_t* mm,
+	int size,
+	unsigned long pid
+	);
+
+extern int
+jmem_free(
+	jpeg_mm_t* mm,
+	unsigned long ptr,
+	unsigned long pid
+	);
+
+
+extern int
+jmem_get_info(
+	jpeg_mm_t* mm,
+	jmem_info_t* info
+	);
+
+#if defined (__cplusplus)
+}
+#endif
+#endif /* __CNM_VIDEO_MEMORY_MANAGEMENT_H__ */
+

+ 853 - 0
codaj12/jdi/nonos/jdi.c

@@ -0,0 +1,853 @@
+/*
+ * Copyright (c) 2018, Chips&Media
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#if defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(WIN32) || defined(__MINGW32__)
+#elif defined(linux) || defined(__linux) || defined(ANDROID)
+#else
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "../jdi.h"
+#include "jpulog.h"
+
+
+#define JPU_BIT_REG_SIZE		0x300
+#define JPU_BIT_REG_BASE		(0x10000000 + 0x3000)
+
+#define JDI_DRAM_PHYSICAL_BASE	0x00
+#define JDI_DRAM_PHYSICAL_SIZE	(128*1024*1024)
+#define JDI_SYSTEM_ENDIAN	JDI_LITTLE_ENDIAN
+
+typedef struct jpu_buffer_t jpudrv_buffer_t;
+
+typedef struct jpu_buffer_pool_t
+{
+	jpudrv_buffer_t jdb;
+	int inuse;
+} jpu_buffer_pool_t;
+
+static int s_jpu_fd;
+static jpu_instance_pool_t *s_pjip;
+static jpu_instance_pool_t s_jip;
+static int s_task_num;
+static int s_clock_state;
+static jpudrv_buffer_t s_jdb_video_memory;
+static jpudrv_buffer_t s_jdb_register;
+static jpu_buffer_pool_t s_jpu_buffer_pool[MAX_JPU_BUFFER_POOL];
+static int s_jpu_buffer_pool_count;
+
+static Int32 swap_endian(BYTE* data, Uint32 len, Uint32 endian);
+
+int jdi_probe()
+{
+	int ret;
+
+	ret = jdi_init();
+	jdi_release();
+
+	return ret;
+}
+
+/* @return number of task
+ */
+int jdi_get_task_num()
+{
+    if (s_jpu_fd == -1 || s_jpu_fd == 0x00) {
+        return 0;
+    }
+
+    return s_task_num;
+}
+
+
+int jdi_init()
+{
+	int ret;
+
+	if (s_jpu_fd != -1 && s_jpu_fd != 0x00)
+	{
+		s_task_num++;
+		return 0;
+	}
+
+    s_jpu_fd = 1;
+
+	memset((void *)&s_jpu_buffer_pool, 0x00, sizeof(jpu_buffer_pool_t)*MAX_JPU_BUFFER_POOL);
+	s_jpu_buffer_pool_count = 0;
+
+	if (!(s_pjip = jdi_get_instance_pool()))
+	{
+		JLOG(ERR, "[jdi] fail to create instance pool for saving context \n");
+		goto ERR_JDI_INIT;
+	}
+
+
+	s_jdb_video_memory.phys_addr = JDI_DRAM_PHYSICAL_BASE;
+	s_jdb_video_memory.size = JDI_DRAM_PHYSICAL_SIZE;
+
+	if (!s_pjip->instance_pool_inited)
+	{
+		memset(&s_pjip->vmem, 0x00, sizeof(jpeg_mm_t));
+		ret = jmem_init(&s_pjip->vmem, (unsigned long)s_jdb_video_memory.phys_addr, s_jdb_video_memory.size);
+		if (ret < 0)
+		{
+			JLOG(ERR, "[JDI] fail to init jpu memory management logic\n");
+			goto ERR_JDI_INIT;
+		}
+	}
+
+	s_jdb_register.phys_addr = JPU_BIT_REG_BASE;
+	s_jdb_register.virt_addr = JPU_BIT_REG_BASE;
+	s_jdb_register.size = JPU_BIT_REG_SIZE;
+
+
+	jdi_set_clock_gate(1);
+
+	s_task_num++;
+
+	JLOG(INFO, "[jdi] success to init driver \n");
+	return s_jpu_fd;
+
+ERR_JDI_INIT:
+
+	jdi_release();
+	return -1;
+}
+
+int jdi_release()
+{
+
+	if (s_jpu_fd == -1 || s_jpu_fd == 0x00)
+		return 0;
+
+	if (jdi_lock() < 0)
+	{
+		JLOG(ERR, "[jdi] fail to handle lock function\n");
+		return -1;
+	}
+
+	if (s_task_num > 1) // means that the opened instance remains
+	{
+		s_task_num--;
+		jdi_unlock();
+		return 0;
+	}
+
+	s_task_num--;
+
+	memset(&s_jdb_register, 0x00, sizeof(jpudrv_buffer_t));
+
+	if (s_jpu_fd != -1 && s_jpu_fd != 0x00)
+		s_jpu_fd = -1;
+
+	s_pjip = NULL;
+
+	jdi_unlock();
+
+
+	return 0;
+}
+
+
+jpu_instance_pool_t *jdi_get_instance_pool()
+{
+	if (!s_pjip)
+	{
+		s_pjip = &s_jip;
+
+		memset(s_pjip, 0x00, sizeof(jpu_instance_pool_t));
+	}
+
+	return (jpu_instance_pool_t *)s_pjip;
+}
+
+int jdi_open_instance(unsigned long instIdx)
+{
+	if(!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00)
+		return -1;
+
+	s_pjip->jpu_instance_num++;
+
+	return 0;
+}
+
+int jdi_close_instance(unsigned long instIdx)
+{
+	if(!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00)
+		return -1;
+
+	s_pjip->jpu_instance_num--;
+
+	return 0;
+}
+
+
+int jdi_get_instance_num()
+{
+	if(!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00)
+		return -1;
+
+	return s_pjip->jpu_instance_num;
+}
+
+int jdi_hw_reset()
+{
+	if(!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00)
+		return -1;
+
+	// to do any action for hw reset
+
+	return 0;
+}
+
+
+
+int jdi_lock()
+{
+
+	return 0;
+}
+void jdi_unlock()
+{
+
+}
+
+void jdi_write_register(unsigned long addr, unsigned int data)
+{
+	unsigned long *reg_addr;
+
+	if(!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00)
+		return;
+
+	reg_addr = (unsigned long *)(addr + (unsigned long)s_jdb_register.virt_addr);
+	//*(volatile unsigned long *)reg_addr = data;
+	*(volatile unsigned int *)reg_addr = data;
+
+}
+
+unsigned long jdi_read_register(unsigned long addr)
+{
+	unsigned long *reg_addr;
+
+	reg_addr = (unsigned long *)(addr + (unsigned long)s_jdb_register.virt_addr);
+	//return *(volatile unsigned long *)reg_addr;
+	return *(volatile unsigned int *)reg_addr;
+}
+
+int jdi_write_memory(unsigned long addr, unsigned char *data, int len, int endian)
+{
+	jpudrv_buffer_t jdb = {0, };
+	unsigned long offset;
+	int i;
+
+
+	if(!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00)
+		return -1;
+
+	for (i=0; i<MAX_JPU_BUFFER_POOL; i++)
+	{
+		if (s_jpu_buffer_pool[i].inuse == 1)
+		{
+			jdb = s_jpu_buffer_pool[i].jdb;
+			if (addr >= jdb.phys_addr && addr < (jdb.phys_addr + jdb.size))
+				break;
+		}
+	}
+
+	if (!jdb.size) {
+		JLOG(ERR, "address 0x%08x is not mapped address!!!\n", addr);
+		return -1;
+	}
+
+	offset = addr - (unsigned long)jdb.phys_addr;
+
+
+	swap_endian(data, len, endian);
+
+	memcpy((void *)((unsigned long)jdb.virt_addr+offset), data, len);
+
+	return len;
+}
+
+int jdi_read_memory(unsigned long addr, unsigned char *data, int len, int endian)
+{
+	jpudrv_buffer_t jdb = {0};
+	unsigned long offset;
+	int i;
+
+	if(!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00)
+		return -1;
+
+	for (i=0; i<MAX_JPU_BUFFER_POOL; i++)
+	{
+		if (s_jpu_buffer_pool[i].inuse == 1)
+		{
+			jdb = s_jpu_buffer_pool[i].jdb;
+			if (addr >= jdb.phys_addr && addr < (jdb.phys_addr + jdb.size))
+				break;
+		}
+	}
+
+	if (!jdb.size)
+		return -1;
+
+
+	offset = addr - (unsigned long)jdb.phys_addr;
+
+
+
+	memcpy(data, (const void *)((unsigned long)jdb.virt_addr+offset), len);
+	swap_endian(data, (Uint32)len,  (Uint32)endian);
+
+	return len;
+}
+
+int jdi_allocate_dma_memory(jpu_buffer_t *vb)
+{
+	int i;
+	unsigned long offset;
+	jpudrv_buffer_t jdb = {0, };
+
+	if(!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00)
+		return -1;
+
+	jdb.size = vb->size;
+	jdb.phys_addr = (unsigned long)jmem_alloc(&s_pjip->vmem, jdb.size, 0);
+
+	if (jdb.phys_addr == (unsigned long)-1)
+		return -1; // not enough memory
+
+
+	offset = (unsigned long)(jdb.phys_addr - s_jdb_video_memory.phys_addr);
+	jdb.base = (unsigned long )s_jdb_video_memory.base + offset;
+	jdb.virt_addr = jdb.phys_addr;
+
+	vb->phys_addr = (unsigned long)jdb.phys_addr;
+	vb->base = (unsigned long)jdb.base;
+	vb->virt_addr = (unsigned long)vb->phys_addr;
+
+
+	for (i=0; i<MAX_JPU_BUFFER_POOL; i++)
+	{
+		if (s_jpu_buffer_pool[i].inuse == 0)
+		{
+			s_jpu_buffer_pool[i].jdb = jdb;
+			s_jpu_buffer_pool_count++;
+			s_jpu_buffer_pool[i].inuse = 1;
+			break;
+		}
+	}
+
+	return 0;
+}
+
+void jdi_free_dma_memory(jpu_buffer_t *vb)
+{
+	int i;
+	jpudrv_buffer_t jdb = {0, };
+
+
+	if(!s_pjip || s_jpu_fd == -1 || s_jpu_fd == 0x00)
+		return ;
+
+	if (vb->size == 0)
+		return ;
+
+
+
+	for (i=0; i<MAX_JPU_BUFFER_POOL; i++)
+	{
+		if (s_jpu_buffer_pool[i].jdb.phys_addr == vb->phys_addr)
+		{
+			s_jpu_buffer_pool[i].inuse = 0;
+			s_jpu_buffer_pool_count--;
+			jdb = s_jpu_buffer_pool[i].jdb;
+			break;
+		}
+	}
+
+	if (!jdb.size)
+	{
+		JLOG(ERR, "[JDI] invalid buffer to free address = 0x%x\n", (int)jdb.virt_addr);
+		return ;
+	}
+
+	jmem_free(&s_pjip->vmem, (unsigned long)jdb.phys_addr, 0);
+	memset(vb, 0, sizeof(jpu_buffer_t));
+}
+
+
+int jdi_set_clock_gate(int enable)
+{
+	s_clock_state = enable;
+    return 0;
+}
+
+
+int jdi_get_clock_gate()
+{
+
+	return s_clock_state;
+}
+
+int jdi_wait_inst_ctrl_busy(int timeout, unsigned int addr_flag_reg, unsigned int flag)
+{
+	unsigned int data_flag_reg;
+
+	JLOG(ERR, "<%s:%d> Need to implement counter\n", __FUNCTION__, __LINE__);
+
+	while(1)
+	{
+		data_flag_reg = jdi_read_register(addr_flag_reg);
+
+		if (((data_flag_reg >> 4)&0xf) == flag) {
+			break;
+		}
+
+		//if (timeout > 0 && (cur - elapse) > timeout) {
+		//	JLOG(ERR, "[jDI] jdi_wait_inst_ctrl_busy timeout, 0x%x=0x%lx\n", addr_flag_reg, jdi_read_register(addr_flag_reg));
+		//	return -1;
+		//}
+	}
+	return 0;
+}
+
+int jdi_wait_interrupt(int timeout, unsigned int addr_int_reason, unsigned long instIdx)
+{
+	//int count = 0;
+
+	while(1)
+	{
+		if (jdi_read_register(addr_int_reason))
+			break;
+
+		//Sleep(1);	// 1ms sec
+		//if (count++ > timeout)
+		//	return -1;
+	}
+
+	return 0;
+}
+
+void jdi_log(int cmd, int step, int inst)
+{
+	int i;
+
+	switch(cmd)
+	{
+	case JDI_LOG_CMD_PICRUN:
+		if (step == 1)	//
+			JLOG(INFO, "\n**PIC_RUN start\n");
+		else
+			JLOG(INFO, "\n**PIC_RUN end \n");
+		break;
+	}
+
+	for (i=0; i<=0x238; i=i+16)
+	{
+		JLOG(INFO, "0x%04xh: 0x%08x 0x%08x 0x%08x 0x%08x\n", i,
+			jdi_read_register(i), jdi_read_register(i+4),
+			jdi_read_register(i+8), jdi_read_register(i+0xc));
+	}
+}
+
+static void SwapByte(Uint8* data, Uint32 len)
+{
+    Uint8   temp;
+    Uint32  i;
+
+    for (i=0; i<len; i+=2) {
+        temp      = data[i];
+        data[i]   = data[i+1];
+        data[i+1] = temp;
+    }
+}
+
+static void SwapWord(Uint8* data, Uint32 len)
+{
+    Uint16  temp;
+    Uint16* ptr = (Uint16*)data;
+    Int32   i, size = len/sizeof(Uint16);
+
+    for (i=0; i<size; i+=2) {
+        temp      = ptr[i];
+        ptr[i]   = ptr[i+1];
+        ptr[i+1] = temp;
+    }
+}
+
+static void SwapDword(Uint8* data, Uint32 len)
+{
+    Uint32  temp;
+    Uint32* ptr = (Uint32*)data;
+    Int32   i, size = len/sizeof(Uint32);
+
+    for (i=0; i<size; i+=2) {
+        temp      = ptr[i];
+        ptr[i]   = ptr[i+1];
+        ptr[i+1] = temp;
+    }
+}
+
+
+static Int32 swap_endian(BYTE* data, Uint32 len, Uint32 endian)
+{
+    Uint8   endianMask[8] = {   // endianMask : [2] - 4byte unit swap
+        0x00, 0x07, 0x04, 0x03, //              [1] - 2byte unit swap
+        0x06, 0x05, 0x02, 0x01  //              [0] - 1byte unit swap
+    };
+    Uint8   targetEndian;
+    Uint8   systemEndian;
+    Uint8   changes;
+    BOOL    byteSwap=FALSE, wordSwap=FALSE, dwordSwap=FALSE;
+
+    if (endian > 7) {
+        JLOG(ERR, "Invalid endian mode: %d, expected value: 0~7\n", endian);
+        return -1;
+    }
+
+    targetEndian = endianMask[endian];
+    systemEndian = endianMask[JDI_SYSTEM_ENDIAN];
+    changes      = targetEndian ^ systemEndian;
+    byteSwap     = changes & 0x01 ? TRUE : FALSE;
+    wordSwap     = changes & 0x02 ? TRUE : FALSE;
+    dwordSwap    = changes & 0x04 ? TRUE : FALSE;
+
+    if (byteSwap == TRUE)  SwapByte(data, len);
+    if (wordSwap == TRUE)  SwapWord(data, len);
+    if (dwordSwap == TRUE) SwapDword(data, len);
+
+    return changes == 0 ? 0 : 1;
+}
+
+
+
+int kbhit(void)
+{
+	return 0;
+}
+int  getch(void)
+{
+	return -1;
+}
+
+
+/*
+* newlib_stubs.c
+* the bellow code is just to build ref-code. customers will removed the bellow code because they need a library which is related to the system library such as newlibc
+*/
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/times.h>
+#include <sys/unistd.h>
+
+
+#ifndef STDOUT_USART
+#define STDOUT_USART 0
+#endif
+
+#ifndef STDERR_USART
+#define STDERR_USART 0
+#endif
+
+#ifndef STDIN_USART
+#define STDIN_USART 0
+#endif
+
+#undef errno
+extern int errno;
+
+/*
+environ
+A pointer to a list of environment variables and their values.
+For a minimal environment, this empty list is adequate:
+*/
+char *__env[1] = { 0 };
+char **environ = __env;
+
+int _write(int file, char *ptr, int len);
+
+void _exit(int status) {
+	_write(1, "exit", 4);
+	while (1) {
+		;
+	}
+}
+
+int _open(int file) {
+		return -1;
+}
+int _close(int file) {
+	return -1;
+}
+/*
+execve
+Transfer control to a new process. Minimal implementation (for a system without processes):
+*/
+int _execve(char *name, char **argv, char **env) {
+	errno = ENOMEM;
+	return -1;
+}
+/*
+fork
+Create a new process. Minimal implementation (for a system without processes):
+*/
+
+int _fork() {
+	errno = EAGAIN;
+	return -1;
+}
+/*
+fstat
+Status of an open file. For consistency with other minimal implementations in these examples,
+all files are regarded as character special devices.
+The `sys/stat.h' header file required is distributed in the `include' subdirectory for this C library.
+*/
+int _fstat(int file, struct stat *st) {
+	st->st_mode = S_IFCHR;
+	return 0;
+}
+
+/*
+getpid
+Process-ID; this is sometimes used to generate strings unlikely to conflict with other processes. Minimal implementation, for a system without processes:
+*/
+
+int _getpid() {
+	return 1;
+}
+
+/*
+isatty
+Query whether output stream is a terminal. For consistency with the other minimal implementations,
+*/
+int _isatty(int file) {
+	switch (file){
+	case STDOUT_FILENO:
+	case STDERR_FILENO:
+	case STDIN_FILENO:
+		return 1;
+	default:
+		//errno = ENOTTY;
+		errno = EBADF;
+		return 0;
+	}
+}
+
+
+/*
+kill
+Send a signal. Minimal implementation:
+*/
+int _kill(int pid, int sig) {
+	errno = EINVAL;
+	return (-1);
+}
+
+/*
+link
+Establish a new name for an existing file. Minimal implementation:
+*/
+
+int _link(char *old, char *new) {
+	errno = EMLINK;
+	return -1;
+}
+
+/*
+lseek
+Set position in a file. Minimal implementation:
+*/
+int _lseek(int file, int ptr, int dir) {
+	return 0;
+}
+
+static char* __get_MSP(void)
+{
+	JLOG(ERR, "<%s:%d> Need to implement it\n", __FUNCTION__, __LINE__);
+	return NULL;
+}
+
+/*
+sbrk
+Increase program data space.
+Malloc and related functions depend on this
+*/
+caddr_t _sbrk(int incr) {
+
+	// extern char _ebss; // Defined by the linker
+	char _ebss;
+	static char *heap_end;
+	char *prev_heap_end;
+
+	JLOG(ERR, "<%s:%d> check _ebss to implement it\n", __FUNCTION__, __LINE__);
+	if (heap_end == 0) {
+		heap_end = &_ebss;
+	}
+	prev_heap_end = heap_end;
+
+	char * stack = (char*) __get_MSP();
+	if (heap_end + incr >  stack)
+	{
+		_write (STDERR_FILENO, "Heap and stack collision\n", 25);
+		errno = ENOMEM;
+		return  (caddr_t) -1;
+		//abort ();
+	}
+
+	heap_end += incr;
+	return (caddr_t) prev_heap_end;
+
+}
+
+/*
+read
+Read a character to a file. `libc' subroutines will use this system routine for input from all files, including stdin
+Returns -1 on error or blocks until the number of characters have been read.
+*/
+
+
+int _read(int file, char *ptr, int len) {
+	int n;
+	int num = 0;
+	switch (file) {
+	case STDIN_FILENO:
+		for (n = 0; n < len; n++) {
+			char c=0;
+#if   STDIN_USART == 1
+			while ((USART1->SR & USART_FLAG_RXNE) == (uint16_t)RESET) {}
+			c = (char)(USART1->DR & (uint16_t)0x01FF);
+#elif STDIN_USART == 2
+			while ((USART2->SR & USART_FLAG_RXNE) == (uint16_t) RESET) {}
+			c = (char) (USART2->DR & (uint16_t) 0x01FF);
+#elif STDIN_USART == 3
+			while ((USART3->SR & USART_FLAG_RXNE) == (uint16_t)RESET) {}
+			c = (char)(USART3->DR & (uint16_t)0x01FF);
+#endif
+			*ptr++ = c;
+			num++;
+		}
+		break;
+	default:
+		errno = EBADF;
+		return -1;
+	}
+	return num;
+}
+
+/*
+stat
+Status of a file (by name). Minimal implementation:
+int    _EXFUN(stat,( const char *__path, struct stat *__sbuf ));
+*/
+
+int _stat(const char *filepath, struct stat *st) {
+	st->st_mode = S_IFCHR;
+	return 0;
+}
+
+/*
+times
+Timing information for current process. Minimal implementation:
+*/
+
+clock_t _times(struct tms *buf) {
+	return -1;
+}
+
+/*
+unlink
+Remove a file's directory entry. Minimal implementation:
+*/
+int _unlink(char *name) {
+	errno = ENOENT;
+	return -1;
+}
+
+/*
+wait
+Wait for a child process. Minimal implementation:
+*/
+int _wait(int *status) {
+	errno = ECHILD;
+	return -1;
+}
+
+/*
+write
+Write a character to a file. `libc' subroutines will use this system routine for output to all files, including stdout
+Returns -1 on error or number of bytes sent
+*/
+int _write(int file, char *ptr, int len) {
+	int n;
+	switch (file) {
+	case STDOUT_FILENO: /*stdout*/
+		for (n = 0; n < len; n++) {
+#if STDOUT_USART == 1
+			while ((USART1->SR & USART_FLAG_TC) == (uint16_t)RESET) {}
+			USART1->DR = (*ptr++ & (uint16_t)0x01FF);
+#elif  STDOUT_USART == 2
+			while ((USART2->SR & USART_FLAG_TC) == (uint16_t) RESET) {
+			}
+			USART2->DR = (*ptr++ & (uint16_t) 0x01FF);
+#elif  STDOUT_USART == 3
+			while ((USART3->SR & USART_FLAG_TC) == (uint16_t)RESET) {}
+			USART3->DR = (*ptr++ & (uint16_t)0x01FF);
+#endif
+		}
+		break;
+	case STDERR_FILENO: /* stderr */
+		for (n = 0; n < len; n++) {
+#if STDERR_USART == 1
+			while ((USART1->SR & USART_FLAG_TC) == (uint16_t)RESET) {}
+			USART1->DR = (*ptr++ & (uint16_t)0x01FF);
+#elif  STDERR_USART == 2
+			while ((USART2->SR & USART_FLAG_TC) == (uint16_t) RESET) {
+			}
+			USART2->DR = (*ptr++ & (uint16_t) 0x01FF);
+#elif  STDERR_USART == 3
+			while ((USART3->SR & USART_FLAG_TC) == (uint16_t)RESET) {}
+			USART3->DR = (*ptr++ & (uint16_t)0x01FF);
+#endif
+		}
+		break;
+	default:
+		errno = EBADF;
+		return -1;
+	}
+	return len;
+}
+
+int _gettimeofday( struct timeval *tv, void *tzvp )
+{
+    Uint64 t = 0;//__your_system_time_function_here__();  // get uptime in nanoseconds
+    tv->tv_sec = t / 1000000000;  // convert to seconds
+    tv->tv_usec = ( t % 1000000000 ) / 1000;  // get remaining microseconds
+
+    JLOG(WARN, "<%s:%d> NEED TO IMPLEMENT %s\n", __FUNCTION__, __LINE__, __FUNCTION__);
+    return 0;
+}
+
+
+#endif

+ 39 - 0
codaj12/jpuapi/Android.mk

@@ -0,0 +1,39 @@
+LOCAL_PATH := $(call my-dir)
+
+# Building the vpuapi
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ 	jpuapi.c \
+	jpuapifunc.c \
+	../src/jpuhelper.c \
+	../src/jpulog.c
+
+ LOCAL_SRC_FILES += \
+	../jdi/linux/jdi.c \
+
+
+LOCAL_MODULE_TAGS := eng
+LOCAL_MODULE := libjpu
+
+# LOCAL_CFLAGS +=  -DCNM_FPGA_PLATFORM
+
+
+LOCAL_SHARED_LIBRARIES :=       \
+		libutils		\
+		libcutils		\
+		libdl  			\
+		libdvm			\
+		liblog
+
+							
+
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/src		\
+					$(TOP)/hardware/jpu	\
+					$(TOP)/hardware/jpu/include		\
+							
+
+					
+
+include $(BUILD_SHARED_LIBRARY)
+

+ 1731 - 0
codaj12/jpuapi/jpuapi.c

@@ -0,0 +1,1731 @@
+/*
+ * Copyright (c) 2018, Chips&Media
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "jpuapifunc.h"
+#include "jpuapi.h"
+#include "regdefine.h"
+#include "jpulog.h"
+
+static JPUCap   g_JpuAttributes;
+
+int JPU_IsBusy(JpgHandle handle)
+{
+    Uint32 val;
+    JpgInst *pJpgInst = (JpgInst *)handle;
+    Int32 instRegIndex;
+
+    if (pJpgInst->sliceInstMode == TRUE) {
+        instRegIndex = pJpgInst->instIndex;
+    }
+    else {
+        instRegIndex = 0;
+    }
+    val = JpuReadInstReg(instRegIndex, MJPEG_PIC_STATUS_REG);
+
+    if ((val & (1<<INT_JPU_DONE)) ||
+        (val & (1<<INT_JPU_ERROR)))
+        return 0;
+
+    return 1;
+}
+
+void JPU_ClrStatus(JpgHandle handle, Uint32 val)
+{
+    JpgInst *pJpgInst = (JpgInst *)handle;
+    Int32 instRegIndex;
+
+    if (pJpgInst->sliceInstMode == TRUE) {
+        instRegIndex = pJpgInst->instIndex;
+    }
+    else {
+        instRegIndex = 0;
+    }
+    if (val != 0)
+        JpuWriteInstReg(instRegIndex, MJPEG_PIC_STATUS_REG, val);
+}
+Uint32 JPU_GetStatus(JpgHandle handle)
+{
+    JpgInst *pJpgInst = (JpgInst *)handle;
+    Int32 instRegIndex;
+
+    if (pJpgInst->sliceInstMode == TRUE) {
+        instRegIndex = pJpgInst->instIndex;
+    }
+    else {
+        instRegIndex = 0;
+    }
+
+    return JpuReadInstReg(instRegIndex, MJPEG_PIC_STATUS_REG);
+}
+
+
+Uint32 JPU_IsInit()
+{
+    jpu_instance_pool_t *pjip;
+
+    pjip = (jpu_instance_pool_t *)jdi_get_instance_pool();
+
+    if (!pjip)
+        return 0;
+
+    return 1;
+}
+
+
+Int32	JPU_WaitInterrupt(JpgHandle handle, int timeout)
+{
+    Uint32 val;
+    Uint32 instPicStatusRegAddr;
+    Int32 instRegIndex;
+
+    Int32 reason = 0;
+
+    JpgInst *pJpgInst = (JpgInst *)handle;
+
+    if (pJpgInst->sliceInstMode == TRUE) {
+        instRegIndex = pJpgInst->instIndex;
+    }
+    else {
+        instRegIndex = 0;
+    }
+
+    instPicStatusRegAddr = ((instRegIndex*NPT_REG_SIZE) + MJPEG_PIC_STATUS_REG);
+
+    reason = jdi_wait_interrupt(timeout, instPicStatusRegAddr, instRegIndex);
+    if (reason == -1)
+        return -1;
+
+    if (reason & (1<<INT_JPU_DONE) || reason & (1<<INT_JPU_SLICE_DONE)) {
+        val = JpuReadReg(MJPEG_INST_CTRL_STATUS_REG);
+        if ((((val & 0xf) >> instRegIndex) & 0x01) == 0) {
+            return -2;
+        }
+    }
+
+    return reason;
+}
+
+
+
+int JPU_GetOpenInstanceNum()
+{
+    jpu_instance_pool_t *pjip;
+
+    pjip = (jpu_instance_pool_t *)jdi_get_instance_pool();
+    if (!pjip)
+        return -1;
+
+    return pjip->jpu_instance_num;
+}
+
+JpgRet JPU_Init()
+{
+    jpu_instance_pool_t *pjip;
+    Uint32              val;
+
+    if (jdi_init() < 0) {
+        return JPG_RET_FAILURE;
+    }
+
+    if (jdi_get_task_num() > 1) {
+        return JPG_RET_CALLED_BEFORE;
+    }
+
+    JpgEnterLock();
+    pjip = (jpu_instance_pool_t *)jdi_get_instance_pool();
+    if (!pjip) {
+        JpgLeaveLock();
+        return JPG_RET_FAILURE;
+    }
+
+    //jdi_log(JDI_LOG_CMD_INIT, 1, 0);
+    JPU_SWReset(NULL);
+    JpuWriteReg(MJPEG_INST_CTRL_START_REG, (1<<0));
+
+    val = JpuReadInstReg(0, MJPEG_VERSION_INFO_REG);
+    // JPU Capabilities
+    g_JpuAttributes.productId    = (val>>24) & 0xf;
+    g_JpuAttributes.revisoin     = (val & 0xffffff);
+    g_JpuAttributes.support12bit = (val>>28) & 0x01;
+
+    //jdi_log(JDI_LOG_CMD_INIT, 0, 0);
+    JpgLeaveLock();
+    return JPG_RET_SUCCESS;
+}
+
+void JPU_DeInit()
+{
+    JpgEnterLock();
+    if (jdi_get_task_num() == 1) {
+        JpuWriteReg(MJPEG_INST_CTRL_START_REG, 0);
+    }
+    JpgLeaveLock();
+    jdi_release();
+}
+
+JpgRet JPU_GetVersionInfo(Uint32 *apiVersion, Uint32 *hwRevision, Uint32 *hwProductId)
+{
+    if (JPU_IsInit() == 0) {
+        return JPG_RET_NOT_INITIALIZED;
+    }
+
+    JpgEnterLock();
+    if (apiVersion) {
+        *apiVersion = API_VERSION;
+    }
+    if (hwRevision) {
+        *hwRevision = g_JpuAttributes.revisoin;
+    }
+    if (hwProductId) {
+        *hwProductId = g_JpuAttributes.productId;
+    }
+    JpgLeaveLock();
+    return JPG_RET_SUCCESS;
+}
+
+JpgRet JPU_DecOpen(JpgDecHandle * pHandle, JpgDecOpenParam * pop)
+{
+    JpgInst*    pJpgInst;
+    JpgDecInfo* pDecInfo;
+    JpgRet      ret;
+    ret = CheckJpgDecOpenParam(pop);
+    if (ret != JPG_RET_SUCCESS) {
+        return ret;
+    }
+
+    JpgEnterLock();
+    ret = GetJpgInstance(&pJpgInst);
+    if (ret == JPG_RET_FAILURE) {
+        *pHandle = 0;
+        JpgLeaveLock();
+        return JPG_RET_FAILURE;
+    }
+
+    *pHandle = pJpgInst;
+
+    pDecInfo = &pJpgInst->JpgInfo->decInfo;
+    memset(pDecInfo, 0x00, sizeof(JpgDecInfo));
+
+    pDecInfo->streamWrPtr = pop->bitstreamBuffer;
+    pDecInfo->streamRdPtr = pop->bitstreamBuffer;
+
+    pDecInfo->streamBufStartAddr = pop->bitstreamBuffer;
+    pDecInfo->streamBufSize     = pop->bitstreamBufferSize;
+    pDecInfo->streamBufEndAddr  = pop->bitstreamBuffer + pop->bitstreamBufferSize;
+    pDecInfo->pBitStream        = pop->pBitStream;
+    pDecInfo->streamEndian      = pop->streamEndian;
+    pDecInfo->frameEndian       = pop->frameEndian;
+    pDecInfo->chromaInterleave  = pop->chromaInterleave;
+    pDecInfo->packedFormat      = pop->packedFormat;
+    pDecInfo->roiEnable         = pop->roiEnable;
+    pDecInfo->roiWidth          = pop->roiWidth;
+    pDecInfo->roiHeight         = pop->roiHeight;
+    pDecInfo->roiOffsetX        = pop->roiOffsetX;
+    pDecInfo->roiOffsetY        = pop->roiOffsetY;
+    pDecInfo->pixelJustification = pop->pixelJustification;
+    pDecInfo->intrEnableBit     = pop->intrEnableBit;
+    pJpgInst->sliceInstMode     = 0;    /* The decoder does not support the slice-decoding */
+    pDecInfo->rotationIndex     = pop->rotation / 90;
+    pDecInfo->mirrorIndex       = pop->mirror;
+    /* convert output format */
+    switch (pop->outputFormat) {
+    case FORMAT_400: ret = JPG_RET_INVALID_PARAM; break;
+    case FORMAT_420: pDecInfo->ofmt = O_FMT_420;  break;
+    case FORMAT_422: pDecInfo->ofmt = O_FMT_422;  break;
+    case FORMAT_440: ret = JPG_RET_INVALID_PARAM; break;
+    case FORMAT_444: pDecInfo->ofmt = O_FMT_444;  break;
+    case FORMAT_MAX: pDecInfo->ofmt = O_FMT_NONE; break;
+    default:         ret = JPG_RET_INVALID_PARAM; break;
+    }
+
+    pDecInfo->userqMatTab = 0;
+    pDecInfo->decIdx = 0;
+
+    JpgLeaveLock();
+
+    return ret;
+}
+
+JpgRet JPU_DecClose(JpgDecHandle handle)
+{
+    JpgInst * pJpgInst;
+    JpgRet ret;
+
+    ret = CheckJpgInstValidity(handle);
+    if (ret != JPG_RET_SUCCESS)
+        return ret;
+
+    pJpgInst = handle;
+
+    JpgEnterLock();
+
+    if (GetJpgPendingInstEx(pJpgInst->instIndex)) {
+        JpgLeaveLock();
+        return JPG_RET_FRAME_NOT_COMPLETE;
+    }
+
+    FreeJpgInstance(pJpgInst);
+    JpgLeaveLock();
+
+    return JPG_RET_SUCCESS;
+}
+
+JpgRet JPU_DecGetInitialInfo(JpgDecHandle handle, JpgDecInitialInfo * info)
+{
+    JpgInst*    pJpgInst;
+    JpgDecInfo* pDecInfo;
+    JpgRet      ret;
+    int         err;
+
+    ret = CheckJpgInstValidity(handle);
+    if (ret != JPG_RET_SUCCESS)
+        return ret;
+
+    if (info == 0) {
+        return JPG_RET_INVALID_PARAM;
+    }
+    pJpgInst = handle;
+    pDecInfo = &pJpgInst->JpgInfo->decInfo;
+
+    if (0 >= (err=JpegDecodeHeader(pDecInfo))) {
+        /* The value of -2 indicates that the bitstream in the buffer is not enough to decode a header. */
+        return (-2 == err) ? JPG_RET_BIT_EMPTY : JPG_RET_FAILURE;
+    }
+
+    if (pDecInfo->jpg12bit == TRUE && g_JpuAttributes.support12bit == FALSE) {
+        return JPG_RET_NOT_SUPPORT;
+    }
+
+    info->picWidth = pDecInfo->picWidth;
+    info->picHeight = pDecInfo->picHeight;
+    info->minFrameBufferCount = 1;
+    info->sourceFormat = (FrameFormat)pDecInfo->format;
+    info->ecsPtr = pDecInfo->ecsPtr;
+
+    pDecInfo->initialInfoObtained = 1;
+    pDecInfo->minFrameBufferNum = 1;
+
+
+    if ((pDecInfo->packedFormat == PACKED_FORMAT_444) && (pDecInfo->format != FORMAT_444)) {
+        return JPG_RET_INVALID_PARAM;
+    }
+
+    if (pDecInfo->roiEnable) {
+        if (pDecInfo->format == FORMAT_400) {
+            pDecInfo->roiMcuWidth = pDecInfo->roiWidth/8;
+        }
+        else  {
+            pDecInfo->roiMcuWidth = pDecInfo->roiWidth/pDecInfo->mcuWidth;
+        }
+        pDecInfo->roiMcuHeight = pDecInfo->roiHeight/pDecInfo->mcuHeight;
+        pDecInfo->roiMcuOffsetX = pDecInfo->roiOffsetX/pDecInfo->mcuWidth;
+        pDecInfo->roiMcuOffsetY = pDecInfo->roiOffsetY/pDecInfo->mcuHeight;
+
+        if ((pDecInfo->roiOffsetX > pDecInfo->alignedWidth)
+            || (pDecInfo->roiOffsetY > pDecInfo->alignedHeight)
+            || (pDecInfo->roiOffsetX + pDecInfo->roiWidth > pDecInfo->alignedWidth)
+            || (pDecInfo->roiOffsetY + pDecInfo->roiHeight > pDecInfo->alignedHeight))
+            return JPG_RET_INVALID_PARAM;
+
+        if (pDecInfo->format == FORMAT_400) {
+            if (((pDecInfo->roiOffsetX + pDecInfo->roiWidth) < 8) || ((pDecInfo->roiOffsetY + pDecInfo->roiHeight) < pDecInfo->mcuHeight))
+                return JPG_RET_INVALID_PARAM;
+        }
+        else {
+            if (((pDecInfo->roiOffsetX + pDecInfo->roiWidth) < pDecInfo->mcuWidth) || ((pDecInfo->roiOffsetY + pDecInfo->roiHeight) < pDecInfo->mcuHeight))
+                return JPG_RET_INVALID_PARAM;
+        }
+
+        if (pDecInfo->format == FORMAT_400)
+            pDecInfo->roiFrameWidth = pDecInfo->roiMcuWidth * 8;
+        else
+            pDecInfo->roiFrameWidth = pDecInfo->roiMcuWidth * pDecInfo->mcuWidth;
+        pDecInfo->roiFrameHeight = pDecInfo->roiMcuHeight*pDecInfo->mcuHeight;
+        info->roiFrameWidth   = pDecInfo->roiFrameWidth;
+        info->roiFrameHeight  = pDecInfo->roiFrameHeight;
+        info->roiFrameOffsetX = pDecInfo->roiMcuOffsetX*pDecInfo->mcuWidth;
+        info->roiFrameOffsetY = pDecInfo->roiMcuOffsetY*pDecInfo->mcuHeight;
+    }
+    info->bitDepth        = pDecInfo->bitDepth;
+
+
+    return JPG_RET_SUCCESS;
+}
+
+
+JpgRet JPU_DecRegisterFrameBuffer(JpgDecHandle handle, FrameBuffer * bufArray, int num, int stride)
+{
+    JpgInst * pJpgInst;
+    JpgDecInfo * pDecInfo;
+    JpgRet ret;
+
+
+    ret = CheckJpgInstValidity(handle);
+    if (ret != JPG_RET_SUCCESS)
+        return ret;
+
+    pJpgInst = handle;
+    pDecInfo = &pJpgInst->JpgInfo->decInfo;
+
+
+    if (!pDecInfo->initialInfoObtained) {
+        return JPG_RET_WRONG_CALL_SEQUENCE;
+    }
+
+    if (bufArray == 0) {
+        return JPG_RET_INVALID_FRAME_BUFFER;
+    }
+
+    if (num < pDecInfo->minFrameBufferNum) {
+        return JPG_RET_INSUFFICIENT_FRAME_BUFFERS;
+    }
+
+    if ((stride % 8) != 0) {
+        return JPG_RET_INVALID_STRIDE;
+    }
+
+    pDecInfo->frameBufPool    = bufArray;
+    pDecInfo->numFrameBuffers = num;
+    pDecInfo->stride          = stride;
+    pDecInfo->stride_c        = bufArray[0].strideC;
+
+    return JPG_RET_SUCCESS;
+}
+
+JpgRet JPU_DecGetBitstreamBuffer(JpgDecHandle handle,
+    PhysicalAddress * prdPtr,
+    PhysicalAddress * pwrPtr,
+    int * size)
+{
+    JpgInst * pJpgInst;
+    JpgDecInfo * pDecInfo;
+    JpgRet ret;
+    PhysicalAddress rdPtr;
+    PhysicalAddress wrPtr;
+    int room;
+    Int32 instRegIndex;
+
+    ret = CheckJpgInstValidity(handle);
+    if (ret != JPG_RET_SUCCESS)
+        return ret;
+
+    pJpgInst = handle;
+    pDecInfo = &pJpgInst->JpgInfo->decInfo;
+
+    if (pJpgInst->sliceInstMode == TRUE) {
+        instRegIndex = pJpgInst->instIndex;
+    }
+    else {
+        instRegIndex = 0;
+    }
+
+    if (GetJpgPendingInstEx(pJpgInst->instIndex) == pJpgInst) {
+        rdPtr = JpuReadInstReg(instRegIndex, MJPEG_BBC_RD_PTR_REG);
+    }
+    else {
+        rdPtr = pDecInfo->streamRdPtr;
+    }
+
+    wrPtr = pDecInfo->streamWrPtr;
+
+    if (wrPtr == pDecInfo->streamBufStartAddr) {
+        if (pDecInfo->frameOffset == 0) {
+            room = (pDecInfo->streamBufEndAddr-pDecInfo->streamBufStartAddr);
+        }
+        else {
+            room = (pDecInfo->frameOffset);
+        }
+    }
+    else {
+        room = (pDecInfo->streamBufEndAddr - wrPtr);
+    }
+
+    room = ((room>>9)<<9); // multiple of 512
+
+    if (prdPtr) *prdPtr = rdPtr;
+    if (pwrPtr) *pwrPtr = wrPtr;
+    if (size)   *size = room;
+
+    return JPG_RET_SUCCESS;
+}
+
+
+JpgRet JPU_DecUpdateBitstreamBuffer(JpgDecHandle handle, int size)
+{
+    JpgInst * pJpgInst;
+    JpgDecInfo * pDecInfo;
+    PhysicalAddress wrPtr;
+    PhysicalAddress rdPtr;
+    JpgRet ret;
+    int		val = 0;
+    Int32 instRegIndex;
+
+    ret = CheckJpgInstValidity(handle);
+    if (ret != JPG_RET_SUCCESS)
+        return ret;
+
+    pJpgInst = handle;
+    pDecInfo = &pJpgInst->JpgInfo->decInfo;
+    wrPtr = pDecInfo->streamWrPtr;
+
+    if (pJpgInst->sliceInstMode == TRUE) {
+        instRegIndex = pJpgInst->instIndex;
+    }
+    else {
+        instRegIndex = 0;
+    }
+
+    if (size == 0)
+    {
+        val = (wrPtr-pDecInfo->streamBufStartAddr) / 256;
+        if ((wrPtr-pDecInfo->streamBufStartAddr) % 256)
+            val = val + 1;
+
+        if (GetJpgPendingInstEx(pJpgInst->instIndex) == pJpgInst) {
+            JpuWriteInstReg(instRegIndex, MJPEG_BBC_STRM_CTRL_REG, (1UL << 31 | val));
+        }
+        pDecInfo->streamEndflag = 1;
+        return JPG_RET_SUCCESS;
+    }
+
+    wrPtr = pDecInfo->streamWrPtr;
+    wrPtr += size;
+
+    if (wrPtr == pDecInfo->streamBufEndAddr) {
+        wrPtr = pDecInfo->streamBufStartAddr;
+    }
+
+    pDecInfo->streamWrPtr = wrPtr;
+
+    if (GetJpgPendingInstEx(pJpgInst->instIndex) == pJpgInst) {
+        rdPtr = JpuReadInstReg(instRegIndex, MJPEG_BBC_RD_PTR_REG);
+
+        if (rdPtr >= pDecInfo->streamBufEndAddr) {
+            JLOG(INFO, "!!!!! WRAP-AROUND !!!!!\n");
+            JpuWriteInstReg(instRegIndex, MJPEG_BBC_CUR_POS_REG, 0);
+            JpuWriteInstReg(instRegIndex, MJPEG_GBU_TCNT_REG, 0);
+            JpuWriteInstReg(instRegIndex, (MJPEG_GBU_TCNT_REG+4), 0);
+        }
+
+        JpuWriteInstReg(instRegIndex, MJPEG_BBC_WR_PTR_REG, wrPtr);
+        if (wrPtr == pDecInfo->streamBufStartAddr) {
+            JpuWriteInstReg(instRegIndex, MJPEG_BBC_END_ADDR_REG, pDecInfo->streamBufEndAddr);
+        }
+        else {
+            JpuWriteInstReg(instRegIndex, MJPEG_BBC_END_ADDR_REG, wrPtr);
+        }
+    }
+    else {
+        rdPtr = pDecInfo->streamRdPtr;
+    }
+
+    pDecInfo->streamRdPtr = rdPtr;
+
+    return JPG_RET_SUCCESS;
+}
+
+JpgRet JPU_SWReset(JpgHandle handle)
+{
+    Uint32 val;
+
+    int clock_state;
+    JpgInst *pJpgInst;
+
+    pJpgInst = ((JpgInst *)handle);
+    clock_state = jdi_get_clock_gate();
+
+    if (clock_state == 0)
+        jdi_set_clock_gate(1);
+
+    if (handle)
+        jdi_log(JDI_LOG_CMD_RESET, 1, pJpgInst->instIndex);
+
+    val = JpuReadReg(MJPEG_INST_CTRL_START_REG);
+    val |= (1<<2);
+    JpuWriteReg(MJPEG_INST_CTRL_START_REG, val);
+    if (jdi_wait_inst_ctrl_busy(JPU_INST_CTRL_TIMEOUT_MS, MJPEG_INST_CTRL_STATUS_REG, INST_CTRL_IDLE) == -1) {// wait for INST_CTRL become IDLE
+        if (handle)
+            jdi_log(JDI_LOG_CMD_RESET, 0, pJpgInst->instIndex);
+        val &= ~(1<<2);
+        JpuWriteReg(MJPEG_INST_CTRL_START_REG, val);
+        if (clock_state == 0)
+            jdi_set_clock_gate(0);
+        return JPG_RET_INST_CTRL_ERROR;
+    }
+    val &= ~(1<<2);
+    JpuWriteReg(MJPEG_INST_CTRL_START_REG, val);
+
+    if (handle)
+        jdi_log(JDI_LOG_CMD_RESET, 0, pJpgInst->instIndex);
+
+    if (clock_state == 0)
+        jdi_set_clock_gate(0);
+
+    return JPG_RET_SUCCESS;
+}
+JpgRet JPU_HWReset()
+{
+    if (jdi_hw_reset() < 0 )
+        return JPG_RET_FAILURE;
+
+    return JPG_RET_SUCCESS;
+}
+
+JpgRet JPU_DecSetRdPtr(JpgDecHandle handle, PhysicalAddress addr, BOOL updateWrPtr)
+{
+    JpgInst*    pJpgInst;
+    JpgDecInfo* pDecInfo;
+    JpgRet      ret;
+
+    ret = CheckJpgInstValidity(handle);
+    if (ret != JPG_RET_SUCCESS)
+        return ret;
+
+    pJpgInst = (JpgInst*)handle;
+    pDecInfo = &pJpgInst->JpgInfo->decInfo;
+
+    JpgEnterLock();
+
+    if (GetJpgPendingInstEx(pJpgInst->instIndex)) {
+        JpgLeaveLock();
+        return JPG_RET_FRAME_NOT_COMPLETE;
+    }
+    pDecInfo->streamRdPtr = addr;
+    if (updateWrPtr)
+        pDecInfo->streamWrPtr = addr;
+
+    pDecInfo->frameOffset = addr - pDecInfo->streamBufStartAddr;
+    pDecInfo->consumeByte = 0;
+
+    JpuWriteReg(MJPEG_BBC_RD_PTR_REG, pDecInfo->streamRdPtr);
+
+    JpgLeaveLock();
+
+    return JPG_RET_SUCCESS;
+}
+
+JpgRet JPU_DecSetRdPtrEx(JpgDecHandle handle, PhysicalAddress addr, BOOL updateWrPtr)
+{
+    JpgInst*    pJpgInst;
+    JpgDecInfo* pDecInfo;
+    JpgRet      ret;
+
+    ret = CheckJpgInstValidity(handle);
+    if (ret != JPG_RET_SUCCESS)
+        return ret;
+
+    pJpgInst = (JpgInst*)handle;
+    pDecInfo = &pJpgInst->JpgInfo->decInfo;
+
+    JpgEnterLock();
+
+    if (GetJpgPendingInstEx(pJpgInst->instIndex)) {
+        JpgLeaveLock();
+        return JPG_RET_FRAME_NOT_COMPLETE;
+    }
+    pDecInfo->streamRdPtr = addr;
+    pDecInfo->streamBufStartAddr = addr;
+    if (updateWrPtr)
+        pDecInfo->streamWrPtr = addr;
+
+    pDecInfo->frameOffset = 0;
+    pDecInfo->consumeByte = 0;
+
+    JpuWriteReg(MJPEG_BBC_RD_PTR_REG, pDecInfo->streamRdPtr);
+
+    JpgLeaveLock();
+
+    return JPG_RET_SUCCESS;
+}
+
+JpgRet JPU_DecStartOneFrame(JpgDecHandle handle, JpgDecParam *param)
+{
+    JpgInst * pJpgInst;
+    JpgDecInfo * pDecInfo;
+    JpgRet ret;
+    Uint32 val;
+    PhysicalAddress rdPtr, wrPtr;
+    BOOL    is12Bit     = FALSE;
+    BOOL    ppuEnable   = FALSE;
+    Int32 instRegIndex;
+    BOOL bTableInfoUpdate;
+    ret = CheckJpgInstValidity(handle);
+    if (ret != JPG_RET_SUCCESS)
+        return ret;
+
+
+    pJpgInst = handle;
+    pDecInfo = &pJpgInst->JpgInfo->decInfo;
+    is12Bit  = (pDecInfo->bitDepth == 8) ? FALSE : TRUE;
+
+    if (pDecInfo->frameBufPool == 0) { // This means frame buffers have not been registered.
+        return JPG_RET_WRONG_CALL_SEQUENCE;
+    }
+
+    if (pJpgInst->sliceInstMode == TRUE) {
+        instRegIndex = pJpgInst->instIndex;
+    }
+    else {
+        instRegIndex = 0;
+    }
+
+    JpgEnterLock();
+    if (GetJpgPendingInstEx(pJpgInst->instIndex) == pJpgInst) {
+        JpgLeaveLock();
+        return JPG_RET_FRAME_NOT_COMPLETE;
+    }
+
+
+    if (pDecInfo->frameOffset < 0) {
+        SetJpgPendingInstEx(0, pJpgInst->instIndex);
+        return JPG_RET_EOS;
+    }
+
+    pDecInfo->q_prec0 = 0;
+    pDecInfo->q_prec1 = 0;
+    pDecInfo->q_prec2 = 0;
+    pDecInfo->q_prec3 = 0;
+
+    //check for stream empty case
+    if (pDecInfo->streamEndflag == 0) {
+        rdPtr = pDecInfo->streamRdPtr;
+        wrPtr = pDecInfo->streamWrPtr;
+        if (wrPtr == pDecInfo->streamBufStartAddr)
+            wrPtr = pDecInfo->streamBufEndAddr;
+        if (rdPtr > wrPtr) { // wrap-around case
+            if ( ((pDecInfo->streamBufEndAddr-rdPtr) + (wrPtr-pDecInfo->streamBufStartAddr)) <1024 ) {
+                JpgLeaveLock();
+                return JPG_RET_BIT_EMPTY;
+            }
+        }
+        else {
+            if (wrPtr - rdPtr < 1024) {
+                JpgLeaveLock();
+                return JPG_RET_BIT_EMPTY;
+            }
+        }
+    }
+
+    {
+        val = JpegDecodeHeader(pDecInfo);
+        if (val == 0) {
+            JpgLeaveLock();
+            return JPG_RET_FAILURE;
+        }
+
+        if (val == (Uint32)-2) {	// wrap around case
+            pDecInfo->frameOffset = 0;
+            pDecInfo->ecsPtr = 0;
+            val = JpegDecodeHeader(pDecInfo);
+            if (val == 0) {
+                JpgLeaveLock();
+                return JPG_RET_FAILURE;
+            }
+        }
+
+        if (val == (Uint32)-1) {	//stream empty case
+            if (pDecInfo->streamEndflag == 1) {
+                SetJpgPendingInstEx(0, pJpgInst->instIndex);
+                pDecInfo->frameOffset = -1;
+                if (pJpgInst->sliceInstMode == TRUE) {
+                    JpgLeaveLock();
+                }
+                return JPG_RET_EOS;
+            }
+            JpgLeaveLock();
+            return JPG_RET_BIT_EMPTY;
+        }
+    }
+
+    JpuWriteInstReg(instRegIndex, MJPEG_INTR_MASK_REG, ((~pDecInfo->intrEnableBit) & 0x3ff));
+    /* The registers related to the slice encoding should be clear */
+    JpuWriteInstReg(instRegIndex, MJPEG_SLICE_INFO_REG,    pDecInfo->alignedHeight);
+    JpuWriteInstReg(instRegIndex, MJPEG_SLICE_DPB_POS_REG, pDecInfo->alignedHeight);
+    JpuWriteInstReg(instRegIndex, MJPEG_SLICE_POS_REG,     0);
+    JpuWriteInstReg(instRegIndex, MJPEG_PIC_SETMB_REG,     0);
+
+    if (pDecInfo->streamRdPtr == pDecInfo->streamBufEndAddr) {
+        JpuWriteInstReg(instRegIndex, MJPEG_BBC_CUR_POS_REG, 0);
+        JpuWriteInstReg(instRegIndex, MJPEG_GBU_TCNT_REG, 0);
+        JpuWriteInstReg(instRegIndex, (MJPEG_GBU_TCNT_REG+4), 0);
+    }
+
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_WR_PTR_REG, pDecInfo->streamWrPtr);
+    if (pDecInfo->streamWrPtr == pDecInfo->streamBufStartAddr) {
+        JpuWriteInstReg(instRegIndex, MJPEG_BBC_END_ADDR_REG, pDecInfo->streamBufEndAddr);
+    }
+    else {
+        JpuWriteInstReg(instRegIndex, MJPEG_BBC_END_ADDR_REG, JPU_CEIL(256, pDecInfo->streamWrPtr));
+    }
+
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_BAS_ADDR_REG, pDecInfo->streamBufStartAddr);
+    JpuWriteInstReg(instRegIndex, MJPEG_GBU_TCNT_REG, 0);
+    JpuWriteInstReg(instRegIndex, (MJPEG_GBU_TCNT_REG+4), 0);
+    JpuWriteInstReg(instRegIndex, MJPEG_PIC_ERRMB_REG, 0);
+    JpuWriteInstReg(instRegIndex, MJPEG_PIC_CTRL_REG, is12Bit << 31 | pDecInfo->q_prec0 << 30 | pDecInfo->q_prec1 << 29 | pDecInfo->q_prec2 << 28 | pDecInfo->q_prec3 << 27 |
+                                                       pDecInfo->huffAcIdx << 13 | pDecInfo->huffDcIdx << 7 | pDecInfo->userHuffTab << 6 |
+                                                       (JPU_CHECK_WRITE_RESPONSE_BVALID_SIGNAL << 2) | 0);
+
+    JpuWriteInstReg(instRegIndex, MJPEG_PIC_SIZE_REG, (pDecInfo->alignedWidth << 16) | pDecInfo->alignedHeight);
+
+    JpuWriteInstReg(instRegIndex, MJPEG_OP_INFO_REG,  pDecInfo->busReqNum);
+    JpuWriteInstReg(instRegIndex, MJPEG_MCU_INFO_REG, (pDecInfo->mcuBlockNum&0x0f) << 17 | (pDecInfo->compNum&0x07) << 14    |
+                                                      (pDecInfo->compInfo[0]&0x3f) << 8  | (pDecInfo->compInfo[1]&0x0f) << 4 |
+                                                      (pDecInfo->compInfo[2]&0x0f));
+
+    //enable intlv NV12: 10, NV21: 11
+    //packedFormat:0 => 4'd0
+    //packedFormat:1,2,3,4 => 4, 5, 6, 7,
+    //packedFormat:5 => 8
+    //packedFormat:6 => 9
+    val = (pDecInfo->ofmt << 9) | (pDecInfo->frameEndian << 6) | ((pDecInfo->chromaInterleave==0)?0:(pDecInfo->chromaInterleave==1)?2:3);
+    if (pDecInfo->packedFormat == PACKED_FORMAT_NONE) {
+        val |= (0<<5) | (0<<4);
+    }
+    else if (pDecInfo->packedFormat == PACKED_FORMAT_444) {
+        val |= (1<<5) | (0<<4) | (0<<2);
+    }
+    else {
+        val |= (0<<5) | (1<<4) | ((pDecInfo->packedFormat-1)<<2);
+    }
+    val |= (pDecInfo->pixelJustification << 11);
+    JpuWriteInstReg(instRegIndex, MJPEG_DPB_CONFIG_REG, val);
+    JpuWriteInstReg(instRegIndex, MJPEG_RST_INTVAL_REG, pDecInfo->rstIntval);
+
+    if (param) {
+        if (param->scaleDownRatioWidth > 0 )
+            pDecInfo->iHorScaleMode = param->scaleDownRatioWidth;
+        if (param->scaleDownRatioHeight > 0 )
+            pDecInfo->iVerScaleMode = param->scaleDownRatioHeight;
+    }
+    if (pDecInfo->iHorScaleMode | pDecInfo->iVerScaleMode)
+        val = ((pDecInfo->iHorScaleMode&0x3)<<2) | ((pDecInfo->iVerScaleMode&0x3)) | 0x10 ;
+    else {
+        val = 0;
+    }
+    JpuWriteInstReg(instRegIndex, MJPEG_SCL_INFO_REG, val);
+
+    bTableInfoUpdate = FALSE;
+    if (pDecInfo->userHuffTab) {
+        bTableInfoUpdate = TRUE;
+    }
+
+    if (bTableInfoUpdate == TRUE) {
+        if (is12Bit == TRUE){
+            if (!JpgDecHuffTabSetUp_12b(pDecInfo, instRegIndex)) {
+                JpgLeaveLock();
+                return JPG_RET_INVALID_PARAM;
+            }
+        }else{
+            if (!JpgDecHuffTabSetUp(pDecInfo, instRegIndex)) {
+                JpgLeaveLock();
+                return JPG_RET_INVALID_PARAM;
+            }
+        }
+    }
+
+    bTableInfoUpdate = TRUE; // it always should be TRUE for multi-instance
+    if (bTableInfoUpdate == TRUE) {
+        if (!JpgDecQMatTabSetUp(pDecInfo, instRegIndex)) {
+            JpgLeaveLock();
+            return JPG_RET_INVALID_PARAM;
+        }
+    }
+
+    JpgDecGramSetup(pDecInfo, instRegIndex);
+
+    if (pDecInfo->streamEndflag == 1) {
+        val = JpuReadInstReg(instRegIndex, MJPEG_BBC_STRM_CTRL_REG);
+        if ((val & (1UL << 31)) == 0 ) {
+            val = (pDecInfo->streamWrPtr-pDecInfo->streamBufStartAddr) / 256;
+            if ((pDecInfo->streamWrPtr-pDecInfo->streamBufStartAddr) % 256)
+                val = val + 1;
+            JpuWriteInstReg(instRegIndex, MJPEG_BBC_STRM_CTRL_REG, (1UL << 31 | val));
+        }
+    }
+    else {
+        JpuWriteInstReg(instRegIndex, MJPEG_BBC_STRM_CTRL_REG, 0);
+    }
+
+    JpuWriteInstReg(instRegIndex, MJPEG_RST_INDEX_REG, 0);	// RST index at the beginning.
+    JpuWriteInstReg(instRegIndex, MJPEG_RST_COUNT_REG, 0);
+
+    JpuWriteInstReg(instRegIndex, MJPEG_DPCM_DIFF_Y_REG, 0);
+    JpuWriteInstReg(instRegIndex, MJPEG_DPCM_DIFF_CB_REG, 0);
+    JpuWriteInstReg(instRegIndex, MJPEG_DPCM_DIFF_CR_REG, 0);
+
+    JpuWriteInstReg(instRegIndex, MJPEG_GBU_FF_RPTR_REG, pDecInfo->bitPtr);
+    JpuWriteInstReg(instRegIndex, MJPEG_GBU_CTRL_REG, 3);
+
+    ppuEnable = (pDecInfo->rotationIndex > 0) || (pDecInfo->mirrorIndex > 0);
+    JpuWriteInstReg(instRegIndex, MJPEG_ROT_INFO_REG, (ppuEnable<<4) | (pDecInfo->mirrorIndex<<2) | pDecInfo->rotationIndex);
+
+    val = (pDecInfo->frameIdx % pDecInfo->numFrameBuffers);
+    JpuWriteInstReg(instRegIndex, MJPEG_DPB_BASE00_REG, pDecInfo->frameBufPool[val].bufY);
+    JpuWriteInstReg(instRegIndex, MJPEG_DPB_BASE01_REG, pDecInfo->frameBufPool[val].bufCb);
+    JpuWriteInstReg(instRegIndex, MJPEG_DPB_BASE02_REG, pDecInfo->frameBufPool[val].bufCr);
+    JpuWriteInstReg(instRegIndex, MJPEG_DPB_YSTRIDE_REG, pDecInfo->stride);
+    JpuWriteInstReg(instRegIndex, MJPEG_DPB_CSTRIDE_REG, pDecInfo->stride_c);
+
+    if (pDecInfo->roiEnable) {
+        JpuWriteInstReg(instRegIndex, MJPEG_CLP_INFO_REG, 1);
+        JpuWriteInstReg(instRegIndex, MJPEG_CLP_BASE_REG, pDecInfo->roiOffsetX << 16 | pDecInfo->roiOffsetY);	// pixel unit
+        JpuWriteInstReg(instRegIndex, MJPEG_CLP_SIZE_REG, (pDecInfo->roiFrameWidth << 16) | pDecInfo->roiFrameHeight); // pixel Unit
+    }
+    else {
+        JpuWriteInstReg(instRegIndex, MJPEG_CLP_INFO_REG, 0);
+    }
+
+    if (pJpgInst->loggingEnable)
+        jdi_log(JDI_LOG_CMD_PICRUN, 1, instRegIndex);
+
+    if (pJpgInst->sliceInstMode == TRUE) {
+        JpuWriteInstReg(instRegIndex, MJPEG_PIC_START_REG, (1<<JPG_DEC_SLICE_ENABLE_START_PIC));
+    }
+    else {
+        JpuWriteInstReg(instRegIndex, MJPEG_PIC_START_REG, (1<<JPG_ENABLE_START_PIC));
+    }
+
+    pDecInfo->decIdx++;
+
+    SetJpgPendingInstEx(pJpgInst, pJpgInst->instIndex);
+    if (pJpgInst->sliceInstMode == TRUE) {
+        JpgLeaveLock();
+    }
+    return JPG_RET_SUCCESS;
+}
+
+JpgRet JPU_DecGetOutputInfo(JpgDecHandle handle, JpgDecOutputInfo * info)
+{
+    JpgInst*    pJpgInst;
+    JpgDecInfo* pDecInfo;
+    JpgRet      ret;
+    Uint32      val = 0;
+    Int32       instRegIndex;
+
+    ret = CheckJpgInstValidity(handle);
+    if (ret != JPG_RET_SUCCESS) {
+        return ret;
+    }
+
+    if (info == 0) {
+        return JPG_RET_INVALID_PARAM;
+    }
+
+    pJpgInst = handle;
+    pDecInfo = &pJpgInst->JpgInfo->decInfo;
+
+    if (pJpgInst->sliceInstMode == TRUE) {
+        instRegIndex = pJpgInst->instIndex;
+    }
+    else {
+        instRegIndex = 0;
+    }
+
+    if (pJpgInst->sliceInstMode == TRUE) {
+        JpgEnterLock();
+    }
+
+    if (pJpgInst != GetJpgPendingInstEx(pJpgInst->instIndex)) {
+        JpgLeaveLock();
+        return JPG_RET_WRONG_CALL_SEQUENCE;
+    }
+
+
+    if (pDecInfo->frameOffset < 0)
+    {
+        info->numOfErrMBs = 0;
+        info->decodingSuccess = 1;
+        info->indexFrameDisplay = -1;
+        SetJpgPendingInstEx(0, pJpgInst->instIndex);
+
+        JpgLeaveLock();
+        return JPG_RET_SUCCESS;
+    }
+
+    if (pDecInfo->roiEnable) {
+        info->decPicWidth = pDecInfo->roiMcuWidth*pDecInfo->mcuWidth;
+        info->decPicHeight = pDecInfo->roiMcuHeight*pDecInfo->mcuHeight;
+    }
+    else {
+        info->decPicWidth = pDecInfo->alignedWidth;
+        info->decPicHeight = pDecInfo->alignedHeight;
+    }
+
+    info->decPicWidth  >>= pDecInfo->iHorScaleMode;
+    info->decPicHeight >>= pDecInfo->iVerScaleMode;
+
+    info->indexFrameDisplay = (pDecInfo->frameIdx%pDecInfo->numFrameBuffers);
+    info->consumedByte = (JpuReadInstReg(instRegIndex, MJPEG_GBU_TCNT_REG))/8;
+    pDecInfo->streamRdPtr = JpuReadInstReg(instRegIndex, MJPEG_BBC_RD_PTR_REG);
+    pDecInfo->consumeByte = info->consumedByte - 16 - pDecInfo->ecsPtr;
+	
+	/*
+ 		fix up the program may not be able to exit normally when decoder some pictures.
+		due to  pDecInfo->consumeByte==0 when not first enter.
+	*/
+	if(pDecInfo->consumeByte == 0) 
+		pDecInfo->consumeByte += 2;
+
+    info->bytePosFrameStart = pDecInfo->frameOffset;
+    info->ecsPtr = pDecInfo->ecsPtr;
+    info->rdPtr  = pDecInfo->streamRdPtr;
+    info->wrPtr  = JpuReadInstReg(instRegIndex, MJPEG_BBC_WR_PTR_REG);
+
+    pDecInfo->ecsPtr = 0;
+    pDecInfo->frameIdx++;
+
+    val = JpuReadInstReg(instRegIndex, MJPEG_PIC_STATUS_REG);
+    if (val & (1<<INT_JPU_DONE)) {
+        info->decodingSuccess  = 1;
+        info->numOfErrMBs      = 0;
+    }
+    else if (val & (1<<INT_JPU_ERROR)){
+        info->numOfErrMBs = JpuReadInstReg(instRegIndex, MJPEG_PIC_ERRMB_REG);
+        info->decodingSuccess = 0;
+
+    }
+
+#ifndef JPU_IRQ_CONTROL
+	info->decodingSuccess  = 1;
+	info->numOfErrMBs      = 0;
+#endif
+
+    info->frameCycle = JpuReadInstReg(instRegIndex, MJPEG_CYCLE_INFO_REG);
+
+    if (val != 0)
+        JpuWriteInstReg(instRegIndex, MJPEG_PIC_STATUS_REG, val);
+
+    if (pJpgInst->loggingEnable)
+        jdi_log(JDI_LOG_CMD_PICRUN, 0, instRegIndex);
+
+
+    JpuWriteInstReg(instRegIndex, MJPEG_PIC_START_REG, 0);
+
+    val = JpuReadReg(MJPEG_INST_CTRL_STATUS_REG);
+    val &= ~(1UL<<instRegIndex);
+    JpuWriteReg(MJPEG_INST_CTRL_STATUS_REG, val);
+
+    SetJpgPendingInstEx(0, pJpgInst->instIndex);
+    JpgLeaveLock();
+
+    return JPG_RET_SUCCESS;
+}
+
+
+JpgRet JPU_DecGiveCommand(
+    JpgDecHandle handle,
+    JpgCommand cmd,
+    void * param)
+{
+    JpgInst * pJpgInst;
+    JpgDecInfo * pDecInfo;
+    JpgRet ret;
+
+    ret = CheckJpgInstValidity(handle);
+    if (ret != JPG_RET_SUCCESS)
+        return ret;
+
+
+    pJpgInst = handle;
+    pDecInfo = &pJpgInst->JpgInfo->decInfo;
+    switch (cmd)
+    {
+    case SET_JPG_SCALE_HOR:
+        {
+            int scale;
+            scale = *(int *)param;
+            if (pDecInfo->alignedWidth < 128 || pDecInfo->alignedHeight < 128) {
+                if (scale) {
+                    return JPG_RET_INVALID_PARAM;
+                }
+            }
+
+            pDecInfo->iHorScaleMode = scale;
+            break;
+        }
+    case SET_JPG_SCALE_VER:
+        {
+            int scale;
+            scale = *(int *)param;
+            if (pDecInfo->alignedWidth < 128 || pDecInfo->alignedHeight < 128) {
+                if (scale) {
+                    return JPG_RET_INVALID_PARAM;
+                }
+            }
+            pDecInfo->iVerScaleMode = scale;
+            break;
+        }
+    case ENABLE_LOGGING:
+        {
+            pJpgInst->loggingEnable = 1;
+        }
+        break;
+    case DISABLE_LOGGING:
+        {
+            pJpgInst->loggingEnable = 0;
+        }
+        break;
+    default:
+        return JPG_RET_INVALID_COMMAND;
+    }
+    return JPG_RET_SUCCESS;
+}
+
+JpgRet JPU_EncOpen(JpgEncHandle * pHandle, JpgEncOpenParam * pop)
+{
+    JpgInst*    pJpgInst;
+    JpgEncInfo* pEncInfo;
+    JpgRet      ret;
+    Uint32      i;
+    Uint32      mcuWidth, mcuHeight;
+    Uint32      comp0McuWidth, comp0McuHeight;
+    BOOL        rotation_90_270 = FALSE;
+    FrameFormat format;
+
+    ret = CheckJpgEncOpenParam(pop, &g_JpuAttributes);
+    if (ret != JPG_RET_SUCCESS) {
+        return ret;
+    }
+
+    JpgEnterLock();
+    ret = GetJpgInstance(&pJpgInst);
+    if (ret == JPG_RET_FAILURE) {
+        JpgLeaveLock();
+        return JPG_RET_FAILURE;
+    }
+
+    *pHandle = pJpgInst;
+    pEncInfo = &pJpgInst->JpgInfo->encInfo;
+    memset(pEncInfo, 0x00, sizeof(JpgEncInfo));
+    pEncInfo->streamRdPtr        = pop->bitstreamBuffer;
+    pEncInfo->streamWrPtr        = pop->bitstreamBuffer;
+    pEncInfo->sliceHeight        = pop->sliceHeight;
+    pEncInfo->intrEnableBit      = pop->intrEnableBit;
+
+    pEncInfo->streamBufStartAddr = pop->bitstreamBuffer;
+    pEncInfo->streamBufEndAddr   = pop->bitstreamBuffer + pop->bitstreamBufferSize - (4096);
+    pEncInfo->streamEndian       = pop->streamEndian;
+    pEncInfo->frameEndian        = pop->frameEndian;
+    pEncInfo->chromaInterleave   = pop->chromaInterleave;
+    pEncInfo->format             = pop->sourceFormat;
+    pEncInfo->picWidth           = pop->picWidth;
+    pEncInfo->picHeight          = pop->picHeight;
+
+    if (pop->rotation == 90 || pop->rotation == 270) {
+        if (pEncInfo->format == FORMAT_422)      format = FORMAT_440;
+        else if (pEncInfo->format == FORMAT_440) format = FORMAT_422;
+        else                                     format = pEncInfo->format;
+        rotation_90_270 = TRUE;
+    }
+    else {
+        format = pEncInfo->format;
+    }
+
+    // Picture size alignment
+    if (format == FORMAT_420 || format == FORMAT_422) {
+        pEncInfo->alignedWidth = JPU_CEIL(16, pEncInfo->picWidth);
+        mcuWidth = 16;
+    }
+    else {
+        pEncInfo->alignedWidth = JPU_CEIL(8, pEncInfo->picWidth);
+        mcuWidth = (format == FORMAT_400) ? 32 : 8;
+    }
+
+    if (format == FORMAT_420 || format == FORMAT_440) {
+        pEncInfo->alignedHeight = JPU_CEIL(16, pEncInfo->picHeight);
+        mcuHeight = 16;
+    }
+    else {
+        pEncInfo->alignedHeight = JPU_CEIL(8, pEncInfo->picHeight);
+        mcuHeight = 8;
+    }
+
+    pEncInfo->mcuWidth  = mcuWidth;
+    pEncInfo->mcuHeight = mcuHeight;
+    if (format == FORMAT_400) {
+        if (pop->rotation == 90 || pop->rotation == 270) {
+            pEncInfo->mcuWidth  = mcuHeight;
+            pEncInfo->mcuHeight = mcuWidth;
+        }
+    }
+
+    comp0McuWidth  = pEncInfo->mcuWidth;
+    comp0McuHeight = pEncInfo->mcuHeight;
+    if (rotation_90_270 == TRUE) {
+        if (pEncInfo->format == FORMAT_420 || pEncInfo->format == FORMAT_422) {
+            comp0McuWidth = 16;
+        }
+        else  {
+            comp0McuWidth = 8;
+        }
+
+        if (pEncInfo->format == FORMAT_420 || pEncInfo->format == FORMAT_440) {
+            comp0McuHeight = 16;
+        }
+        else if (pEncInfo->format == FORMAT_400) {
+            comp0McuHeight = 32;
+        }
+        else {
+            comp0McuHeight = 8;
+        }
+    }
+
+    if (pop->sliceInstMode == TRUE) {
+        Uint32 ppuHeight = (rotation_90_270 == TRUE) ? pEncInfo->alignedWidth : pEncInfo->alignedHeight;
+        if (pop->sliceHeight % pEncInfo->mcuHeight) {
+            JpgLeaveLock();
+            return JPG_RET_INVALID_PARAM;
+        }
+
+        if (pop->sliceHeight > ppuHeight) {
+            JpgLeaveLock();
+            return JPG_RET_INVALID_PARAM;
+        }
+
+        if (pop->sliceHeight < pEncInfo->mcuHeight) {
+            JpgLeaveLock();
+            return JPG_RET_INVALID_PARAM;
+        }
+    }
+
+    pJpgInst->sliceInstMode = pop->sliceInstMode;
+    pEncInfo->rstIntval     = pop->restartInterval;
+    pEncInfo->jpg12bit      = pop->jpg12bit;
+    pEncInfo->q_prec0       = pop->q_prec0;
+    pEncInfo->q_prec1       = pop->q_prec1;
+    pEncInfo->pixelJustification = pop->pixelJustification;
+    if (pop->jpg12bit){
+        for (i=0; i<8; i++)
+            pEncInfo->pHuffVal[i] = pop->huffVal[i];
+        for (i=0; i<8; i++)
+            pEncInfo->pHuffBits[i] = pop->huffBits[i];
+    }else{
+        for (i=0; i<4; i++)
+            pEncInfo->pHuffVal[i] = pop->huffVal[i];
+        for (i=0; i<4; i++)
+            pEncInfo->pHuffBits[i] = pop->huffBits[i];
+    }
+
+    for (i=0; i<4; i++)
+        pEncInfo->pQMatTab[i] = pop->qMatTab[i];
+
+    pEncInfo->pCInfoTab[0] = sJpuCompInfoTable[2/*pEncInfo->format*/];
+    pEncInfo->pCInfoTab[1] = pEncInfo->pCInfoTab[0] + 6;
+    pEncInfo->pCInfoTab[2] = pEncInfo->pCInfoTab[1] + 6;
+    pEncInfo->pCInfoTab[3] = pEncInfo->pCInfoTab[2] + 6;
+
+    if (pop->packedFormat == PACKED_FORMAT_444 && pEncInfo->format != FORMAT_444) {
+        return JPG_RET_INVALID_PARAM;
+    }
+
+    pEncInfo->packedFormat = pop->packedFormat;
+    if (pEncInfo->format == FORMAT_400) {
+        pEncInfo->compInfo[1] = 0;
+        pEncInfo->compInfo[2] = 0;
+    }
+    else {
+        pEncInfo->compInfo[1] = 5;
+        pEncInfo->compInfo[2] = 5;
+    }
+
+    if (pEncInfo->format == FORMAT_400) {
+        pEncInfo->compNum = 1;
+    }
+    else
+        pEncInfo->compNum = 3;
+
+    if (pEncInfo->format == FORMAT_420) {
+        pEncInfo->mcuBlockNum = 6;
+    }
+    else if (pEncInfo->format == FORMAT_422) {
+        pEncInfo->mcuBlockNum = 4;
+    } else if (pEncInfo->format == FORMAT_440) { /* aka YUV440 */
+        pEncInfo->mcuBlockNum = 4;
+    } else if (pEncInfo->format == FORMAT_444) {
+        pEncInfo->mcuBlockNum = 3;
+    } else if (pEncInfo->format == FORMAT_400) {
+        Uint32 picHeight = (90 == pop->rotation || 270 == pop->rotation) ? pEncInfo->picWidth : pEncInfo->picHeight;
+        if (0 < pEncInfo->rstIntval && picHeight == pEncInfo->sliceHeight) {
+            pEncInfo->mcuBlockNum = 1;
+            comp0McuWidth         = 8;
+            comp0McuHeight        = 8;
+        }
+        else {
+            pEncInfo->mcuBlockNum = 4;
+        }
+    }
+    pEncInfo->compInfo[0] = (comp0McuWidth >> 3) << 3 | (comp0McuHeight >> 3);
+
+    pEncInfo->busReqNum = (pop->jpg12bit == FALSE) ? GetEnc8bitBusReqNum(pEncInfo->packedFormat, pEncInfo->format) :
+                                                     GetEnc12bitBusReqNum(pEncInfo->packedFormat, pEncInfo->format);
+
+
+    pEncInfo->tiledModeEnable = pop->tiledModeEnable;
+
+    pEncInfo->encIdx = 0;
+    pEncInfo->encSlicePosY = 0;
+    pEncInfo->rotationIndex = pop->rotation/90;
+    pEncInfo->mirrorIndex   = pop->mirror;
+    JpgLeaveLock();
+
+    return JPG_RET_SUCCESS;
+
+}
+
+JpgRet JPU_EncClose(JpgEncHandle handle)
+{
+    JpgInst * pJpgInst;
+    JpgRet ret;
+
+    ret = CheckJpgInstValidity(handle);
+    if (ret != JPG_RET_SUCCESS)
+        return ret;
+
+    JpgEnterLock();
+
+    pJpgInst = handle;
+    if (GetJpgPendingInstEx(pJpgInst->instIndex)) {
+        JpgLeaveLock();
+        return JPG_RET_FRAME_NOT_COMPLETE;
+    }
+
+    FreeJpgInstance(pJpgInst);
+
+    JpgLeaveLock();
+
+    return JPG_RET_SUCCESS;
+}
+
+
+
+JpgRet JPU_EncGetBitstreamBuffer( JpgEncHandle handle,
+    PhysicalAddress * prdPtr,
+    PhysicalAddress * pwrPtr,
+    int * size)
+{
+    JpgInst * pJpgInst;
+    JpgRet ret;
+    Int32 instRegIndex;
+
+    ret = CheckJpgInstValidity(handle);
+    if (ret != JPG_RET_SUCCESS)
+        return ret;
+
+    if ( prdPtr == 0 || pwrPtr == 0 || size == 0) {
+        return JPG_RET_INVALID_PARAM;
+    }
+
+    pJpgInst = handle;
+
+    if (pJpgInst->sliceInstMode == TRUE) {
+        instRegIndex = pJpgInst->instIndex;
+    }
+    else {
+        instRegIndex = 0;
+    }
+
+
+    *pwrPtr = JpuReadInstReg(instRegIndex, MJPEG_BBC_WR_PTR_REG);
+    *prdPtr = JpuReadInstReg(instRegIndex, MJPEG_BBC_RD_PTR_REG);
+
+    *size = *pwrPtr - *prdPtr;
+
+    return JPG_RET_SUCCESS;
+
+}
+
+JpgRet JPU_EncUpdateBitstreamBuffer(
+    JpgEncHandle handle,
+    int size)
+{
+    JpgInst * pJpgInst;
+    JpgEncInfo * pEncInfo;
+    JpgRet ret;
+    Int32 instRegIndex;
+
+    ret = CheckJpgInstValidity(handle);
+    if (ret != JPG_RET_SUCCESS)
+        return ret;
+
+    pJpgInst = handle;
+
+    pEncInfo = &pJpgInst->JpgInfo->encInfo;
+    if (GetJpgPendingInstEx(pJpgInst->instIndex) == pJpgInst) {
+        if (pJpgInst->sliceInstMode == TRUE) {
+            instRegIndex = pJpgInst->instIndex;
+        }
+        else {
+            instRegIndex = 0;
+        }
+
+        pEncInfo->streamWrPtr = JpuReadInstReg(instRegIndex, MJPEG_BBC_WR_PTR_REG);
+        pEncInfo->streamRdPtr += size;
+        if ((pEncInfo->streamWrPtr >= pEncInfo->streamBufEndAddr) || (size == 0)) {	//Full Interrupt case. wrap to the start address
+            JpuWriteInstReg(instRegIndex, MJPEG_BBC_CUR_POS_REG, 0);
+            JpuWriteInstReg(instRegIndex, MJPEG_BBC_BAS_ADDR_REG, pEncInfo->streamBufStartAddr);
+            JpuWriteInstReg(instRegIndex, MJPEG_BBC_EXT_ADDR_REG, pEncInfo->streamBufStartAddr);
+            JpuWriteInstReg(instRegIndex, MJPEG_BBC_END_ADDR_REG, pEncInfo->streamBufEndAddr);
+            pEncInfo->streamRdPtr = pEncInfo->streamBufStartAddr;
+            pEncInfo->streamWrPtr = pEncInfo->streamBufStartAddr;
+            JpuWriteInstReg(instRegIndex, MJPEG_BBC_RD_PTR_REG, pEncInfo->streamRdPtr);
+            JpuWriteInstReg(instRegIndex, MJPEG_BBC_WR_PTR_REG, pEncInfo->streamWrPtr);
+        }
+    }
+    else {
+        pEncInfo->streamRdPtr = pEncInfo->streamBufStartAddr;
+        pEncInfo->streamWrPtr = pEncInfo->streamBufStartAddr;
+    }
+
+    return JPG_RET_SUCCESS;
+}
+
+
+JpgRet JPU_EncStartOneFrame(JpgEncHandle handle, JpgEncParam * param)
+{
+    JpgInst * pJpgInst;
+    JpgEncInfo * pEncInfo;
+    FrameBuffer * pBasFrame;
+    JpgRet ret;
+    Uint32 val;
+    Int32 instRegIndex;
+    BOOL bTableInfoUpdate;
+    Uint32  rotMirEnable = 0;
+    Uint32  rotMirMode   = 0;
+
+    ret = CheckJpgInstValidity(handle);
+    if (ret != JPG_RET_SUCCESS)
+        return ret;
+
+
+    pJpgInst = handle;
+    pEncInfo = &pJpgInst->JpgInfo->encInfo;
+
+
+    ret = CheckJpgEncParam(handle, param);
+    if (ret != JPG_RET_SUCCESS) {
+        return ret;
+    }
+
+    pBasFrame = param->sourceFrame;
+
+    JpgEnterLock();
+
+    if (GetJpgPendingInstEx(pJpgInst->instIndex) == pJpgInst) {
+        JpgLeaveLock();
+        return JPG_RET_FRAME_NOT_COMPLETE;
+    }
+
+    if (pJpgInst->sliceInstMode == TRUE) {
+        instRegIndex = pJpgInst->instIndex;
+    }
+    else {
+        instRegIndex = 0;
+    }
+
+    JpuWriteInstReg(instRegIndex, MJPEG_INTR_MASK_REG, ((~pEncInfo->intrEnableBit) & 0x3ff));
+    JpuWriteInstReg(instRegIndex, MJPEG_SLICE_INFO_REG, pEncInfo->sliceHeight);
+    JpuWriteInstReg(instRegIndex, MJPEG_SLICE_DPB_POS_REG, pEncInfo->picHeight); // assume that the all of source buffer is available
+    JpuWriteInstReg(instRegIndex, MJPEG_SLICE_POS_REG, pEncInfo->encSlicePosY);
+    val = (0 << 16) | (pEncInfo->encSlicePosY / pEncInfo->mcuHeight);
+    JpuWriteInstReg(instRegIndex, MJPEG_PIC_SETMB_REG,val);
+
+    JpuWriteInstReg(instRegIndex, MJPEG_CLP_INFO_REG, 0);	//off ROI enable due to not supported feature for encoder.
+
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_BAS_ADDR_REG, pEncInfo->streamBufStartAddr);
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_END_ADDR_REG, pEncInfo->streamBufEndAddr);
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_WR_PTR_REG, pEncInfo->streamWrPtr);
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_RD_PTR_REG, pEncInfo->streamRdPtr);
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_CUR_POS_REG, 0);
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_DATA_CNT_REG, JPU_GBU_SIZE / 4);	// 64 * 4 byte == 32 * 8 byte
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_EXT_ADDR_REG, pEncInfo->streamBufStartAddr);
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_INT_ADDR_REG, 0);
+
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_BAS_ADDR_REG, pEncInfo->streamWrPtr);
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_EXT_ADDR_REG, pEncInfo->streamWrPtr);
+
+    JpuWriteInstReg(instRegIndex, MJPEG_GBU_BPTR_REG, 0);
+    JpuWriteInstReg(instRegIndex, MJPEG_GBU_WPTR_REG, 0);
+
+    JpuWriteInstReg(instRegIndex, MJPEG_GBU_BBSR_REG, 0);
+    JpuWriteInstReg(instRegIndex, MJPEG_GBU_CTRL_REG, 0);
+
+    JpuWriteInstReg(instRegIndex, MJPEG_GBU_BBER_REG, ((JPU_GBU_SIZE / 4) * 2) - 1);
+    JpuWriteInstReg(instRegIndex, MJPEG_GBU_BBIR_REG, JPU_GBU_SIZE / 4);	// 64 * 4 byte == 32 * 8 byte
+    JpuWriteInstReg(instRegIndex, MJPEG_GBU_BBHR_REG, JPU_GBU_SIZE / 4);	// 64 * 4 byte == 32 * 8 byte
+
+#define DEFAULT_TDI_TAI_DATA 0x055
+    JpuWriteInstReg(instRegIndex, MJPEG_PIC_CTRL_REG, (pEncInfo->jpg12bit<<31) | (pEncInfo->q_prec0<<30) | (pEncInfo->q_prec1<<29) | (pEncInfo->tiledModeEnable<<19) |
+                                                      (DEFAULT_TDI_TAI_DATA<<7) | 0x18 | (1<<6) | (JPU_CHECK_WRITE_RESPONSE_BVALID_SIGNAL<<2));
+    JpuWriteInstReg(instRegIndex, MJPEG_SCL_INFO_REG, 0);
+
+    val = 0;
+    //PackMode[3:0]: 0(NONE), 8(PACK444), 4,5,6,7(YUYV => VYUY)
+    val = (pEncInfo->frameEndian << 6) | ((pEncInfo->chromaInterleave==0)?0:(pEncInfo->chromaInterleave==1)?2:3);
+    if (pEncInfo->packedFormat == PACKED_FORMAT_NONE) {
+        val |= (0<<5) | (0<<4) | (0<<2);
+    }
+    else if (pEncInfo->packedFormat == PACKED_FORMAT_444) {
+        val |= (1<<5) | (0<<4) | (0<<2);
+    }
+    else {
+        val |= (0<<5) | (1<<4) | ((pEncInfo->packedFormat-1)<<2);
+    }
+    val |= (pEncInfo->pixelJustification << 11);
+
+    JpuWriteInstReg(instRegIndex, MJPEG_DPB_CONFIG_REG, val);
+
+    JpuWriteInstReg(instRegIndex, MJPEG_RST_INTVAL_REG, pEncInfo->rstIntval);
+    if (pEncInfo->encSlicePosY == 0) {
+        JpuWriteInstReg(instRegIndex, MJPEG_RST_INDEX_REG, 0);// RST index from 0.
+        JpuWriteInstReg(instRegIndex, MJPEG_BBC_STRM_CTRL_REG, 0);// clear BBC ctrl status.
+    }
+
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_CTRL_REG, (pEncInfo->streamEndian << 1) | 1);
+    JpuWriteInstReg(instRegIndex, MJPEG_OP_INFO_REG, pEncInfo->busReqNum);
+
+
+    bTableInfoUpdate = FALSE;
+    if (pEncInfo->encSlicePosY == 0) {
+        bTableInfoUpdate = TRUE; // if sliceMode is disabled. HW process frame by frame between instances. so Huff table can be updated between instances. instances can have the different HuffTable.
+    }
+
+    if (bTableInfoUpdate == TRUE) {
+        // Load HUFFTab
+        if (pEncInfo->jpg12bit){
+            if (!JpgEncLoadHuffTab_12b(pJpgInst, instRegIndex)) {
+                JpgLeaveLock();
+                return JPG_RET_INVALID_PARAM;
+            }
+        }else{
+            if (!JpgEncLoadHuffTab(pJpgInst, instRegIndex)) {
+                JpgLeaveLock();
+                return JPG_RET_INVALID_PARAM;
+            }
+        }
+    }
+
+    bTableInfoUpdate = FALSE;
+    if (pEncInfo->encSlicePosY == 0) {
+        bTableInfoUpdate = TRUE;
+    }
+
+    if (bTableInfoUpdate == TRUE) {
+        // Load QMATTab
+        if (!JpgEncLoadQMatTab(pJpgInst, instRegIndex)) {
+            JpgLeaveLock();
+            return JPG_RET_INVALID_PARAM;
+        }
+    }
+
+
+
+    JpuWriteInstReg(instRegIndex, MJPEG_PIC_SIZE_REG, pEncInfo->alignedWidth<<16 | pEncInfo->alignedHeight);
+
+    if (pEncInfo->rotationIndex || pEncInfo->mirrorIndex) {
+        rotMirEnable = 0x10;
+        rotMirMode   = (pEncInfo->mirrorIndex << 2) | pEncInfo->rotationIndex;
+    }
+    JpuWriteInstReg(instRegIndex, MJPEG_ROT_INFO_REG, rotMirEnable | rotMirMode);
+
+    JpuWriteInstReg(instRegIndex, MJPEG_MCU_INFO_REG, (pEncInfo->mcuBlockNum&0x0f) << 17 | (pEncInfo->compNum&0x07) << 14    |
+                                                      (pEncInfo->compInfo[0]&0x3f) << 8  | (pEncInfo->compInfo[1]&0x0f) << 4 |
+                                                      (pEncInfo->compInfo[2]&0x0f));
+
+    //JpgEncGbuResetReg
+    JpuWriteInstReg(instRegIndex, MJPEG_GBU_CTRL_REG, pEncInfo->stuffByteEnable<<3);     // stuffing "FF" data where frame end
+
+    JpuWriteInstReg(instRegIndex, MJPEG_DPB_BASE00_REG,  pBasFrame->bufY);
+    JpuWriteInstReg(instRegIndex, MJPEG_DPB_BASE01_REG,  pBasFrame->bufCb);
+    JpuWriteInstReg(instRegIndex, MJPEG_DPB_BASE02_REG,  pBasFrame->bufCr);
+    JpuWriteInstReg(instRegIndex, MJPEG_DPB_YSTRIDE_REG, pBasFrame->stride);
+    JpuWriteInstReg(instRegIndex, MJPEG_DPB_CSTRIDE_REG, pBasFrame->strideC);
+
+
+    if (pJpgInst->loggingEnable)
+        jdi_log(JDI_LOG_CMD_PICRUN, 1, instRegIndex);
+
+
+    JpuWriteInstReg(instRegIndex, MJPEG_PIC_START_REG, (1<<JPG_ENABLE_START_PIC));
+
+    pEncInfo->encIdx++;
+
+
+    SetJpgPendingInstEx(pJpgInst, pJpgInst->instIndex);
+    if (pJpgInst->sliceInstMode == TRUE) {
+        JpgLeaveLock();
+    }
+    return JPG_RET_SUCCESS;
+}
+
+
+JpgRet JPU_EncGetOutputInfo(
+    JpgEncHandle handle,
+    JpgEncOutputInfo * info
+    )
+{
+    JpgInst * pJpgInst;
+    JpgEncInfo * pEncInfo;
+    Uint32 val;
+    Uint32 intReason;
+    JpgRet ret;
+    Int32 instRegIndex;
+
+    ret = CheckJpgInstValidity(handle);
+    if (ret != JPG_RET_SUCCESS) {
+        return ret;
+    }
+
+    if (info == 0) {
+        return JPG_RET_INVALID_PARAM;
+    }
+
+    pJpgInst = handle;
+    pEncInfo = &pJpgInst->JpgInfo->encInfo;
+
+
+    if (pJpgInst->sliceInstMode == TRUE) {
+        JpgEnterLock();
+    }
+    if (pJpgInst != GetJpgPendingInstEx(pJpgInst->instIndex)) {
+        JpgLeaveLock();
+        return JPG_RET_WRONG_CALL_SEQUENCE;
+    }
+
+    if (pJpgInst->sliceInstMode == TRUE) {
+        instRegIndex = pJpgInst->instIndex;
+    }
+    else {
+        instRegIndex = 0;
+    }
+
+    info->frameCycle = JpuReadInstReg(instRegIndex, MJPEG_CYCLE_INFO_REG);
+    intReason = JpuReadInstReg(instRegIndex, MJPEG_PIC_STATUS_REG);
+
+    if ((intReason & 0x4) >> 2) {
+        JpgLeaveLock();
+        return JPG_RET_WRONG_CALL_SEQUENCE;
+    }
+
+    info->encodedSliceYPos = JpuReadInstReg(instRegIndex, MJPEG_SLICE_POS_REG);
+    pEncInfo->encSlicePosY = info->encodedSliceYPos;
+    if (intReason & (1<<INT_JPU_DONE))
+        pEncInfo->encSlicePosY = 0;
+
+    pEncInfo->streamWrPtr = JpuReadInstReg(instRegIndex, MJPEG_BBC_WR_PTR_REG);
+    pEncInfo->streamRdPtr = JpuReadInstReg(instRegIndex, MJPEG_BBC_RD_PTR_REG);
+    info->bitstreamBuffer = pEncInfo->streamRdPtr;
+    info->bitstreamSize = pEncInfo->streamWrPtr - pEncInfo->streamRdPtr;
+    info->streamWrPtr = pEncInfo->streamWrPtr;
+    info->streamRdPtr = pEncInfo->streamRdPtr;
+
+    if (intReason != 0) {
+        JpuWriteInstReg(instRegIndex, MJPEG_PIC_STATUS_REG, intReason);
+
+        if (intReason & (1<<INT_JPU_SLICE_DONE))
+            info->encodeState = ENCODE_STATE_SLICE_DONE;
+        if (intReason & (1<<INT_JPU_DONE))
+            info->encodeState = ENCODE_STATE_FRAME_DONE;
+    }
+	
+#ifndef JPU_IRQ_CONTROL
+    info->encodeState = ENCODE_STATE_FRAME_DONE;
+#endif
+
+    if (pJpgInst->loggingEnable)
+        jdi_log(JDI_LOG_CMD_PICRUN, 0, instRegIndex);
+
+    JpuWriteInstReg(instRegIndex, MJPEG_PIC_START_REG, 0);
+
+    val = JpuReadReg(MJPEG_INST_CTRL_STATUS_REG);
+    val &= ~(1UL<<instRegIndex);
+    JpuWriteReg(MJPEG_INST_CTRL_STATUS_REG, val);
+
+    SetJpgPendingInstEx(0, pJpgInst->instIndex);
+
+    JpgLeaveLock();
+    return JPG_RET_SUCCESS;
+}
+
+
+JpgRet JPU_EncGiveCommand(
+    JpgEncHandle handle,
+    JpgCommand cmd,
+    void * param)
+{
+    JpgInst * pJpgInst;
+    JpgEncInfo * pEncInfo;
+    JpgRet ret;
+
+    ret = CheckJpgInstValidity(handle);
+    if (ret != JPG_RET_SUCCESS)
+        return ret;
+
+
+    pJpgInst = handle;
+    pEncInfo = &pJpgInst->JpgInfo->encInfo;
+    switch (cmd)
+    {
+    case ENC_JPG_GET_HEADER:
+        {
+            if (param == 0) {
+                return JPG_RET_INVALID_PARAM;
+            }
+
+            if (!JpgEncEncodeHeader(handle, param)) {
+                return JPG_RET_INVALID_PARAM;
+            }
+            break;
+        }
+    case SET_JPG_USE_STUFFING_BYTE_FF:
+        {
+            int enable;
+            enable = *(int *)param;
+            pEncInfo->stuffByteEnable = enable;
+            break;
+        }
+    case SET_JPG_QUALITY_FACTOR:
+        {
+            Uint32 encQualityPercentage;
+            encQualityPercentage = *(Uint32*)param;
+            JpgEncSetQualityFactor(handle, encQualityPercentage, TRUE);
+            break;
+        }
+    case ENABLE_LOGGING:
+        {
+            pJpgInst->loggingEnable = 1;
+        }
+        break;
+    case DISABLE_LOGGING:
+        {
+            pJpgInst->loggingEnable = 0;
+        }
+        break;
+
+    default:
+        return JPG_RET_INVALID_COMMAND;
+    }
+    return JPG_RET_SUCCESS;
+}

+ 1426 - 0
codaj12/jpuapi/jpuapi.h

@@ -0,0 +1,1426 @@
+/*
+ * Copyright (c) 2018, Chips&Media
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JPUAPI_H_INCLUDED
+#define JPUAPI_H_INCLUDED
+
+#include "jpuconfig.h"
+#include "../jdi/jdi.h"
+#include "jputypes.h"
+
+/* _n: number, _s: significance */
+#define JPU_CEIL(_s, _n)        (((_n)+(_s-1))&~(_s-1))
+#define JPU_FLOOR(_s, _n)       (_n&~(_s-1))
+//------------------------------------------------------------------------------
+// common struct and definition
+//------------------------------------------------------------------------------
+
+/**
+* @brief
+This is a special enumeration type for representing the JPEG profiles.
+*/
+typedef enum {
+    /* Non-differential, Huffman coding */
+    JPEG_BASELINE_DCT,            /**< JPEG baseline profile */
+    JPEG_EXTENDED_SEQUENTIAL_DCT, /**< JPEG extended sequential profile */
+    /* The others are not supported on CODAJ12 */
+} JpgProfile;
+
+/**
+* @brief
+This is a special enumeration type for some configuration commands from host
+processor to the JPU. Most of these commands can be called occasionally, not
+periodically for changing the configuration of decoder operations running on the
+JPU. Details of these commands will be presented in the next chapter.
+*/
+typedef enum {
+    SET_JPG_SCALE_HOR, /**< This command sets the scale down ratio for picture width. The scale ratio value can be either 1(1/2 scale), 2(1/4 scale) or 3(1/8 scale). */
+    SET_JPG_SCALE_VER, /**< This command sets the scale down ratio for picture height. The scale ratio value can be either 1(1/2 scale), 2(1/4 scale) or 3(1/8 scale). */
+    SET_JPG_USE_STUFFING_BYTE_FF, /**< This command sets use of stuffing byte, 0xFF. */
+    SET_JPG_QUALITY_FACTOR, /**< This command sets use of quality factor. */
+    ENC_JPG_GET_HEADER,  /**< This command generates JPEG high-level header syntaxes. */
+    ENABLE_LOGGING,      /**< This command activates message logging once JPU_DecOpen() or JPU_EncOpen() is called. */
+    DISABLE_LOGGING,     /**< This command deactivates message logging. (default) */
+    JPG_CMD_END
+} JpgCommand;
+
+
+/**
+* @brief
+This is a type for representing physical addresses which is recognizable by the
+JPU. In general, the JPU hardware does not know about virtual address space
+which is set and handled by host processor. All these virtual addresses are
+translated into physical addresses by Memory Management Unit. All data buffer
+addresses such as stream buffer, frame buffer, should be given to the JPU as an
+address on physical address space.
+*/
+typedef enum {
+    JPG_RET_SUCCESS, /**< This means that operation was done successfully. */
+    JPG_RET_FAILURE, /**< This means that operation was not done successfully. */
+    JPG_RET_BIT_EMPTY, /**< This means that bitstream buffer is found to be empty during decode operation. */
+    JPG_RET_EOS, /**< This means the end of stream. */
+    JPG_RET_INVALID_HANDLE, /**< This means that the given handle for the current API function call was invalid(for example, not initialized yet, improper function call for the given handle, etc.).  */
+    JPG_RET_INVALID_PARAM,  /**< This means that the given argument parameters (for example, input data structure) was invalid (not initialized yet or not valid anymore). */
+    JPG_RET_INVALID_COMMAND, /**< This means that the given command was invalid (for example, undefined, or not allowed in the given instances). */
+    JPG_RET_ROTATOR_OUTPUT_NOT_SET, /**< This means that rotator output buffer was not allocated even though postprocessor (rotation, mirroring, or deringing) is enabled.  */
+    JPG_RET_ROTATOR_STRIDE_NOT_SET, /**< This means that rotator stride was not provided even though postprocessor (rotation, mirroring, or deringing) is enabled. */
+    JPG_RET_FRAME_NOT_COMPLETE, /**< This means that frame decoding operation was not completed yet, so the given API function call cannot be allowed. */
+    JPG_RET_INVALID_FRAME_BUFFER, /**< This means that the given source frame buffer pointers were invalid in encoder (not initialized yet or not valid anymore).  */
+    JPG_RET_INSUFFICIENT_FRAME_BUFFERS, /**< This means that the given numbers of frame buffers were not enough for the operations of the given handle. */
+    JPG_RET_INVALID_STRIDE, /**< This means that the given stride was invalid (for example, 0, not a multiple of 8 or smaller than picture size). */
+    JPG_RET_WRONG_CALL_SEQUENCE, /**< This means that the current API function call was invalid considering the allowed sequences between API functions (for example, missing one crucial function call before  this function call). */
+    JPG_RET_CALLED_BEFORE, /**< This means that multiple calls of the current API function for a given instance are invalid. */
+    JPG_RET_NOT_INITIALIZED, /**< This means that JPU was not initialized yet. Before calling any API functions, the initialization API function, JPU_Init(), should be called at the beginning. */
+    JPG_RET_INSUFFICIENT_RESOURCE, /**< This means that JPU cannot allocate memory due to lack of memory. */
+    JPG_RET_INST_CTRL_ERROR, /**< This means there was a fault in instance control. */
+    JPG_RET_NOT_SUPPORT, /**< This means that HOST application uses an API option that is not supported in current hardware. */
+} JpgRet;
+
+/**
+* @brief
+This is a special enumeration type for representing the current encoder states.
+*/
+typedef enum {
+    ENCODE_STATE_NEW_FRAME = 0,  /**< The state indicates the start of a new frame. It appears for slice encoding. */
+    ENCODE_STATE_FRAME_DONE = 0, /**< The state indicates the completion of encoding a frame. */
+    ENCODE_STATE_SLICE_DONE = 1  /**< The state indicates the completion of encoding a slice. */
+} EncodeState;
+
+
+/**
+* @brief
+This is an enumeration type for representing mirroring directions.
+*/
+typedef enum {
+    MIRDIR_NONE, /**< No mirroring */
+    MIRDIR_VER,  /**< Vertical mirroring */
+    MIRDIR_HOR,  /**< Horizontal mirroring */
+    MIRDIR_HOR_VER /**< Horizontal and veritical mirroring */
+} JpgMirrorDirection;
+
+/**
+* @brief
+This is an enumeration type for representing frame buffer formats.
+*/
+typedef enum {
+    FORMAT_420 = 0, /**< YUV420 format */
+    FORMAT_422 = 1, /**< YUV422 format */
+    FORMAT_440 = 2, /**< YUV440 format */
+    FORMAT_444 = 3, /**< YUV444 format */
+    FORMAT_400 = 4, /**< YUV400 format */
+    FORMAT_MAX
+} FrameFormat;
+
+/**
+* @brief
+This is an enumeration type for representing a CbCr interleave mode of frame buffer.
+*/
+typedef enum {
+    CBCR_SEPARATED = 0, /**< Cb data and Cr data are located in each separate plane. */
+    CBCR_INTERLEAVE, /**< Chroma data are interleaved in Cb and Cr order. */
+    CRCB_INTERLEAVE  /**< Chroma data are interleaved in Cr and Cb order. */
+} CbCrInterLeave;
+
+/**
+* @brief
+This is an enumeration type for representing a packed format of frame buffer.
+*/
+typedef enum {
+    PACKED_FORMAT_NONE,
+    PACKED_FORMAT_422_YUYV,  /**< This is YUV422 packed format with YUYV component order. */
+    PACKED_FORMAT_422_UYVY,  /**< This is YUV422 packed format with UYVY component order. */
+    PACKED_FORMAT_422_YVYU,  /**< This is YUV422 packed format with YVYU component order. */
+    PACKED_FORMAT_422_VYUY,  /**< This is YUV422 packed format with VYUY component order. */
+    PACKED_FORMAT_444,       /**< This is YUV444 packed format.  */
+    PACKED_FORMAT_MAX
+} PackedFormat;
+
+typedef enum {
+    O_FMT_NONE,
+    O_FMT_420,
+    O_FMT_422,
+    O_FMT_444,
+    O_FMT_MAX
+} OutputFormat;
+
+/* Assume that pixel endianness is big-endian.
+ * b0 is low address in a framebuffer.
+ * b1 is high address in a framebuffer.
+ * pixel consists of b0 and b1.
+ * RIGHT JUSTIFICATION: (default)
+ * lsb         msb
+ * |----|--------|
+ * |0000| pixel  |
+ * |----|--------|
+ * | b0   |   b1 |
+ * |-------------|
+ * LEFT JUSTIFICATION:
+ * lsb         msb
+ * |--------|----|
+ * | pixel  |0000|
+ * |--------|----|
+ * | b0   |   b1 |
+ * |-------------|
+ */
+enum JPU_PIXEL_JUSTIFICATION {
+    PIXEL_16BIT_MSB_JUSTIFIED,
+    PIXEL_16BIT_LSB_JUSTIFIED,
+    PIXEL_16BIT_JUSTIFICATION_MAX,
+};
+
+/**
+* @brief
+This is an enumeration type for representing the JPU interrupt reasons.
+*/
+typedef enum {
+    INT_JPU_DONE = 0,  /**< This interrupt indicates the completion of encoding/decoding a frame. */
+    INT_JPU_ERROR = 1, /**< This interrupt indicates occurrence of error. */
+    INT_JPU_BIT_BUF_EMPTY = 2, /**< This interrupt indicates JPU encounters empty bitstream buffer while decoding. */
+    INT_JPU_BIT_BUF_FULL = 2,  /**< This interrupt indicates full state of bitstream buffer while encoding. */     /* For encoder */
+    INT_JPU_SLICE_DONE = 9,    /**< This interrupt indicates the completion of encoding a slice. */     /* For encoder */
+}InterruptJpu;
+
+/**
+* @brief
+This is an enumeration type for representing quantization and Huffman table encoding modes.
+*/
+typedef enum {
+    JPG_TBL_NORMAL,
+} JpgTableMode;
+
+/**
+* @brief
+This is an enumeration type for representing encode header modes.
+*/
+typedef enum {
+    ENC_HEADER_MODE_NORMAL,  /**< Generation of the whole JPEG header syntaxes  */
+    ENC_HEADER_MODE_SOS_ONLY /**< Generation of scan header syntax only  */
+} JpgEncHeaderMode;
+
+/**
+* @brief This is an enumeration type for representing scale down ratios.
+*/
+enum JPU_DOWNSCALE_VAL {
+    JPG_SCALE_DOWN_NONE,     /**< No scaling */
+    JPG_SCALE_DOWN_ONE_HALF, /**< 1/2 scale*/
+    JPG_SCALE_DOWN_ONE_QUARTER, /**< 1/4 scale */
+    JPG_SCALE_DOWN_ONE_EIGHTS,  /**< 1/8 scale */
+    JPG_SCALE_DOWN_MAX
+};
+
+/**
+* @brief This is an enumeration type for representing a product ID.
+*/
+enum JPU_PRODUCT_ID {
+    PRODUCT_ID_CODAJ12 = 12,
+};
+
+/**
+* @brief
+@verbatim
+This is a data structure for representing frame buffer pointers of each Y/Cb/Cr color
+component. In case of CbCr interleave mode, Cb and Cr frame data are written to memory area starting
+from the given bufCb address.
+
+All of the Y/Cb/Cr component addresses must be 8-byte aligned.
+A pixel value occupies 1 byte for JPEG baseline sequential and 2 bytes for JPEG extended sequential(12bit).
+In case the frame format is YCbCr420, the sizes of Cb and Cr buffer are 1/4 of Y buffer size.
+Host application must allocate frame buffers for each Y/Cb/Cr component in consideration of alignment and chroma format buffer size .
+
+@endverbatim
+*/
+typedef struct {
+    PhysicalAddress bufY;  /**< It indicates the base address for Y component in the physical address space when linear map is used. */
+    PhysicalAddress bufCb; /**< It indicates the base address for Cb component in the physical address space when linear map is used. */
+    PhysicalAddress bufCr; /**< It indicates the base address for Cr component in the physical address space when linear map is used. */
+    Uint32          stride; /**< A horizontal stride for luma frame buffer */    /* luma stride */
+    Uint32          strideC;/**< A horizontal stride for chroma frame buffer */    /* chroma stride */
+    FrameFormat     format; /**< <<jpuapi_h_OutputFormat>> */
+/**
+@verbatim
+Bitstream buffer endianess
+
+@* 0 : little endian format
+@* 1 : big endian format
+@* 2 : 32 bits little endian format
+@* 3 : 32 bits big endian format
+@endverbatim
+*/
+    Uint32          endian;
+} FrameBuffer;
+
+struct JpgInst;
+
+/**
+* @brief
+This is a dedicated type for JPG handle returned when an instance is opened.
+An instance can be referred to by the corresponding handle.
+Application does not need to care about it.
+*/
+typedef struct JpgInst * JpgHandle;
+
+//------------------------------------------------------------------------------
+// decode struct and definition
+//------------------------------------------------------------------------------
+
+typedef struct JpgInst JpgDecInst;
+
+/**
+* @brief
+@verbatim
+This is a dedicated type for decoder handle returned when a decoder instance is
+opened. A decoder instance can be referred to by the corresponding handle.
+JpgDecInst is a type managed internally by API. Application does not need to
+care about it.
+
+NOTE: This type is vaild for decoder only.
+@endverbatim
+*/
+typedef JpgDecInst * JpgDecHandle;
+
+/* JPU Capabilities */
+/**
+* @brief
+This is a data structure for representing JPU capabilities.
+*/
+typedef struct {
+    Uint32  productId;     /**< Product ID number, 12 */
+    Uint32  revisoin;      /**< Revision number of hardware */
+    BOOL    support12bit;  /**< It indicates whether to support an extended sequential JPEG, 12bit. */
+} JPUCap;
+
+/**
+* @brief
+This data structure is used when host application wants to open a new decoder instance.
+*/
+typedef struct {
+    PhysicalAddress bitstreamBuffer; 		/**< The start address of bit stream buffer from which the decoder can get the next bitstream. This address must be 8-byte aligned.*/
+    Uint32          bitstreamBufferSize;	/**< The virtual address according to bitstreamBuffer. This address is needed when the host wants to access bitstream.*/
+    BYTE*           pBitStream;				/**< The size of the buffer pointed by bitstreamBuffer in byte. This value must be a multiple of 1024. The maximum size is 16383 x 1024 bytes.*/
+/**
+@verbatim
+Bitstream buffer endianess
+
+@* 0 : little endian format
+@* 1 : big endian format
+@* 2 : 32 bits little endian format
+@* 3 : 32 bits big endian format
+@endverbatim
+*/
+    Uint32          streamEndian;
+/**
+@verbatim
+Frame buffer endianess
+
+* 0 : little endian format
+* 1 : big endian format
+* 2 : 32 bits little endian format
+* 3 : 32 bits big endian format
+@endverbatim
+*/
+    Uint32          frameEndian;
+/**
+@verbatim
+@* 0: CbCr data is written in separate frame memories (chroma separate mode)
+@* 1: CbCr data is interleaved in chroma memory. (chroma interleave mode)
+@endverbatim
+*/
+    CbCrInterLeave  chromaInterleave;
+    PackedFormat    packedFormat;			/**< This is for packed image format. It is valid only when source image format is written in YUV444 or RGB24. */
+    BOOL            roiEnable;				/**< This enables the ROI (Region of Interest). */
+    Uint32          roiOffsetX;				/**< This is ROI offset for width. */
+    Uint32          roiOffsetY;				/**< This is ROI offset for height. */
+    Uint32          roiWidth;				/**< This is ROI width from RoiOffsetX. */
+    Uint32          roiHeight;				/**< This is ROI width from RoiOffsetY. */
+    Uint32          pixelJustification;     /**< It specifies pixel justification of source image for 12bit encoding mode. */ /* avaliable in 16bit pixel. */
+    Uint32          intrEnableBit;          /**< It specifies an interrupt enable bit. For the meaning of each bit, refer to <<jpuapi_h_InterruptJpu>>. */
+    Uint32          rotation;              /**< It rotates decoded images in 0, 90, 180, or 270 degree */
+    JpgMirrorDirection  mirror;            /**< <<jpuapi_h_JpgMirrorDirection>> */
+    FrameFormat     outputFormat;          /**< <<jpuapi_h_OutputFormat>> */
+} JpgDecOpenParam;
+
+/**
+* @brief
+Data structure to get information necessary to start decoding from the decoder.
+*/
+typedef struct {
+/**
+@verbatim
+Horizontal picture size in pixels
+
+This width value will be used while allocating decoder frame buffers. In some
+cases, this returned value, the display picture width declared on stream header,
+should be modified before allocating frame buffers. When picture width is not a
+multiple of 16, picture width for buffer allocation should be re-calculated from
+the declared display width as follows:
+
+ picBufWidth = {( picWidth + 15)/16}* 16,
+
+where picBufWidth is the horizontal picture buffer width. When picWidth is a
+multiple of 16, picWidth = picBufWidth.
+*/
+	int         picWidth;
+/**
+@verbatim
+Vertical picture size in pixels
+
+This height value will be used while allocating decoder frame buffers. In some
+cases, this returned value, the display picture height declared on stream
+header, should be modified before allocating frame buffers. When picture height
+is not a multiple of 16, picture height for buffer allocation should be
+re-calculated from the declared display height as follows:
+
+ picBufHeight = {( picHeight + 15)/16}* 16,
+
+where picBufHeight is the vertical picture buffer height. When picHeight is a
+multiple of 16, picHeight = picBufHeight.
+@endverbatim
+*/
+    int         picHeight;
+/**
+This is the minimum number of frame buffers required for decoding. Applications
+must allocate at least as many as this number of frame buffers and register the
+number of buffers to the JPU using JPU_DecRegisterFrameBuffer() before decoding
+pictures.
+*/
+    int         minFrameBufferCount;
+    FrameFormat sourceFormat;  /**< <<jpuapi_h_FrameFormat>> */
+    int         ecsPtr;        /**< This is an entropy-coded segment pointer of the first frame. */
+    int         roiFrameWidth; /**< This is width of ROI region. */
+    int         roiFrameHeight;/**< This is height of ROI region. */
+    int         roiFrameOffsetX; /**< This is x position of ROI region. */
+    int         roiFrameOffsetY; /**< This is y position of ROI region. */
+    Uint32      bitDepth;  /**< 8 for baseline sequential, 12 for extended sequential */
+} JpgDecInitialInfo;
+
+/**
+* @brief
+The data structure to set a scaler ratio.
+*/
+typedef struct {
+    int scaleDownRatioWidth;  /**< The ratio of frame width to scale down */
+/**
+@verbatim
+The ratio of frame height to scale down. It might have one of the following values:
+
+@* 0 : no scale
+@* 1 : (1/2 scale)
+@* 2 : (1/4 scale)
+@* 3 : (1/8 scale)
+@endverbatim
+*/
+    int scaleDownRatioHeight;
+} JpgDecParam;
+
+/**
+* @brief
+The data structure to get result information from decoding a frame.
+*/
+typedef struct {
+/**
+This is the frame buffer index of a picture to be displayed this time among
+frame buffers which were registered using JPU_DecRegisterFrameBuffer(). Frame
+data to be displayed this time will be stored into the frame buffer specified by
+this index. When delay in display does not exist, this index will always be the
+same with indexFrameDecoded.
+At the end of sequence decoding, if there is no more output for display, then
+this value will have -1 (0xFFFF). So by checking this index, host applications
+can easily know whether sequence decoding has been finished or not.
+*/
+    int         indexFrameDisplay;
+    int         numOfErrMBs;        /**< The number of erroneous macroblocks while decoding a picture */
+/**
+@verbatim
+@* 0 : incomplete finish of decoding process
+@* 1 : complete finish of decoding process
+@endverbatim
+*/
+    int	        decodingSuccess;
+    int         decPicHeight;       /**< The JPU reports the height of a decoded picture in pixel unit after decoding one frame. This value will be updated, when sequence information for resolution is changed. */
+    int         decPicWidth;        /**< The JPU reports the width of a decoded picture in pixel unit after decoding one frame. This value will be updated, when sequence information for resolution is changed. */
+    int         consumedByte;       /**< This means how many bytes are consumed in a bitstream. */
+    int         bytePosFrameStart;  /**< This means the position of an SOI maker in bitstream buffer. */
+    int         ecsPtr;             /**< This is a pointer to an entropy-coded segment of current frame. */
+    Uint32      frameCycle;         /**< This variable reports the number of clock cycles taken to decode one frame. */ /* clock cycle */
+    Uint32      rdPtr;              /**< The position of read pointer in the bitstream buffer after completion of frame decoding */
+    Uint32      wrPtr;              /**< The position of write pointer in the bitstream buffer after completion of frame decoding */
+} JpgDecOutputInfo;
+
+
+
+//------------------------------------------------------------------------------
+// encode struct and definition
+//------------------------------------------------------------------------------
+
+typedef struct JpgInst JpgEncInst;
+
+/**
+* @brief
+@verbatim
+This is a dedicated type for encoder handle returned when an encoder instance is
+opened. An encoder instance can be referred to by the corresponding handle.
+JpgEncInst is a type managed internally by API. Application does not need to
+care about it.
+NOTE: This type is vaild for encoder only.
+@endverbatim
+*/
+typedef JpgEncInst * JpgEncHandle;
+
+/**
+* @brief
+This data structure is used when host applications want to open a new encoder
+instance.
+*/
+typedef struct {
+    PhysicalAddress bitstreamBuffer;     /**< The start address of bit stream buffer into which encoder puts bit streams. This address must be a multiple of 4, namely, 4 byte-aligned. */
+    Uint32          bitstreamBufferSize; /**< The size of the buffer in bytes pointed by bitstreamBuffer. This value must be a multiple of 1024. The maximum size is 16383 x 1024 bytes. */
+    Uint32          picWidth;            /**< The width of a picture to be encoded in pixels */
+    Uint32          picHeight;           /**< The height of a picture to be encoded in pixels */
+    FrameFormat     sourceFormat;        /**< <<jpuapi_h_FrameFormat>> */
+    Uint32          restartInterval;     /**< The number of MCU in the restart interval */
+/**
+@verbatim
+Bitstream buffer endianess
+
+@* 0 : little endian format
+@* 1 : big endian format
+@* 2 : 32 bits little endian format
+@* 3 : 32 bits big endian format
+@endverbatim
+*/
+	Uint32          streamEndian;
+/**
+@verbatim
+Frame buffer endianess
+
+@* 0 : little endian format
+@* 1 : big endian format
+@* 2 : 32 bits little endian format
+@* 3 : 32 bits big endian format
+@endverbatim
+*/
+    Uint32          frameEndian;
+/**
+@verbatim
+@* 0 : CbCr data is written in separate frame memories (chroma separate mode)
+@* 1 : CbCr data is interleaved in chroma memory. (chroma interleave mode)
+@endverbatim
+*/
+    CbCrInterLeave  chromaInterleave;
+    BYTE            huffVal[8][256];     /**< A list of the 8-bit symbol values in Huffman tables. */
+    BYTE            huffBits[8][256];    /**< A 16-byte list giving number of codes for each code length from 1 to 16 in Huffman tables. */
+    short           qMatTab[4][64];      /**< Quantization tables */
+    BOOL            jpg12bit;            /**< It enables 12bit encoding mode. */
+    BOOL            q_prec0;             /**< Luma quantization tables for 12bit encoding mode */
+    BOOL            q_prec1;             /**< Chroma quantization tables for 12bit encoding mode */
+    PackedFormat    packedFormat;        /**< It specifies a packed image format. It is valid only when source image format is written in YUV444 or RGB24. */
+    Uint32          pixelJustification;  /**< It specifies pixel justification of source image for 12bit encoding mode. */
+    Uint32          tiledModeEnable;     /**< It enables use of tiled mode. */
+    Uint32          sliceHeight;         /**< It specifies a slice height for slice encoding. */
+    Uint32          intrEnableBit;       /**< It specifies an interrupt enable bit. For the meaning of each bit, refer to <<jpuapi_h_InterruptJpu>>. */
+    BOOL            sliceInstMode;
+    Uint32          rotation;            /**< It rotates source images in 0, 90, 180, or 270 degree before encoding. */
+    Uint32          mirror;              /**< <<jpuapi_h_JpgMirrorDirection>> */
+} JpgEncOpenParam;
+
+
+/**
+* @brief
+This is a data structure for configuring one frame encoding operation.
+*/
+typedef struct {
+    FrameBuffer * sourceFrame; /**< This member must represent the frame buffer containing source image to be encoded. */
+} JpgEncParam;
+
+/**
+* @brief
+This is a data structure for reporting the results of picture encoding operations.
+*/
+typedef struct {
+/**
+The Physical address of the starting point of newly encoded picture stream
+If dynamic buffer allocation is enabled in line-buffer mode, this value will be
+identical with the specified picture stream buffer address by host applications.
+*/
+    PhysicalAddress bitstreamBuffer;
+    Uint32 bitstreamSize;            /**< The byte size of encoded bitstream */
+    PhysicalAddress streamRdPtr;     /**< A read pointer of bitstream buffer */
+    PhysicalAddress streamWrPtr;     /**< A write pointer of bitstream buffer */
+    Uint32 encodedSliceYPos;         /**< A vertical position of the currently encoded slice */
+    EncodeState encodeState;         /**< A result of the current encoding, completion of encoding the whole picture or completion of encoding a specific slice */
+    Uint32  frameCycle;              /**< This variable reports the number of clock cycles taken to decode one frame. */ /* clock cycle */
+} JpgEncOutputInfo;
+
+/**
+* @brief
+This is a data structure for generating an encoding header.
+*/
+typedef struct {
+    PhysicalAddress paraSet;   /**< The physical address of bitstream buffer where header bitstream is saved  */
+    BYTE *pParaSet;            /**< The virtual address of bitstream buffer where header bitstream is saved  */
+    int size;                  /**< The allocation size of buffer for saving header bitstream */
+/**
+@verbatim
+Header encoding mode
+
+@* ENC_HEADER_MODE_NORMAL: generates all sorts of headers.
+@* ENC_HEADER_MODE_SOS_ONLY: generates only SOS header (not any other such as SOI, APP, DRI, DQT, DHT, and SOF headers).
+@endverbatim
+*/
+    int headerMode;
+/**
+@verbatim
+Quantization table merge option
+
+@* 0: do not merge quantization table
+@* 1: merge quantization table
+@endverbatim
+*/
+    int quantMode;
+/**
+@verbatim
+Huffman table merge option
+
+@* 0: do not merge huffman table
+@* 1: merge huffman table
+@endverbatim
+*/
+    int huffMode;
+    int disableAPPMarker;      /**< It disables generating an App Marker in encoding header. */
+    int enableSofStuffing;     /**< It enables to fill 0xff at the end of header if it is not 8-byte aligned after encoding the header. (defalut: 0x00) */
+} JpgEncParamSet;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+* @brief This function returns whether the JPU is initialized and ready to be used.
+* @return
+@verbatim
+@* 0: The JPU hardware is not initialized yet. In that case, host application should call JPU_Init().
+@* 1: The JPU hardware is initialized.
+@endverbatim
+*/
+Uint32 JPU_IsInit(
+	void
+	);
+
+/**
+* @brief This function waits until an interrupt arises and returns the interrupt reason if it occurs.
+* @param handle [Input] An instance handle obtained from JPU_EncOpen() or JPU_DecOpen()
+* @param timeout [Input] A timeout value in millisecond
+* @return
+@verbatim
+@* 0: The JPU hardware is not initialized yet. In that case, host application should call JPU_Init().
+@* 1: The JPU hardware is initialized.
+@endverbatim
+*/
+    Int32		JPU_WaitInterrupt(JpgHandle handle, int timeout);
+/**
+* @brief This function returns whether JPU has completed processing a frame or not.
+* @param handle [Input] An instance handle obtained from JPU_EncOpen() or JPU_DecOpen()
+* @return
+@verbatim
+@* 0: The JPU hardware is idle.
+@* Non-zero value: The JPU hardware is busy with processing a frame.
+@endverbatim
+*/
+	int			JPU_IsBusy(JpgHandle handle);
+/**
+* @brief This function returns the reason of JPU interrupt.
+* @param handle [Input] An instance handle obtained from JPU_EncOpen() or JPU_DecOpen()
+* @return
+@verbatim
+@* 0: No Interrupt, The JPU hardware is idle.
+@* Non-zero value: It is an interrupt reason. Refer to <<jpuapi_h_InterruptJpu>> to know the meaning of each bit.
+@endverbatim
+*/
+    Uint32		JPU_GetStatus(JpgHandle handle);
+/**
+* @brief Clearing Interrupt
+* @param handle [Input] An instance handle obtained from JPU_EncOpen()
+* @param val [Input] The interrupt bit to be cleared
+* @return None
+*/
+    void		JPU_ClrStatus(JpgHandle handle, Uint32 val);
+
+/**
+* @brief This function initializes the JPU hardware and proper data structures/resources. Applications
+must call this function only once before using the JPU.
+* @param None
+* @return
+@verbatim
+*JPG_RET_SUCCESS*::
+Operation was done successfully, which means the JPU initialized successfully.
+*JPG_RET_FAILURE*::
+Operation was failed, which means the JPU initialized with fail.
+@endverbatim
+*/
+    JpgRet		JPU_Init();
+/**
+* @brief This function frees all the resources allocated by API.
+* @param None
+* @return None
+*/
+	void		JPU_DeInit();
+/**
+* @brief This function returns the number of instances that have opened.
+* @param None
+* @return The number of instance that is currently running
+*/
+    int			JPU_GetOpenInstanceNum();
+/**
+* @brief Applications can read out the version information running on the system.
+* @param  apiVersion [output] API version ID
+* @param  hwRevision [output] Hardware versi
+* @param  hwProductId [output] Product ID
+* @return
+@verbatim
+*JPG_RET_SUCCESS*::
+Operation was done successfully, which means version information is acquired
+successfully.
+
+*JPG_RET_NOT_INITIALIZED*::
+JPU was not initialized at all before calling this function. Application should
+initialize JPU by calling JPU_Init() before calling this function.
+@endverbatim
+*/
+    JpgRet		JPU_GetVersionInfo(
+        Uint32 *apiVersion,
+        Uint32 *hwRevision,
+        Uint32 *hwProductId);
+
+/**
+* @brief
+This function resets JPU and initializes all the internal contexts.
+It can be done by user's system reset signal and implmentation of jdi_hw_reset().
+* @param None
+* @return
+@verbatim
+*JPG_RET_SUCCESS*::
+Operation was done successfully, which means the JPU has been reset successfully.
+
+*JPG_RET_FAILURE*::
+Operation was failed, which means the JPU was unable to reset.
+@endverbatim
+*/
+	JpgRet JPU_HWReset();
+/**
+* @brief This function resets JPU by using the reset register.
+* @param None
+* @return
+@verbatim
+*JPG_RET_SUCCESS*::
+Operation was done successfully, which means the JPU has been reset successfully.
+@endverbatim
+*/
+    JpgRet JPU_SWReset();
+
+    // function for decode
+/**
+* @brief
+In order to decode, applications must open the decoder. By calling this
+function, applications can get a handle by which they can refer to a decoder
+instance. Because the JPU is multiple instance codec, applications need this
+kind of handle. Once an application gets a handle, the application must pass
+this handle to all subsequent decoder-related functions.
+* @param handle [Output] A pointer to a JpgDecHandle type variable which will
+specify each instance for application.
+* @param openParam [Input] A pointer to a JpgDecOpenParam type structure which describes
+required parameters for creating a new decoder instance.
+* @return
+@verbatim
+*JPG_RET_SUCCESS*::
+Operation was done successfully, which means a new decoder instance was created
+successfully.
+
+*JPG_RET_FAILURE*::
+Operation was failed, which means getting a new decoder instance was not done
+successfully. If there is no free instance anymore, this value will be returned
+in this function call.
+
+*JPG_RET_INVALID_HANDLE*::
+This means the given handle for current API function call was invalid (for
+example, not initialized yet, improper function call for the given handle,
+etc.).
+@endverbatim
+*/
+	JpgRet JPU_DecOpen(
+		JpgDecHandle* handle,
+		JpgDecOpenParam* openParam);
+/**
+* @brief
+When an application finished decoding a sequence and wanted to release this
+instance for other processing, the applicaton should close this instance. After
+completion of this function call, the instance referred to by handle will get
+free. Once an application closes an instance, the application cannot call any
+further decoder-specific function with the current handle before re-opening a
+new decoder instance with the same handle.
+* @param handle [Input] A decoder handle obtained from JPU_DecOpen()
+* @return
+@verbatim
+*JPG_RET_SUCCESS*::
+Operation was done successfully, which means current decoder instance was closed
+successfully.
+
+*JPG_RET_INVALID_HANDLE*::
+This means the given handle for current API function call was invalid (for
+example, not initialized yet, improper function call for the given handle,
+etc.).
+@endverbatim
+*/
+    JpgRet JPU_DecClose(
+		JpgDecHandle handle);
+/**
+* @brief
+@verbatim
+Applications must pass the address of a JpgDecInitialInfo structure, where the
+decoder will store information such as picture size, number of necessary frame
+buffers, etc. For the details, see definition of the section called
+JpgDecInitialInfo data structure. This function should be called once after
+creating a decoder instance and before starting frame decoding.
+
+It is application\'s responsibility to provide sufficient amount of bitstream to
+the decoder by calling JPU_DecUpdateBitstreamBuffer() so that bitstream buffer
+does not get empty before this function returns.
+@endverbatim
+* @param handle [Input] A decoder handle obtained from JPU_DecOpen()
+* @param info [Output] A pointer to JpgDecInitialInfo data structure
+* @return
+@verbatim
+*JPG_RET_SUCCESS*::
+Operation was done successfully, which means required information of the stream
+data to be decoded was received successfully.
+
+*JPG_RET_FAILURE*::
+Operation was failed, which means there was an error in getting information for
+configuring the decoder.
+
+*JPG_RET_INVALID_PARAM*::
+The given argument parameter, info, was invalid, which means it has a null
+pointer, or given values for some member variables are improper values.
+
+*JPG_RET_INVALID_HANDLE*::
+This means the given handle for current API function call was invalid (for
+example, not initialized yet, improper function call for the given handle,
+etc.).
+@endverbatim
+*/
+    JpgRet JPU_DecGetInitialInfo(
+        JpgDecHandle handle,
+        JpgDecInitialInfo * info);
+/**
+* @brief
+@verbatim
+This function is used for registering frame buffers with the acquired
+information from JPU_DecGetInitialInfo(). The frame buffers pointed to by
+bufArray will be managed internally within the JPU. These include reference
+frames, reconstructed frame, etc. Applications must not change the contents of
+the array of frame buffers during the life time of the instance, and num must
+not be less than minFrameBufferCount obtained by JPU_DecGetInitialInfo().
+
+The distance between a pixel in a row and the corresponding pixel in the next
+row is called a stride. The value of stride must be a multiple of 8. The address
+of the first pixel in the second row does not necessarily coincide with the
+value next to the last pixel in the first row. In other words, a stride can be
+greater than the picture width in pixels.
+
+Applications should not set a stride value smaller than the picture width. So,
+for Y component, application must allocate at least a space of size (frame
+height  stride), and Cb or Cr component, (frame height/2  stride/2),
+respectively.
+
+But make sure that in Cb/Cr non-interleave (separate Cb/Cr) map, the stride for
+luminance frame buffers should be multiple of 16 so that the stride for
+chrominance frame buffers can become a multiple of 8.
+In case of MJPEG encoding, the address of frame buffer is not necessary and only
+stride value is required, which will be used as source image stride.
+@endverbatim
+* @param handle [Input] A decoder handle obtained from JPU_DecOpen()
+* @param bufArray [Input] A number of the minimum frame buffer count
+* @param num [Input] A number of frame buffers
+* @param stride [Input] A stride value of the given frame buffers
+* @return
+@verbatim
+*JPG_RET_SUCCESS*::
+Operation was done successfully, which means registering frame buffer
+information was done successfully.
+
+*JPG_RET_INVALID_HANDLE*::
+This means the given handle for current API function call was invalid (for
+example, not initialized yet, improper function call for the given handle,
+etc.).
+
+*JPG_RET_WRONG_CALL_SEQUENCE*::
+This means current API function call was invalid considering the allowed
+sequences between API functions. An application might call this function before
+calling JPU_DecGetInitialInfo() successfully. This function should be called
+after successful calling JPU_DecGetInitialInfo().
+
+*JPG_RET_INVALID_FRAME_BUFFER*::
+This happens when bufArray was invalid, which means bufArray was not initialized
+yet or not valid anymore.
+
+*JPG_RET_INSUFFICIENT_FRAME_BUFFERS*::
+This means the given number of frame buffers, num, was not enough for the
+decoder operations of the given handle. It should be greater than or equal to
+the value requested by JPU_DecGetInitialInfo().
+
+*JPG_RET_INVALID_STRIDE*::
+The given argument stride was invalid, which means it is smaller than the
+decoded picture width, or is not a multiple of 8 in this case.
+@endverbatim
+*/
+    JpgRet JPU_DecRegisterFrameBuffer(
+        JpgDecHandle handle,
+        FrameBuffer * bufArray,
+        int num,
+        int stride);
+/**
+* @brief
+@verbatim
+This function is used for registering frame buffers with the acquired
+information from JPU_DecGetInitialInfo(). The frame buffers pointed to by
+bufArray will be managed internally within the JPU. These include reference
+frames, reconstructed frame, etc. Applications must not change the contents of
+the array of frame buffers during the life time of the instance, and num must
+not be less than minFrameBufferCount obtained by JPU_DecGetInitialInfo().
+
+The distance between a pixel in a row and the corresponding pixel in the next
+row is called a stride. The value of stride must be a multiple of 8. The address
+of the first pixel in the second row does not necessarily coincide with the
+value next to the last pixel in the first row. In other words, a stride can be
+greater than the picture width in pixels.
+
+Applications should not set a stride value smaller than the picture width. So,
+for Y component, application must allocate at least a space of size (frame
+height  stride), and Cb or Cr component, (frame height/2  stride/2),
+respectively.
+
+But make sure that in Cb/Cr non-interleave (separate Cb/Cr) map, the stride for
+luminance frame buffers should be multiple of 16 so that the stride for
+chrominance frame buffers can become a multiple of 8.
+In case of MJPEG encoding, the address of frame buffer is not necessary and only
+stride value is required, which will be used as source image stride.
+@endverbatim
+* @param handle [Input] A decoder handle obtained from JPU_DecOpen()
+* @param prdPrt [Input] A stream buffer read pointer for the current decoder instance
+* @param pwrPtr [Input] A stream buffer write pointer for the current decoder instance
+* @param size [Input] A variable specifying the available space in bitstream buffer for the current decoder instance
+* @return
+@verbatim
+*JPG_RET_SUCCESS*::
+Operation was done successfully, which means registering frame buffer
+information was done successfully.
+
+*JPG_RET_INVALID_HANDLE*::
+This means the given handle for current API function call was invalid (for
+example, not initialized yet, improper function call for the given handle,
+etc.).
+
+*JPG_RET_WRONG_CALL_SEQUENCE*::
+This means current API function call was invalid considering the allowed
+sequences between API functions. An application might call this function before
+calling JPU_DecGetInitialInfo() successfully. This function should be called
+after successful calling JPU_DecGetInitialInfo().
+
+*JPG_RET_INVALID_FRAME_BUFFER*::
+This happens when bufArray was invalid, which means bufArray was not initialized
+yet or not valid anymore.
+
+*JPG_RET_INSUFFICIENT_FRAME_BUFFERS*::
+This means the given number of frame buffers, num, was not enough for the
+decoder operations of the given handle. It should be greater than or equal to
+the value requested by JPU_DecGetInitialInfo().
+
+*JPG_RET_INVALID_STRIDE*::
+The given argument stride was invalid, which means it is smaller than the
+decoded picture width, or is not a multiple of 8 in this case.
+@endverbatim
+*/
+	JpgRet JPU_DecGetBitstreamBuffer(
+        JpgDecHandle handle,
+        PhysicalAddress * prdPrt,
+        PhysicalAddress * pwrPtr,
+        int * size );
+/**
+* @brief
+Applications must let decoder know how much bitstream has been transferred to
+the address obtained from JPU_DecGetBitstreamBuffer(). By just giving the size
+as an argument, API automatically handles pointer wrap-around and updates the
+write pointer.
+* @param handle [Input] A decoder handle obtained from JPU_DecOpen()
+* @param size [Input] A variable specifying the amount of bits transferred into
+bitstream buffer for the current decoder instance
+* @return
+@verbatim
+*JPG_RET_SUCCESS*::
+Operation was done successfully, which means putting new stream data was done
+successfully.
+
+*JPG_RET_INVALID_HANDLE*::
+This means the given handle for current API function call was invalid (for
+example, not initialized yet, improper function call for the given handle,
+etc.).
+@endverbatim
+*/
+	JpgRet JPU_DecUpdateBitstreamBuffer(
+        JpgDecHandle handle,
+        int size);
+
+/**
+* @brief
+This function starts decoding one frame. Returning from this function does not
+mean the completion of decoding one frame, and it is just that decoding one
+frame was initiated. Every call of this function should be matched with
+JPU_DecGetOutputInfo() with the same handle. Without calling a pair of these
+funtions, applications cannot call any other API functions except for
+JPU_IsBusy(), JPU_DecGetBitstreamBuffer(), and JPU_DecUpdateBitstreamBuffer().
+* @param handle [Input] A decoder handle obtained from JPU_DecOpen()
+* @param param [Input] A pointer to a JpgDecParam type structure which describes picture decoding parameters for the given decoder instance
+* @return
+@verbatim
+*JPG_RET_SUCCESS*::
+Operation was done successfully, which means decoding a new frame was started
+successfully.
+
+NOTE: This return value does not mean that decoding a frame was completed
+successfully.
+
+*JPG_RET_FAIURE*::
+Operation was failed, which means there was an error in starting a frame.
+
+*JPG_RET_INVALID_PARAM*::
+This happens when param was invalid, which means param was not initialized yet
+or not valid anymore.
+
+*JPG_RET_INVALID_HANDLE*::
+This means the given handle for current API function call was invalid (for
+example, not initialized yet, improper function call for the given handle,
+etc.).
+
+*JPG_RET_FRAME_NOT_COMPLETE*::
+This means frame decoding operation was not completed yet, so the given API
+function call cannot be performed this time. A frame decoding operation should
+be completed by calling JPU_DecGetOutputInfo(). Even though the result of the
+current frame operation is not necessary, application should call
+JPU_DecGetOutputInfo() to proceed this function call.
+
+*JPG_RET_WRONG_CALL_SEQUENCE*::
+This means current API function call was invalid considering the allowed
+sequences between API functions. An application might call this function before
+successfully calling JPU_DecRegisterFrameBuffer(). This function should be
+called after calling JPU_ DecRegisterFrameBuffer() successfully.
+
+*JPG_RET_BIT_EMPTY*::
+This means the bit-stream buffer is empty. So, API requests the bit-stream data.
+
+*JPG_RET_EOS*::
+This means the stream ends.
+@endverbatim
+*/
+    JpgRet JPU_DecStartOneFrame(
+        JpgDecHandle handle,
+        JpgDecParam *param );
+/**
+* @brief
+Application can get the information of output of decoding. The information
+includes the information of a frame buffer which contains the reconstructed
+image. Host applications should call this function after frame decoding is
+finished and before starting the further processing.
+* @param handle [Input] A decoder handle obtained from JPU_DecOpen()
+* @param info [Output] A pointer to a JpgDecOutputInfo type structure which
+describes picture decoding results for the current decoder instance.
+* @return
+@verbatim
+*JPG_RET_SUCCESS*::
+Operation was done successfully, which means receiving the output information of
+current frame was done successfully.
+
+*JPG_RET_INVALID_HANDLE*::
+This means the given handle for current API function call was invalid (for
+example, not initialized yet, improper function call for the given handle,
+etc.).
+
+*JPG_RET_WRONG_CALL_SEQUENCE*::
+This means current API function call was invalid considering the allowed
+sequences between API functions. It might happen because JPU_DecStartOneFrame()
+with the same handle was not called before calling this function.
+
+*JPG_RET_INVALID_PARAM*::
+The given argument parameter, info, was invalid, which means it has a null
+pointer, or given values for some member variables are improper values.
+@endverbatim
+*/
+	JpgRet JPU_DecGetOutputInfo(
+        JpgDecHandle handle,
+        JpgDecOutputInfo * info);
+/**
+* @brief
+@verbatim
+This function is provided to let application have a certain level of freedom for
+re-configuring decoder operation after creating a decoder instance. Some options
+which can be changed dynamically during decoding as the video sequence has been
+included. Some command-specific return codes are also presented.
+
+The list of valid commands can be summarized as follows:
+
+@* SET_JPG_SCALE_HOR
+@* SET_JPG_SCALE_VER
+@* ENABLE_LOGGING
+@* DISABLE_LOGGING
+@endverbatim
+* @param handle [Input] A decoder handle obtained from JPU_DecOpen()
+* @param cmd [Intput] A variable specifying the given command of <<jpuapi_h_JpgCommand>>
+* @param parameter [Input/Output] A pointer to command-specific data structure which
+describes picture I/O parameters for the current decoder instance
+* @return
+@verbatim
+*JPG_RET_INVALID_COMMAND*::
+The given argument, cmd, was invalid, which means the given cmd was undefined,
+or not allowed in the current instance.
+
+*JPG_RET_SUCCESS*::
+Operation was done successfully.
+
+*JPG_RET_INVALID_HANDLE*::
+This means the given handle for current API function call was invalid (for
+example, not initialized yet, improper function call for the given handle,
+etc.).
+@endverbatim
+*/
+	JpgRet JPU_DecGiveCommand(
+        JpgDecHandle handle,
+        JpgCommand cmd,
+        void * parameter);
+/**
+* @brief
+This function specifies the location of read pointer in bitstream buffer.
+It can also set a write pointer with same value of read pointer (addr) when updateWrPtr is not a zero value,
+which allows to flush up the bitstream buffer at once.
+* @param handle [Input] A decoder handle obtained from JPU_DecOpen()
+* @param addr [Input] Updated read or write pointer
+* @param updateWrPtr [Input] A flag whether to update a write pointer or not as well as a read pointer.
+* @return
+@verbatim
+*JPG_RET_SUCCESS*::
+Operation was done successfully, which means required information of the stream data to be
+decoded was received successfully.
+
+*JPG_RET_FAIURE*::
+Operation was failed, which means there was an error in starting a frame.
+
+*JPG_RET_INVALID_HANDLE*::
+This means the given handle for current API function call was invalid (for
+example, not initialized yet, improper function call for the given handle,
+etc.).
+
+*JPG_RET_FRAME_NOT_COMPLETE*::
+This means frame decoding operation was not completed yet, so the given API function call
+cannot be performed this time. A frame decoding operation should be completed by calling
+JPU_DecSetRdPtr().
+@endverbatim
+*/
+	JpgRet JPU_DecSetRdPtr(
+        JpgDecHandle handle,
+        PhysicalAddress addr,
+        BOOL updateWrPtr);
+/**
+* @brief
+This function is used to change the location of read pointer in bitstream buffer.
+It is useful when host application decodes MJPEG with binary of every frame which is obtained from demuxer.
+After frame decoding, host application can use this function which allows the given read pointer to be the base address of bitstream buffer like in line buffer mode.
+* @param handle [Input] A decoder handle obtained from JPU_DecOpen()
+* @param addr [Input] Updated read or write pointer
+* @param updateWrPtr [Input] A flag whether to update a write pointer or not as well as a read pointer.
+* @return
+@verbatim
+*JPG_RET_SUCCESS*::
+Operation was done successfully, which means required information of the stream data to be
+decoded was received successfully.
+
+*JPG_RET_FAIURE*::
+Operation was failed, which means there was an error in starting a frame.
+
+*JPG_RET_INVALID_HANDLE*::
+This means the given handle for current API function call was invalid (for
+example, not initialized yet, improper function call for the given handle,
+etc.).
+
+*JPG_RET_FRAME_NOT_COMPLETE*::
+This means frame decoding operation was not completed yet, so the given API function call
+cannot be performed this time. A frame decoding operation should be completed by calling
+JPU_DecSetRdPtr().
+
+@endverbatim
+*/
+	JpgRet JPU_DecSetRdPtrEx(
+        JpgDecHandle handle,
+        PhysicalAddress addr,
+        BOOL updateWrPtr);
+
+    // function for encode
+/**
+* @brief
+In order to start a new encoder operation, applications must open a new instance
+for this encoder operation.
+* @param handle [Output] A pointer to a JpgEncHandle type variable
+* @param openParam [Input] A pointer to a JpgEncOpenParam type structure
+* @return
+@verbatim
+*JPG_RET_SUCCESS*::
+Operation was done successfully, which means a new encoder instance was opened
+successfully.
+
+*JPG_RET_FAILURE*::
+Operation was failed, which means getting a new encoder instance was not done
+successfully. If there is no free instance anymore, this value will be returned
+in this function call.
+
+*JPG_RET_INVALID_HANDLE*::
+This means the given handle for current API function call was invalid (for
+example, not initialized yet, improper function call for the given handle,
+etc.).
+@endverbatim
+*/
+    JpgRet JPU_EncOpen(
+		JpgEncHandle* handle,
+		JpgEncOpenParam* openParam);
+/**
+* @brief
+When an application finished encoding operations and wanted to release this
+instance for other processing, the application should close this instance by
+calling this function. After completion of this function call, the instance
+referred to by handle will get free. Once an application closes an instance, the
+application cannot call any further encoder-specific function with the current
+handle before re-opening a new instance with the same handle.
+* @param handle [Input] An encoder handle obtained from JPU_EncOpen()
+* @return
+@verbatim
+*JPG_RET_SUCCESS*::
+Operation was done successfully. That means current encoder instance was closed
+successfully.
+
+*JPG_RET_INVALID_HANDLE*::
+This means the given handle for current API function call was invalid (for
+example, not initialized yet, improper function call for the given handle,
+etc.).
+
+*JPG_RET_FRAME_NOT_COMPLETE*::
+This means frame decoding or encoding operation was not completed yet, so the
+given API function call cannot be performed this time. A frame encoding or
+decoding operation should be completed by calling JPU_EncGetOutputInfo() or
+JPU_DecGetOutputInfo(). Even though the result of the current frame operation is
+not necessary, applications should call JPU_EncGetOutputInfo() or
+JPU_DecGetOutputInfo() to proceed this function call.
+@endverbatim
+*/
+    JpgRet JPU_EncClose(
+		JpgEncHandle handle);
+/**
+* @brief
+After encoding frame, applications must get bitstream from the encoder. To do
+that, they must know where to get bitstream and the maximum size. Applications
+can get the information by calling this function.
+* @param handle [Input] A encoder handle obtained from JPU_EncOpen()
+* @param prdPrt [Output] A stream buffer read pointer for the current encoder instance
+* @param pwrPtr [Output] A stream buffer write pointer for the current encoder instance
+* @param size [Output] A variable specifying the available space in bitstream buffer
+for the current encoder instance
+* @return
+@verbatim
+*JPG_RET_SUCCESS*::
+Operation was done successfully, which means required information for encoder
+stream buffer was received successfully.
+
+*RETCODE_INVALID_PARAM*::
+The given argument parameter, prdPrt, pwrPtr or size, was invalid, which means
+it has a null pointer, or given values for some member variables are improper
+values.
+@endverbatim
+*/
+    JpgRet JPU_EncGetBitstreamBuffer(
+        JpgEncHandle handle,
+        PhysicalAddress * prdPrt,
+        PhysicalAddress * pwrPtr,
+        int * size);
+/**
+* @brief
+Applications must let encoder know how much bitstream has been transferred from
+the address obtained from JPU_EncGetBitstreamBuffer(). By just giving the size
+as an argument, API automatically handles pointer wrap-around and updates the
+read pointer.
+* @param handle [Input] A encoder handle obtained from JPU_EncOpen()
+* @param size [Input] A variable specifying the amount of bits being filled from
+bitstream buffer for the current encoder instance.
+If 0 is given, JPUAPI forces a read pointer and a write pointer to be wrapped around and to be updated.
+* @return
+@verbatim
+*JPG_RET_SUCCESS*::
+Operation was done successfully, which means putting new stream data was done
+successfully.
+
+*JPG_RET_INVALID_HANDLE*::
+This means the given handle for current API function call was invalid (for
+example, not initialized yet, improper function call for the given handle,
+etc.).
+@endverbatim
+*/
+	JpgRet JPU_EncUpdateBitstreamBuffer(
+        JpgEncHandle handle,
+        int size);
+/**
+* @brief
+@verbatim
+This function starts encoding one frame. Returning from this function does not
+mean the completion of encoding one frame, and it is just that encoding one
+frame was initiated.
+
+Every call of this function should be matched with JPU_EncGetOutputInfo() with
+the same handle. Without calling a pair of these funtions, applications cannot
+call any other API functions except for JPU_IsBusy(),
+JPU_EncGetBitstreamBuffer(), and JPU_EncUpdateBitstreamBuffer().
+@endverbatim
+* @param handle [Input] An encoder handle obtained from JPU_EncOpen()
+* @param param [Input] A pointer to JpgEncParam type structure which describes
+picture encoding parameters for the current encoder instance.
+* @return
+@verbatim
+*JPG_RET_SUCCESS*::
+Operation was done successfully, which means encoding a new frame was started
+successfully.
+
+NOTE: This return value does not mean that encoding a frame was completed
+successfully.
+
+*JPG_RET_INVALID_HANDLE*::
+This means the given handle for current API function call was invalid (for
+example, not initialized yet, improper function call for the given handle,
+etc.).
+
+*JPG_RET_FRAME_NOT_COMPLETE*::
+This means frame decoding or encoding operation was not completed yet, so the
+given API function call cannot be performed this time. A frame encoding or
+decoding operation should be completed by calling JPU_EncGetOutputInfo() or
+JPU_DecGetOutputInfo(). Even though the result of the current frame operation is
+not necessary, applications should call JPU_EncGetOutputInfo() or
+JPU_DecGetOutputInfo() to proceed this function call.
+
+*JPG_RET_INVALID_PARAM*::
+The given argument parameter, param, was invalid, which means it has a null
+pointer, or given values for some member variables are improper values.
+@endverbatim
+*/
+	JpgRet JPU_EncStartOneFrame(
+        JpgEncHandle handle,
+        JpgEncParam * param );
+/**
+* @brief
+This function gets information of the output of encoding. Application can know
+about picture type, the address and size of the generated bitstream, the number
+of generated slices, the end addresses of the slices, and macroblock bit
+position information. Host application should call this function after frame
+encoding is finished, and before starting the further processing.
+* @param handle [Input] An encoder handle obtained from JPU_EncOpen().
+* @param info [Output] A pointer to a JpgEncOutputInfo  type structure which
+describes picture encoding results for the current encoder instance.
+* @return
+@verbatim
+*JPG_RET_SUCCESS*::
+Operation was done successfully, which means the output information of current
+frame encoding was received successfully.
+
+*JPG_RET_INVALID_HANDLE*::
+This means the given handle for current API function call was invalid (for
+example, not initialized yet, improper function call for the given handle,
+etc.).
+
+*JPG_RET_WRONG_CALL_SEQUENCE*::
+This means current API function call was invalid considering the allowed
+sequences between API functions. An application might call this function before
+calling JPU_EncStartOneFrame() successfully. This function should be called
+after successful calling of JPU_EncStartOneFrame().
+
+*JPG_RET_INVALID_PARAM*::
+The given argument parameter, info, was invalid, which means it has a null
+pointer, or given values for some member variables are improper values.
+@endverbatim
+*/
+	JpgRet JPU_EncGetOutputInfo(
+        JpgEncHandle handle,
+        JpgEncOutputInfo * info);
+/**
+* @brief
+@verbatim
+This function is provided to let application have a certain level of freedom for
+re-configuring encoder operation after creating an encoder instance. Some
+options which can be changed dynamically during encoding as the video sequence
+has been included. Some command-specific return codes are also presented.
+
+The list of valid commands can be summarized as follows:
+
+@* SET_JPG_USE_STUFFING_BYTE_FF
+@* ENC_JPG_GET_HEADER
+@* ENABLE_LOGGING
+@* DISABLE_LOGGING
+@endverbatim
+* @param handle [Input] An encoder handle obtained from JPU_EncOpen()
+* @param cmd [Input] A variable specifying the given command of <<jpuapi_h_JpgCommand>>
+* @param param [Input/Output] A pointer to command-specific data structure which
+describes picture I/O parameters for the current encoder instance
+* @return
+@verbatim
+*JPG_RET_INVALID_COMMAND*::
+This means the given argument, cmd, was invalid which means the given cmd was
+undefined, or not allowed in the current instance.
+
+*JPG_RET_INVALID_PARAM*::
+The given argument parameter, info, was invalid, which means it has a null
+pointer, or given values for some member variables are improper values.
+
+*JPG_RET_SUCCESS*::
+Operation was done successfully, which means the given cmd was received
+successfully.
+
+*JPG_RET_INVALID_HANDLE*::
+This means the given handle for current API function call was invalid (for
+example, not initialized yet, improper function call for the given handle,
+etc.).
+
+@endverbatim
+*/
+	JpgRet JPU_EncGiveCommand(
+        JpgEncHandle handle,
+        JpgCommand cmd,
+        void * parameter);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 2993 - 0
codaj12/jpuapi/jpuapifunc.c

@@ -0,0 +1,2993 @@
+/*
+ * Copyright (c) 2018, Chips&Media
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "jpuapifunc.h"
+#include "regdefine.h"
+#include "jpulog.h"
+
+/******************************************************************************
+Codec Instance Slot Management
+******************************************************************************/
+// gGetBits defined but not used
+//static Uint32 tGetBits(JpgDecInfo *jpg, int endian, int byteCnt);
+
+const char lendian[4] = {0x49, 0x49, 0x2A, 0x00};
+const char bendian[4] = {0x4D, 0x4D, 0x00, 0x2A};
+
+const char *jfif = "JFIF";
+const char *jfxx = "JFXX";
+const char *exif = "Exif";
+
+Uint8 sJpuCompInfoTable[5][24] = {
+    { 00, 02, 02, 00, 00, 00, 01, 01, 01, 01, 01, 01, 02, 01, 01, 01, 01, 01, 03, 00, 00, 00, 00, 00 }, //420
+    { 00, 02, 01, 00, 00, 00, 01, 01, 01, 01, 01, 01, 02, 01, 01, 01, 01, 01, 03, 00, 00, 00, 00, 00 }, //422H
+    { 00, 01, 02, 00, 00, 00, 01, 01, 01, 01, 01, 01, 02, 01, 01, 01, 01, 01, 03, 00, 00, 00, 00, 00 }, //422V
+    { 00, 01, 01, 00, 00, 00, 01, 01, 01, 01, 01, 01, 02, 01, 01, 01, 01, 01, 03, 00, 00, 00, 00, 00 }, //444
+    { 00, 01, 01, 00, 00, 00, 01, 00, 00, 00, 00, 00, 02, 00, 00, 00, 00, 00, 03, 00, 00, 00, 00, 00 }, //400
+};
+
+Uint8 sJpuCompInfoTable_EX[5][24] = {
+    { 00, 02, 02, 00, 02, 02, 01, 01, 01, 01, 03, 03, 02, 01, 01, 01, 03, 03, 03, 00, 00, 00, 00, 00 }, //420
+    { 00, 02, 01, 00, 02, 02, 01, 01, 01, 01, 03, 03, 02, 01, 01, 01, 03, 03, 03, 00, 00, 00, 00, 00 }, //422H
+    { 00, 01, 02, 00, 02, 02, 01, 01, 01, 01, 03, 03, 02, 01, 01, 01, 03, 03, 03, 00, 00, 00, 00, 00 }, //422V
+    { 00, 01, 01, 00, 02, 02, 01, 01, 01, 01, 03, 03, 02, 01, 01, 01, 03, 03, 03, 00, 00, 00, 00, 00 }, //444
+    { 00, 01, 01, 00, 00, 00, 01, 00, 00, 00, 00, 00, 02, 00, 00, 00, 00, 00, 03, 00, 00, 00, 00, 00 }, //400
+};
+
+/*
+ * The parameters of input source: iPackMode
+ * The parameters of jpeg sample : iFormat
+ */
+Uint32 GetDec8bitBusReqNum(FrameFormat iFormat, PackedFormat oPackMode)
+{
+    Uint32 num = 0;
+
+    if (oPackMode == PACKED_FORMAT_NONE) {
+        switch (iFormat) {
+        case FORMAT_400: num = 2; break;
+        case FORMAT_420: num = 4; break;
+        case FORMAT_422: num = 4; break;
+        case FORMAT_440: num = 8; break;
+        case FORMAT_444: num = 8; break;
+        default:         num = 0; break;
+        }
+    }
+    else {
+        switch (oPackMode) {
+        case PACKED_FORMAT_422_YUYV:
+        case PACKED_FORMAT_422_YVYU:
+        case PACKED_FORMAT_422_UYVY:
+        case PACKED_FORMAT_422_VYUY:
+            if (iFormat == FORMAT_400)      num = 1;
+            else if (iFormat == FORMAT_420) num = 2;
+            else if (iFormat == FORMAT_422) num = 2;
+            else                            num = 4;
+            break;
+        case PACKED_FORMAT_444:
+            num = 8;
+            break;
+        default:
+            num = 0;
+            break;
+        }
+    }
+
+    return num;
+}
+
+Uint32 GetDec12bitBusReqNum(FrameFormat iFormat, PackedFormat oPackMode)
+{
+    Uint32 num = 0;
+
+    if (oPackMode == PACKED_FORMAT_NONE) {
+        switch (iFormat) {
+        case FORMAT_400: num = 1; break;
+        case FORMAT_420: num = 2; break;
+        case FORMAT_422: num = 2; break;
+        case FORMAT_440: num = 4; break;
+        case FORMAT_444: num = 4; break;
+        default:         num = 0; break;
+        }
+    }
+    else {
+        switch (oPackMode) {
+        case PACKED_FORMAT_422_YUYV:
+        case PACKED_FORMAT_422_YVYU:
+        case PACKED_FORMAT_422_UYVY:
+        case PACKED_FORMAT_422_VYUY:
+            if (iFormat == FORMAT_400)      num = 1;
+            else if (iFormat == FORMAT_420) num = 1;
+            else if (iFormat == FORMAT_422) num = 1;
+            else if (iFormat == FORMAT_440) num = 2;
+            else if (iFormat == FORMAT_444) num = 2;
+            else                            num = 0;
+            break;
+        case PACKED_FORMAT_444:
+            num = 4;
+            break;
+        default:
+            num = 0;
+            break;
+        }
+    }
+
+    return num;
+}
+
+/*
+ * The parameters of input source: packMode
+ * The parameters of jpeg sample : oFormat
+ */
+Uint32 GetEnc8bitBusReqNum(PackedFormat iPackMode, FrameFormat oFormat)
+{
+    Uint32 num = 0;
+
+    if (iPackMode == PACKED_FORMAT_NONE) {
+        switch (oFormat) {
+        case FORMAT_400: num = 4; break;
+        case FORMAT_440: num = 8; break;
+        case FORMAT_444: num = 8; break;
+        default:         num = 4; break;
+        }
+    }
+    else {
+        switch (iPackMode) {
+        case PACKED_FORMAT_422_YUYV:
+        case PACKED_FORMAT_422_YVYU:
+        case PACKED_FORMAT_422_UYVY:
+        case PACKED_FORMAT_422_VYUY:
+            if (oFormat == FORMAT_400)      num = 2;
+            else if (oFormat == FORMAT_440) num = 4;
+            else if (oFormat == FORMAT_444) num = 4;
+            else                            num = 2;
+            break;
+        case PACKED_FORMAT_444:
+            num = 8;
+            break;
+        default:
+            num = 0;
+            break;
+        }
+    }
+
+    return num;
+}
+
+/*
+ * The parameters of input source: packMode
+ * The parameters of jpeg sample : oFormat
+ */
+Uint32 GetEnc12bitBusReqNum(PackedFormat iPackMode, FrameFormat oFormat)
+{
+    Uint32 num = 0;
+
+    if (iPackMode == PACKED_FORMAT_NONE) {
+        switch (oFormat) {
+        case FORMAT_400: num = 2; break;
+        case FORMAT_440: num = 4; break;
+        case FORMAT_444: num = 4; break;
+        default:         num = 2; break;
+        }
+    }
+    else {
+        switch (iPackMode) {
+        case PACKED_FORMAT_422_YUYV:
+        case PACKED_FORMAT_422_YVYU:
+        case PACKED_FORMAT_422_UYVY:
+        case PACKED_FORMAT_422_VYUY:
+            num = (oFormat == FORMAT_440 || oFormat == FORMAT_444) ? 2 : 1;
+            break;
+        case PACKED_FORMAT_444:
+            num = 4;
+            break;
+        default:
+            num = 0;
+            break;
+        }
+    }
+
+    return num;
+}
+
+/*
+* GetJpgInstance() obtains a instance.
+* It stores a pointer to the allocated instance in *ppInst
+* and returns JPG_RET_SUCCESS on success.
+* Failure results in 0(null pointer) in *ppInst and JPG_RET_FAILURE.
+*/
+
+JpgRet GetJpgInstance(JpgInst ** ppInst)
+{
+    Int32                   i;
+    Uint32                  handleSize;
+    JpgInst*                pJpgInst = 0;
+    jpu_instance_pool_t*    jip;
+
+    jip = (jpu_instance_pool_t *)jdi_get_instance_pool();
+    if (!jip)
+        return JPG_RET_INVALID_HANDLE;
+
+
+    for (i = 0; i < MAX_NUM_INSTANCE; i++) {
+        pJpgInst = (JpgInst *)jip->jpgInstPool[i];
+
+        if (!pJpgInst) {
+            return JPG_RET_FAILURE;
+        }
+        if (!pJpgInst->inUse)
+            break;
+    }
+
+    if (i == MAX_NUM_INSTANCE) {
+        *ppInst = 0;
+        return JPG_RET_FAILURE;
+    }
+
+    pJpgInst->inUse = TRUE;
+    handleSize = sizeof(JpgDecInfo);
+    if (handleSize < sizeof(JpgEncInfo)) {
+        handleSize = sizeof(JpgEncInfo);
+    }
+    if ((pJpgInst->JpgInfo=(void*)malloc(handleSize)) == NULL) {
+        return JPG_RET_INSUFFICIENT_RESOURCE;
+    }
+
+    memset((void*)pJpgInst->JpgInfo, 0x00, sizeof(handleSize));
+    *ppInst = pJpgInst;
+    jip->jpu_instance_num++;
+
+    if (jdi_open_instance(pJpgInst->instIndex) < 0) {
+        return JPG_RET_FAILURE;
+    }
+
+    return JPG_RET_SUCCESS;
+}
+
+void FreeJpgInstance(JpgInst * pJpgInst)
+{
+    jpu_instance_pool_t *jip;
+
+    jip = (jpu_instance_pool_t *)jdi_get_instance_pool();
+    if (!jip)
+        return;
+
+    pJpgInst->inUse = 0;
+    jip->jpu_instance_num--;
+
+    jdi_close_instance(pJpgInst->instIndex);
+
+    free(pJpgInst->JpgInfo);
+    pJpgInst->JpgInfo = NULL;
+}
+
+JpgRet CheckJpgInstValidity(JpgInst * pci)
+{
+    int i;
+    jpu_instance_pool_t *jip;
+
+    jip = (jpu_instance_pool_t *)jdi_get_instance_pool();
+    if (!jip)
+        return JPG_RET_FAILURE;
+
+    for (i = 0; i < MAX_NUM_INSTANCE; ++i) {
+        if ((JpgInst *)jip->jpgInstPool[i] == pci)
+            return JPG_RET_SUCCESS;
+    }
+    return JPG_RET_INVALID_HANDLE;
+}
+
+
+
+/******************************************************************************
+API Subroutines
+******************************************************************************/
+
+
+JpgRet CheckJpgDecOpenParam(JpgDecOpenParam * pop)
+{
+    if (pop == 0) {
+        return JPG_RET_INVALID_PARAM;
+    }
+    if (pop->bitstreamBuffer % 8) {
+        return JPG_RET_INVALID_PARAM;
+    }
+    if (pop->bitstreamBufferSize % 1024 || pop->bitstreamBufferSize < 1024) {
+        return JPG_RET_INVALID_PARAM;
+    }
+
+    if (pop->chromaInterleave != CBCR_SEPARATED &&
+        pop->chromaInterleave != CBCR_INTERLEAVE &&
+        pop->chromaInterleave != CRCB_INTERLEAVE) {
+            return JPG_RET_INVALID_PARAM;
+    }
+
+    if (pop->rotation != 0 && pop->rotation != 90 && pop->rotation != 180 && pop->rotation != 270) {
+        return JPG_RET_INVALID_PARAM;
+    }
+    if ((Uint32)pop->mirror > (Uint32)MIRDIR_HOR_VER) {
+        return JPG_RET_INVALID_PARAM;
+    }
+
+    if (pop->outputFormat == FORMAT_400 || pop->outputFormat == FORMAT_440) {
+        return JPG_RET_INVALID_PARAM;
+    }
+
+    if (pop->packedFormat > PACKED_FORMAT_444) {
+        return JPG_RET_INVALID_PARAM;
+    }
+    if (pop->packedFormat != PACKED_FORMAT_NONE) {
+        if (pop->chromaInterleave != CBCR_SEPARATED) {
+            return JPG_RET_INVALID_PARAM;
+        }
+    }
+
+    return JPG_RET_SUCCESS;
+}
+
+
+int JpgDecHuffTabSetUp(JpgDecInfo *jpg, int instRegIndex)
+{
+    int i, j;
+    int HuffData;	// 16BITS
+    int HuffLength;
+    int temp;
+
+    // MIN Tables
+    JpuWriteInstReg(instRegIndex, MJPEG_HUFF_CTRL_REG, 0x003);
+
+    //DC Luma
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffMin[0][j];
+        temp = (HuffData & 0x8000) >> 15;
+        temp = (temp << 15) | (temp << 14) | (temp << 13) | (temp << 12) | (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | (temp << 7 ) | (temp << 6) | (temp <<5) | (temp<<4) | (temp<<3) | (temp<<2) | (temp<<1)| (temp) ;
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData));	// 32-bit
+    }
+
+    //DC Chroma
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffMin[2][j];
+        temp = (HuffData & 0x8000) >> 15;
+        temp = (temp << 15) | (temp << 14) | (temp << 13) | (temp << 12) | (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | (temp << 7 ) | (temp << 6) | (temp <<5) | (temp<<4) | (temp<<3) | (temp<<2) | (temp<<1)| (temp) ;
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData));	// 32-bit
+    }
+
+    //AC Luma
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffMin[1][j];
+        temp = (HuffData & 0x8000) >> 15;
+        temp = (temp << 15) | (temp << 14) | (temp << 13) | (temp << 12) | (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | (temp << 7 ) | (temp << 6) | (temp <<5) | (temp<<4) | (temp<<3) | (temp<<2) | (temp<<1)| (temp) ;
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData));	// 32-bit
+    }
+
+    //AC Chroma
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffMin[3][j];
+        temp = (HuffData & 0x8000) >> 15;
+        temp = (temp << 15) | (temp << 14) | (temp << 13) | (temp << 12) | (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | (temp << 7 ) | (temp << 6) | (temp <<5) | (temp<<4) | (temp<<3) | (temp<<2) | (temp<<1)| (temp) ;
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData));	// 32-bit
+    }
+    // MAX Tables
+    JpuWriteInstReg(instRegIndex, MJPEG_HUFF_CTRL_REG, 0x403);
+    JpuWriteInstReg(instRegIndex, MJPEG_HUFF_ADDR_REG, 0x440);
+
+    //DC Luma
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffMax[0][j];
+        temp = (HuffData & 0x8000) >> 15;
+        temp = (temp << 15) | (temp << 14) | (temp << 13) | (temp << 12) | (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | (temp << 7 ) | (temp << 6) | (temp <<5) | (temp<<4) | (temp<<3) | (temp<<2) | (temp<<1)| (temp) ;
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData));
+    }
+    //DC Chroma
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffMax[2][j];
+        temp = (HuffData & 0x8000) >> 15;
+        temp = (temp << 15) | (temp << 14) | (temp << 13) | (temp << 12) | (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | (temp << 7 ) | (temp << 6) | (temp <<5) | (temp<<4) | (temp<<3) | (temp<<2) | (temp<<1)| (temp) ;
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData));
+    }
+    //AC Luma
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffMax[1][j];
+        temp = (HuffData & 0x8000) >> 15;
+        temp = (temp << 15) | (temp << 14) | (temp << 13) | (temp << 12) | (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | (temp << 7 ) | (temp << 6) | (temp <<5) | (temp<<4) | (temp<<3) | (temp<<2) | (temp<<1)| (temp) ;
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData));
+    }
+    //AC Chroma
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffMax[3][j];
+        temp = (HuffData & 0x8000) >> 15;
+        temp = (temp << 15) | (temp << 14) | (temp << 13) | (temp << 12) | (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | (temp << 7 ) | (temp << 6) | (temp <<5) | (temp<<4) | (temp<<3) | (temp<<2) | (temp<<1)| (temp) ;
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData));
+    }
+
+    // PTR Tables
+    JpuWriteInstReg (instRegIndex, MJPEG_HUFF_CTRL_REG, 0x803);
+    JpuWriteInstReg (instRegIndex, MJPEG_HUFF_ADDR_REG, 0x880);
+
+
+    //DC Luma
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffPtr[0][j];
+        temp = (HuffData & 0x80) >> 7;
+        temp = (temp<<23)|(temp<<22)|(temp<<21)|(temp<<20)|(temp<<19)|(temp<<18)|(temp<<17)|(temp<<16)|(temp<<15)|(temp<<14)|(temp<<13)|(temp<<12)|(temp<<11)|(temp<<10)|(temp<<9)|(temp<<8)|(temp<<7)|(temp<<6)|(temp<<5)|(temp<<4)|(temp<<3)|(temp<<2)|(temp<<1)|(temp);
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData));
+    }
+    //DC Chroma
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffPtr[2][j];
+        temp = (HuffData & 0x80) >> 7;
+        temp = (temp<<23)|(temp<<22)|(temp<<21)|(temp<<20)|(temp<<19)|(temp<<18)|(temp<<17)|(temp<<16)|(temp<<15)|(temp<<14)|(temp<<13)|(temp<<12)|(temp<<11)|(temp<<10)|(temp<<9)|(temp<<8)|(temp<<7)|(temp<<6)|(temp<<5)|(temp<<4)|(temp<<3)|(temp<<2)|(temp<<1)|(temp);
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData));
+    }
+    //AC Luma
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffPtr[1][j];
+        temp = (HuffData & 0x80) >> 7;
+        temp = (temp<<23)|(temp<<22)|(temp<<21)|(temp<<20)|(temp<<19)|(temp<<18)|(temp<<17)|(temp<<16)|(temp<<15)|(temp<<14)|(temp<<13)|(temp<<12)|(temp<<11)|(temp<<10)|(temp<<9)|(temp<<8)|(temp<<7)|(temp<<6)|(temp<<5)|(temp<<4)|(temp<<3)|(temp<<2)|(temp<<1)|(temp);
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData));
+    }
+    //AC Chroma
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffPtr[3][j];
+        temp = (HuffData & 0x80) >> 7;
+        temp = (temp<<23)|(temp<<22)|(temp<<21)|(temp<<20)|(temp<<19)|(temp<<18)|(temp<<17)|(temp<<16)|(temp<<15)|(temp<<14)|(temp<<13)|(temp<<12)|(temp<<11)|(temp<<10)|(temp<<9)|(temp<<8)|(temp<<7)|(temp<<6)|(temp<<5)|(temp<<4)|(temp<<3)|(temp<<2)|(temp<<1)|(temp);
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData));
+    }
+
+    // VAL Tables
+    JpuWriteInstReg(instRegIndex, MJPEG_HUFF_CTRL_REG, 0xC03);
+
+    // VAL DC Luma
+    HuffLength = 0;
+    for(i=0; i<12; i++)
+        HuffLength += jpg->huffBits[0][i];
+
+    if (HuffLength > 256)
+        return 0;
+
+    for (i=0; i<HuffLength; i++) {	// 8-bit, 12 row, 1 category (DC Luma)
+        HuffData = jpg->huffVal[0][i];
+        temp = (HuffData & 0x80) >> 7;
+        temp = (temp<<23)|(temp<<22)|(temp<<21)|(temp<<20)|(temp<<19)|(temp<<18)|(temp<<17)|(temp<<16)|(temp<<15)|(temp<<14)|(temp<<13)|(temp<<12)|(temp<<11)|(temp<<10)|(temp<<9)|(temp<<8)|(temp<<7)|(temp<<6)|(temp<<5)|(temp<<4)|(temp<<3)|(temp<<2)|(temp<<1)|(temp);
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData));
+    }
+
+    for (i=0; i<12-HuffLength; i++) {
+        JpuWriteInstReg(instRegIndex, MJPEG_HUFF_DATA_REG, 0xFFFFFFFF);
+    }
+
+    // VAL DC Chroma
+    HuffLength = 0;
+    for(i=0; i<12; i++)
+        HuffLength += jpg->huffBits[2][i];
+
+    if (HuffLength > 256)
+        return 0;
+    for (i=0; i<HuffLength; i++) {	// 8-bit, 12 row, 1 category (DC Chroma)
+        HuffData = jpg->huffVal[2][i];
+        temp = (HuffData & 0x80) >> 7;
+        temp = (temp<<23)|(temp<<22)|(temp<<21)|(temp<<20)|(temp<<19)|(temp<<18)|(temp<<17)|(temp<<16)|(temp<<15)|(temp<<14)|(temp<<13)|(temp<<12)|(temp<<11)|(temp<<10)|(temp<<9)|(temp<<8)|(temp<<7)|(temp<<6)|(temp<<5)|(temp<<4)|(temp<<3)|(temp<<2)|(temp<<1)|(temp);
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData));
+    }
+    for (i=0; i<12-HuffLength; i++) {
+        JpuWriteInstReg(instRegIndex, MJPEG_HUFF_DATA_REG, 0xFFFFFFFF);
+    }
+
+    // VAL AC Luma
+    HuffLength = 0;
+    for(i=0; i<162; i++)
+        HuffLength += jpg->huffBits[1][i];
+
+    if (HuffLength > 256)
+        return 0;
+
+    for (i=0; i<HuffLength; i++) {	// 8-bit, 162 row, 1 category (AC Luma)
+        HuffData = jpg->huffVal[1][i];
+        temp = (HuffData & 0x80) >> 7;
+        temp = (temp<<23)|(temp<<22)|(temp<<21)|(temp<<20)|(temp<<19)|(temp<<18)|(temp<<17)|(temp<<16)|(temp<<15)|(temp<<14)|(temp<<13)|(temp<<12)|(temp<<11)|(temp<<10)|(temp<<9)|(temp<<8)|(temp<<7)|(temp<<6)|(temp<<5)|(temp<<4)|(temp<<3)|(temp<<2)|(temp<<1)|(temp);
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData));
+    }
+    for (i=0; i<162-HuffLength; i++) {
+        JpuWriteInstReg(instRegIndex, MJPEG_HUFF_DATA_REG, 0xFFFFFFFF);
+    }
+
+    // VAL AC Chroma
+    HuffLength = 0;
+    for(i=0; i<162; i++)
+        HuffLength += jpg->huffBits[3][i];
+
+    if (HuffLength > 256)
+        return 0;
+
+    for (i=0; i<HuffLength; i++) {	// 8-bit, 162 row, 1 category (AC Chroma)
+        HuffData = jpg->huffVal[3][i];
+        temp = (HuffData & 0x80) >> 7;
+        temp = (temp<<23)|(temp<<22)|(temp<<21)|(temp<<20)|(temp<<19)|(temp<<18)|(temp<<17)|(temp<<16)|(temp<<15)|(temp<<14)|(temp<<13)|(temp<<12)|(temp<<11)|(temp<<10)|(temp<<9)|(temp<<8)|(temp<<7)|(temp<<6)|(temp<<5)|(temp<<4)|(temp<<3)|(temp<<2)|(temp<<1)|(temp);
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData));
+    }
+
+    for (i=0; i<162-HuffLength; i++) {
+        JpuWriteInstReg(instRegIndex, MJPEG_HUFF_DATA_REG, 0xFFFFFFFF);
+    }
+
+    // end SerPeriHuffTab
+    JpuWriteInstReg(instRegIndex, MJPEG_HUFF_CTRL_REG, 0x000);
+
+    return 1;
+}
+
+int JpgDecHuffTabSetUp_12b(JpgDecInfo *jpg, int instRegIndex)
+{
+    int i, j;
+    int HuffData;	// 16BITS
+    int HuffLength;
+    int temp;
+
+    // MIN Tables
+    JpuWriteInstReg(instRegIndex, MJPEG_HUFF_CTRL_REG, 0x003);
+
+    //DC Luma
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffMin[0][j];
+        temp = (HuffData & 0x8000) >> 15;
+        temp = (temp << 15) | (temp << 14) | (temp << 13) | (temp << 12) | (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | (temp << 7 ) | (temp << 6) | (temp <<5) | (temp<<4) | (temp<<3) | (temp<<2) | (temp<<1)| (temp) ;
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData));	// 32-bit
+    }
+    //DC Chroma
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffMin[2][j];
+        temp = (HuffData & 0x8000) >> 15;
+        temp = (temp << 15) | (temp << 14) | (temp << 13) | (temp << 12) | (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | (temp << 7 ) | (temp << 6) | (temp <<5) | (temp<<4) | (temp<<3) | (temp<<2) | (temp<<1)| (temp) ;
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData));	// 32-bit
+    }
+    //AC Luma
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffMin[1][j];
+        temp = (HuffData & 0x8000) >> 15;
+        temp = (temp << 15) | (temp << 14) | (temp << 13) | (temp << 12) | (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | (temp << 7 ) | (temp << 6) | (temp <<5) | (temp<<4) | (temp<<3) | (temp<<2) | (temp<<1)| (temp) ;
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData));	// 32-bit
+    }
+    //AC Chroma
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffMin[3][j];
+        temp = (HuffData & 0x8000) >> 15;
+        temp = (temp << 15) | (temp << 14) | (temp << 13) | (temp << 12) | (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | (temp << 7 ) | (temp << 6) | (temp <<5) | (temp<<4) | (temp<<3) | (temp<<2) | (temp<<1)| (temp) ;
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData));	// 32-bit
+    }
+    //DC EX1
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffMin[4][j];
+        temp = (HuffData & 0x8000) >> 15;
+        temp = (temp << 15) | (temp << 14) | (temp << 13) | (temp << 12) | (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | (temp << 7 ) | (temp << 6) | (temp <<5) | (temp<<4) | (temp<<3) | (temp<<2) | (temp<<1)| (temp) ;
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData));	// 32-bit
+    }
+
+    //AC EX1
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffMin[5][j];
+        temp = (HuffData & 0x8000) >> 15;
+        temp = (temp << 15) | (temp << 14) | (temp << 13) | (temp << 12) | (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | (temp << 7 ) | (temp << 6) | (temp <<5) | (temp<<4) | (temp<<3) | (temp<<2) | (temp<<1)| (temp) ;
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData));	// 32-bit
+    }
+
+    // MAX Tables
+    JpuWriteInstReg(instRegIndex, MJPEG_HUFF_CTRL_REG, 0x403);
+    JpuWriteInstReg(instRegIndex, MJPEG_HUFF_ADDR_REG, 0x480);
+
+    //DC Luma
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffMax[0][j];
+        temp = (HuffData & 0x8000) >> 15;
+        temp = (temp << 15) | (temp << 14) | (temp << 13) | (temp << 12) | (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | (temp << 7 ) | (temp << 6) | (temp <<5) | (temp<<4) | (temp<<3) | (temp<<2) | (temp<<1)| (temp) ;
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData));
+    }
+    //DC Chroma
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffMax[2][j];
+        temp = (HuffData & 0x8000) >> 15;
+        temp = (temp << 15) | (temp << 14) | (temp << 13) | (temp << 12) | (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | (temp << 7 ) | (temp << 6) | (temp <<5) | (temp<<4) | (temp<<3) | (temp<<2) | (temp<<1)| (temp) ;
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData));
+    }
+    //AC Luma
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffMax[1][j];
+        temp = (HuffData & 0x8000) >> 15;
+        temp = (temp << 15) | (temp << 14) | (temp << 13) | (temp << 12) | (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | (temp << 7 ) | (temp << 6) | (temp <<5) | (temp<<4) | (temp<<3) | (temp<<2) | (temp<<1)| (temp) ;
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData));
+    }
+    //AC Chroma
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffMax[3][j];
+        temp = (HuffData & 0x8000) >> 15;
+        temp = (temp << 15) | (temp << 14) | (temp << 13) | (temp << 12) | (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | (temp << 7 ) | (temp << 6) | (temp <<5) | (temp<<4) | (temp<<3) | (temp<<2) | (temp<<1)| (temp) ;
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData));
+    }
+    //DC EX1
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffMax[4][j];
+        temp = (HuffData & 0x8000) >> 15;
+        temp = (temp << 15) | (temp << 14) | (temp << 13) | (temp << 12) | (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | (temp << 7 ) | (temp << 6) | (temp <<5) | (temp<<4) | (temp<<3) | (temp<<2) | (temp<<1)| (temp) ;
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData));
+    }
+
+    //AC EX1
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffMax[5][j];
+        temp = (HuffData & 0x8000) >> 15;
+        temp = (temp << 15) | (temp << 14) | (temp << 13) | (temp << 12) | (temp << 11) | (temp << 10) | (temp << 9) | (temp << 8) | (temp << 7 ) | (temp << 6) | (temp <<5) | (temp<<4) | (temp<<3) | (temp<<2) | (temp<<1)| (temp) ;
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFF) << 16) | HuffData));
+    }
+
+    // PTR Tables
+    JpuWriteInstReg (instRegIndex, MJPEG_HUFF_CTRL_REG, 0x803);
+    JpuWriteInstReg (instRegIndex, MJPEG_HUFF_ADDR_REG, 0x900);
+
+    //DC Luma
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffPtr[0][j];
+        temp = (HuffData & 0x80) >> 7;
+        temp = (temp<<23)|(temp<<22)|(temp<<21)|(temp<<20)|(temp<<19)|(temp<<18)|(temp<<17)|(temp<<16)|(temp<<15)|(temp<<14)|(temp<<13)|(temp<<12)|(temp<<11)|(temp<<10)|(temp<<9)|(temp<<8)|(temp<<7)|(temp<<6)|(temp<<5)|(temp<<4)|(temp<<3)|(temp<<2)|(temp<<1)|(temp);
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData));
+    }
+    //DC Chroma
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffPtr[2][j];
+        temp = (HuffData & 0x80) >> 7;
+        temp = (temp<<23)|(temp<<22)|(temp<<21)|(temp<<20)|(temp<<19)|(temp<<18)|(temp<<17)|(temp<<16)|(temp<<15)|(temp<<14)|(temp<<13)|(temp<<12)|(temp<<11)|(temp<<10)|(temp<<9)|(temp<<8)|(temp<<7)|(temp<<6)|(temp<<5)|(temp<<4)|(temp<<3)|(temp<<2)|(temp<<1)|(temp);
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData));
+    }
+    //AC Luma
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffPtr[1][j];
+        temp = (HuffData & 0x80) >> 7;
+        temp = (temp<<23)|(temp<<22)|(temp<<21)|(temp<<20)|(temp<<19)|(temp<<18)|(temp<<17)|(temp<<16)|(temp<<15)|(temp<<14)|(temp<<13)|(temp<<12)|(temp<<11)|(temp<<10)|(temp<<9)|(temp<<8)|(temp<<7)|(temp<<6)|(temp<<5)|(temp<<4)|(temp<<3)|(temp<<2)|(temp<<1)|(temp);
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData));
+    }
+    //AC Chroma
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffPtr[3][j];
+        temp = (HuffData & 0x80) >> 7;
+        temp = (temp<<23)|(temp<<22)|(temp<<21)|(temp<<20)|(temp<<19)|(temp<<18)|(temp<<17)|(temp<<16)|(temp<<15)|(temp<<14)|(temp<<13)|(temp<<12)|(temp<<11)|(temp<<10)|(temp<<9)|(temp<<8)|(temp<<7)|(temp<<6)|(temp<<5)|(temp<<4)|(temp<<3)|(temp<<2)|(temp<<1)|(temp);
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData));
+    }
+    //DC EX1
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffPtr[4][j];
+        temp = (HuffData & 0x80) >> 7;
+        temp = (temp<<23)|(temp<<22)|(temp<<21)|(temp<<20)|(temp<<19)|(temp<<18)|(temp<<17)|(temp<<16)|(temp<<15)|(temp<<14)|(temp<<13)|(temp<<12)|(temp<<11)|(temp<<10)|(temp<<9)|(temp<<8)|(temp<<7)|(temp<<6)|(temp<<5)|(temp<<4)|(temp<<3)|(temp<<2)|(temp<<1)|(temp);
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData));
+    }
+
+    //AC EX1
+    for(j=0; j<16; j++)
+    {
+        HuffData = jpg->huffPtr[5][j];
+        temp = (HuffData & 0x80) >> 7;
+        temp = (temp<<23)|(temp<<22)|(temp<<21)|(temp<<20)|(temp<<19)|(temp<<18)|(temp<<17)|(temp<<16)|(temp<<15)|(temp<<14)|(temp<<13)|(temp<<12)|(temp<<11)|(temp<<10)|(temp<<9)|(temp<<8)|(temp<<7)|(temp<<6)|(temp<<5)|(temp<<4)|(temp<<3)|(temp<<2)|(temp<<1)|(temp);
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData));
+    }
+
+    // VAL Tables
+    JpuWriteInstReg(instRegIndex, MJPEG_HUFF_CTRL_REG, 0xC03);
+
+    // VAL DC Luma
+    HuffLength = 0;
+    for(i=0; i<16; i++) {
+        HuffLength += jpg->huffBits[0][i];
+    }
+
+	if (HuffLength > 256) {
+        return 0;
+    }
+
+    for (i=0; i<HuffLength; i++) {	// 8-bit, 12 row, 1 category (DC Luma)
+        HuffData = jpg->huffVal[0][i];
+        temp = (HuffData & 0x80) >> 7;
+        temp = (temp<<23)|(temp<<22)|(temp<<21)|(temp<<20)|(temp<<19)|(temp<<18)|(temp<<17)|(temp<<16)|(temp<<15)|(temp<<14)|(temp<<13)|(temp<<12)|(temp<<11)|(temp<<10)|(temp<<9)|(temp<<8)|(temp<<7)|(temp<<6)|(temp<<5)|(temp<<4)|(temp<<3)|(temp<<2)|(temp<<1)|(temp);
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData));
+    }
+    for (i=0; i<16-HuffLength; i++) {
+        JpuWriteInstReg(instRegIndex, MJPEG_HUFF_DATA_REG, 0xFFFFFFFF);
+    }
+
+    // VAL DC Chroma
+    HuffLength = 0;
+    for(i=0; i<16; i++) {
+        HuffLength += jpg->huffBits[2][i];
+    }
+
+	if (HuffLength > 256) {
+        return 0;
+    }
+
+    for (i=0; i<HuffLength; i++) {	// 8-bit, 12 row, 1 category (DC Chroma)
+        HuffData = jpg->huffVal[2][i];
+        temp = (HuffData & 0x80) >> 7;
+        temp = (temp<<23)|(temp<<22)|(temp<<21)|(temp<<20)|(temp<<19)|(temp<<18)|(temp<<17)|(temp<<16)|(temp<<15)|(temp<<14)|(temp<<13)|(temp<<12)|(temp<<11)|(temp<<10)|(temp<<9)|(temp<<8)|(temp<<7)|(temp<<6)|(temp<<5)|(temp<<4)|(temp<<3)|(temp<<2)|(temp<<1)|(temp);
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData));
+    }
+    for (i=0; i<16-HuffLength; i++) {
+        JpuWriteInstReg(instRegIndex, MJPEG_HUFF_DATA_REG, 0xFFFFFFFF);
+    }
+
+    // VAL AC Luma
+    HuffLength = 0;
+    for(i=0; i<256; i++) {
+        HuffLength += jpg->huffBits[1][i];
+    }
+
+	if (HuffLength > 256) {
+        return 0;
+    }
+
+    for (i=0; i<HuffLength; i++) {	// 8-bit, 162 row, 1 category (AC Luma)
+        HuffData = jpg->huffVal[1][i];
+        temp = (HuffData & 0x80) >> 7;
+        temp = (temp<<23)|(temp<<22)|(temp<<21)|(temp<<20)|(temp<<19)|(temp<<18)|(temp<<17)|(temp<<16)|(temp<<15)|(temp<<14)|(temp<<13)|(temp<<12)|(temp<<11)|(temp<<10)|(temp<<9)|(temp<<8)|(temp<<7)|(temp<<6)|(temp<<5)|(temp<<4)|(temp<<3)|(temp<<2)|(temp<<1)|(temp);
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData));
+    }
+    for (i=0; i<256-HuffLength; i++) {
+        JpuWriteInstReg(instRegIndex, MJPEG_HUFF_DATA_REG, 0xFFFFFFFF);
+    }
+
+    // VAL AC Chroma
+    HuffLength = 0;
+    for(i=0; i<256; i++) {
+        HuffLength += jpg->huffBits[3][i];
+    }
+
+	if (HuffLength > 256) {
+        return 0;
+    }
+
+    for (i=0; i<HuffLength; i++) {	// 8-bit, 162 row, 1 category (AC Chroma)
+        HuffData = jpg->huffVal[3][i];
+        temp = (HuffData & 0x80) >> 7;
+        temp = (temp<<23)|(temp<<22)|(temp<<21)|(temp<<20)|(temp<<19)|(temp<<18)|(temp<<17)|(temp<<16)|(temp<<15)|(temp<<14)|(temp<<13)|(temp<<12)|(temp<<11)|(temp<<10)|(temp<<9)|(temp<<8)|(temp<<7)|(temp<<6)|(temp<<5)|(temp<<4)|(temp<<3)|(temp<<2)|(temp<<1)|(temp);
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData));
+    }
+    for (i=0; i<256-HuffLength; i++) {
+        JpuWriteInstReg(instRegIndex, MJPEG_HUFF_DATA_REG, 0xFFFFFFFF);
+    }
+
+    // VAL DC EX1
+    HuffLength = 0;
+    for(i=0; i<16; i++) {
+        HuffLength += jpg->huffBits[4][i];
+    }
+
+	if (HuffLength > 256) {
+        return 0;
+    }
+
+    for (i=0; i<HuffLength; i++) {	// 8-bit, 12 row, 1 category (DC Luma)
+        HuffData = jpg->huffVal[4][i];
+        temp = (HuffData & 0x80) >> 7;
+        temp = (temp<<23)|(temp<<22)|(temp<<21)|(temp<<20)|(temp<<19)|(temp<<18)|(temp<<17)|(temp<<16)|(temp<<15)|(temp<<14)|(temp<<13)|(temp<<12)|(temp<<11)|(temp<<10)|(temp<<9)|(temp<<8)|(temp<<7)|(temp<<6)|(temp<<5)|(temp<<4)|(temp<<3)|(temp<<2)|(temp<<1)|(temp);
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData));
+    }
+    for (i=0; i<16-HuffLength; i++) {
+        JpuWriteInstReg(instRegIndex, MJPEG_HUFF_DATA_REG, 0xFFFFFFFF);
+    }
+
+    // VAL AC EX1
+    HuffLength = 0;
+    for(i=0; i<256; i++) {
+        HuffLength += jpg->huffBits[5][i];
+    }
+
+	if (HuffLength > 256) {
+        return 0;
+    }
+
+    for (i=0; i<HuffLength; i++) {	// 8-bit, 162 row, 1 category (AC Luma)
+        HuffData = jpg->huffVal[5][i];
+        temp = (HuffData & 0x80) >> 7;
+        temp = (temp<<23)|(temp<<22)|(temp<<21)|(temp<<20)|(temp<<19)|(temp<<18)|(temp<<17)|(temp<<16)|(temp<<15)|(temp<<14)|(temp<<13)|(temp<<12)|(temp<<11)|(temp<<10)|(temp<<9)|(temp<<8)|(temp<<7)|(temp<<6)|(temp<<5)|(temp<<4)|(temp<<3)|(temp<<2)|(temp<<1)|(temp);
+        JpuWriteInstReg (instRegIndex, MJPEG_HUFF_DATA_REG, (((temp & 0xFFFFFF) << 8) | HuffData));
+    }
+    for (i=0; i<256-HuffLength; i++) {
+        JpuWriteInstReg(instRegIndex, MJPEG_HUFF_DATA_REG, 0xFFFFFFFF);
+    }
+
+    // end SerPeriHuffTab
+    JpuWriteInstReg(instRegIndex, MJPEG_HUFF_CTRL_REG, 0x000);
+
+    return 1;
+}
+
+int JpgDecQMatTabSetUp(JpgDecInfo *jpg, int instRegIndex)
+{
+    int i;
+    int table;
+    int val;
+
+    // SetPeriQMatTab
+    // Comp 0
+    JpuWriteInstReg(instRegIndex, MJPEG_QMAT_CTRL_REG, 0x03);
+    table = jpg->cInfoTab[0][3];
+
+	if (table >= 4)
+        return 0;
+
+    for (i=0; i<64; i++) {
+        val = jpg->qMatTab[table][i];
+        JpuWriteInstReg(instRegIndex, MJPEG_QMAT_DATA_REG, val);
+    }
+    JpuWriteInstReg(instRegIndex, MJPEG_QMAT_CTRL_REG, 0x00);
+
+    // Comp 1
+    JpuWriteInstReg(instRegIndex, MJPEG_QMAT_CTRL_REG, 0x43);
+    table = jpg->cInfoTab[1][3];
+	if (table >= 4)
+        return 0;
+
+    for (i=0; i<64; i++) {
+        val = jpg->qMatTab[table][i];
+        JpuWriteInstReg(instRegIndex, MJPEG_QMAT_DATA_REG, val);
+    }
+    JpuWriteInstReg(instRegIndex, MJPEG_QMAT_CTRL_REG, 0x00);
+
+    // Comp 2
+    JpuWriteInstReg(instRegIndex, MJPEG_QMAT_CTRL_REG, 0x83);
+    table = jpg->cInfoTab[2][3];
+	if (table >= 4)
+        return 0;
+
+    for (i=0; i<64; i++) {
+        val = jpg->qMatTab[table][i];
+        JpuWriteInstReg(instRegIndex, MJPEG_QMAT_DATA_REG, val);
+    }
+    JpuWriteInstReg(instRegIndex, MJPEG_QMAT_CTRL_REG, 0x00);
+
+    return 1;
+}
+
+void JpgDecGramSetup(JpgDecInfo * jpg, int instRegIndex)
+{
+    int dExtBitBufCurPos;
+    int dExtBitBufBaseAddr;
+    int dMibStatus;
+
+    dMibStatus			= 1;
+    dExtBitBufCurPos	= jpg->pagePtr;
+    dExtBitBufBaseAddr	= jpg->streamBufStartAddr;
+
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_CUR_POS_REG, dExtBitBufCurPos);
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_EXT_ADDR_REG, dExtBitBufBaseAddr + (dExtBitBufCurPos << 8));
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_INT_ADDR_REG, (dExtBitBufCurPos & 1) << 6);
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_DATA_CNT_REG, JPU_GBU_SIZE / 4);	// 64 * 4 byte == 32 * 8 byte
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_COMMAND_REG, (jpg->streamEndian << 1) | 0);
+
+    while (dMibStatus == 1) {
+        dMibStatus = JpuReadInstReg(instRegIndex, MJPEG_BBC_BUSY_REG);
+    }
+
+    dMibStatus			= 1;
+    dExtBitBufCurPos	= dExtBitBufCurPos + 1;
+
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_CUR_POS_REG, dExtBitBufCurPos);
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_EXT_ADDR_REG, dExtBitBufBaseAddr + (dExtBitBufCurPos << 8));
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_INT_ADDR_REG, (dExtBitBufCurPos & 1) << 6);
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_DATA_CNT_REG, JPU_GBU_SIZE / 4);	// 64 * 4 byte == 32 * 8 byte
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_COMMAND_REG, (jpg->streamEndian << 1) | 0);
+
+    while (dMibStatus == 1) {
+        dMibStatus = JpuReadInstReg(instRegIndex, MJPEG_BBC_BUSY_REG);
+    }
+
+    dExtBitBufCurPos	= dExtBitBufCurPos + 1;
+
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_CUR_POS_REG, dExtBitBufCurPos);	// next unit page pointer
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_CTRL_REG, (jpg->streamEndian<< 1) | 1);
+
+
+    JpuWriteInstReg(instRegIndex, MJPEG_GBU_WPTR_REG, jpg->wordPtr);
+
+    JpuWriteInstReg(instRegIndex, MJPEG_GBU_BBSR_REG, 0);
+    JpuWriteInstReg(instRegIndex, MJPEG_GBU_BBER_REG, ((JPU_GBU_SIZE / 4) * 2) - 1);
+
+    if (jpg->pagePtr & 1) {
+        JpuWriteInstReg(instRegIndex, MJPEG_GBU_BBIR_REG, 0);
+        JpuWriteInstReg(instRegIndex, MJPEG_GBU_BBHR_REG, 0);
+    }
+    else {
+        JpuWriteInstReg(instRegIndex, MJPEG_GBU_BBIR_REG, JPU_GBU_SIZE / 4);	// 64 * 4 byte == 32 * 8 byte
+        JpuWriteInstReg(instRegIndex, MJPEG_GBU_BBHR_REG, JPU_GBU_SIZE / 4);	// 64 * 4 byte == 32 * 8 byte
+    }
+    JpuWriteInstReg(instRegIndex, MJPEG_GBU_CTRL_REG, 4);
+    JpuWriteInstReg(instRegIndex, MJPEG_GBU_FF_RPTR_REG, jpg->bitPtr);
+}
+
+enum {
+    SAMPLE_420 = 0xA,
+    SAMPLE_H422 = 0x9,
+    SAMPLE_V422 = 0x6,
+    SAMPLE_444 = 0x5,
+    SAMPLE_400 = 0x1
+};
+
+const BYTE cDefHuffBits[8][16] =
+{
+    {	// DC index 0 (Luminance DC)
+        0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
+            0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    }
+    ,
+    {	// AC index 0 (Luminance AC)
+        0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
+            0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D
+    }
+    ,
+    {	// DC index 1 (Chrominance DC)
+        0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+            0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
+    }
+    ,
+    {	// AC index 1 (Chrominance AC)
+        0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
+            0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77
+    }
+};
+
+const BYTE cDefHuffVal[8][162] =
+{
+    {	// DC index 0 (Luminance DC)
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+            0x08, 0x09, 0x0A, 0x0B
+    }
+    ,
+    {	// AC index 0 (Luminance AC)
+        0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
+            0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
+            0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08,
+            0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0,
+            0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16,
+            0x17, 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28,
+            0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+            0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+            0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+            0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+            0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+            0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+            0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+            0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
+            0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,
+            0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5,
+            0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4,
+            0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2,
+            0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA,
+            0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
+            0xF9, 0xFA
+    }
+    ,
+    {	// DC index 1 (Chrominance DC)
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+            0x08, 0x09, 0x0A, 0x0B
+    }
+    ,
+    {	// AC index 1 (Chrominance AC)
+        0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
+            0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
+            0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
+            0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0,
+            0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34,
+            0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26,
+            0x27, 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38,
+            0x39, 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
+            0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+            0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+            0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+            0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+            0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96,
+            0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5,
+            0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4,
+            0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3,
+            0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2,
+            0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA,
+            0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9,
+            0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
+            0xF9, 0xFA
+    }
+};
+
+const BYTE cDefHuffBits_ES[8][16] = {
+    {	// DC index 0 (Luminance DC)
+        0x00, 0x02, 0x03, 0x01, 0x00, 0x03, 0x01, 0x01,
+        0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
+    },
+    {	// AC index 0 (Luminance AC)
+        0x00, 0x01, 0x04, 0x02, 0x02, 0x02, 0x01, 0x04,
+        0x01, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0xEB
+    },
+    {	// DC index 1 (Chrominance DC)
+        0x00, 0x02, 0x02, 0x02, 0x03, 0x01, 0x01, 0x01,
+        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    },
+    {	// AC index 1 (Chrominance AC)
+        0x00, 0x01, 0x03, 0x02, 0x05, 0x01, 0x05, 0x05,
+        0x03, 0x07, 0x04, 0x04, 0x03, 0x04, 0x06, 0xCB
+    },
+    {	// DC EX1 (Luminance DC)
+        0x00, 0x02, 0x03, 0x01, 0x00, 0x03, 0x01, 0x01,
+        0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
+    },
+    {	// AC EX1 (Luminance AC)
+        0x00, 0x01, 0x04, 0x02, 0x02, 0x02, 0x01, 0x04,
+        0x01, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0xEB
+    },
+    {	// DC EX2 (Chrominance DC)
+        0x00, 0x02, 0x02, 0x02, 0x03, 0x01, 0x01, 0x01,
+            0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    },
+    {	// AC EX2 (Chrominance AC)
+        0x00, 0x01, 0x03, 0x02, 0x05, 0x01, 0x05, 0x05,
+        0x03, 0x07, 0x04, 0x04, 0x03, 0x04, 0x06, 0xCB
+    }
+};
+
+const BYTE cDefHuffVal_ES[8][256] = {
+    {	// DC index 0 (Luminance DC)
+        0x08, 0x09, 0x06, 0x07, 0x0A, 0x05, 0x03, 0x04,
+        0x0B, 0x02, 0x00, 0x01, 0x0C
+    },
+    {	// AC index 0 (Luminance AC)
+        0x02,0x01,0x03,0x04,0x05,0x06,0x07,0x08,0x12,0x09,0x11,0x13,0x00,0x14,0x21,0x22,
+        0x15,0x0a,0x23,0x31,0x16,0x32,0x17,0x24,0x33,0x41,0x18,0x25,0x42,0x51,0x0b,0x26,
+        0x19,0x43,0x52,0x61,0x35,0x62,0x71,0x0c,0x0d,0x0e,0x0f,0x10,0x1a,0x1b,0x1c,0x1d,
+        0x1e,0x1f,0x20,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x34,0x36,0x37,
+        0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,
+        0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,
+        0x5d,0x5e,0x5f,0x60,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,
+        0x6f,0x70,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,
+        0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
+        0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,
+        0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,
+        0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,
+        0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,
+        0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf,
+        0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,
+        0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
+    },
+    {	// DC index 1 (Chrominance DC)
+        0x06, 0x07, 0x05, 0x08, 0x04, 0x09, 0x02, 0x03,
+        0x0A, 0x01, 0x0B, 0x00, 0x0C
+    },
+    {	// AC index 1 (Chrominance AC)
+        0x01,0x02,0x03,0x11,0x04,0x21,0x00,0x05,0x06,0x12,0x31,0x41,0x07,0x13,0x22,0x51,
+        0x61,0x08,0x14,0x32,0x71,0x81,0x42,0x91,0xa1,0x09,0x15,0x23,0x52,0xb1,0xc1,0xf0,
+        0x16,0x62,0xd1,0xe1,0x0a,0x24,0x72,0xf1,0x17,0x82,0x92,0x33,0x43,0x53,0xb2,0x0b,
+        0x0c,0x18,0x35,0xa2,0xc2,0x0d,0x0e,0x0f,0x10,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
+        0x20,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x34,0x36,0x37,
+        0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,
+        0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,
+        0x5e,0x5f,0x60,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
+        0x70,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,0x80,0x83,
+        0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,0x90,0x93,0x94,0x95,
+        0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,0xa0,0xa3,0xa4,0xa5,0xa6,0xa7,
+        0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,0xb0,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,
+        0xba,0xbb,0xbc,0xbd,0xbe,0xbf,0xc0,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,
+        0xcc,0xcd,0xce,0xcf,0xd0,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,
+        0xdd,0xde,0xdf,0xe0,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,
+        0xee,0xef,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
+    },
+    {	// DC EX1 (Luminance DC)
+        0x08, 0x09, 0x06, 0x07, 0x0A, 0x05, 0x03, 0x04,
+            0x0B, 0x02, 0x00, 0x01, 0x0C
+    },
+    {	// AC EX1 (Luminance AC)
+        0x02,0x01,0x03,0x04,0x05,0x06,0x07,0x08,0x12,0x09,0x11,0x13,0x00,0x14,0x21,0x22,
+        0x15,0x0a,0x23,0x31,0x16,0x32,0x17,0x24,0x33,0x41,0x18,0x25,0x42,0x51,0x0b,0x26,
+        0x19,0x43,0x52,0x61,0x35,0x62,0x71,0x0c,0x0d,0x0e,0x0f,0x10,0x1a,0x1b,0x1c,0x1d,
+        0x1e,0x1f,0x20,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x34,0x36,0x37,
+        0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,
+        0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,
+        0x5d,0x5e,0x5f,0x60,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,
+        0x6f,0x70,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,
+        0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
+        0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,
+        0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,
+        0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,
+        0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,
+        0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf,
+        0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,
+        0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
+    },
+    {	// DC EX2 (Chrominance DC)
+        0x06, 0x07, 0x05, 0x08, 0x04, 0x09, 0x02, 0x03,
+        0x0A, 0x01, 0x0B, 0x00, 0x0C
+    },
+    {	// AC EX2 (Chrominance AC)
+        0x01,0x02,0x03,0x11,0x04,0x21,0x00,0x05,0x06,0x12,0x31,0x41,0x07,0x13,0x22,0x51,
+        0x61,0x08,0x14,0x32,0x71,0x81,0x42,0x91,0xa1,0x09,0x15,0x23,0x52,0xb1,0xc1,0xf0,
+        0x16,0x62,0xd1,0xe1,0x0a,0x24,0x72,0xf1,0x17,0x82,0x92,0x33,0x43,0x53,0xb2,0x0b,
+        0x0c,0x18,0x35,0xa2,0xc2,0x0d,0x0e,0x0f,0x10,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
+        0x20,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x34,0x36,0x37,
+        0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,
+        0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,
+        0x5e,0x5f,0x60,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
+        0x70,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,0x80,0x83,
+        0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,0x90,0x93,0x94,0x95,
+        0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,0xa0,0xa3,0xa4,0xa5,0xa6,0xa7,
+        0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,0xb0,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,
+        0xba,0xbb,0xbc,0xbd,0xbe,0xbf,0xc0,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,
+        0xcc,0xcd,0xce,0xcf,0xd0,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,
+        0xdd,0xde,0xdf,0xe0,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,
+        0xee,0xef,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
+    }
+};
+
+enum {
+    Marker			= 0xFF,
+    FF_Marker		= 0x00,
+
+    SOI_Marker		= 0xFFD8,			// Start of image
+    EOI_Marker		= 0xFFD9,			// End of image
+
+    JFIF_CODE		= 0xFFE0,			// Application
+    EXIF_CODE		= 0xFFE1,
+
+    DRI_Marker		= 0xFFDD,			// Define restart interval
+    RST_Marker		= 0xD,				// 0xD0 ~0xD7
+
+    DQT_Marker		= 0xFFDB,			// Define quantization table(s)
+    DHT_Marker		= 0xFFC4,			// Define Huffman table(s)
+
+    SOF_Marker		= 0xFFC0,			// Start of frame : Baseline DCT
+    SOS_Marker		= 0xFFDA,			// Start of scan
+    SOF_Marker_ES	= 0xFFC1,			// Start of frame : Extended Sequential
+};
+
+
+int check_start_code(JpgDecInfo *jpg)
+{
+    if (show_bits(&jpg->gbc, 8) == 0xFF)
+        return 1;
+    else
+        return 0;
+}
+
+
+int find_start_code(JpgDecInfo *jpg)
+{
+    int word;
+
+    for(;;)
+    {
+        if (get_bits_left(&jpg->gbc) <= 16)
+        {
+            ////printf("hit end of stream\n");
+            return 0;
+        }
+
+        word = show_bits(&jpg->gbc, 16);
+        if ((word > 0xFF00) && (word < 0xFFFF))
+            break;
+
+
+        get_bits(&jpg->gbc, 8);
+    }
+
+    return word;
+}
+
+int find_start_soi_code(JpgDecInfo *jpg)
+{
+    int word;
+
+    for(;;)
+    {
+        if (get_bits_left(&jpg->gbc) <= 16)
+        {
+            ////printf("hit end of stream\n");
+            return 0;
+        }
+
+        word = show_bits(&jpg->gbc, 16);
+        if ((word > 0xFF00) && (word < 0xFFFF))
+        {
+            if (word != SOI_Marker)
+                get_bits(&jpg->gbc, 8);
+            break;
+        }
+
+
+        get_bits(&jpg->gbc, 8);
+    }
+
+    return word;
+}
+
+
+
+int decode_app_header(JpgDecInfo *jpg)
+{
+    int length;
+
+    if (get_bits_left(&jpg->gbc) < 16)
+        return 0;
+    length = get_bits(&jpg->gbc, 16);
+    length -= 2;
+
+    while(length-- > 0)
+    {
+        if (get_bits_left(&jpg->gbc) < 8)
+            return 0;
+        get_bits(&jpg->gbc, 8);
+    }
+
+
+    return 1;
+}
+
+
+int decode_dri_header(JpgDecInfo *jpg)
+{
+    //Length, Lr
+    if (get_bits_left(&jpg->gbc) < 16*2)
+        return 0;
+    get_bits(&jpg->gbc, 16);
+
+    jpg->rstIntval = get_bits(&jpg->gbc, 16);
+
+
+    return 1;
+}
+
+int decode_dqt_header(JpgDecInfo *jpg)
+{
+    int Pq;
+    int Tq;
+    int i;
+    int tmp;
+    if (get_bits_left(&jpg->gbc) < 16)
+        return 0;
+
+    // Lq, Length of DQT
+    get_bits(&jpg->gbc, 16);
+
+    do {
+
+        if (get_bits_left(&jpg->gbc) < 4+4+8*64)
+            return 0;
+
+        // Pq, Quantization Precision
+        tmp = get_bits(&jpg->gbc, 8);
+        // Tq, Quantization table destination identifier
+        Pq = (tmp>>4) & 0xf;
+        Tq = tmp&0xf;
+
+        if (Tq == 0)
+            jpg->q_prec0 = Pq;
+        else if (Tq == 1)
+            jpg->q_prec1 = Pq;
+        else if (Tq == 2)
+            jpg->q_prec2 = Pq;
+        else if (Tq == 3)
+            jpg->q_prec3 = Pq;
+		else
+			return 0;
+
+        for (i=0; i<64; i++){
+            if (Pq)
+                jpg->qMatTab[Tq][i] = (short)get_bits(&jpg->gbc, 16) & 0xffff;
+            else
+                jpg->qMatTab[Tq][i] = (BYTE)get_bits(&jpg->gbc, 8) & 0x00ff;
+        }
+    } while(!check_start_code(jpg));
+
+    return 1;
+}
+
+int decode_dth_header(JpgDecInfo *jpg)
+{
+    int Tc;
+    int Th;
+    int ThTc;
+    int bitCnt;
+    int i;
+    int tmp;
+    // Length, Lh
+    if (get_bits_left(&jpg->gbc) < 16)
+        return 0;
+
+    get_bits(&jpg->gbc, 16);
+
+    do {
+
+        if (get_bits_left(&jpg->gbc) < 8 + 8*16)
+            return 0;
+
+        // Table class - DC, AC
+        tmp = get_bits(&jpg->gbc, 8);
+        // Table destination identifier
+        Tc = (tmp>>4) & 0xf;
+        Th = tmp&0xf;
+
+        // DC_ID0 (0x00) -> 0
+        // AC_ID0 (0x10) -> 1
+        // DC_ID1 (0x01) -> 2
+        // AC_ID1 (0x11) -> 3
+        // DC_EX1 (0x02) -> 4
+        // AC_EX1 (0x12) -> 5
+        // DC_EX2 (0x03) -> 6
+        // AC_EX2 (0x13) -> 7
+
+        //Since only DC_ID0, DC_ID1, if th is 2 or 3, always set userHuffTab
+        /* According to ITU-T.81 Table B.5, maximum Tc value is 1 and maximum Th value is 3.*/
+        if (Tc > 1 || Th > 3) {
+            return 0;
+        }
+
+        ThTc = ((Th&3)<<1) | (Tc&1);
+        if (jpg->numHuffmanTable >= THTC_LIST_CNT)
+            return 0;
+
+        jpg->thtc[jpg->numHuffmanTable++] = ThTc;
+        // Get Huff Bits list
+        bitCnt = 0;
+        for (i=0; i<16; i++) {
+            jpg->huffBits[ThTc][i] = (BYTE)get_bits(&jpg->gbc, 8);
+            bitCnt += jpg->huffBits[ThTc][i];
+        }
+
+		if (bitCnt > 256)
+			return 0;
+
+        if (get_bits_left(&jpg->gbc) <  8*bitCnt)
+            return 0;
+
+        // Get Huff Val list
+        for (i=0; i<bitCnt; i++) {
+            jpg->huffVal[ThTc][i] = (BYTE)get_bits(&jpg->gbc, 8);
+        }
+    } while(!check_start_code(jpg));
+
+
+    return 1;
+}
+int decode_sof_header(JpgDecInfo *jpg)
+{
+    int samplePrecision;
+    int sampleFactor;
+    int i;
+    int Tqi;
+    BYTE compID;
+    int hSampFact[3] = {0,};
+    int vSampFact[3] = {0,};
+    int picX, picY;
+    int numComp;
+    int tmp;
+
+    if (get_bits_left(&jpg->gbc) < 16+8+16+16+8)
+        return 0;
+    // LF, Length of SOF
+    get_bits(&jpg->gbc, 16);
+
+    // Sample Precision: Baseline(8), P
+    samplePrecision = get_bits(&jpg->gbc, 8);
+    jpg->bitDepth   = samplePrecision;
+    jpg->jpg12bit   = (samplePrecision == 12) ? 1 : 0;
+
+    picY = get_bits(&jpg->gbc, 16);
+    if (picY > MAX_MJPG_PIC_WIDTH)
+    {
+        //printf("Picture Vertical Size limits Maximum size\n");
+        return 0;
+    }
+
+    picX = get_bits(&jpg->gbc, 16);
+    if (picX > MAX_MJPG_PIC_HEIGHT)
+    {
+        //printf("Picture Horizontal Size limits Maximum size\n");
+        return 0;
+    }
+
+    //Number of Components in Frame: Nf
+    numComp = get_bits(&jpg->gbc, 8);
+    if (numComp > 3)
+    {
+        //printf("Picture Horizontal Size limits Maximum size\n");
+        return 0;
+    }
+
+    if (get_bits_left(&jpg->gbc) < numComp*(8+4+4+8))
+        return 0;
+    for (i=0; i<numComp; i++)
+    {
+        // Component ID, Ci 0 ~ 255
+        compID = (BYTE)get_bits(&jpg->gbc, 8);
+        tmp = get_bits(&jpg->gbc, 8);
+        // Horizontal Sampling Factor, Hi
+        hSampFact[i] = (tmp>>4) & 0xf;
+        // Vertical Sampling Factor, Vi
+        vSampFact[i] = tmp&0xf;
+        // Quantization Table Selector, Tqi
+        Tqi = get_bits(&jpg->gbc, 8);
+
+        jpg->cInfoTab[i][0] = compID;
+        jpg->cInfoTab[i][1] = (BYTE)hSampFact[i];
+        jpg->cInfoTab[i][2] = (BYTE)vSampFact[i];
+        jpg->cInfoTab[i][3] = (BYTE)Tqi;
+    }
+
+    //if ( hSampFact[0]>2 || vSampFact[0]>2 || ( numComp == 3 && ( hSampFact[1]!=1 || hSampFact[2]!=1 || vSampFact[1]!=1 || vSampFact[2]!=1) ) )
+    //printf("Not Supported Sampling Factor\n");
+
+    if (numComp == 1)
+        sampleFactor = SAMPLE_400;
+    else
+        sampleFactor = ((hSampFact[0]&3)<<2) | (vSampFact[0]&3);
+
+    switch(sampleFactor) {
+    case SAMPLE_420:
+        jpg->format = FORMAT_420;
+        break;
+    case SAMPLE_H422:
+        jpg->format = FORMAT_422;
+        break;
+    case SAMPLE_V422:
+        jpg->format = FORMAT_440;
+        break;
+    case SAMPLE_444:
+        jpg->format = FORMAT_444;
+        break;
+    default:	// 4:0:0
+        jpg->format = FORMAT_400;
+        break;
+    }
+
+    jpg->picWidth = picX;
+    jpg->picHeight = picY;
+
+    return 1;
+}
+
+int decode_sos_header(JpgDecInfo *jpg)
+{
+    int i, j;
+    int len;
+    int numComp;
+    int compID;
+    int ecsPtr;
+    int ss, se, ah, al;
+    int dcHufTblIdx[3] = {0,};
+    int acHufTblIdx[3] = {0,};
+    int tmp;
+
+    if (get_bits_left(&jpg->gbc) < 8)
+        return 0;
+    // Length, Ls
+    len = get_bits(&jpg->gbc, 16);
+
+    jpg->ecsPtr = get_bits_count(&jpg->gbc)/8 + len - 2 ;
+
+    ecsPtr = jpg->ecsPtr+jpg->frameOffset;
+
+    //printf("ecsPtr=0x%x frameOffset=0x%x, ecsOffset=0x%x, wrPtr=0x%x, rdPtr0x%x\n", jpg->ecsPtr, jpg->frameOffset, ecsPtr, jpg->streamWrPtr, jpg->streamRdPtr);
+
+    jpg->pagePtr = ecsPtr >> 8;									 //page unit  ecsPtr/256;
+    jpg->wordPtr = (ecsPtr & 0xF0) >> 2;	                     // word unit ((ecsPtr % 256) & 0xF0) / 4;
+
+    if (jpg->pagePtr & 1)
+        jpg->wordPtr += 64;
+    if (jpg->wordPtr & 1)
+        jpg->wordPtr -= 1; // to make even.
+
+    jpg->bitPtr = (ecsPtr & 0xF) << 3;	                        // bit unit (ecsPtr & 0xF) * 8;
+
+    if (get_bits_left(&jpg->gbc) < 8)
+        return 0;
+    //Number of Components in Scan: Ns
+    numComp = get_bits(&jpg->gbc, 8);
+	if (numComp > 3)
+		return 0;
+
+    if (get_bits_left(&jpg->gbc) < numComp*(8+4+4))
+        return 0;
+    for (i=0; i<numComp; i++) {
+        // Component ID, Csj 0 ~ 255
+        compID = get_bits(&jpg->gbc, 8);
+        tmp = get_bits(&jpg->gbc, 8);
+        // dc entropy coding table selector, Tdj
+        dcHufTblIdx[i] = (tmp>>4) & 0xf;
+        // ac entropy coding table selector, Taj
+        acHufTblIdx[i] = tmp&0xf;
+
+
+        for (j=0; j<numComp; j++)
+        {
+            if (compID == jpg->cInfoTab[j][0])
+            {
+                jpg->cInfoTab[j][4] = (BYTE)dcHufTblIdx[i];
+                jpg->cInfoTab[j][5] = (BYTE)acHufTblIdx[i];
+            }
+        }
+    }
+
+    if (get_bits_left(&jpg->gbc) < 8+8+4+4)
+        return 0;
+    // Ss 0
+    ss = get_bits(&jpg->gbc, 8);
+    // Se 3F
+    se = get_bits(&jpg->gbc, 8);
+    tmp = get_bits(&jpg->gbc, 8);
+    // Ah 0
+    ah = (i>>4) & 0xf;
+    // Al 0
+    al = tmp&0xf;
+
+    if ((ss != 0) || (se != 0x3F) || (ah != 0) || (al != 0))
+    {
+        //printf("The Jpeg Image must be another profile\n");
+        return 0;
+    }
+
+    return 1;
+}
+
+static void genDecHuffTab(JpgDecInfo *jpg, int tabNum)
+{
+    unsigned char *huffPtr, *huffBits;
+    Uint32 *huffMax, *huffMin;
+
+    int ptrCnt =0;
+    int huffCode = 0;
+    int zeroFlag = 0;
+    int dataFlag = 0;
+    int i;
+
+    huffBits	= jpg->huffBits[tabNum];
+    huffPtr		= jpg->huffPtr[tabNum];
+    huffMax		= jpg->huffMax[tabNum];
+    huffMin		= jpg->huffMin[tabNum];
+
+    for (i=0; i<16; i++)
+    {
+        if (huffBits[i]) // if there is bit cnt value
+        {
+            huffPtr[i] = (BYTE)ptrCnt;
+            ptrCnt += huffBits[i];
+            huffMin[i] = huffCode;
+            huffMax[i] = huffCode + (huffBits[i] - 1);
+            dataFlag = 1;
+            zeroFlag = 0;
+        }
+        else
+        {
+            huffPtr[i] = 0xFF;
+            huffMin[i] = 0xFFFF;
+            huffMax[i] = 0xFFFF;
+            zeroFlag = 1;
+        }
+
+        if (dataFlag == 1)
+        {
+            if (zeroFlag == 1)
+                huffCode <<= 1;
+            else
+                huffCode = (huffMax[i] + 1) << 1;
+        }
+    }
+
+}
+
+
+
+
+
+int JpuGbuInit(vpu_getbit_context_t *ctx, BYTE *buffer, int size)
+{
+
+    ctx->buffer = buffer;
+    ctx->index = 0;
+    ctx->size = size/8;
+
+    return 1;
+}
+
+int JpuGbuGetUsedBitCount(vpu_getbit_context_t *ctx)
+{
+    return ctx->index*8;
+}
+
+int JpuGbuGetLeftBitCount(vpu_getbit_context_t *ctx)
+{
+    return (ctx->size*8) - JpuGbuGetUsedBitCount(ctx);
+}
+
+unsigned int JpuGbuGetBit(vpu_getbit_context_t *ctx, int bit_num)
+{
+    BYTE *p;
+    unsigned int b = 0x0;
+
+    if (bit_num > JpuGbuGetLeftBitCount(ctx))
+        return (unsigned int)-1;
+
+    p = ctx->buffer + ctx->index;
+
+    if (bit_num == 8)
+    {
+        b = *p;
+        ctx->index++;
+    }
+    else if(bit_num == 16)
+    {
+        b = *p++<<8;
+        b |= *p++;
+        ctx->index += 2;
+    }
+    else if(bit_num == 32)
+    {
+        b = *p++<<24;
+        b |= (*p++<<16);
+        b |= (*p++<<8);
+        b |= (*p++<<0);
+        ctx->index += 4;
+    }
+
+
+    return b;
+}
+
+unsigned int JpuGguShowBit(vpu_getbit_context_t *ctx, int bit_num)
+{
+    BYTE *p;
+    unsigned int b = 0x0;
+
+    if (bit_num > JpuGbuGetLeftBitCount(ctx))
+        return (unsigned int)-1;
+
+    p = ctx->buffer + ctx->index;
+
+    if (bit_num == 8)
+    {
+        b = *p;
+    }
+    else if(bit_num == 16)
+    {
+        b = *p++<<8;
+        b |= *p++;
+    }
+    else if(bit_num == 32)
+    {
+        b = *p++<<24;
+        b |= (*p++<<16);
+        b |= (*p++<<8);
+        b |= (*p++<<0);
+    }
+
+    return b;
+}
+
+
+
+static int wraparound_bistream_data(JpgDecInfo *jpg, int return_type)
+{
+    BYTE *dst;
+    BYTE *src;
+    BYTE *data;
+    int data_size;
+    int src_size;
+    int dst_size;
+
+    data_size = jpg->streamWrPtr - jpg->streamBufStartAddr;
+    data = (BYTE *)malloc(data_size);
+
+    if (data)
+        JpuReadMem(jpg->streamBufStartAddr, data, data_size, jpg->streamEndian);
+
+    src_size = jpg->streamBufSize - jpg->frameOffset;
+    src = (BYTE *)malloc(src_size);
+    dst_size = ((src_size+(JPU_GBU_SIZE-1))&~(JPU_GBU_SIZE-1));
+    dst = (BYTE *)malloc(dst_size);
+    if (dst && src)
+    {
+        memset(dst, 0x00, dst_size);
+        JpuReadMem(jpg->streamBufStartAddr+jpg->frameOffset, src, src_size, jpg->streamEndian);
+        memcpy(dst+(dst_size-src_size), src, src_size);
+        JpuWriteMem(jpg->streamBufStartAddr, dst, dst_size, jpg->streamEndian);
+        if (data)
+            JpuWriteMem(jpg->streamBufStartAddr+dst_size, data, data_size, jpg->streamEndian);
+    }
+
+    if(src)
+        free(src);
+    if(dst)
+        free(dst);
+    if (data)
+        free(data);
+
+    if (return_type == -2) {// header wraparound
+        jpg->streamWrPtr = jpg->streamBufStartAddr+dst_size+data_size;
+        jpg->consumeByte = 0;
+        return -2;
+    }
+    else if(return_type == -1){	// ecsPtr wraparound
+        jpg->streamWrPtr = jpg->streamBufStartAddr+dst_size+data_size;
+        jpg->frameOffset = 0;
+        return -1;
+    }
+
+    return 0;
+}
+
+
+static void CheckUserHuffmanTable(JpgDecInfo* jpg)
+{
+    Uint32 ThTc, i, bitCnt;
+
+    for (ThTc=0; ThTc<THTC_LIST_CNT; ThTc++) {
+        if (jpg->thtc[ThTc] == -1) break;
+        bitCnt = 0;
+        for (i=0; i<16; i++) {
+            bitCnt += jpg->huffBits[ThTc][i];
+            if (jpg->jpg12bit) {
+                jpg->userHuffTab = (cDefHuffBits_ES[ThTc][i] != jpg->huffBits[ThTc][i]);
+            }
+            else {
+                jpg->userHuffTab = (cDefHuffBits[ThTc][i] != jpg->huffBits[ThTc][i]);
+            }
+            if (jpg->userHuffTab == TRUE) return;
+        }
+
+		if (bitCnt > 256)
+			return;
+
+        // Get Huff Val list
+        for (i=0; i<bitCnt; i++) {
+            if (jpg->jpg12bit) {
+                jpg->userHuffTab = (cDefHuffVal_ES[ThTc][i] != jpg->huffVal[ThTc][i]);
+            }
+            else {
+                jpg->userHuffTab = (cDefHuffVal[ThTc][i] != jpg->huffVal[ThTc][i]);
+            }
+            if (jpg->userHuffTab == TRUE) return;
+        }
+    }
+}
+
+int JpegDecodeHeader(JpgDecInfo *jpg)
+{
+    unsigned int code;
+    int ret;
+    int i;
+    int temp;
+    int wrOffset;
+    BYTE *b = jpg->pBitStream+jpg->frameOffset;
+    int size;
+    BOOL yuv400_4Blocks = TRUE;   /* process 4block at a time for improving performance */
+
+    for (i=0; i<THTC_LIST_CNT; i++) {
+        jpg->thtc[i] = -1;
+    }
+    jpg->numHuffmanTable = 0;
+
+    ret = 1;
+    if (jpg->streamWrPtr == jpg->streamBufStartAddr)
+    {
+        size = jpg->streamBufSize-jpg->frameOffset;
+        wrOffset = jpg->streamBufSize;
+    }
+    else
+    {
+        if (jpg->frameOffset >= (int)(jpg->streamWrPtr-jpg->streamBufStartAddr))
+            size = jpg->streamBufSize - jpg->frameOffset;
+        else
+            size = (jpg->streamWrPtr-jpg->streamBufStartAddr)-jpg->frameOffset;
+        wrOffset = (jpg->streamWrPtr-jpg->streamBufStartAddr);
+    }
+
+    if (!b || !size) {
+        ret = -1;
+        goto DONE_DEC_HEADER;
+    }
+
+    // find start code of next frame
+    if (!jpg->ecsPtr)
+    {
+        int nextOffset = 0;
+        int soiOffset = 0;
+
+        if (jpg->consumeByte != 0)	// meaning is frameIdx > 0
+        {
+            nextOffset = jpg->consumeByte;
+            if (nextOffset <= 0)
+                nextOffset = 2;	//in order to consume start code.
+        }
+
+        //consume to find the start code of next frame.
+        b += nextOffset;
+        size -= nextOffset;
+
+        if (size < 0)
+        {
+            jpg->consumeByte -= (b - (jpg->pBitStream+jpg->streamBufSize));
+            if (jpg->consumeByte < 0) {
+                ret = 0;
+                goto DONE_DEC_HEADER;
+            }
+            ret = -1;
+            goto DONE_DEC_HEADER;
+        }
+
+        init_get_bits(&jpg->gbc, b, size*8);
+        for (;;)
+        {
+            code = find_start_soi_code(jpg);
+            if (code == 0)
+            {
+                ret = -1;
+                goto DONE_DEC_HEADER;
+            }
+
+            if (code == SOI_Marker)
+                break;
+
+        }
+
+        soiOffset = get_bits_count(&jpg->gbc)/8;
+
+        b += soiOffset;
+        size -= soiOffset;
+        jpg->frameOffset += (soiOffset+ nextOffset);
+    }
+
+    if (jpg->headerSize > 0 && (jpg->headerSize > (jpg->streamBufSize - jpg->frameOffset - JPU_GBU_SIZE))) { // if header size is smaller than room of stream end. copy the buffer to bistream start.
+        return wraparound_bistream_data(jpg, -2);
+    }
+
+
+    init_get_bits(&jpg->gbc, b, size*8);
+    // Initialize component information table
+    for (i=0; i<4; i++)
+    {
+        jpg->cInfoTab[i][0] = 0;
+        jpg->cInfoTab[i][1] = 0;
+        jpg->cInfoTab[i][2] = 0;
+        jpg->cInfoTab[i][3] = 0;
+        jpg->cInfoTab[i][4] = 0;
+        jpg->cInfoTab[i][5] = 0;
+    }
+
+    for (;;)
+    {
+        if (find_start_code(jpg) == 0)
+        {
+            ret = -1;
+            goto DONE_DEC_HEADER;
+        }
+
+        code = get_bits(&jpg->gbc, 16); //getbit 2byte
+        switch (code) {
+        case SOI_Marker:
+            break;
+        case JFIF_CODE:
+        case EXIF_CODE:
+            if (!decode_app_header(jpg))
+            {
+                ret = -1;
+                goto DONE_DEC_HEADER;
+            }
+            break;
+        case DRI_Marker:
+            if (!decode_dri_header(jpg))
+            {
+                ret = -1;
+                goto DONE_DEC_HEADER;
+            }
+            break;
+        case DQT_Marker:
+            if (!decode_dqt_header(jpg))
+            {
+                ret = -1;
+                goto DONE_DEC_HEADER;
+            }
+            break;
+        case DHT_Marker:
+            if (!decode_dth_header(jpg))
+            {
+                ret = -1;
+                goto DONE_DEC_HEADER;
+            }
+            break;
+        case SOF_Marker:
+        case SOF_Marker_ES:
+            if (!decode_sof_header(jpg))
+            {
+                ret = -1;
+                goto DONE_DEC_HEADER;
+            }
+            break;
+        case SOS_Marker:
+            if (!decode_sos_header(jpg))
+            {
+                ret = -1;
+                goto DONE_DEC_HEADER;
+            }
+            if (!jpg->headerSize)
+                jpg->headerSize = jpg->ecsPtr;	// we assume header size of all frame is same for mjpeg case
+            goto DONE_DEC_HEADER;
+        case EOI_Marker:
+            goto DONE_DEC_HEADER;
+        default:
+            switch (code&0xFFF0)
+            {
+            case 0xFFE0:	// 0xFFEX
+            case 0xFFF0:	// 0xFFFX
+                if (get_bits_left(&jpg->gbc) <=0 ) {
+                    {
+                        ret = -1;
+                        goto DONE_DEC_HEADER;
+                    }
+                }
+                else
+                {
+                    if (!decode_app_header(jpg))
+                    {
+                        ret = -1;
+                        goto DONE_DEC_HEADER;
+                    }
+                    break;
+                }
+            default:
+                //in case,  restart marker is founded.
+                if( (code&0xFFF0) >= 0xFFD0 && (code&0xFFF0) <= 0xFFD7)
+                    break;
+                else
+                    //printf("code = [%x]\n", code);
+                    return	0;
+            }
+            break;
+        }
+    }
+
+DONE_DEC_HEADER:
+
+    if (ret == -1)
+    {
+        if (wrOffset < jpg->frameOffset)
+            return -2;
+
+        if (0 == get_bits_left(&jpg->gbc)) {
+            return -2;
+        }
+
+        return -1;
+    }
+
+    if (!jpg->ecsPtr)
+        return 0;
+
+    if (wrOffset - (jpg->frameOffset+jpg->ecsPtr)  < JPU_GBU_SIZE &&
+        jpg->streamEndflag == 0) {
+            return -1;
+    }
+
+    // this bellow is workaround to avoid the case that JPU is run over without interrupt.
+    if (jpg->streamBufSize - (jpg->frameOffset+jpg->ecsPtr) < JPU_GBU_SIZE)
+        return wraparound_bistream_data(jpg, -1);
+
+    CheckUserHuffmanTable(jpg);
+
+    // Generate Huffman table information
+    if (jpg->jpg12bit){
+        for(i=0; i<8; i++)
+            genDecHuffTab(jpg, i);
+    }else{
+        for(i=0; i<4; i++)
+            genDecHuffTab(jpg, i);
+    }
+
+    // Q Idx
+    temp =             jpg->cInfoTab[0][3];
+    temp = temp << 1 | jpg->cInfoTab[1][3];
+    temp = temp << 1 | jpg->cInfoTab[2][3];
+    jpg->Qidx = temp;
+
+
+    // Huff Idx[DC, AC]
+    temp =             jpg->cInfoTab[0][4];
+
+    if (jpg->jpg12bit == 0){
+        temp = temp << 1 | jpg->cInfoTab[1][4];
+        temp = temp << 1 | jpg->cInfoTab[2][4];
+    }else{
+        temp = temp << 2 | jpg->cInfoTab[1][4];
+        temp = temp << 2 | jpg->cInfoTab[2][4];
+    }
+    jpg->huffDcIdx = temp;
+
+    temp =             jpg->cInfoTab[0][5];
+    if (jpg->jpg12bit == 0){
+        temp = temp << 1 | jpg->cInfoTab[1][5];
+        temp = temp << 1 | jpg->cInfoTab[2][5];
+    }else{
+        temp = temp << 2 | jpg->cInfoTab[1][5];
+        temp = temp << 2 | jpg->cInfoTab[2][5];
+    }
+    jpg->huffAcIdx = temp;
+
+
+    switch(jpg->format)
+    {
+    case FORMAT_420:
+        jpg->mcuBlockNum = 6;
+        jpg->compNum = 3;
+        jpg->compInfo[1] = 5;
+        jpg->compInfo[2] = 5;
+        jpg->alignedWidth = ((jpg->picWidth+15)&~15);
+        jpg->alignedHeight = ((jpg->picHeight+15)&~15);
+        jpg->mcuWidth  = 16;
+        jpg->mcuHeight = 16;
+        break;
+    case FORMAT_422:
+        jpg->mcuBlockNum = 4;
+        jpg->compNum = 3;
+        jpg->compInfo[1] = 5;
+        jpg->compInfo[2] = 5;
+        jpg->alignedWidth = ((jpg->picWidth+15)&~15);
+        jpg->alignedHeight = ((jpg->picHeight+7)&~7);
+        jpg->mcuWidth  = 16;
+        jpg->mcuHeight = 8;
+        break;
+    case FORMAT_440:
+        jpg->mcuBlockNum = 4;
+        jpg->compNum = 3;
+        jpg->compInfo[1] = 5;
+        jpg->compInfo[2] = 5;
+        jpg->alignedWidth = ((jpg->picWidth+7)&~7);
+        jpg->alignedHeight = ((jpg->picHeight+15)&~15);
+        jpg->mcuWidth  = 8;
+        jpg->mcuHeight = 16;
+        break;
+    case FORMAT_444:
+        jpg->mcuBlockNum = 3;
+        jpg->compNum = 3;
+        jpg->compInfo[1] = 5;
+        jpg->compInfo[2] = 5;
+        jpg->alignedWidth = ((jpg->picWidth+7)&~7);
+        jpg->alignedHeight = ((jpg->picHeight+7)&~7);
+        jpg->mcuWidth  = 8;
+        jpg->mcuHeight = 8;
+        break;
+    case FORMAT_400:
+        jpg->compNum = 1;
+        jpg->compInfo[1] = 0;
+        jpg->compInfo[2] = 0;
+        jpg->alignedWidth = ((jpg->picWidth+7)&~7);
+        jpg->alignedHeight = ((jpg->picHeight+7)&~7);
+        if (jpg->roiEnable == TRUE) {
+            Uint32 offsetX = JPU_FLOOR(8, jpg->roiOffsetX);
+            yuv400_4Blocks = (BOOL)((offsetX%32) == 0);
+        }
+        if (yuv400_4Blocks == TRUE) {
+            jpg->mcuBlockNum = 4;
+            jpg->mcuWidth    = 32;
+            jpg->mcuHeight   = 8;
+        }
+        else {
+            jpg->mcuBlockNum = 1;
+            jpg->mcuWidth    = 8;
+            jpg->mcuHeight   = 8;
+        }
+        break;
+    default:
+        return 0;
+    }
+    jpg->compInfo[0] = (jpg->mcuWidth >> 3) << 3 | (jpg->mcuHeight >> 3);
+
+    jpg->busReqNum = (jpg->jpg12bit == FALSE) ? GetDec8bitBusReqNum(jpg->format, jpg->packedFormat) :
+                                                GetDec12bitBusReqNum(jpg->format, jpg->packedFormat);
+
+    return 1;
+}
+
+JpgRet CheckJpgEncOpenParam(JpgEncOpenParam * pop, JPUCap* cap)
+{
+    int picWidth;
+    int picHeight;
+
+    if (pop == 0) {
+        return JPG_RET_INVALID_PARAM;
+    }
+
+    picWidth = pop->picWidth;
+    picHeight = pop->picHeight;
+
+    if (pop->bitstreamBuffer % 8) {
+        return JPG_RET_INVALID_PARAM;
+    }
+    if ((pop->bitstreamBufferSize - (4096)) < 4096) {
+        return JPG_RET_INVALID_PARAM;
+    }
+
+    if ((pop->bitstreamBufferSize - (4096)) % 4096) {
+        return JPG_RET_INVALID_PARAM;
+    }
+
+    if (picWidth < 16 || picWidth > MAX_MJPG_PIC_WIDTH ) {
+        return JPG_RET_INVALID_PARAM;
+    }
+    if (picHeight < 16 || picHeight > MAX_MJPG_PIC_HEIGHT ) {
+        return JPG_RET_INVALID_PARAM;
+    }
+    if (pop->intrEnableBit == 0) {
+        return JPG_RET_INVALID_PARAM;
+    }
+
+    if (pop->jpg12bit == TRUE && cap->support12bit == FALSE) {
+        return JPG_RET_NOT_SUPPORT;
+    }
+
+    return JPG_RET_SUCCESS;
+}
+
+
+JpgRet CheckJpgEncParam(JpgEncHandle handle, JpgEncParam * param)
+{
+    JpgInst *pJpgInst;
+    JpgEncInfo *pEncInfo;
+
+    pJpgInst = handle;
+    pEncInfo = &pJpgInst->JpgInfo->encInfo;
+
+    if (param == 0) {
+        return JPG_RET_INVALID_PARAM;
+    }
+
+    if (pEncInfo->packedFormat != PACKED_FORMAT_NONE) {
+        if (pEncInfo->packedFormat == PACKED_FORMAT_444) {
+            if (param->sourceFrame->stride < pEncInfo->picWidth*2) {
+                return JPG_RET_INVALID_PARAM;
+            }
+        }
+        if (pEncInfo->packedFormat == PACKED_FORMAT_444) {
+            if (param->sourceFrame->stride < pEncInfo->picWidth*3) {
+                return JPG_RET_INVALID_PARAM;
+            }
+        }
+    }
+
+    return JPG_RET_SUCCESS;
+}
+
+
+
+int JpgEncGenHuffTab(JpgEncInfo * pEncInfo, int tabNum)
+{
+    int p, i, l, lastp, si, maxsymbol;
+
+    int huffsize[256] = {0,};
+    int huffcode[256] = {0,};
+    int code;
+
+    BYTE *bitleng, *huffval;
+    Uint32 *ehufco, *ehufsi;
+
+    if (tabNum > 3)
+        return 0;
+
+    bitleng	= pEncInfo->pHuffBits[tabNum];
+    huffval	= pEncInfo->pHuffVal[tabNum];
+    ehufco	= pEncInfo->huffCode[tabNum];
+    ehufsi	= pEncInfo->huffSize[tabNum];
+
+    maxsymbol = tabNum & 1 ? 256 : 16;
+
+    /* Figure C.1: make table of Huffman code length for each symbol */
+
+    p = 0;
+    for (l=1; l<=16; l++) {
+        i = bitleng[l-1];
+        if (i < 0 || p + i > maxsymbol)
+            return 0;
+        while (i--)
+            huffsize[p++] = l;
+    }
+    lastp = p;
+
+    /* Figure C.2: generate the codes themselves */
+    /* We also validate that the counts represent a legal Huffman code tree. */
+
+    code = 0;
+    si = huffsize[0];
+    p = 0;
+    while(p < lastp){
+        while (huffsize[p] == si) {
+            huffcode[p++] = code;
+            code++;
+        }
+        if (code >= (1 << si))
+            return 0;
+        code <<= 1;
+        si++;
+    }
+
+    memset(ehufsi, 0, sizeof(int) * 256);
+    memset(ehufco, 0, sizeof(int) * 256);
+
+    /* Figure C.3: generate encoding tables */
+    /* These are code and size indexed by symbol value */
+
+    for(i=0; i<256; i++)
+        ehufsi[i] = 0x00;
+
+    for(i=0; i<256; i++)
+        ehufco[i] = 0x00;
+
+    for (p=0; p<lastp; p++) {
+        i = huffval[p];
+        if (i < 0 || i >= maxsymbol || ehufsi[i])
+            return 0;
+        ehufco[i] = huffcode[p];
+        ehufsi[i] = huffsize[p];
+    }
+
+    return 1;
+}
+
+int JpgEncLoadHuffTab(JpgInst *pJpgInst, int instRegIndex)
+{
+    int i, j, t;
+    int huffData;
+    JpgEncInfo * pEncInfo;
+
+    pEncInfo = &pJpgInst->JpgInfo->encInfo;
+
+
+    for (i=0; i<4; i++)
+        JpgEncGenHuffTab(pEncInfo, i);
+
+    JpuWriteInstReg(instRegIndex, MJPEG_HUFF_CTRL_REG, 0x3);
+
+    for (j=0; j<4; j++)
+    {
+
+        t = (j==0) ? AC_TABLE_INDEX0 : (j==1) ? AC_TABLE_INDEX1 : (j==2) ? DC_TABLE_INDEX0 : DC_TABLE_INDEX1;
+
+        for (i=0; i<256; i++)
+        {
+            if ((t==DC_TABLE_INDEX0 || t==DC_TABLE_INDEX1) && (i>15))	// DC
+                break;
+
+            if ((pEncInfo->huffSize[t][i] == 0) && (pEncInfo->huffCode[t][i] == 0))
+                huffData = 0;
+            else
+            {
+                huffData =                    (pEncInfo->huffSize[t][i] - 1);	// Code length (1 ~ 16), 4-bit
+                huffData = (huffData << 16) | (pEncInfo->huffCode[t][i]    );	// Code word, 16-bit
+            }
+            JpuWriteInstReg(instRegIndex, MJPEG_HUFF_DATA_REG, huffData);
+        }
+    }
+    JpuWriteInstReg(instRegIndex, MJPEG_HUFF_CTRL_REG, 0x0);
+    return 1;
+}
+
+int JpgEncLoadHuffTab_12b(JpgInst *pJpgInst, int instRegIndex)
+{
+    int i, j, t;
+    int huffData;
+    JpgEncInfo * pEncInfo;
+
+    pEncInfo = &pJpgInst->JpgInfo->encInfo;
+
+    for (i=0; i<8; i++)
+        JpgEncGenHuffTab(pEncInfo, i);
+
+    JpuWriteInstReg(instRegIndex, MJPEG_HUFF_CTRL_REG, 0x3);
+
+    for (j=0; j<8; j++)
+    {
+
+        t = (j==0) ? AC_TABLE_INDEX0 : (j==1) ? AC_TABLE_INDEX1 : (j==2) ? DC_TABLE_INDEX0 : (j==3)? DC_TABLE_INDEX1 : (j==4) ? AC_TABLE_INDEX2 : (j==5) ? AC_TABLE_INDEX3 : (j==6) ? DC_TABLE_INDEX2 : DC_TABLE_INDEX3;
+
+        for (i=0; i<256; i++)
+        {
+            //only support 3 huffman tables
+            if (t==DC_TABLE_INDEX3 || t==AC_TABLE_INDEX3)
+                break;
+
+            if ((t==DC_TABLE_INDEX0 || t==DC_TABLE_INDEX1 || t==DC_TABLE_INDEX2 || t==DC_TABLE_INDEX3) && (i>15))	// DC
+                break;
+
+            if ((pEncInfo->huffSize[t][i] == 0) && (pEncInfo->huffCode[t][i] == 0))
+                huffData = 0;
+            else
+            {
+                huffData =                    (pEncInfo->huffSize[t][i] - 1);	// Code length (1 ~ 16), 4-bit
+                huffData = (huffData << 16) | (pEncInfo->huffCode[t][i]    );	// Code word, 16-bit
+            }
+            JpuWriteInstReg(instRegIndex, MJPEG_HUFF_DATA_REG, huffData);
+        }
+    }
+    JpuWriteInstReg(instRegIndex, MJPEG_HUFF_CTRL_REG, 0x0);
+    return 1;
+}
+
+int JpgEncLoadQMatTab(JpgInst *pJpgInst, int instRegIndex)
+{
+
+#ifdef WIN32
+    __int64 dividend = 0x80000;
+    __int64 quotient;
+    __int64 dividend_32b = 0x80000000;
+#else
+    long long int dividend = 0x80000;
+    long long int quotient;
+    long long int dividend_32b = 0x80000000;
+#endif
+    int quantID;
+    int divisor;
+    int comp;
+    int i, t;
+    int qprec = 0;
+    JpgEncInfo * pEncInfo;
+
+    pEncInfo = &pJpgInst->JpgInfo->encInfo;
+
+    for (comp=0; comp<3; comp++) {
+        quantID = pEncInfo->pCInfoTab[comp][3];
+        if (quantID >= 4)
+            return 0;
+        t = (comp==0)? Q_COMPONENT0 :
+            (comp==1)? Q_COMPONENT1 : Q_COMPONENT2;
+        JpuWriteInstReg(instRegIndex, MJPEG_QMAT_CTRL_REG, 0x3 + t);
+
+        if (pEncInfo->jpg12bit != 0){
+            if (comp == 0)
+                qprec = pEncInfo->q_prec0;
+            else
+                qprec = pEncInfo->q_prec1;
+        }
+
+        for (i=0; i<64; i++) {
+            divisor = pEncInfo->pQMatTab[quantID][i];
+            if (qprec)
+                quotient= dividend_32b / divisor;
+            else
+                quotient= dividend / divisor;
+            // enhace bit precision & rounding Q
+            if (qprec){
+                JpuWriteInstReg(instRegIndex, MJPEG_QMAT_DATA_REG, (int)(divisor & 0xFFFF));
+                JpuWriteInstReg(instRegIndex, MJPEG_QMAT_DATA_REG, (int)(quotient & 0xFFFFFFFF));
+            }else
+                JpuWriteInstReg(instRegIndex, MJPEG_QMAT_DATA_REG, (int)(divisor<<20)|(int)(quotient & 0xFFFFF));
+
+        }
+        JpuWriteInstReg(instRegIndex, MJPEG_QMAT_CTRL_REG, t);
+    }
+
+
+    return 1;
+}
+
+
+#define PUT_BYTE(_p, _b) \
+    if (tot++ > len) return 0; \
+    *_p++ = (unsigned char)(_b);
+
+
+int JpgEncEncodeHeader(JpgEncHandle handle, JpgEncParamSet * para)
+{
+    JpgInst *pJpgInst;
+    JpgEncInfo *pEncInfo;
+    BYTE *p;
+    int tot, len, pad;
+    BYTE *pCInfoTab[4];
+    int frameFormat;
+    Int32 i;
+    Uint32  width, height;
+
+    tot = 0;
+    pJpgInst = handle;
+    pEncInfo = &pJpgInst->JpgInfo->encInfo;
+
+    p = para->pParaSet;
+    len = para->size;
+
+    // SOI Header
+    PUT_BYTE(p, 0xff);
+    PUT_BYTE(p, 0xD8);
+
+
+    if (!para->disableAPPMarker)
+    {
+        // APP9 Header
+        PUT_BYTE(p, 0xFF);
+        PUT_BYTE(p, 0xE9);
+
+        PUT_BYTE(p, 0x00);
+        PUT_BYTE(p, 0x04);
+
+        PUT_BYTE(p, (pEncInfo->frameIdx >> 8));
+        PUT_BYTE(p, (pEncInfo->frameIdx & 0xFF));
+    }
+
+
+    // DRI header
+    if (pEncInfo->rstIntval) {
+
+        PUT_BYTE(p, 0xFF);
+        PUT_BYTE(p, 0xDD);
+
+        PUT_BYTE(p, 0x00);
+        PUT_BYTE(p, 0x04);
+
+        PUT_BYTE(p, (pEncInfo->rstIntval >> 8));
+        PUT_BYTE(p, (pEncInfo->rstIntval & 0xff));
+
+    }
+
+    // DQT Header
+    PUT_BYTE(p, 0xFF);
+    PUT_BYTE(p, 0xDB);
+
+    if (para->quantMode == JPG_TBL_NORMAL)
+    {
+        PUT_BYTE(p, 0x00);
+        if (pEncInfo->q_prec0 == TRUE) {
+            PUT_BYTE(p, 0x83);
+        }
+        else {
+            PUT_BYTE(p, 0x43);
+        }
+
+        if (pEncInfo->q_prec0 == TRUE) {
+            PUT_BYTE(p, 0x10);	// Pq
+        }
+        else {
+            PUT_BYTE(p, 0x00);	// Pq
+        }
+
+        for (i=0; i<64; i++) {
+            if (pEncInfo->q_prec0 == TRUE) {
+                Uint16 q = pEncInfo->pQMatTab[0][i];
+                PUT_BYTE(p, (q>>8)&0xff);
+                PUT_BYTE(p, q&0xff);
+            }
+            else {
+                PUT_BYTE(p, pEncInfo->pQMatTab[0][i]);
+            }
+        }
+
+        if (pEncInfo->format != FORMAT_400) {
+            PUT_BYTE(p, 0xFF);
+            PUT_BYTE(p, 0xDB);
+
+            PUT_BYTE(p, 0x00);
+            if (pEncInfo->q_prec1 == TRUE) {
+                PUT_BYTE(p, 0x83);
+            }
+            else {
+                PUT_BYTE(p, 0x43);
+            }
+            if (pEncInfo->q_prec1 == TRUE) {
+                PUT_BYTE(p, 0x11);	// Pq
+            }
+            else {
+                PUT_BYTE(p, 0x01);	// Pq
+            }
+
+            for (i=0; i<64; i++) {
+                if (pEncInfo->q_prec1 == TRUE) {
+                    Uint16 q = pEncInfo->pQMatTab[1][i];
+                    PUT_BYTE(p, (q>>8)&0xff);
+                    PUT_BYTE(p, q&0xff);
+                }
+                else {
+                    PUT_BYTE(p, pEncInfo->pQMatTab[1][i]);
+                }
+            }
+        }
+    }
+    else// if (para->quantMode == JPG_TBL_MERGE)
+    {
+
+        if (pEncInfo->format != FORMAT_400)
+        {
+            Uint16 qLength = 0x84;
+            if (pEncInfo->q_prec0 == TRUE) {
+                qLength += 64;
+            }
+            if (pEncInfo->q_prec1 == TRUE) {
+                qLength += 64;
+            }
+            PUT_BYTE(p, (qLength>>8)&0xff);
+            PUT_BYTE(p, qLength&0xff);
+        }
+        else
+        {
+            Uint16 qLength = 0x43;
+            if (pEncInfo->q_prec0 == TRUE) {
+                qLength += 64;
+            }
+            PUT_BYTE(p, (qLength>>8)&0xff);
+            PUT_BYTE(p, qLength&0xff);
+        }
+
+        PUT_BYTE(p, 0x00 | (pEncInfo->q_prec0 << 4));	// Luma
+        for (i=0; i<64; i++) {
+            if (pEncInfo->q_prec0 == TRUE) {
+                Uint16 q = pEncInfo->pQMatTab[0][i];
+                PUT_BYTE(p, (q>>8)&0xff);
+                PUT_BYTE(p, q&0xff);
+            }
+            else {
+                PUT_BYTE(p, pEncInfo->pQMatTab[0][i]);
+            }
+        }
+
+        if (pEncInfo->format != FORMAT_400) {
+            PUT_BYTE(p, 0x01 | (pEncInfo->q_prec1 << 4));	// Croma
+            for (i=0; i<64; i++) {
+                if (pEncInfo->q_prec0 == TRUE) {
+                    Uint16 q = pEncInfo->pQMatTab[1][i];
+                    PUT_BYTE(p, (q>>8)&0xff);
+                    PUT_BYTE(p, q&0xff);
+                }
+                else {
+                    PUT_BYTE(p, pEncInfo->pQMatTab[1][i]);
+                }
+            }
+        }
+    }
+
+    // DHT Header
+    PUT_BYTE(p, 0xFF);
+    PUT_BYTE(p, 0xC4);
+
+    if (para->huffMode == JPG_TBL_NORMAL)
+    {
+        Int32  numHuffValDC = pEncInfo->jpg12bit == TRUE ? 13 : 12;
+        Int32  numHuffValAC = pEncInfo->jpg12bit == TRUE ? 256: 162;
+        Uint16 LhDC         = pEncInfo->jpg12bit == TRUE ? 32 : 31;
+        Uint16 LhAC         = pEncInfo->jpg12bit == TRUE ? 275 : 181;
+
+        /* Lh: Huffman table definition length */
+
+        PUT_BYTE(p, (LhDC>>8));
+        PUT_BYTE(p, LhDC&0xff);
+
+        PUT_BYTE(p, 0x00);  /* TcTh : DC : ID0 */
+
+        for (i=0; i<16; i++) {
+            PUT_BYTE(p, pEncInfo->pHuffBits[0][i]);
+        }
+
+        for (i=0; i<numHuffValDC; i++) {
+            PUT_BYTE(p, pEncInfo->pHuffVal[0][i]);
+        }
+
+        PUT_BYTE(p, 0xFF);
+        PUT_BYTE(p, 0xC4);
+
+        PUT_BYTE(p, (LhAC>>8));
+        PUT_BYTE(p, LhAC&0xff);
+
+        PUT_BYTE(p, 0x10);  /* TcTh = AC : ID0 */
+
+        for (i=0; i<16; i++) {
+            PUT_BYTE(p, pEncInfo->pHuffBits[1][i]);
+        }
+
+        for (i=0; i<numHuffValAC; i++) {
+            PUT_BYTE(p, pEncInfo->pHuffVal[1][i]);
+        }
+
+        if (pEncInfo->format != FORMAT_400) {
+
+            PUT_BYTE(p, 0xFF);
+            PUT_BYTE(p, 0xC4);
+
+            PUT_BYTE(p, (LhDC>>8)&0xff);
+            PUT_BYTE(p, LhDC&0xff);
+
+            PUT_BYTE(p, 0x01);
+
+
+            for (i=0; i<16; i++) {
+                PUT_BYTE(p, pEncInfo->pHuffBits[2][i]);
+            }
+            for (i=0; i<numHuffValDC; i++) {
+                PUT_BYTE(p, pEncInfo->pHuffVal[2][i]);
+            }
+
+            PUT_BYTE(p, 0xFF);
+            PUT_BYTE(p, 0xC4);
+
+            PUT_BYTE(p, (LhAC>>8)&0xff);
+            PUT_BYTE(p, LhAC&0xff);
+
+            PUT_BYTE(p, 0x11);
+
+
+            for (i=0; i<16; i++) {
+                PUT_BYTE(p, pEncInfo->pHuffBits[3][i]);
+            }
+
+            for (i=0; i<numHuffValAC; i++) {
+                PUT_BYTE(p, pEncInfo->pHuffVal[3][i]);
+            }
+            if (pEncInfo->jpg12bit == TRUE) {
+                PUT_BYTE(p, 0xFF);
+                PUT_BYTE(p, 0xC4);
+
+                PUT_BYTE(p, (LhDC>>8)&0xff);
+                PUT_BYTE(p, LhDC&0xff);
+
+                PUT_BYTE(p, 0x02);  /* TcTh = DC : ID2 */
+
+
+                for (i=0; i<16; i++) {
+                    PUT_BYTE(p, pEncInfo->pHuffBits[4][i]);
+                }
+                for (i=0; i<numHuffValDC; i++) {
+                    PUT_BYTE(p, pEncInfo->pHuffVal[4][i]);
+                }
+
+                PUT_BYTE(p, 0xFF);
+                PUT_BYTE(p, 0xC4);
+
+                PUT_BYTE(p, (LhAC>>8)&0xff);
+                PUT_BYTE(p, LhAC&0xff);
+
+                PUT_BYTE(p, 0x12);  /* TcTh = AC : ID2 */
+
+
+                for (i=0; i<16; i++) {
+                    PUT_BYTE(p, pEncInfo->pHuffBits[5][i]);
+                }
+
+                for (i=0; i<numHuffValAC; i++) {
+                    PUT_BYTE(p, pEncInfo->pHuffVal[5][i]);
+                }
+            }
+        }
+    }
+    else// if (para->huffMode == JPG_TBL_MERGE)
+    {
+        if (pEncInfo->format != FORMAT_400)
+        {
+            PUT_BYTE(p, 0x01);
+            PUT_BYTE(p, 0xA2);
+            //PUT_BYTE(p, 2 + 1*4 + 28 + 178 + 28 + 178 );
+        }
+        else
+        {
+            PUT_BYTE(p, 0x00);
+            PUT_BYTE(p, 0xD4);
+            //PUT_BYTE(p, 2 + 1*4 + 28 + 178 );
+        }
+
+        PUT_BYTE(p, 0x00);
+
+        for (i=0; i<16; i++) {
+            PUT_BYTE(p, pEncInfo->pHuffBits[0][i]);
+        }
+
+        for (i=0; i<12; i++) {
+            PUT_BYTE(p, pEncInfo->pHuffVal[0][i]);
+        }
+
+
+        PUT_BYTE(p, 0x10);
+
+        for (i=0; i<16; i++) {
+            PUT_BYTE(p, pEncInfo->pHuffBits[1][i]);
+        }
+
+        for (i=0; i<162; i++) {
+            PUT_BYTE(p, pEncInfo->pHuffVal[1][i]);
+        }
+
+
+        if (pEncInfo->format != FORMAT_400) {
+
+            PUT_BYTE(p, 0x01);
+
+
+            for (i=0; i<16; i++) {
+                PUT_BYTE(p, pEncInfo->pHuffBits[2][i]);
+            }
+            for (i=0; i<12; i++) {
+                PUT_BYTE(p, pEncInfo->pHuffVal[2][i]);
+            }
+
+
+            PUT_BYTE(p, 0x11);
+
+            for (i=0; i<16; i++) {
+                PUT_BYTE(p, pEncInfo->pHuffBits[3][i]);
+            }
+
+            for (i=0; i<162; i++) {
+                PUT_BYTE(p, pEncInfo->pHuffVal[3][i]);
+            }
+        }
+    }
+
+    // SOF header
+    PUT_BYTE(p, 0xFF);
+    PUT_BYTE(p, (pEncInfo->jpg12bit == TRUE ? 0xC1 : 0xC0));
+    PUT_BYTE(p, (((8+(pEncInfo->compNum*3)) >> 8) & 0xFF));
+    PUT_BYTE(p, ((8+(pEncInfo->compNum*3)) & 0xFF));
+    PUT_BYTE(p, (pEncInfo->jpg12bit == TRUE ? 12 : 8));
+    width       = pEncInfo->picWidth;
+    height      = pEncInfo->picHeight;
+    frameFormat = pEncInfo->format;
+    if (pEncInfo->rotationIndex == 1 || pEncInfo->rotationIndex == 3) {
+        // rotation angle = rotationIndex x 90;
+        width  = pEncInfo->picHeight;
+        height = pEncInfo->picWidth;
+        if (frameFormat == FORMAT_422)      frameFormat = FORMAT_440;
+        else if (frameFormat == FORMAT_440) frameFormat = FORMAT_422;
+    }
+    PUT_BYTE(p, (height >> 8));
+    PUT_BYTE(p, (height & 0xFF));
+    PUT_BYTE(p, (width >> 8));
+    PUT_BYTE(p, (width & 0xFF));
+    PUT_BYTE(p, pEncInfo->compNum);
+
+
+    pCInfoTab[0] = sJpuCompInfoTable[frameFormat];
+    pCInfoTab[1] = pCInfoTab[0] + 6;
+    pCInfoTab[2] = pCInfoTab[1] + 6;
+    pCInfoTab[3] = pCInfoTab[2] + 6;
+
+    for (i=0; i<pEncInfo->compNum; i++) {
+        PUT_BYTE(p, (i+1));
+        PUT_BYTE(p, ((pCInfoTab[i][1]<<4) & 0xF0) + (pCInfoTab[i][2] & 0x0F));
+        PUT_BYTE(p, pCInfoTab[i][3]);
+    }
+
+    if (para->enableSofStuffing)
+    {
+        pad = 0;
+        if (tot % 8) {
+            pad = tot % 8;
+            pad = 8-pad;
+            for (i=0; i<pad; i++) {
+                PUT_BYTE(p, 0xFF);
+            }
+        }
+    }
+
+    pEncInfo->frameIdx++;
+    para->size = tot;
+
+    return tot;
+}
+
+
+void JpgEncSetQualityFactor(JpgEncHandle handle, Uint32 quality, BOOL useStdTable)
+{
+    JpgInst *pJpgInst;
+    JpgEncInfo *pEncInfo;
+    Uint32 scaleFactor;
+    Uint32 i;
+    Uint32 temp;
+
+    pJpgInst = handle;
+    pEncInfo = &pJpgInst->JpgInfo->encInfo;
+    /* These are the sample quantization tables given in JPEG spec section K.1.
+    * The spec says that the values given produce "good" quality, and
+    * when divided by 2, "very good" quality.
+    */
+    static const Uint32 std_luminance_quant_tbl[64] = {
+        16, 11, 10, 16, 24, 40, 51, 61,
+        12, 12, 14, 19, 26, 58, 60, 55,
+        14, 13, 16, 24, 40, 57, 69, 56,
+        14, 17, 22, 29, 51, 87, 80, 62,
+        18, 22, 37, 56, 68, 109, 103, 77,
+        24, 35, 55, 64, 81, 104, 113, 92,
+        49, 64, 78, 87, 103, 121, 120, 101,
+        72, 92, 95, 98, 112, 100, 103, 99
+    };
+    static const Uint32 std_chrominance_quant_tbl[64] = {
+        17, 18, 24, 47, 99, 99, 99, 99,
+        18, 21, 26, 66, 99, 99, 99, 99,
+        24, 26, 56, 99, 99, 99, 99, 99,
+        47, 66, 99, 99, 99, 99, 99, 99,
+        99, 99, 99, 99, 99, 99, 99, 99,
+        99, 99, 99, 99, 99, 99, 99, 99,
+        99, 99, 99, 99, 99, 99, 99, 99,
+        99, 99, 99, 99, 99, 99, 99, 99
+    };
+    Uint32 pLumaQTable[64];
+    Uint32 pChromaQTable[64];
+    Uint32 qSize = 1, qTableSize;
+    Uint32 minQvalue = MIN_Q8_ELEMENT;
+
+    if (quality <= 0) quality = 1;
+    if (quality > 100) quality = 100;
+
+    for (i = 0; i<64; i++) {
+        pLumaQTable[i] = (useStdTable == TRUE) ? std_luminance_quant_tbl[i] : (Int32)pEncInfo->pQMatTab[DC_TABLE_INDEX0][i];
+    }
+    for (i = 0; i<64; i++) {
+        pChromaQTable[i] = (useStdTable == TRUE) ? std_chrominance_quant_tbl[i] : (Int32)pEncInfo->pQMatTab[AC_TABLE_INDEX0][i];
+    }
+
+    minQvalue = (pEncInfo->jpg12bit == TRUE) ? MIN_Q16_ELEMENT : MIN_Q8_ELEMENT;
+
+    /* The basic table is used as-is (scaling 100) for a quality of 50.
+    * Qualities 50..100 are converted to scaling percentage 200 - 2*Q;
+    * note that at Q=100 the scaling is 0, which will cause jpeg_add_quant_table
+    * to make all the table entries 1 (hence, minimum quantization loss).
+    * Qualities 1..50 are converted to scaling percentage 5000/Q.
+    */
+    if (quality < 50)
+        scaleFactor = 5000 / quality;
+    else
+        scaleFactor = 200 - quality * 2;
+
+
+    for (i = 0; i < 64; i++) {
+        temp = (pLumaQTable[i] * scaleFactor + 50) / 100;
+        /* limit the values to the valid range */
+        temp = (temp < minQvalue) ? minQvalue : temp;
+
+        if (temp > 32767)
+            temp = 32767; /* max quantizer needed for 12 bits */
+        if (pEncInfo->q_prec0 == FALSE && temp > 255)
+            temp = 255;                 /* limit to baseline range if requested */
+        pEncInfo->pQMatTab[DC_TABLE_INDEX0][i] = temp;
+    }
+
+    for (i = 0; i < 64; i++) {
+        temp = (pChromaQTable[i] * scaleFactor + 50) / 100;
+        /* limit the values to the valid range */
+        temp = (temp < minQvalue) ? minQvalue : temp;
+
+        if (temp > 32767) temp = 32767;    /* max quantizer needed for 12 bits */
+        if (pEncInfo->q_prec1 == FALSE && temp > 255)
+            temp = 255;                     /* limit to baseline range if requested */
+
+        pEncInfo->pQMatTab[AC_TABLE_INDEX0][i] = temp;
+    }
+
+    qSize = pEncInfo->jpg12bit ? 2 : 1;
+
+    //setting of qmatrix table information
+#ifdef USE_CNM_DEFAULT_QMAT_TABLE
+    memset((void*)pEncInfo->pQMatTab[DC_TABLE_INDEX0], 0x00, 64 * qSize);
+    memcpy((void*)pEncInfo->pQMatTab[DC_TABLE_INDEX0], (void*)lumaQ2, 64 * qSize);
+
+    memset((void*)pEncInfo->pQMatTab[AC_TABLE_INDEX0], 0x00, 64 * qSize);
+    memcpy((void*)ppEncInfo->pQMatTab[AC_TABLE_INDEX0], (void*)chromaBQ2, 64 * qSize);
+#endif
+
+    qTableSize = 64 * qSize;
+    memcpy((void*)pEncInfo->pQMatTab[DC_TABLE_INDEX1], (void*)pEncInfo->pQMatTab[DC_TABLE_INDEX0], qTableSize);
+    memcpy((void*)pEncInfo->pQMatTab[AC_TABLE_INDEX1], (void*)pEncInfo->pQMatTab[AC_TABLE_INDEX0], qTableSize);
+}
+
+JpgRet JpgEnterLock()
+{
+    jdi_lock();
+
+    return JPG_RET_SUCCESS;
+
+}
+
+JpgRet JpgLeaveLock()
+{
+
+    jdi_unlock();
+    return JPG_RET_SUCCESS;
+}
+
+JpgRet JpgSetClockGateEx(Uint32 on, Uint32 instIdx)
+{
+    JpgInst *inst;
+    jpu_instance_pool_t *jip;
+
+    jip = (jpu_instance_pool_t *)jdi_get_instance_pool();
+    if (!jip)
+        return JPG_RET_FAILURE;
+
+    inst = (JpgInst *)jip->instPendingInst[instIdx];
+    if(inst && !on)
+        return JPG_RET_SUCCESS;
+
+    jdi_set_clock_gate(on);
+
+    return JPG_RET_SUCCESS;
+}
+
+
+JpgInst *GetJpgPendingInstEx(Uint32 instIdx)
+{
+    jpu_instance_pool_t *jip;
+
+    jip = (jpu_instance_pool_t *)jdi_get_instance_pool();
+    if (!jip)
+        return NULL;
+
+    if (instIdx >= MAX_NUM_INSTANCE)
+        return NULL;
+
+    return jip->instPendingInst[instIdx];
+}
+
+
+
+void SetJpgPendingInstEx(JpgInst *inst, Uint32 instIdx)
+{
+    jpu_instance_pool_t *jip;
+
+    jip = (jpu_instance_pool_t *)jdi_get_instance_pool();
+    if (!jip)
+        return;
+
+    if (instIdx >= MAX_NUM_INSTANCE)
+        return;
+    jip->instPendingInst[instIdx] = inst;
+}
+
+void ClearJpgPendingInstEx(Uint32 instIdx)
+{
+    jpu_instance_pool_t *jip;
+
+    jip = (jpu_instance_pool_t *)jdi_get_instance_pool();
+    if (!jip)
+        return;
+
+    if (instIdx >= MAX_NUM_INSTANCE)
+        return;
+
+    if(jip->instPendingInst[instIdx])
+        jip->instPendingInst[instIdx] = 0;
+}
+

+ 332 - 0
codaj12/jpuapi/jpuapifunc.h

@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 2018, Chips&Media
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JPUAPI_UTIL_H_INCLUDED
+#define JPUAPI_UTIL_H_INCLUDED
+
+#include "jpuapi.h"
+
+#define DC_TABLE_INDEX0				0
+#define AC_TABLE_INDEX0				1
+#define DC_TABLE_INDEX1				2
+#define AC_TABLE_INDEX1				3
+
+#define DC_TABLE_INDEX2				4
+#define AC_TABLE_INDEX2				5
+#define DC_TABLE_INDEX3				6
+#define AC_TABLE_INDEX3				7
+
+#define Q_COMPONENT0				0
+#define Q_COMPONENT1				0x40
+#define Q_COMPONENT2				0x80
+
+#define THTC_LIST_CNT               8
+
+/* CODAJ12 Constraints
+* The minimum value of Qk is 8 for 16bit quantization element, 2 for 8bit quantization element
+*/
+#define MIN_Q16_ELEMENT     8
+#define MIN_Q8_ELEMENT      2
+
+typedef enum {
+    JPG_START_PIC = 0,
+    JPG_START_INIT,
+    JPG_START_PARTIAL,
+    JPG_ENABLE_START_PIC = 4,
+    JPG_DEC_SLICE_ENABLE_START_PIC = 5
+}JpgStartCmd;
+
+
+typedef enum {
+    INST_CTRL_IDLE = 0,
+    INST_CTRL_LOAD = 1,
+    INST_CTRL_RUN = 2,
+    INST_CTRL_PAUSE = 3,
+    INST_CTRL_ENC = 4,
+    INST_CTRL_PIC_DONE = 5,
+    INST_CTRL_SLC_DONE = 6
+}InstCtrlStates;
+
+typedef struct{
+    Uint32	tag;
+    Uint32	type;
+    int		count;
+    int		offset;
+}TAG;
+
+enum {
+    JFIF    	= 0,
+    JFXX_JPG	= 1,
+    JFXX_PAL  	= 2,
+    JFXX_RAW 	= 3,
+    EXIF_JPG	= 4
+};
+
+typedef struct {
+    int			PicX;
+    int			PicY;
+    int			BitPerSample[3];
+    int			Compression; // 1 for uncompressed / 6 for compressed(jpeg)
+    int			PixelComposition; // 2 for RGB / 6 for YCbCr
+    int			SamplePerPixel;
+    int  		PlanrConfig; // 1 for chunky / 2 for planar
+    int			YCbCrSubSample; // 00020002 for YCbCr 4:2:0 / 00020001 for YCbCr 4:2:2
+    Uint32		JpegOffset;
+    Uint32		JpegThumbSize;
+} EXIF_INFO;
+
+
+
+typedef struct {
+    BYTE *buffer;
+    int index;
+    int size;
+} vpu_getbit_context_t;
+
+#define init_get_bits(CTX, BUFFER, SIZE) JpuGbuInit(CTX, BUFFER, SIZE)
+#define show_bits(CTX, NUM) JpuGguShowBit(CTX, NUM)
+#define get_bits(CTX, NUM) JpuGbuGetBit(CTX, NUM)
+#define get_bits_left(CTX) JpuGbuGetLeftBitCount(CTX)
+#define get_bits_count(CTX) JpuGbuGetUsedBitCount(CTX)
+
+typedef struct {
+
+    PhysicalAddress streamWrPtr;
+    PhysicalAddress streamRdPtr;
+    int	streamEndflag;
+    PhysicalAddress streamBufStartAddr;
+    PhysicalAddress streamBufEndAddr;
+    int streamBufSize;
+    BYTE *pBitStream;
+
+    int frameOffset;
+    int consumeByte;
+    int nextOffset;
+    int currOffset;
+
+    FrameBuffer * frameBufPool;
+    int numFrameBuffers;
+    int stride;
+    int initialInfoObtained;
+    int minFrameBufferNum;
+    int streamEndian;
+    int frameEndian;
+    Uint32  chromaInterleave;
+
+    Uint32  picWidth;
+    Uint32  picHeight;
+    Uint32  alignedWidth;
+    Uint32  alignedHeight;
+    int headerSize;
+    int ecsPtr;
+    int pagePtr;
+    int wordPtr;
+    int bitPtr;
+    FrameFormat format;
+    int rstIntval;
+
+    int userHuffTab;
+    int userqMatTab;
+
+    int huffDcIdx;
+    int huffAcIdx;
+    int Qidx;
+
+    BYTE huffVal[8][256];
+    BYTE huffBits[8][256];
+    short qMatTab[4][64];
+    Uint32 huffMin[8][16];
+    Uint32 huffMax[8][16];
+    BYTE huffPtr[8][16];
+    BYTE cInfoTab[4][6];
+
+    int busReqNum;
+    int compNum;
+    int mcuBlockNum;
+    int compInfo[3];
+    int frameIdx;
+    int bitEmpty;
+    int iHorScaleMode;
+    int iVerScaleMode;
+    Uint32  mcuWidth;
+    Uint32  mcuHeight;
+    vpu_getbit_context_t gbc;
+
+
+    //ROI
+    Uint32          roiEnable;
+    Uint32          roiOffsetX;
+    Uint32          roiOffsetY;
+    Uint32          roiWidth;
+    Uint32          roiHeight;
+    Uint32          roiMcuOffsetX;
+    Uint32          roiMcuOffsetY;
+    Uint32          roiMcuWidth;
+    Uint32          roiMcuHeight;
+    Uint32          roiFrameWidth;
+    Uint32          roiFrameHeight;
+    PackedFormat    packedFormat;
+
+    int             jpg12bit;
+    int             q_prec0;
+    int             q_prec1;
+    int             q_prec2;
+    int             q_prec3;
+    Uint32          pixelJustification;
+    Uint32          ofmt;
+    Uint32          stride_c;
+    Uint32          bitDepth;
+    Uint32          intrEnableBit;
+    Uint32          decIdx;
+    Uint32          rotationIndex;                  /*!<< 0: 0, 1: 90 CCW, 2: 180 CCW, 3: 270 CCW CCW(Counter Clockwise)*/
+    JpgMirrorDirection mirrorIndex;                 /*!<< 0: none, 1: vertical mirror, 2: horizontal mirror, 3: both */
+    Int32           thtc[THTC_LIST_CNT];            /*!<< Huffman table definition length and table class list : -1 indicates not exist. */
+    Uint32          numHuffmanTable;
+} JpgDecInfo;
+
+typedef struct {
+    PhysicalAddress streamRdPtr;
+    PhysicalAddress streamWrPtr;
+    PhysicalAddress streamBufStartAddr;
+    PhysicalAddress streamBufEndAddr;
+
+    FrameBuffer * frameBufPool;
+    int numFrameBuffers;
+    int stride;
+    int initialInfoObtained;
+
+    Uint32  picWidth;
+    Uint32  picHeight;
+    Uint32  alignedWidth;
+    Uint32  alignedHeight;
+    Uint32  mcuWidth;
+    Uint32  mcuHeight;
+    int seqInited;
+    int frameIdx;
+    FrameFormat format;
+
+    int streamEndian;
+    int frameEndian;
+    Uint32 chromaInterleave;
+
+    int rstIntval;
+    int busReqNum;
+    int mcuBlockNum;
+    int compNum;
+    int compInfo[3];
+
+    // give command
+    int disableAPPMarker;
+    int quantMode;
+    int stuffByteEnable;
+
+    Uint32  huffCode[8][256];
+    Uint32  huffSize[8][256];
+    BYTE*   pHuffVal[8];
+    BYTE*   pHuffBits[8];
+    short*  pQMatTab[4];
+    int     jpg12bit;
+    int     q_prec0;
+    int     q_prec1;
+
+    BYTE *pCInfoTab[4];
+
+    PackedFormat    packedFormat;
+
+    Uint32  pixelJustification;
+    Int32   sliceHeight;
+    Uint32  intrEnableBit;
+    Uint32  encIdx;
+    Uint32  encSlicePosY;
+    Uint32  tiledModeEnable;
+    Uint32  rotationIndex;          /*!<< 0: 0, 1: 90 CCW, 2: 180 CCW, 3: 270 CCW CCW(Counter Clockwise)*/
+    Uint32  mirrorIndex;            /*!<< 0: none, 1: vertical mirror, 2: horizontal mirror, 3: both */
+} JpgEncInfo;
+
+typedef struct JpgInst {
+    Int32   inUse;
+    Int32   instIndex;
+    Int32   loggingEnable;
+	BOOL sliceInstMode;
+    union {
+        JpgEncInfo encInfo;
+        JpgDecInfo decInfo;
+    } *JpgInfo;
+} JpgInst;
+
+
+
+extern Uint8 sJpuCompInfoTable[5][24];
+extern Uint8 sJpuCompInfoTable_EX[5][24];
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+    JpgRet GetJpgInstance(JpgInst ** ppInst);
+    void	FreeJpgInstance(JpgInst * pJpgInst);
+    JpgRet CheckJpgInstValidity(JpgInst * pci);
+    JpgRet CheckJpgDecOpenParam(JpgDecOpenParam * pop);
+
+    int JpuGbuInit(vpu_getbit_context_t *ctx, BYTE *buffer, int size);
+    int JpuGbuGetUsedBitCount(vpu_getbit_context_t *ctx);
+    int JpuGbuGetLeftBitCount(vpu_getbit_context_t *ctx);
+    unsigned int JpuGbuGetBit(vpu_getbit_context_t *ctx, int bit_num);
+    unsigned int JpuGguShowBit(vpu_getbit_context_t *ctx, int bit_num);
+
+    int JpegDecodeHeader(JpgDecInfo * jpg);
+    int JpgDecQMatTabSetUp(JpgDecInfo *jpg, int instRegIndex);
+    int JpgDecHuffTabSetUp(JpgDecInfo *jpg, int instRegIndex);
+    int JpgDecHuffTabSetUp_12b(JpgDecInfo *jpg, int instRegIndex);
+    void JpgDecGramSetup(JpgDecInfo * jpg, int instRegIndex);
+
+
+    JpgRet CheckJpgEncOpenParam(JpgEncOpenParam * pop, JPUCap* cap);
+    JpgRet CheckJpgEncParam(JpgEncHandle handle, JpgEncParam * param);
+    int JpgEncLoadHuffTab(JpgInst *pJpgInst, int instRegIndex);
+    int JpgEncLoadHuffTab_12b(JpgInst *pJpgInst, int instRegIndex);
+    int JpgEncLoadQMatTab(JpgInst *pJpgInst, int instRegIndex);
+    int JpgEncEncodeHeader(JpgEncHandle handle, JpgEncParamSet * para);
+    void JpgEncSetQualityFactor(JpgEncHandle handle, Uint32 level, BOOL useStdTable);
+
+    JpgRet JpgEnterLock();
+    JpgRet JpgLeaveLock();
+    JpgRet JpgSetClockGate(Uint32 on);
+
+    JpgInst *GetJpgPendingInstEx(Uint32 instIdx);
+    void SetJpgPendingInstEx(JpgInst *inst, Uint32 instIdx);
+    void ClearJpgPendingInstEx(Uint32 instIdx);
+
+    Uint32 GetDec8bitBusReqNum(FrameFormat iFormat, PackedFormat oPackMode);
+    Uint32 GetDec12bitBusReqNum(FrameFormat iFormat, PackedFormat oPackMode);
+    Uint32 GetEnc8bitBusReqNum(PackedFormat iPackMode, FrameFormat oFormat);
+    Uint32 GetEnc12bitBusReqNum(PackedFormat iPackMode, FrameFormat oFormat);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif // endif JPUAPI_UTIL_H_INCLUDED

+ 59 - 0
codaj12/jpuapi/jpuconfig.h

@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2018, Chips&Media
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _JPU_CONFIG_H_
+#define _JPU_CONFIG_H_
+
+#include "../config.h"
+
+#define MAX_NUM_JPU_CORE                1
+#define MAX_NUM_INSTANCE                4
+#define MAX_INST_HANDLE_SIZE            48
+
+#define JPU_FRAME_ENDIAN                JDI_LITTLE_ENDIAN
+#define JPU_STREAM_ENDIAN               JDI_LITTLE_ENDIAN
+#define JPU_CHROMA_INTERLEAVE           1        // 0 (chroma separate mode), 1 (cbcr interleave mode), 2 (crcb interleave mode)
+
+#define JPU_STUFFING_BYTE_FF            0        // 0 : ON ("0xFF"), 1 : OFF ("0x00") for stuffing
+
+
+#define MAX_MJPG_PIC_WIDTH              32768
+#define MAX_MJPG_PIC_HEIGHT             32768
+
+
+#define MAX_FRAME                       (19*MAX_NUM_INSTANCE)
+
+#define STREAM_FILL_SIZE                0x10000
+#define STREAM_END_SIZE                 0
+
+#define JPU_GBU_SIZE                    256
+
+#define STREAM_BUF_SIZE                 0x200000
+
+#define JPU_CHECK_WRITE_RESPONSE_BVALID_SIGNAL 0
+
+#define JPU_INTERRUPT_TIMEOUT_MS        (5000*4)
+
+#define JPU_INST_CTRL_TIMEOUT_MS        (5000*4)
+#endif    /* _JPU_CONFIG_H_ */

+ 258 - 0
codaj12/jpuapi/jputable.h

@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2018, Chips&Media
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef JPU_TABLE_H
+#define JPU_TABLE_H
+
+static unsigned char lumaDcBits[16] = {
+0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+static unsigned char lumaDcValue[16] = {
+0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+0x08, 0x09, 0x0A, 0x0B, 0x00, 0x00, 0x00, 0x00,
+};
+static unsigned char lumaAcBits[16] = {
+0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
+0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D,
+};
+static unsigned char lumaAcValue[168] = {
+0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
+0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
+0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08,
+0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0,
+0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16,
+0x17, 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28,
+0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
+0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,
+0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5,
+0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4,
+0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2,
+0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA,
+0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
+0xF9, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+static unsigned char chromaDcBits[16] = {
+0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+static unsigned char chromaDcValue[16] = {
+0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+0x08, 0x09, 0x0A, 0x0B, 0x00, 0x00, 0x00, 0x00,
+};
+static unsigned char chromaAcBits[16] = {
+0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
+0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77,
+};
+static unsigned char chromaAcValue[168] = {
+0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
+0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
+0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
+0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0,
+0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34,
+0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26,
+0x27, 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38,
+0x39, 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
+0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96,
+0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5,
+0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4,
+0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3,
+0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2,
+0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA,
+0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9,
+0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
+0xF9, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+#ifdef NOT_USED
+static unsigned char lumaQ[64] = {
+0x0C, 0x08, 0x08, 0x08, 0x09, 0x08, 0x0C, 0x09,
+0x09, 0x0C, 0x11, 0x0B, 0x0A, 0x0B, 0x11, 0x15,
+0x0F, 0x0C, 0x0C, 0x0F, 0x15, 0x18, 0x13, 0x13,
+0x15, 0x13, 0x13, 0x18, 0x11, 0x0C, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x11, 0x0C, 0x0C, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+};
+
+static unsigned char chromaBQ[64] = {
+0x0D, 0x0B, 0x0B, 0x0D, 0x0E, 0x0D, 0x10, 0x0E,
+0x0E, 0x10, 0x14, 0x0E, 0x0E, 0x0E, 0x14, 0x14,
+0x0E, 0x0E, 0x0E, 0x0E, 0x14, 0x11, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x11, 0x11, 0x0C, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x11, 0x0C, 0x0C, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+};
+static unsigned char chromaRQ[64] = {
+0x0D, 0x0B, 0x0B, 0x0D, 0x0E, 0x0D, 0x10, 0x0E,
+0x0E, 0x10, 0x14, 0x0E, 0x0E, 0x0E, 0x14, 0x14,
+0x0E, 0x0E, 0x0E, 0x0E, 0x14, 0x11, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x11, 0x11, 0x0C, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x11, 0x0C, 0x0C, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+};
+#endif
+static unsigned char lumaQ2[64] = {
+0x06, 0x04, 0x04, 0x04, 0x05, 0x04, 0x06, 0x05,
+0x05, 0x06, 0x09, 0x06, 0x05, 0x06, 0x09, 0x0B,
+0x08, 0x06, 0x06, 0x08, 0x0B, 0x0C, 0x0A, 0x0A,
+0x0B, 0x0A, 0x0A, 0x0C, 0x10, 0x0C, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x10, 0x0C, 0x0C, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+};
+static unsigned char chromaBQ2[64] = {
+0x07, 0x07, 0x07, 0x0D, 0x0C, 0x0D, 0x18, 0x10,
+0x10, 0x18, 0x14, 0x0E, 0x0E, 0x0E, 0x14, 0x14,
+0x0E, 0x0E, 0x0E, 0x0E, 0x14, 0x11, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x11, 0x11, 0x0C, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x11, 0x0C, 0x0C, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+};
+
+#ifdef NOT_USED
+static unsigned char chromaRQ2[64] = {
+0x07, 0x07, 0x07, 0x0D, 0x0C, 0x0D, 0x18, 0x10,
+0x10, 0x18, 0x14, 0x0E, 0x0E, 0x0E, 0x14, 0x14,
+0x0E, 0x0E, 0x0E, 0x0E, 0x14, 0x11, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x11, 0x11, 0x0C, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x11, 0x0C, 0x0C, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+};
+#endif
+
+static unsigned char lumaDcBits_ES[16] = {
+0x00, 0x02, 0x03, 0x01, 0x00, 0x03, 0x01, 0x01,
+0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+static unsigned char lumaDcValue_ES[16] = {
+0x08, 0x09, 0x06, 0x07, 0x0A, 0x05, 0x03, 0x04,
+0x0B, 0x02, 0x00, 0x01, 0x0C,
+};
+static unsigned char lumaAcBits_ES[16] = {
+0x00, 0x01, 0x04, 0x02, 0x02, 0x02, 0x01, 0x04,
+0x01, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0xEB,
+};
+static unsigned char lumaAcValue_ES[256] = {
+0x02, 0x01, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+0x12, 0x09, 0x11, 0x13, 0x00, 0x14, 0x21, 0x22,
+0x15, 0x0a, 0x23, 0x31, 0x16, 0x32, 0x17, 0x24,
+0x33, 0x41, 0x18, 0x25, 0x42, 0x51, 0x0b, 0x26,
+0x19, 0x43, 0x52, 0x61, 0x35, 0x62, 0x71, 0x0c,
+0x0d, 0x0e, 0x0f, 0x10, 0x1a, 0x1b, 0x1c, 0x1d,
+0x1e, 0x1f, 0x20, 0x27, 0x28, 0x29, 0x2a, 0x2b,
+0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x34, 0x36, 0x37,
+0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+0x40, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
+0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x53, 0x54,
+0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c,
+0x5d, 0x5e, 0x5f, 0x60, 0x63, 0x64, 0x65, 0x66,
+0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
+0x6f, 0x70, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+};
+static unsigned char chromaDcBits_ES[16] = {
+0x00, 0x02, 0x02, 0x02, 0x03, 0x01, 0x01, 0x01,
+0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+static unsigned char chromaDcValue_ES[16] = {
+0x06, 0x07, 0x05, 0x08, 0x04, 0x09, 0x02, 0x03,
+0x0A, 0x01, 0x0B, 0x00, 0x0C,
+};
+static unsigned char chromaAcBits_ES[16] = {
+0x00, 0x01, 0x03, 0x02, 0x05, 0x01, 0x05, 0x05,
+0x03, 0x07, 0x04, 0x04, 0x03, 0x04, 0x06, 0xCB,
+};
+static unsigned char chromaAcValue_ES[256] = {
+0x01, 0x02, 0x03, 0x11, 0x04, 0x21, 0x00, 0x05,
+0x06, 0x12, 0x31, 0x41, 0x07, 0x13, 0x22, 0x51,
+0x61, 0x08, 0x14, 0x32, 0x71, 0x81, 0x42, 0x91,
+0xa1, 0x09, 0x15, 0x23, 0x52, 0xb1, 0xc1, 0xf0,
+0x16, 0x62, 0xd1, 0xe1, 0x0a, 0x24, 0x72, 0xf1,
+0x17, 0x82, 0x92, 0x33, 0x43, 0x53, 0xb2, 0x0b,
+0x0c, 0x18, 0x35, 0xa2, 0xc2, 0x0d, 0x0e, 0x0f,
+0x10, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+0x20, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
+0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x34, 0x36, 0x37,
+0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+0x40, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
+0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x54, 0x55,
+0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d,
+0x5e, 0x5f, 0x60, 0x63, 0x64, 0x65, 0x66, 0x67,
+0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+0x70, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x83,
+0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b,
+0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x93, 0x94, 0x95,
+0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d,
+0x9e, 0x9f, 0xa0, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+0xb0, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
+0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc3,
+0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb,
+0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd2, 0xd3, 0xd4,
+0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc,
+0xdd, 0xde, 0xdf, 0xe0, 0xe2, 0xe3, 0xe4, 0xe5,
+0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed,
+0xee, 0xef, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+};
+#endif
+

Some files were not shown because too many files changed in this diff