Browse Source

Merge branch 'CR_1681_vpu_omx_515_Som.Qin' into 'jh7110-devel'

Cr 1681 vpu omx 515 som.qin

See merge request sdk/freelight-u-sdk!86
Jason Zhou 1 year ago
parent
commit
06ec2134ce
100 changed files with 22799 additions and 116 deletions
  1. 3 0
      codaj12/build_for_riscv.sh
  2. 41 0
      codaj12/codaj12Driver_buildroot.mak
  3. 148 0
      codaj12/codaj12_buildroot.mak
  4. 12 3
      codaj12/jdi/jdi.h
  5. 301 0
      codaj12/jdi/linux/driver/jpu-starfive.h
  6. 69 0
      codaj12/jdi/linux/driver/jpu.c
  7. 1 0
      codaj12/jdi/linux/driver/jpu.h
  8. 40 0
      codaj12/jdi/linux/jdi.c
  9. 334 1
      codaj12/jpuapi/jpuapi.c
  10. 14 3
      codaj12/jpuapi/jpuapi.h
  11. 5 1
      codaj12/jpuapi/jpuapifunc.h
  12. 5 1
      codaj12/jpuapi/jpuconfig.h
  13. 5 1
      codaj12/jpuapi/regdefine.h
  14. 41 10
      codaj12/sample/helper/bitstreamfeeder.c
  15. 121 0
      codaj12/sample/helper/bsfeeder_buffer_impl.c
  16. 5 1
      codaj12/sample/helper/cnm_fpga.h
  17. 7 2
      codaj12/sample/helper/datastructure.h
  18. 201 4
      codaj12/sample/helper/jpuhelper.c
  19. 42 0
      codaj12/sample/helper/jpulog.c
  20. 15 2
      codaj12/sample/helper/jpulog.h
  21. 5 1
      codaj12/sample/helper/platform.h
  22. 8 2
      codaj12/sample/helper/yuv_feeder.h
  23. 14 4
      codaj12/sample/main_helper.h
  24. 1 1
      codaj12/sample/main_jpg_enc_test.c
  25. 103 0
      omx-il/Makefile
  26. 202 0
      omx-il/component/helper/sf_queue.c
  27. 38 0
      omx-il/component/helper/sf_queue.h
  28. 103 0
      omx-il/component/helper/sf_semaphore.c
  29. 23 0
      omx-il/component/helper/sf_semaphore.h
  30. 68 0
      omx-il/component/helper/sf_thread.c
  31. 28 0
      omx-il/component/helper/sf_thread.h
  32. 590 0
      omx-il/component/image/common/SF_OMX_mjpeg_common.c
  33. 143 0
      omx-il/component/image/common/SF_OMX_mjpeg_common.h
  34. 1607 0
      omx-il/component/image/dec/SF_OMX_Mjpeg_decoder.c
  35. 2415 0
      omx-il/component/video/wave4/SF_OMX_Wave420L_encoder.c
  36. 268 0
      omx-il/component/video/wave4/SF_OMX_Wave420L_encoder.h
  37. 561 0
      omx-il/component/video/wave5/common/SF_OMX_video_common.c
  38. 143 0
      omx-il/component/video/wave5/common/SF_OMX_video_common.h
  39. 1934 0
      omx-il/component/video/wave5/dec/SF_OMX_Vdec_decoder.c
  40. 1246 0
      omx-il/component/video/wave5/enc/SF_OMX_Venc_encoder.c
  41. 309 0
      omx-il/core/SF_OMX_Core.c
  42. 156 0
      omx-il/core/SF_OMX_Core.h
  43. 1310 0
      omx-il/include/khronos/OMX_Audio.h
  44. 569 0
      omx-il/include/khronos/OMX_Component.h
  45. 61 0
      omx-il/include/khronos/OMX_ComponentExt.h
  46. 193 0
      omx-il/include/khronos/OMX_ContentPipe.h
  47. 1422 0
      omx-il/include/khronos/OMX_Core.h
  48. 73 0
      omx-il/include/khronos/OMX_CoreExt.h
  49. 993 0
      omx-il/include/khronos/OMX_IVCommon.h
  50. 328 0
      omx-il/include/khronos/OMX_Image.h
  51. 55 0
      omx-il/include/khronos/OMX_ImageExt.h
  52. 260 0
      omx-il/include/khronos/OMX_Index.h
  53. 105 0
      omx-il/include/khronos/OMX_IndexExt.h
  54. 366 0
      omx-il/include/khronos/OMX_Other.h
  55. 352 0
      omx-il/include/khronos/OMX_Types.h
  56. 1141 0
      omx-il/include/khronos/OMX_Video.h
  57. 401 0
      omx-il/include/khronos/OMX_VideoExt.h
  58. 488 0
      omx-il/tests/dec_test.c
  59. 497 0
      omx-il/tests/enc_test.c
  60. 590 0
      omx-il/tests/mjpeg_dec_test.c
  61. 41 0
      wave420l/code/WaveEncDriver_buildroot.mak
  62. 275 0
      wave420l/code/WaveEncoder_buildroot.mak
  63. 76 0
      wave420l/code/cfg/encoder_defconfig.cfg
  64. 1 1
      wave420l/code/config.h
  65. 4 0
      wave420l/code/sample/helper/bitstream/bitstreamfeeder.c
  66. 101 0
      wave420l/code/sample/helper/bitstream/bitstreamreader.c
  67. 1 0
      wave420l/code/sample/helper/bitstream/bsfeeder_framesize_impl.c
  68. 5 5
      wave420l/code/sample/helper/main_helper.c
  69. 49 16
      wave420l/code/sample/helper/main_helper.h
  70. 1 1
      wave420l/code/sample/helper/misc/debug.h
  71. 110 2
      wave420l/code/sample/helper/yuv/yuvfeeder.c
  72. 2 0
      wave420l/code/vpuapi/coda9/coda9.h
  73. 1 0
      wave420l/code/vpuapi/vpuapi.c
  74. 5 5
      wave420l/code/vpuapi/wave/common/common.c
  75. 41 0
      wave511/code/WaveDecDriver_buildroot.mak
  76. 1 1
      wave511/code/WaveDecode-ffmpeg.mak
  77. 168 0
      wave511/code/WaveDecode_buildroot.mak
  78. 11 0
      wave511/code/build_env.sh
  79. 2 0
      wave511/code/cp.sh
  80. 7 2
      wave511/code/sample_v2/component/cnm_app.h
  81. 5 1
      wave511/code/sample_v2/component/cnm_app_internal.h
  82. 4 1
      wave511/code/sample_v2/component/component.c
  83. 49 3
      wave511/code/sample_v2/component/component.h
  84. 3 1
      wave511/code/sample_v2/component_decoder/component_dec_decoder.c
  85. 43 0
      wave511/code/sample_v2/component_decoder/component_dec_feeder.c
  86. 177 14
      wave511/code/sample_v2/component_decoder/component_dec_renderer.c
  87. 2 2
      wave511/code/sample_v2/component_decoder/decoder_listener.c
  88. 7 2
      wave511/code/sample_v2/component_decoder/decoder_listener.h
  89. 2 2
      wave511/code/sample_v2/component_encoder/encoder_listener.c
  90. 7 2
      wave511/code/sample_v2/component_encoder/encoder_listener.h
  91. 50 0
      wave511/code/sample_v2/helper/bitstream/bitstreamfeeder.c
  92. 125 0
      wave511/code/sample_v2/helper/bitstream/bsfeeder_buffer_impl.c
  93. 94 9
      wave511/code/sample_v2/helper/main_helper.c
  94. 51 5
      wave511/code/sample_v2/helper/main_helper.h
  95. 325 0
      wave511/code/sample_v2/helper/misc/cnm_video_helper.c
  96. 1 1
      wave511/code/sample_v2/helper/misc/datastructure.c
  97. 8 2
      wave511/code/sample_v2/helper/misc/debug.h
  98. 6 1
      wave511/code/sample_v2/helper/misc/pbu.h
  99. 298 0
      wave511/code/vdi/linux/driver/vdec-starfive.h
  100. 61 0
      wave511/code/vdi/linux/driver/vdec.c

+ 3 - 0
codaj12/build_for_riscv.sh

@@ -45,3 +45,6 @@ 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 ../../work/buildroot_initramfs_sysroot/root/
+
+

+ 41 - 0
codaj12/codaj12Driver_buildroot.mak

@@ -0,0 +1,41 @@
+# 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 ARCH=riscv
+export SUBARCH=riscv
+export CROSS_COMPILE=riscv64-buildroot-linux-gnu-
+
+DRV_PATH  := $(shell pwd)/jdi/linux/driver
+EXTRA_CFLAGS +=	$(DEBFLAGS) -I$(LDDINCDIR) -Wall
+
+ifneq ($(KERNELRELEASE),)
+# call from kernel build system
+
+obj-m	:= jdec.o
+
+else
+
+default:
+	$(MAKE) -C $(KERNELDIR)	M=$(DRV_PATH) LDDINCDIR=$(DRV_PATH)/../include modules
+
+endif
+
+
+
+clean:
+	rm -rf $(DRV_PATH)/*.o $(DRV_PATH)/*~ $(DRV_PATH)/core $(DRV_PATH)/.depend $(DRV_PATH)/.*.cmd $(DRV_PATH)/*.ko $(DRV_PATH)/*.mod.c $(DRV_PATH)/modules.order $(DRV_PATH)/.tmp_versions $(DRV_PATH)/*.dwo $(DRV_PATH)/.*.dwo
+
+depend .depend dep:
+	$(CC) $(CFLAGS)	-M *.c > .depend
+
+
+ifeq (.depend,$(wildcard .depend))
+include	.depend
+endif

+ 148 - 0
codaj12/codaj12_buildroot.mak

@@ -0,0 +1,148 @@
+# ----------------------------------------------------------------------
+#
+# codaj12
+#
+# ----------------------------------------------------------------------
+.PHONY: CREATE_DIR
+BUILD_CONFIGURATION := EmbeddedRiscvLinux
+PRODUCT := CODAJ12
+PRODUCT := CODDAJ12C
+
+USE_PTHREAD = yes
+USE_RTL_SIM = no
+LINT_HOME   = etc/lint
+
+UNAME = $(shell uname -a)
+ifneq (,$(findstring i386, $(UNAME)))
+    USE_32BIT = yes
+endif
+
+ifeq ($(RTL_SIM), 1)
+USE_RTL_SIM = yes
+endif
+
+REFC    := 0
+
+ifeq ($(USE_32BIT), yes)
+PLATFORM    = nativelinux
+else
+PLATFORM    = nativelinux_64bit
+endif
+
+CROSS_CC_PREFIX =
+JDI_C           = jdi/linux/jdi.c
+VDI_OSAL_C      =
+MM_C            =
+PLATFORM_FLAGS  =
+JDI_VPATH       = jdi/linux
+ifeq ("$(BUILD_CONFIGURATION)", "NonOS")
+    CROSS_CC_PREFIX = arm-none-eabi-
+    JDI_C           = jdi/nonos/jdi.c
+    VDI_OSAL_C      =
+    MM_C            = jdi/mm.c
+    USE_PTHREAD     = no
+    PLATFORM        = none
+    DEFINES         = -DLIB_C_STUB
+    PLATFORM_FLAGS  =
+    JDI_VPATH       = jdi/nonos
+    NONOS_RULE      = options_nonos.lnt
+endif
+ifeq ("$(BUILD_CONFIGURATION)", "EmbeddedLinux")
+    CROSS_CC_PREFIX = arm-none-linux-gnueabi-
+    PLATFORM        = armlinux
+endif
+
+ifeq ("$(BUILD_CONFIGURATION)", "EmbeddedRiscvLinux")
+    CROSS_CC_PREFIX = riscv64-buildroot-linux-gnu-
+    PLATFORM        = riscvlinux
+endif
+CC  = $(CROSS_CC_PREFIX)gcc
+CXX = $(CROSS_CC_PREFIX)g++
+LINKER=$(CC)
+AR  = $(CROSS_CC_PREFIX)ar
+
+INCLUDES = -I./jpuapi -I./ffmpeg/include -I./sample/helper -I./sample -I./jdi -I../
+ifeq ($(USE_RTL_SIM), yes)
+DEFINES += -DCNM_SIM_PLATFORM -DCNM_SIM_DPI_INTERFACE -DSUPPORT_DECODER
+DEFINES += -D$(PRODUCT) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
+else
+DEFINES += -D$(PRODUCT) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
+endif	# USE_SIM_PLATFORM
+DEFINES += -DUSE_FEEDING_METHOD_BUFFER
+
+CFLAGS  += -g -I. -Wno-format-truncation -Wl,--fatal-warning $(INCLUDES) $(DEFINES) $(PLATFORM_FLAGS)
+ifeq ($(USE_RTL_SIM), yes)
+ifeq ($(IUS), 1)
+CFLAGS  += -fPIC # ncverilog is 64bit version
+endif
+endif
+ARFLAGS += cru
+
+LDFLAGS  = $(PLATFORM_FLAGS)
+
+ifeq ($(USE_PTHREAD), yes)
+LDLIBS  += -lpthread
+endif
+LDLIBS  += -lm
+
+BUILDLIST=DECTEST
+MAKEFILE=codaj12_buildroot.mak
+DECTEST=libcodadec.so
+
+OBJDIR=obj
+ALLOBJS=*.o
+ALLDEPS=*.dep
+ALLLIBS=*.a
+RM=rm -f
+MKDIR=mkdir -p
+
+SOURCES_COMMON = 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 bsfeeder_buffer_impl.c\
+                $(JDI_C)             \
+                $(VDI_OSAL_C)        \
+                $(MM_C)
+
+VPATH = jdi:
+VPATH += sample:
+VPATH += sample/helper:
+VPATH += $(JDI_VPATH):jpuapi
+
+VPATH2=$(patsubst %,-I%,$(subst :, ,$(VPATH)))
+
+OBJECTNAMES_COMMON=$(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCES_COMMON)))
+OBJECTPATHS_COMMON=$(addprefix $(OBJDIR)/,$(notdir $(OBJECTNAMES_COMMON)))
+
+SOURCES_DECTEST = sample/main_jpg_dec_test.c
+ifeq ($(USE_RTL_SIM), yes)
+	SOURCES_DECTEST += sample/main_sim.c
+endif
+
+OBJECTNAMES_DECTEST=$(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCES_DECTEST)))
+OBJECTPATHS_DECTEST=$(addprefix $(OBJDIR)/,$(notdir $(OBJECTNAMES_DECTEST))) $(OBJECTPATHS_COMMON)
+
+all: $(BUILDLIST)
+
+ifeq ($(USE_RTL_SIM), yes)
+DECTEST: CREATE_DIR $(OBJECTPATHS_COMMON)
+else
+DECTEST: CREATE_DIR $(OBJECTPATHS_COMMON)
+	$(LINKER) -g -fPIC -shared -o $(DECTEST) $(LDFLAGS) -Wl,-gc-section -Wl,--start-group $(OBJECTPATHS_COMMON) $(LDLIBS) -Wl,--end-group
+endif
+
+
+-include $(OBJECTPATHS:.o=.dep)
+
+clean:
+	$(RM) $(DECTEST)
+	$(RM) $(OBJDIR)/$(ALLOBJS)
+	$(RM) $(OBJDIR)/$(ALLDEPS)
+
+CREATE_DIR:
+	-mkdir -p $(OBJDIR)
+
+obj/%.o: %.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+lint:
+	"$(LINT_HOME)/flint" -i"$(LINT_HOME)" $(DEFINES) $(INCLUDES) $(VPATH2) linux_std.lnt $(HAPS_RULE) $(NONOS_RULE)  $(SOURCES_COMMON)
+

+ 12 - 3
codaj12/jdi/jdi.h

@@ -28,9 +28,17 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdarg.h>
-#include "../jpuapi/jpuconfig.h"
-#include "mm.h"
-#include "jputypes.h"
+
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "codaj12/jpuapi/jpuconfig.h"
+    #include "codaj12/jdi/mm.h"
+    #include "codaj12/jpuapi/jputypes.h"
+#else
+    #include "../jpuapi/jpuconfig.h"
+    #include "mm.h"
+    #include "jputypes.h"
+#endif
+
 
 #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
@@ -103,6 +111,7 @@ extern "C" {
 
     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_attach_dma_memory(jpu_buffer_t *vb);
 
     int jdi_lock();
     void jdi_unlock();

+ 301 - 0
codaj12/jdi/linux/driver/jpu-starfive.h

@@ -0,0 +1,301 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 StarFive Technology Co., Ltd.
+ */
+#ifndef __JPU_STARFIVE_H__
+#define __JPU_STARFIVE_H__
+
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+#include <linux/reset-controller.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/clk-provider.h>
+
+#define JPU_ID_NUM 5
+
+struct starfive_jpu_data {
+	struct device *dev;
+
+	struct clk *clk_jpu_id[JPU_ID_NUM];
+	struct reset_control *rst_jpu_id[JPU_ID_NUM];
+
+};
+
+static struct starfive_jpu_data *sf_jpu = NULL;
+
+const char jpu_data_id[JPU_ID_NUM][15] = {
+	"jpcgc300_main",
+	"vdecbrg_main",
+	"jpeg_axi",
+	"jpeg_cclk",
+	"jpeg_apb",
+};
+
+
+void starfive_jpu_rst_status(void)
+{
+	int i;
+	int rst_state;
+	for (i = 0; i < JPU_ID_NUM; i++) {
+		rst_state = reset_control_status(sf_jpu->rst_jpu_id[i]);
+		dev_dbg(sf_jpu->dev, "status_rst%d:%d", i, rst_state);
+	}
+
+	return;
+}
+
+void starfive_jpu_clk_status(void)
+{
+	int i;
+	int clk_state;
+	for (i = 0; i < JPU_ID_NUM; i++) {
+		clk_state = __clk_is_enabled(sf_jpu->clk_jpu_id[i]);
+		dev_dbg(sf_jpu->dev, "status_clk%d:%d", i, clk_state);
+	}
+
+	return;
+}
+
+/*Do not assert the reset: jpeg_axi, jpcgc300_main, vdecbrg_main. */
+void starfive_jpu_rst_exit(void)
+{
+    int i;
+	int ret;
+	for (i = 3; i < JPU_ID_NUM; i++) {
+		ret = reset_control_assert(sf_jpu->rst_jpu_id[i]);
+		if (ret) {
+			dev_err(sf_jpu->dev, "JPU reset assert failed:\n");
+			dev_err(sf_jpu->dev, jpu_data_id[i]);
+		}
+	}
+	return;
+}
+
+/*Do not disable the clock: jpeg_axi, jpcgc300_main, vdecbrg_main. */
+void starfive_jpu_clk_exit(void)
+{
+	int i;
+	for (i = 2; i < JPU_ID_NUM; i++) {
+		clk_disable_unprepare(sf_jpu->clk_jpu_id[i]);
+	}
+	return;
+}
+
+static int starfive_jpu_clk_init(void)
+{
+	int ret = 0;
+	int i;
+	for (i = 0; i < JPU_ID_NUM; i++) {
+		ret = clk_prepare_enable(sf_jpu->clk_jpu_id[i]);
+		if (ret) {
+			dev_err(sf_jpu->dev, "JPU enable clock failed:\n");
+			dev_err(sf_jpu->dev, jpu_data_id[i]);
+			goto init_clk_failed;
+		}
+	}
+
+	return 0;
+
+init_clk_failed:
+	for(; i > 2 ; i--) {
+		clk_disable_unprepare(sf_jpu->clk_jpu_id[i-1]);
+	}
+
+	return ret;
+}
+
+static int starfive_jpu_get_clk(void)
+{
+	int ret = 0;
+	int i;
+	for ( i = 0; i < JPU_ID_NUM ; i++) {
+		sf_jpu->clk_jpu_id[i] = devm_clk_get(sf_jpu->dev, jpu_data_id[i]);
+		if (IS_ERR(sf_jpu->clk_jpu_id[i])) {
+			dev_err(sf_jpu->dev, "JPU get clock failed: \n");
+			dev_err(sf_jpu->dev,  jpu_data_id[i]);
+			ret = PTR_ERR(sf_jpu->clk_jpu_id[i]);
+			goto get_clk_failed;
+		}
+	}
+
+	return 0;
+
+get_clk_failed:
+	for( ; i > 0 ; i--) {
+		devm_clk_put(sf_jpu->dev, sf_jpu->clk_jpu_id[i-1]);
+	}
+
+	return ret;
+}
+
+static int starfive_jpu_reset_init(void)
+{
+	int ret = 0;
+	int i;
+	for (i = 2; i < JPU_ID_NUM ; i++) {
+		ret = reset_control_deassert(sf_jpu->rst_jpu_id[i]);
+		if (ret) {
+			dev_err(sf_jpu->dev, "JPU reset deassert failed: \n");
+			dev_err(sf_jpu->dev, jpu_data_id[i]);
+			goto init_reset_failed;
+		}
+	}
+
+	return 0;
+
+init_reset_failed:
+	for (; i > 3 ; i--) {
+		reset_control_assert(sf_jpu->rst_jpu_id[i-1]);
+	}
+
+	return ret;
+}
+
+/*Do not manipulate the reset: jpcgc300_main, vdecbrg_main. */
+static int starfive_jpu_get_resets(void)
+{
+	int ret = 0;
+	int i;
+	for (i = 2; i < JPU_ID_NUM ; i++) {
+		sf_jpu->rst_jpu_id[i] = devm_reset_control_get_exclusive(sf_jpu->dev, jpu_data_id[i]);
+		if (IS_ERR(sf_jpu->rst_jpu_id[i])) {
+			dev_err(sf_jpu->dev, "failed to get JPU reset: \n");
+			dev_err(sf_jpu->dev,  jpu_data_id[i]);
+			ret = PTR_ERR(sf_jpu->rst_jpu_id[i]);
+			goto get_resets_failed;
+		}
+	}
+
+	return 0;
+
+get_resets_failed:
+	for (; i > 0; i--) {
+		reset_control_put(sf_jpu->rst_jpu_id[i-1]);
+	}
+
+	return ret;
+}
+
+int starfive_jpu_data_init(struct device *dev)
+{
+	int ret = 0;
+
+	if (sf_jpu == NULL){
+		sf_jpu = devm_kzalloc(dev, sizeof(*sf_jpu), GFP_KERNEL);
+		if (!sf_jpu)
+			return -ENOMEM;
+		sf_jpu->dev = dev;
+
+		ret = starfive_jpu_get_clk();
+		if (ret) {
+			dev_err(sf_jpu->dev, "failed to get jpu clock\n");
+			return ret;
+		}
+
+		ret = starfive_jpu_get_resets();
+		if (ret) {
+			dev_err(sf_jpu->dev, "failed to get jpu resets\n");
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+int starfive_jpu_clk_enable(struct device *dev)
+{
+    int ret = 0;
+
+	ret = starfive_jpu_data_init(dev);
+	if (ret)
+		return ret;
+
+	ret = starfive_jpu_clk_init();
+	if (ret) {
+		dev_err(sf_jpu->dev, "failed to enable jpu clock\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+int starfive_jpu_clk_disable(struct device *dev)
+{
+    int ret = 0;
+
+	ret = starfive_jpu_data_init(dev);
+	if (ret)
+		return ret;
+
+	starfive_jpu_clk_exit();
+
+	return 0;
+}
+
+int starfive_jpu_rst_deassert(struct device *dev)
+{
+    int ret = 0;
+
+	ret = starfive_jpu_data_init(dev);
+	if (ret)
+		return ret;
+
+	ret = starfive_jpu_reset_init();
+	if (ret) {
+		dev_err(sf_jpu->dev, "failed to deassert jpu resets\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+int starfive_jpu_rst_assert(struct device *dev)
+{
+    int ret = 0;
+
+	ret = starfive_jpu_data_init(dev);
+	if (ret)
+		return ret;
+
+	starfive_jpu_rst_exit();
+
+	return 0;
+}
+
+
+int starfive_jpu_clk_rst_init(struct platform_device *pdev)
+{
+    int ret = 0;
+
+	ret = starfive_jpu_data_init(&pdev->dev);
+	if (ret)
+		return ret;
+
+	ret = starfive_jpu_clk_init();
+	if (ret) {
+		dev_err(sf_jpu->dev, "failed to enable jpu clock\n");
+		return ret;
+	}
+
+	starfive_jpu_rst_exit();
+	mdelay(1);
+	ret = starfive_jpu_reset_init();
+	if (ret) {
+		dev_err(sf_jpu->dev, "failed to set jpu reset\n");
+		goto init_failed;
+	}
+
+	dev_info(sf_jpu->dev,"success to init JPU clock & reset.");
+    return 0;
+
+init_failed:
+    starfive_jpu_clk_exit();
+    return ret;
+
+}
+
+#endif
+

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

@@ -406,6 +406,75 @@ static long jpu_ioctl(struct file *filp, u_int cmd, u_long arg)
             DPRINTK("[JPUDRV][-]JDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY\n");
         }
         break;
+    case JDI_IOCTL_GET_PHYSICAL_MEMORY:
+        {
+            jpudrv_buffer_pool_t *jbp = NULL;
+            void *user_address = NULL;
+            struct task_struct *my_struct = NULL;
+            struct mm_struct *mm = NULL;
+            unsigned long address = 0;
+            pgd_t *pgd = NULL;
+
+            DPRINTK("[JPUDRV][+]JDI_IOCTL_GET_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;
+                }
+
+                user_address = (void *)jbp->jb.virt_addr;
+                my_struct = get_current();
+                mm = my_struct->mm;
+                address = (unsigned long)user_address;
+                pgd = pgd_offset(mm, address);
+
+                if (!pgd_none(*pgd) && !pgd_bad(*pgd)) {
+                    p4d_t *p4d = p4d_offset(pgd, address);
+                    pud_t *pud = pud_offset(p4d, address);
+                    if (!pud_none(*pud) && !pud_bad(*pud)) {
+                        pmd_t *pmd = pmd_offset(pud, address);
+                        if (!pmd_none(*pmd) && !pmd_bad(*pmd)) {
+                            pte_t *pte = pte_offset_map(pmd, address);
+                            if (!pte_none(*pte)) {
+                                struct page *pg = pte_page(*pte);
+                                unsigned long phys = page_to_phys(pg);
+                                unsigned long virt = (unsigned long)phys_to_virt(phys);
+                                printk("phy address = %lx, virt = %lx\r\n", phys, virt);
+                                jbp->jb.phys_addr = phys;
+                                jbp->jb.base = virt;
+                            }
+                            pte_unmap(pte);
+                        }
+                    }
+                }
+                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_GET_PHYSICAL_MEMORY\n");
+        }
+        break;
     case JDI_IOCTL_FREE_PHYSICALMEMORY:
         {
             jpudrv_buffer_pool_t *jbp, *n;

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

@@ -20,6 +20,7 @@
 #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 JDI_IOCTL_GET_PHYSICAL_MEMORY               _IO(JDI_IOCTL_MAGIC, 12)
 
 #define MEM2SYS(addr) ((addr) > 0x40000000 && (addr) < 0x240000000 ? ((addr)+0x400000000):(addr))
 

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

@@ -530,6 +530,46 @@ int jdi_read_memory(unsigned long addr, unsigned char *data, int len, int endian
     return len;
 }
 
+int jdi_attach_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.virt_addr = vb->virt_addr;
+    if (ioctl(jdi->jpu_fd, JDI_IOCTL_GET_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;
+
+    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_attach_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;
+}
+
 int jdi_allocate_dma_memory(jpu_buffer_t *vb)
 {
     jdi_info_t *jdi;

+ 334 - 1
codaj12/jpuapi/jpuapi.c

@@ -230,7 +230,7 @@ JpgRet JPU_DecOpen(JpgDecHandle * pHandle, JpgDecOpenParam * pop)
 
     pDecInfo->streamWrPtr = pop->bitstreamBuffer;
     pDecInfo->streamRdPtr = pop->bitstreamBuffer;
-
+    JLOG(INFO, "streamWrPtr = %x\r\n", pop->bitstreamBuffer);
     pDecInfo->streamBufStartAddr = pop->bitstreamBuffer;
     pDecInfo->streamBufSize     = pop->bitstreamBufferSize;
     pDecInfo->streamBufEndAddr  = pop->bitstreamBuffer + pop->bitstreamBufferSize;
@@ -374,6 +374,21 @@ JpgRet JPU_DecGetInitialInfo(JpgDecHandle handle, JpgDecInitialInfo * info)
     return JPG_RET_SUCCESS;
 }
 
+FrameBuffer *JPU_GetFrameBufPool(JpgDecHandle handle)
+{
+    JpgInst * pJpgInst;
+    JpgDecInfo * pDecInfo;
+    JpgRet ret;
+
+
+    ret = CheckJpgInstValidity(handle);
+    if (ret != JPG_RET_SUCCESS)
+        return NULL;
+
+    pJpgInst = handle;
+    pDecInfo = &pJpgInst->JpgInfo->decInfo;
+    return pDecInfo->frameBufPool;
+}
 
 JpgRet JPU_DecRegisterFrameBuffer(JpgDecHandle handle, FrameBuffer * bufArray, int num, int stride)
 {
@@ -414,6 +429,61 @@ JpgRet JPU_DecRegisterFrameBuffer(JpgDecHandle handle, FrameBuffer * bufArray, i
     return JPG_RET_SUCCESS;
 }
 
+JpgRet JPU_DecRegisterFrameBuffer2(JpgDecHandle handle, FrameBuffer * bufArray, int stride)
+{
+    JpgInst * pJpgInst;
+    JpgDecInfo * pDecInfo;
+    JpgRet ret;
+    int number;
+
+    ret = CheckJpgInstValidity(handle);
+    if (ret != JPG_RET_SUCCESS)
+        return ret;
+
+    pJpgInst = handle;
+    pDecInfo = &pJpgInst->JpgInfo->decInfo;
+    number = pDecInfo->numFrameBuffers;
+
+    if (!pDecInfo->initialInfoObtained) {
+        return JPG_RET_WRONG_CALL_SEQUENCE;
+    }
+
+    if (bufArray == 0) {
+        return JPG_RET_INVALID_FRAME_BUFFER;
+    }
+
+    if ((stride % 8) != 0) {
+        return JPG_RET_INVALID_STRIDE;
+    }
+
+
+    if (pDecInfo->frameBufPool == NULL)
+    {
+        //First register
+        JLOG(INFO, "%s First register frame buffer\r\n", __FUNCTION__);
+        pDecInfo->frameBufPool = bufArray;
+        pDecInfo->stride          = stride;
+        pDecInfo->stride_c        = bufArray->strideC;
+    }
+
+    //check wether frameBufPool and bufArray match
+    if (pDecInfo->frameBufPool[number].bufY != bufArray->bufY)
+    {
+        JLOG(ERR, "Does not support discontinuous array!\n");
+        return JPG_RET_FAILURE;
+    }
+    number ++;
+
+    if (number >= MAX_FRAME)
+    {
+        JLOG(ERR, "Too lot of frame buffer! %d/%d\n", number, MAX_FRAME);
+        return JPG_RET_FAILURE;
+    }
+    pDecInfo->numFrameBuffers = number;
+    JLOG(INFO, "%s numFrameBuffers = %d\r\n", __FUNCTION__, pDecInfo->numFrameBuffers);
+    return JPG_RET_SUCCESS;
+}
+
 JpgRet JPU_DecGetBitstreamBuffer(JpgDecHandle handle,
     PhysicalAddress * prdPtr,
     PhysicalAddress * pwrPtr,
@@ -883,6 +953,269 @@ JpgRet JPU_DecStartOneFrame(JpgDecHandle handle, JpgDecParam *param)
     JpuWriteInstReg(instRegIndex, MJPEG_ROT_INFO_REG, (ppuEnable<<4) | (pDecInfo->mirrorIndex<<2) | pDecInfo->rotationIndex);
 
     val = (pDecInfo->frameIdx % pDecInfo->numFrameBuffers);
+    // JLOG(INFO, "%s: bufY = %lx bufCb = %lx bufCr = %lx stride = %d stride_c = %d\r\n", __FUNCTION__,
+    //     pDecInfo->frameBufPool[val].bufY, pDecInfo->frameBufPool[val].bufCb, pDecInfo->frameBufPool[val].bufCr,
+    //     pDecInfo->stride, pDecInfo->stride_c);
+    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_DecStartOneFrameBySerialNum(JpgDecHandle handle, JpgDecParam *param,int bufferIndex)
+{
+    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 = (Uint32)bufferIndex;
+    // JLOG(INFO, "%s: bufY = %lx bufCb = %lx bufCr = %lx stride = %d stride_c = %d\r\n", __FUNCTION__,
+    //     pDecInfo->frameBufPool[val].bufY, pDecInfo->frameBufPool[val].bufCb, pDecInfo->frameBufPool[val].bufCr,
+    //     pDecInfo->stride, pDecInfo->stride_c);
     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);

+ 14 - 3
codaj12/jpuapi/jpuapi.h

@@ -26,9 +26,15 @@
 #ifndef JPUAPI_H_INCLUDED
 #define JPUAPI_H_INCLUDED
 
-#include "jpuconfig.h"
-#include "../jdi/jdi.h"
-#include "jputypes.h"
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "codaj12/jpuapi/jpuconfig.h"
+    #include "codaj12/jdi/jdi.h"
+    #include "codaj12/jpuapi/jputypes.h"
+#else
+    #include "jpuconfig.h"
+    #include "../jdi/jdi.h"
+    #include "jputypes.h"
+#endif
 
 /* _n: number, _s: significance */
 #define JPU_CEIL(_s, _n)        (((_n)+(_s-1))&~(_s-1))
@@ -1047,6 +1053,11 @@ This means the stream ends.
     JpgRet JPU_DecStartOneFrame(
         JpgDecHandle handle,
         JpgDecParam *param );
+
+    JpgRet JPU_DecStartOneFrameBySerialNum(
+        JpgDecHandle handle,
+        JpgDecParam *param,
+        int bufferIndex );
 /**
 * @brief
 Application can get the information of output of decoding. The information

+ 5 - 1
codaj12/jpuapi/jpuapifunc.h

@@ -26,7 +26,11 @@
 #ifndef JPUAPI_UTIL_H_INCLUDED
 #define JPUAPI_UTIL_H_INCLUDED
 
-#include "jpuapi.h"
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "codaj12/jpuapi/jpuapi.h"
+#else
+    #include "jpuapi.h"
+#endif
 
 #define DC_TABLE_INDEX0				0
 #define AC_TABLE_INDEX0				1

+ 5 - 1
codaj12/jpuapi/jpuconfig.h

@@ -25,7 +25,11 @@
 #ifndef _JPU_CONFIG_H_
 #define _JPU_CONFIG_H_
 
-#include "../config.h"
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "codaj12/config.h"
+#else
+    #include "../config.h"
+#endif
 
 #define MAX_NUM_JPU_CORE                1
 #define MAX_NUM_INSTANCE                4

+ 5 - 1
codaj12/jpuapi/regdefine.h

@@ -22,8 +22,12 @@
  * (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 "../config.h"
 
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "codaj12/config.h"
+#else
+    #include "../config.h"
+#endif
 
 #ifndef NPT_REGDEFINE_H_INCLUDED
 #define NPT_REGDEFINE_H_INCLUDED

+ 41 - 10
codaj12/sample/helper/bitstreamfeeder.c

@@ -45,6 +45,11 @@ extern void* BSFeederFrameSize_Create(const char* path);
 extern BOOL BSFeederFrameSize_Destroy(void* feeder);
 extern Int32 BSFeederFrameSize_Act(void* feeder, BSChunk* packet);
 
+extern void* BSFeederBuffer_Create(const char* path);
+extern BOOL BSFeederBuffer_Destroy(void* feeder);
+extern Int32 BSFeederBuffer_Act(void* feeder,BSChunk* chunk);
+extern BOOL BSFeederBuffer_Rewind(void* feeder);
+extern void BSFeederBuffer_SetFeedingSize(void* feeder,Uint32 feedingSize);
 /**
 * Abstract Bitstream Feeader Functions 
 */
@@ -61,6 +66,11 @@ BSFeeder BitstreamFeeder_Create(const char* path, FeedingMethod method, EndianMo
     case FEEDING_METHOD_FRAME_SIZE:
         feeder = BSFeederFrameSize_Create(path);
         break;
+#endif
+#ifdef USE_FEEDING_METHOD_BUFFER
+    case FEEDING_METHOD_BUFFER:
+        feeder = BSFeederBuffer_Create(path);
+        break;
 #endif
     default:
         feeder = NULL;
@@ -83,6 +93,15 @@ BSFeeder BitstreamFeeder_Create(const char* path, FeedingMethod method, EndianMo
     return (BSFeeder)handle;
 }
 
+Uint32 BitstreamFeeder_SetData(BSFeeder feeder, void *data, Uint32 size)
+{
+    BitstreamFeeder* bsf = (BitstreamFeeder*)feeder;
+    bsf->remainData = data;
+    bsf->remainDataSize = size;
+
+    return 0;
+}
+
 Uint32 BitstreamFeeder_Act(BSFeeder feeder, JpgDecHandle handle, jpu_buffer_t* bsBuffer)
 {
     BitstreamFeeder* bsf = (BitstreamFeeder*)feeder;
@@ -98,9 +117,9 @@ Uint32 BitstreamFeeder_Act(BSFeeder feeder, JpgDecHandle handle, jpu_buffer_t* b
     }
 
     JPU_DecGetBitstreamBuffer(handle, NULL/* rdPtr */, &wrPtr, &room);
-
+    JLOG(INFO, "wrptr address = %x\r\n", wrPtr);
     endian = bsf->endian;
-
+    JLOG(INFO, "endian = %d\r\n", endian);
     if (bsf->remainData == NULL) {
         chunk.size = bsBuffer->size; 
         chunk.data = malloc(chunk.size);
@@ -117,6 +136,11 @@ Uint32 BitstreamFeeder_Act(BSFeeder feeder, JpgDecHandle handle, jpu_buffer_t* b
         case FEEDING_METHOD_FRAME_SIZE:
             feedingSize = BSFeederFrameSize_Act(bsf->actualFeeder, &chunk);
             break;
+#endif
+#ifdef USE_FEEDING_METHOD_BUFFER
+        case FEEDING_METHOD_BUFFER:
+            feedingSize = BSFeederBuffer_Act(bsf->actualFeeder, &chunk);
+            break;
 #endif
         default:
             JLOG(ERR, "%s:%d Invalid method(%d)\n", __FUNCTION__, __LINE__, bsf->method);
@@ -125,6 +149,7 @@ Uint32 BitstreamFeeder_Act(BSFeeder feeder, JpgDecHandle handle, jpu_buffer_t* b
         }
     }
     else {
+        JLOG(INFO, "Get data from remain\r\n");
         chunk.data  = bsf->remainData;
         feedingSize = bsf->remainDataSize;
     }
@@ -161,11 +186,12 @@ Uint32 BitstreamFeeder_Act(BSFeeder feeder, JpgDecHandle handle, jpu_buffer_t* b
             rightSize = endAddr-wrPtr;
             leftSize  = (wrPtr+wSize) - endAddr;
             if (rightSize > 0) {
+                JLOG(INFO, "1 wrptr address = %x, addr = %p, size = %x\r\n", wrPtr, ptr, rightSize);
                 JpuWriteMem(wrPtr, ptr, rightSize, (int)endian);
             }
             wrPtr = base;
         }
-
+        JLOG(INFO, "2 wrptr address = %x, ptr = %p, rightsize = %x, size = %x\r\n", wrPtr, ptr, rightSize, leftSize);
         JpuWriteMem(wrPtr, ptr+rightSize, leftSize, (int)endian);
 
         JPU_DecUpdateBitstreamBuffer(handle, wSize);
@@ -174,11 +200,11 @@ Uint32 BitstreamFeeder_Act(BSFeeder feeder, JpgDecHandle handle, jpu_buffer_t* b
     if (TRUE == chunk.eos) {
         JPU_DecUpdateBitstreamBuffer(handle, 0);
     }
-
+    JLOG(INFO, "bsf->remainData = %p, chunk.data = %p\r\n", bsf->remainData, chunk.data);
     bsf->eos = chunk.eos;
-    if (NULL == bsf->remainData) 
-        free(chunk.data);
-
+    // if (NULL == bsf->remainData)
+    //     free(chunk.data);
+    JLOG(INFO, "%s out\r\n", __FUNCTION__);
     return feedingSize;
 }
 
@@ -210,15 +236,20 @@ BOOL BitstreamFeeder_Destroy(BSFeeder feeder)
     case FEEDING_METHOD_FRAME_SIZE:
         BSFeederFrameSize_Destroy(bsf->actualFeeder);
         break;
+#endif
+#ifdef USE_FEEDING_METHOD_BUFFER
+    case FEEDING_METHOD_BUFFER:
+        BSFeederBuffer_Destroy(bsf->actualFeeder);
+        break;
 #endif
     default:
         JLOG(ERR, "%s:%d Invalid method(%d)\n", __FUNCTION__, __LINE__, bsf->method);
         break;
     }
 
-    if (bsf->remainData) {
-        free(bsf->remainData);
-    }
+    // if (bsf->remainData) {
+    //     free(bsf->remainData);
+    // }
 
     free(bsf);
 

+ 121 - 0
codaj12/sample/helper/bsfeeder_buffer_impl.c

@@ -0,0 +1,121 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <errno.h>
+
+#include "jpuapifunc.h"
+#include "main_helper.h"
+
+#define MAX_FEEDING_SIZE 0x400000    /* 4MBytes */
+#define DEFAULT_FEEDING_SIZE 0x20000 /* 128KBytes */
+
+typedef struct FeederFixedContext
+{
+    void *address;
+    Uint32 size;
+    Uint32 offset;
+    Uint32 feedingSize;
+    BOOL eos;
+} FeederFixedContext;
+
+void *BSFeederBuffer_Create(const char *path)
+{
+    FeederFixedContext *context = NULL;
+
+    context = (FeederFixedContext *)malloc(sizeof(FeederFixedContext));
+    if (context == NULL)
+    {
+        JLOG(ERR, "%s:%d failed to allocate memory\n", __FUNCTION__, __LINE__);
+        return NULL;
+    }
+
+    context->feedingSize = DEFAULT_FEEDING_SIZE;
+    context->eos = FALSE;
+    context->offset = 0;
+    return (void *)context;
+}
+
+BOOL BSFeederBuffer_Destroy(void *feeder)
+{
+    FeederFixedContext *context = (FeederFixedContext *)feeder;
+
+    if (context == NULL)
+    {
+        JLOG(ERR, "%s:%d Null handle\n", __FUNCTION__, __LINE__);
+        return FALSE;
+    }
+
+    free(context);
+
+    return TRUE;
+}
+
+void BSFeederBuffer_SetData(
+    void *feeder,
+    char *address,
+    Uint32 size)
+{
+    FeederFixedContext *context = (FeederFixedContext *)feeder;
+    context->address = address;
+    context->size = size;
+}
+
+void BSFeederBuffer_SetEos(void *feeder)
+{
+    FeederFixedContext *context = (FeederFixedContext *)feeder;
+    context->eos = TRUE;
+}
+
+BOOL BSFeederBuffer_GetEos(void *feeder)
+{
+    FeederFixedContext *context = (FeederFixedContext *)feeder;
+    return context->eos;
+}
+
+Int32 BSFeederBuffer_Act(
+    void *feeder,
+    BSChunk *chunk)
+{
+    FeederFixedContext *context = (FeederFixedContext *)feeder;
+
+    if (context == NULL)
+    {
+        JLOG(ERR, "%s:%d Null handle\n", __FUNCTION__, __LINE__);
+        return 0;
+    }
+    // Due to memory performance, memset is temporarily commented
+    // memset(chunk->data, 0x00, chunk->size);
+    if (context->size == 0)
+    {
+        chunk->eos = TRUE;
+        return 0;
+    }
+
+    do
+    {
+        memcpy(chunk->data, context->address, context->size);
+    } while (FALSE);
+
+    return context->size;
+}
+
+BOOL BSFeederBuffer_Rewind(
+    void *feeder)
+{
+    FeederFixedContext *context = (FeederFixedContext *)feeder;
+
+    context->eos = FALSE;
+
+    return TRUE;
+}
+
+void BSFeederBuffer_SetFeedingSize(
+    void *feeder,
+    Uint32 feedingSize)
+{
+    FeederFixedContext *context = (FeederFixedContext *)feeder;
+    if (feedingSize > 0)
+    {
+        context->feedingSize = feedingSize;
+    }
+}

+ 5 - 1
codaj12/sample/helper/cnm_fpga.h

@@ -26,7 +26,11 @@
 #ifndef CNM_FPGA_H_INCLUDED
 #define CNM_FPGA_H_INCLUDED
 
-#include "jputypes.h"
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "codaj12/jpuapi/jputypes.h"
+#else
+    #include "jputypes.h"
+#endif
 
 #ifdef __cplusplus
 extern "C" {

+ 7 - 2
codaj12/sample/helper/datastructure.h

@@ -25,8 +25,13 @@
 #ifndef __DATA_STRUCTURE_H__
 #define __DATA_STRUCTURE_H__
 
-#include "jputypes.h"
-#include "platform.h"
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "codaj12/jpuapi/jputypes.h"
+    #include "codaj12/sample/helper/platform.h"
+#else
+    #include "jputypes.h"
+    #include "platform.h"
+#endif
 
 #ifdef __cplusplus
 extern "C" {

+ 201 - 4
codaj12/sample/helper/jpuhelper.c

@@ -33,7 +33,7 @@
 #include "jpulog.h"
 #include "main_helper.h"
 
-static fb_context s_fb[MAX_NUM_INSTANCE];
+fb_context s_fb[MAX_NUM_INSTANCE];
 
 static int StoreYuvImageBurstFormat_V20(int chromaStride, Uint8 * dst, int picWidth, int picHeight, Uint32 bitDepth,Uint64 addrY, Uint64 addrCb, Uint64 addrCr, Uint32 stride, FrameFormat format, int endian, CbCrInterLeave interLeave, PackedFormat packed);
 // Figure A.6 - Zig-zag sequence of quantized DCT coefficients
@@ -559,7 +559,7 @@ BOOL GetJpgEncOpenParam(JpgEncOpenParam *pEncOP, EncConfigParam *pEncConfig)
     memset(&mjpgParam, 0x00, sizeof(EncMjpgParam));
 
     encCfg.prec = pEncConfig->extendedSequential;
-    sprintf(cfgPath, "%s/%s", pEncConfig->strCfgDir, pEncConfig->cfgFileName);
+    snprintf(cfgPath, sizeof(cfgPath), "%s/%s", pEncConfig->strCfgDir, pEncConfig->cfgFileName);
 
     if (parseJpgCfgFile(&encCfg, cfgPath) == 0) {
         return FALSE;
@@ -609,13 +609,13 @@ BOOL GetJpgEncOpenParam(JpgEncOpenParam *pEncOP, EncConfigParam *pEncConfig)
             mjpgParam.chromaQ12bit = (BOOL)encCfg.QMatPrec1;
             mjpgParam.extendedSequence = TRUE;
         }
-        sprintf(huffmanTablePath, "%s/%s", pEncConfig->strCfgDir, encCfg.HuffTabName);
+        snprintf(huffmanTablePath, sizeof(huffmanTablePath), "%s/%s", pEncConfig->strCfgDir, encCfg.HuffTabName);
         ret = jpgGetHuffTable(huffmanTablePath, &mjpgParam, pEncOP->jpg12bit);
         if (ret == 0) {
             return ret;
         }
 
-        sprintf(QMatTabPath, "%s/%s", pEncConfig->strCfgDir, encCfg.QMatTabName);
+        snprintf(QMatTabPath, sizeof(QMatTabPath), "%s/%s", pEncConfig->strCfgDir, encCfg.QMatTabName);
         if ((ret=jpgGetQMatrix(QMatTabPath, &mjpgParam)) == FALSE) {
             return ret;
         }
@@ -1119,6 +1119,196 @@ BOOL AllocateFrameBuffer(Uint32 instIdx, FrameFormat subsample, CbCrInterLeave c
     return TRUE;
 }
 
+BOOL UpdateFrameBuffers(Uint32 instIdx, Uint32 num, FRAME_BUF *frameBuf)
+{
+    fb_context *fb = &s_fb[instIdx];
+    Uint32 index = num - 1;
+    fb->last_num = num;
+    fb->last_addr = frameBuf[index].vbY.phys_addr;
+    fb->last_addr += fb->frameBuf[index].vbCb.size;
+    fb->last_addr = JPU_CEIL(8, fb->last_addr);
+    fb->last_addr += fb->frameBuf[index].vbCr.size;
+    fb->last_addr = JPU_CEIL(8, fb->last_addr);
+    JLOG(INFO, "%s: Update %d buffers\r\n",__FUNCTION__, num);
+    memcpy(fb->frameBuf, frameBuf, sizeof(FRAME_BUF) * num);
+    return TRUE;
+}
+
+BOOL AttachOneFrameBuffer(Uint32 instIdx, FrameFormat subsample, CbCrInterLeave cbcrIntlv, PackedFormat packed,
+                         Uint32 rotation, BOOL scalerOn, Uint32 width, Uint32 height, Uint32 bitDepth,
+                         void *virtAddress, Uint32 size, Uint32 *bufferIndex)
+{
+    fb_context *fb;
+    Uint32  fbLumaStride, fbLumaHeight, fbChromaStride, fbChromaHeight;
+    Uint32  fbLumaSize, fbChromaSize;
+    Uint32  fbSize;
+    Uint32  bytePerPixel = (bitDepth + 7)/8;
+    Uint32  i;
+
+
+    JLOG(INFO, "%s function in width, height = [%d, %d]\r\n", __FUNCTION__, width, height);
+    if (rotation == 90 || rotation == 270) {
+        if (subsample == FORMAT_422) subsample = FORMAT_440;
+        else if (subsample == FORMAT_440) subsample = FORMAT_422;
+    }
+
+    GetFrameBufStride(subsample, cbcrIntlv, packed, scalerOn, width, height, bytePerPixel, &fbLumaStride, &fbLumaHeight, &fbChromaStride, &fbChromaHeight);
+    fbLumaSize   = fbLumaStride * fbLumaHeight;
+    fbChromaSize = fbChromaStride * fbChromaHeight;
+
+    if (cbcrIntlv == CBCR_SEPARATED) {
+        /* fbChromaSize MUST be zero when format is packed mode */
+        fbSize = fbLumaSize + 2*fbChromaSize;
+
+    }
+    else {
+        /* Semi-planar */
+        fbSize = fbLumaSize + fbChromaSize;
+    }
+
+    fb = &s_fb[instIdx];
+    fb->vb_base.virt_addr = (unsigned long)virtAddress;
+    fb->vb_base.size = fbSize;
+    if (jdi_attach_dma_memory(&fb->vb_base) < 0) {
+        JLOG(ERR, "Fail to attach frame buffer\n");
+        return FALSE;
+    }
+    fb->last_addr = fb->vb_base.phys_addr;
+
+    i = fb->last_num;
+    JLOG(INFO, "%s: store on index %d\r\n", __FUNCTION__, i);
+    fb->frameBuf[i].Format = subsample;
+    fb->frameBuf[i].Index  = i;
+    fb->frameBuf[i].vbY.phys_addr = fb->vb_base.phys_addr;
+    fb->frameBuf[i].vbY.size = fbLumaSize;
+    // Store virt addr
+    fb->frameBuf[i].vbY.virt_addr = fb->vb_base.virt_addr;
+
+    fb->last_addr += fb->frameBuf[i].vbY.size;
+    fb->last_addr = JPU_CEIL(8, fb->last_addr);
+    JLOG(INFO, "%s: fbChromaSize = %d, fbLumaSize = %d\r\n", __FUNCTION__, fbChromaSize, fbLumaSize);
+    if (fbChromaSize) {
+        fb->frameBuf[i].vbCb.phys_addr = fb->last_addr;
+        fb->frameBuf[i].vbCb.size = fbChromaSize;
+
+        fb->last_addr += fb->frameBuf[i].vbCb.size;
+        fb->last_addr = JPU_CEIL(8, fb->last_addr);
+
+        fb->frameBuf[i].vbCr.phys_addr = (cbcrIntlv == CBCR_SEPARATED) ? fb->last_addr : 0;
+        fb->frameBuf[i].vbCr.size      = (cbcrIntlv == CBCR_SEPARATED) ? fbChromaSize  : 0;
+
+        fb->last_addr += fb->frameBuf[i].vbCr.size;
+        fb->last_addr = JPU_CEIL(8, fb->last_addr);
+    }
+    JLOG(INFO, "%s vbCb = %x size = %d, vbCr = %x size = %d\r\n", __FUNCTION__, fb->frameBuf[i].vbCb.phys_addr,
+        fb->frameBuf[i].vbCb.size, fb->frameBuf[i].vbCr.phys_addr, fb->frameBuf[i].vbCr.size);
+    fb->frameBuf[i].strideY = fbLumaStride;
+    fb->frameBuf[i].strideC = fbChromaStride;
+
+    *bufferIndex = fb->last_num;
+    fb->last_num += 1;
+
+    JLOG(INFO, "%s function OUT, number = %d\r\n", __FUNCTION__, fb->last_num);
+    return TRUE;
+
+}
+
+void *AllocateOneFrameBuffer(Uint32 instIdx, FrameFormat subsample, CbCrInterLeave cbcrIntlv, PackedFormat packed,
+                         Uint32 rotation, BOOL scalerOn, Uint32 width, Uint32 height, Uint32 bitDepth, Uint32 *bufferIndex)
+{
+    fb_context *fb;
+    Uint32  fbLumaStride, fbLumaHeight, fbChromaStride, fbChromaHeight;
+    Uint32  fbLumaSize, fbChromaSize, fbSize;
+    Uint32  i;
+    Uint32  bytePerPixel = (bitDepth + 7)/8;
+    void * virt_addr = NULL;
+
+    JLOG(INFO, "%s function in width, height = [%d, %d]\r\n", __FUNCTION__, width, height);
+    if (rotation == 90 || rotation == 270) {
+        if (subsample == FORMAT_422) subsample = FORMAT_440;
+        else if (subsample == FORMAT_440) subsample = FORMAT_422;
+    }
+
+    GetFrameBufStride(subsample, cbcrIntlv, packed, scalerOn, width, height, bytePerPixel, &fbLumaStride, &fbLumaHeight, &fbChromaStride, &fbChromaHeight);
+    fbLumaSize   = fbLumaStride * fbLumaHeight;
+    fbChromaSize = fbChromaStride * fbChromaHeight;
+
+    if (cbcrIntlv == CBCR_SEPARATED) {
+        /* fbChromaSize MUST be zero when format is packed mode */
+        fbSize = fbLumaSize + 2*fbChromaSize;
+
+    }
+    else {
+        /* Semi-planar */
+        fbSize = fbLumaSize + fbChromaSize;
+    }
+
+    if (fbSize == 0)
+    {
+        switch (subsample)
+        {
+        case FORMAT_420:
+            fbSize = width * height * 3 / 2;
+            break;
+        case FORMAT_422:
+        case FORMAT_440:
+            fbSize = width * height * 2;
+        case FORMAT_444:
+            fbSize = width * height * 3;
+            /* code */
+            break;
+        default:
+            break;
+        }
+        JLOG(WARN, "%s: fbSize == 0! Use defalut size %d\r\n", __FUNCTION__, fbSize);
+    }
+
+    fb = &s_fb[instIdx];
+    fb->vb_base.size = fbSize;
+    if (jdi_allocate_dma_memory(&fb->vb_base) < 0) {
+        JLOG(ERR, "Fail to allocate frame buffer size=%d\n", fb->vb_base.size);
+        return NULL;
+    }
+    fb->last_addr = fb->vb_base.phys_addr;
+
+    i = fb->last_num;
+    JLOG(INFO, "%s: store on index %d\r\n", __FUNCTION__, i);
+    fb->frameBuf[i].Format = subsample;
+    fb->frameBuf[i].Index  = i;
+    fb->frameBuf[i].vbY.phys_addr = fb->vb_base.phys_addr;
+    fb->frameBuf[i].vbY.size = fbLumaSize;
+    // Store virt addr
+    fb->frameBuf[i].vbY.virt_addr = fb->vb_base.virt_addr;
+
+    fb->last_addr += fb->frameBuf[i].vbY.size;
+    fb->last_addr = JPU_CEIL(8, fb->last_addr);
+    JLOG(INFO, "%s: fbChromaSize = %d, fbLumaSize = %d\r\n", __FUNCTION__, fbChromaSize, fbLumaSize);
+    if (fbChromaSize) {
+        fb->frameBuf[i].vbCb.phys_addr = fb->last_addr;
+        fb->frameBuf[i].vbCb.size = fbChromaSize;
+
+        fb->last_addr += fb->frameBuf[i].vbCb.size;
+        fb->last_addr = JPU_CEIL(8, fb->last_addr);
+
+        fb->frameBuf[i].vbCr.phys_addr = (cbcrIntlv == CBCR_SEPARATED) ? fb->last_addr : 0;
+        fb->frameBuf[i].vbCr.size      = (cbcrIntlv == CBCR_SEPARATED) ? fbChromaSize  : 0;
+
+        fb->last_addr += fb->frameBuf[i].vbCr.size;
+        fb->last_addr = JPU_CEIL(8, fb->last_addr);
+    }
+
+    fb->frameBuf[i].strideY = fbLumaStride;
+    fb->frameBuf[i].strideC = fbChromaStride;
+
+    *bufferIndex = fb->last_num;
+    fb->last_num += 1;
+
+    virt_addr = (void *)fb->vb_base.virt_addr;
+
+    JLOG(INFO, "%s function OUT, number = %d, return = %p\r\n", __FUNCTION__, fb->last_num, virt_addr);
+    return virt_addr;
+}
+
 int GetDPBBufSize(int framebufFormat, int picWidth, int picHeight, int picWidth_C, int interleave)
 {
     int framebufSize = 0;
@@ -1517,6 +1707,13 @@ FRAME_BUF *GetFrameBuffer(int instIdx, int idx)
     return &fb->frameBuf[idx];
 }
 
+Uint32 GetFrameBufferCount(int instIdx)
+{
+    fb_context *fb;
+    fb = &s_fb[instIdx];
+    return fb->last_num;
+}
+
 FRAME_BUF* FindFrameBuffer(int instIdx, PhysicalAddress addrY)
 {
     int i;

+ 42 - 0
codaj12/sample/helper/jpulog.c

@@ -40,6 +40,16 @@ static struct termios initial_settings, new_settings;
 static int peek_character = -1;
 #endif
 
+#define ANSI_COLOR_ERR      "\x1b[31m"       // RED
+#define ANSI_COLOR_TRACE    "\x1b[32m"       // GREEN
+#define ANSI_COLOR_WARN     "\x1b[33m"       // YELLOW
+#define ANSI_COLOR_BLUE     "\x1b[34m"       // BLUE
+#define ANSI_COLOR_INFO     ""
+// For future
+#define ANSI_COLOR_MAGENTA  "\x1b[35m"       // MAGENTA
+#define ANSI_COLOR_CYAN     "\x1b[36m"       // CYAN
+#define ANSI_COLOR_RESET    "\x1b[0m"        // RESET
+
 static int log_colors[MAX_LOG_LEVEL] = {
 	0,
 	TERM_COLOR_R|TERM_COLOR_G|TERM_COLOR_B|TERM_COLOR_BRIGHT, 	//INFO
@@ -51,6 +61,7 @@ static int log_colors[MAX_LOG_LEVEL] = {
 static unsigned log_decor = LOG_HAS_TIME | LOG_HAS_FILE | LOG_HAS_MICRO_SEC |
 			    LOG_HAS_NEWLINE |
 			    LOG_HAS_SPACE | LOG_HAS_COLOR;
+static int max_log_level = ERR;
 static FILE *fpLog  = NULL;
 
 #ifdef WIN32
@@ -78,6 +89,16 @@ void DeInitLog()
     }
 }
 
+void SetMaxLogLevel(int level)
+{
+	max_log_level = level;
+}
+
+int GetMaxLogLevel()
+{
+	return max_log_level;
+}
+
 void SetLogColor(int level, int color)
 {
 	log_colors[level] = color;
@@ -102,6 +123,25 @@ void LogMsg(int level, const char *format, ...)
 {
 	va_list ptr;
 	char logBuf[MAX_PRINT_LENGTH] = {0};
+    char*   prefix = "";
+    char*   postfix= "";
+
+    if (level > max_log_level)
+        return;
+#if defined(SUPPORT_SW_UART) || defined(SUPPORT_SW_UART_V2)
+	pthread_mutex_lock(&s_log_mutex);
+#endif
+
+    if ((log_decor & LOG_HAS_COLOR)) {
+        postfix = ANSI_COLOR_RESET;
+        switch (level) {
+        case INFO:  prefix = ANSI_COLOR_INFO;  break;
+        case ERR:   prefix = ANSI_COLOR_ERR "[ERROR]";   break;
+        case TRACE: prefix = ANSI_COLOR_TRACE; break;
+        case WARN:  prefix = ANSI_COLOR_WARN"[WARN ]";  break;
+        default:    prefix = "";               break;
+        }
+    }
 
 	va_start( ptr, format );
 #if defined(WIN32) || defined(__MINGW32__)
@@ -137,6 +177,8 @@ void LogMsg(int level, const char *format, ...)
 	}
 	puts(logBuf);
 #else
+    fputs(prefix,  stderr);
+    fputs(postfix, stderr);
     fprintf(stderr, logBuf);
     //fputs(logBuf, stderr);
 #endif

+ 15 - 2
codaj12/sample/helper/jpulog.h

@@ -25,11 +25,24 @@
 #ifndef _LOG_H_
 #define _LOG_H_
 
-#include "jputypes.h"
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "codaj12/jpuapi/jputypes.h"
+#else
+    #include "jputypes.h"
+#endif
+
 
 
+enum
+{
+    ERR=0,
+    WARN,
+    TRACE,
+    INFO,
+    DEBUG,
+    MAX_LOG_LEVEL
+};
 
-enum {NONE=0, INFO, WARN, ERR, TRACE, MAX_LOG_LEVEL};
 enum
 {
     LOG_HAS_DAY_NAME   =    1, /**< Include day name [default: no] 	      */

+ 5 - 1
codaj12/sample/helper/platform.h

@@ -25,7 +25,11 @@
 #ifndef __JPU_PLATFORM_H__
 #define __JPU_PLATFORM_H__
 
-#include "jputypes.h"
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "codaj12/jpuapi/jputypes.h"
+#else
+    #include "jputypes.h"
+#endif
 /************************************************************************/
 /* JpuMutex                                                                */
 /************************************************************************/

+ 8 - 2
codaj12/sample/helper/yuv_feeder.h

@@ -25,8 +25,14 @@
 #ifndef __JPU_YUV_FEEDER_H__
 #define __JPU_YUV_FEEDER_H__
 
-#include "jpuapi.h"
-#include "datastructure.h"
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "codaj12/jpuapi/jpuapi.h"
+    #include "codaj12/sample/helper/datastructure.h"
+#else
+    #include "jpuapi.h"
+    #include "datastructure.h"
+#endif
+
 
 #define SOURCE_YUV                  0
 

+ 14 - 4
codaj12/sample/main_helper.h

@@ -26,10 +26,17 @@
 #ifndef JPUHELPER_H_INCLUDED
 #define JPUHELPER_H_INCLUDED
 
-#include "jpulog.h"
-#include "jpuapi.h"
-#include "cnm_fpga.h"
-#include "yuv_feeder.h"
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "codaj12/jpuapi/jpuapi.h"
+    #include "codaj12/sample/helper/jpulog.h"
+    #include "codaj12/sample/helper/cnm_fpga.h"
+    #include "codaj12/sample/helper/yuv_feeder.h"
+#else
+    #include "jpulog.h"
+    #include "jpuapi.h"
+    #include "cnm_fpga.h"
+    #include "yuv_feeder.h"
+#endif
 
 #define MAX_FILE_PATH    256
 
@@ -54,6 +61,9 @@ typedef struct {
 typedef enum {
     FEEDING_METHOD_FIXED_SIZE,
     FEEDING_METHOD_FRAME_SIZE,      /*!<< use FFMPEG demuxer */
+#ifdef USE_FEEDING_METHOD_BUFFER
+    FEEDING_METHOD_BUFFER,
+#endif
     FEEDING_METHOD_MAX
 } FeedingMethod;
 

+ 1 - 1
codaj12/sample/main_jpg_enc_test.c

@@ -335,7 +335,7 @@ BOOL TestEncoder(
     JLOG(INFO, "framebuffer stride = %d, width = %d, height = %d\n", frameBuf[0].stride, framebufWidth, framebufHeight);
     JLOG(INFO, "framebuffer format = %d, packed format = %d, Interleave = %d\n", srcFrameFormat, encOP.packedFormat, encOP.chromaInterleave);
 
-    sprintf(yuvPath, "%s/%s", encConfig.strYuvDir, encConfig.yuvFileName);
+    snprintf(yuvPath, sizeof(yuvPath), "%s/%s", encConfig.strYuvDir, encConfig.yuvFileName);
     GetSourceYuvAttributes(encOP, &sourceAttr);
     if ((yuvFeeder=YuvFeeder_Create(YUV_FEEDER_MODE_NORMAL, yuvPath, sourceAttr, encOP.frameEndian, NULL)) == NULL) {
         goto ERR_ENC_OPEN;

+ 103 - 0
omx-il/Makefile

@@ -0,0 +1,103 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (C) 2021 StarFive Technology Co., Ltd.
+#
+# Project: Starfive Openmax IL Shimlayer
+#
+.PHONY: CREATE_DIR
+BUILD_CONFIGURATION := EmbeddedRiscvLinux
+
+PRODUCT := OMX_IL
+
+ifeq ("$(BUILD_CONFIGURATION)", "EmbeddedRiscvLinux")
+    CROSS_CC_PREFIX = riscv64-buildroot-linux-gnu-
+    PLATFORM        = riscvlinux
+endif
+CC  = $(CROSS_CC_PREFIX)gcc
+CXX = $(CROSS_CC_PREFIX)g++
+LINKER=$(CC)
+AR  = $(CROSS_CC_PREFIX)ar
+
+DEFINES = -DUSE_FEEDING_METHOD_BUFFER
+INCLUDES = -I./include/khronos -I./core -I./component/video/wave5/common -I./component/video/wave4 -I./component/helper
+$(warning "the value of LOCAL_PATH is$(STAGING_DIR)")
+INCLUDES += -I$(STAGING_DIR)/usr/include/
+INCLUDES += -I$(STAGING_DIR)/usr/include/wave420l/
+INCLUDES += -I$(STAGING_DIR)/usr/include/wave420l/vpuapi/
+INCLUDES += -I$(STAGING_DIR)/usr/include/wave420l/sample/helper/
+#INCLUDES += -I$(STAGING_DIR)/usr/include/wave420l/sample/helper/misc/
+
+#mjpeg
+INCLUDES += -I./component/image/common
+
+CFLAGS  += -g -I. $(INCLUDES) $(DEFINES) $(PLATFORM_FLAGS)
+CFLAGS  += -fpic
+ARFLAGS += cru
+LDFLAGS = -ldl -lpthread -Wl,--fatal-warning
+LDFLAGS_FFMPEG = -lavformat -lavcodec -lavutil -lswresample
+
+OBJDIR=obj
+ALLOBJS=*.o
+ALLDEPS=*.dep
+ALLLIBS=*.a
+RM=rm -f
+MKDIR=mkdir -p
+#vpu
+SOURCES_COMMON = SF_OMX_Core.c SF_OMX_video_common.c
+SOURCES_COMMON += SF_OMX_Vdec_decoder.c
+SOURCES_COMMON += SF_OMX_Wave420L_encoder.c
+SOURCES_COMMON += sf_queue.c
+SOURCES_COMMON += sf_thread.c
+SOURCES_COMMON += sf_semaphore.c
+#mjpeg
+SOURCES_COMMON += SF_OMX_mjpeg_common.c SF_OMX_Mjpeg_decoder.c
+#test
+SOURCES_DEC_TEST = dec_test.c
+SOURCES_ENC_TEST = enc_test.c
+MJPET_SOURCES_DEC_TEST = mjpeg_dec_test.c
+
+VPATH  = component/video/wave5/common:
+#VPATH += component/video/enc:
+VPATH += component/video/wave5/dec:
+VPATH += component/video/wave4:
+VPATH += component/helper:
+VPATH += core:
+VPATH += tests:
+
+#mjpeg
+VPATH += component/image/common:
+VPATH += component/image/dec:
+
+OBJECTNAMES_COMMON=$(patsubst %.c,%.o,$(SOURCES_COMMON))
+OBJECTPATHS_COMMON=$(addprefix $(OBJDIR)/,$(notdir $(OBJECTNAMES_COMMON)))
+OBJECTNAMES_DEC_TEST=$(patsubst %.c,%.o,$(SOURCES_DEC_TEST))
+OBJECTPATHS_DEC_TEST=$(addprefix $(OBJDIR)/,$(notdir $(OBJECTNAMES_DEC_TEST)))
+OBJECTNAMES_ENC_TEST=$(patsubst %.c,%.o,$(SOURCES_ENC_TEST))
+OBJECTPATHS_ENC_TEST=$(addprefix $(OBJDIR)/,$(notdir $(OBJECTNAMES_ENC_TEST)))
+
+OBJECTNAMES_MJPEG_DEC_TEST=$(patsubst %.c,%.o,$(MJPET_SOURCES_DEC_TEST))
+OBJECTPATHS_MJPEG_DEC_TEST=$(addprefix $(OBJDIR)/,$(notdir $(OBJECTNAMES_MJPEG_DEC_TEST)))
+
+all: omx-il
+
+omx-il: CREATE_DIR $(OBJECTPATHS_COMMON)
+	$(CC) -g -fPIC -shared -o libsf-omx-il.so $(OBJECTPATHS_COMMON)
+
+test: video-dec-test video-enc-test mjpeg-dec-test
+
+video-dec-test: CREATE_DIR $(OBJECTPATHS_DEC_TEST)
+	$(CC) -o video_dec_test $(LDFLAGS) $(LDFLAGS_FFMPEG) -lsf-omx-il $(OBJECTPATHS_DEC_TEST) -L./
+
+video-enc-test: CREATE_DIR $(OBJECTPATHS_ENC_TEST)
+	$(CC) -o video_enc_test $(LDFLAGS) $(LDFLAGS_FFMPEG) -lsf-omx-il $(OBJECTPATHS_ENC_TEST) -L./
+
+mjpeg-dec-test: CREATE_DIR $(OBJECTPATHS_MJPEG_DEC_TEST)
+	$(CC) -g -o mjpeg_dec_test $(LDFLAGS) $(LDFLAGS_FFMPEG) -lsf-omx-il $(OBJECTPATHS_MJPEG_DEC_TEST) -L./
+
+clean:
+
+CREATE_DIR:
+	-mkdir -p $(OBJDIR)
+
+obj/%.o: %.c $(MAKEFILE)
+	$(CC) $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)

+ 202 - 0
omx-il/component/helper/sf_queue.c

@@ -0,0 +1,202 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ */
+#include "sf_queue.h"
+#include "SF_OMX_Core.h"
+
+SF_Queue* SF_Queue_Create(
+    OMX_U32      itemCount,
+    OMX_U32      itemSize
+    )
+{
+    SF_Queue* queue = NULL;
+    OMX_U32 size  = itemCount*itemSize;
+
+    if ((queue=(SF_Queue *)malloc(sizeof(SF_Queue))) == NULL)
+        return NULL;
+    queue->size   = itemCount;
+    queue->itemSize = itemSize;
+    queue->count  = 0;
+    queue->front  = 0;
+    queue->rear   = 0;
+    queue->buffer = (OMX_U8*)malloc(size);
+    if (pthread_mutex_init(&queue->lock, NULL) < 0) {
+        free(queue);
+        LOG(SF_LOG_ERR, "failed to pthread_mutex_init() errno(%d)\n", errno);
+        return NULL;
+    }
+    if (pthread_cond_init(&queue->cond, NULL) < 0) {
+        free(queue);
+        LOG(SF_LOG_ERR, "failed to pthread_cond_init() errno(%d)\n", errno);
+        return NULL;
+    }
+
+    return queue;
+}
+
+void SF_Queue_Destroy(
+    SF_Queue*      queue
+    )
+{
+    if (queue == NULL)
+        return;
+
+    if (queue->buffer)
+        free(queue->buffer);
+    free(queue);
+}
+
+OMX_ERRORTYPE SF_Queue_Enqueue(
+    SF_Queue*      queue,
+    void*       data
+    )
+{
+    OMX_U8*      ptr;
+    OMX_U32      offset;
+
+    if (queue == NULL) return OMX_ErrorUndefined;
+
+    /* SF_Queue is full */
+    if (queue->count == queue->size)
+        return OMX_ErrorOverflow;
+
+    pthread_mutex_lock(&queue->lock);
+    offset = queue->rear * queue->itemSize;
+
+    ptr = &queue->buffer[offset];
+    memcpy(ptr, data, queue->itemSize);
+    queue->rear++;
+    queue->rear %= queue->size;
+    queue->count++;
+    pthread_mutex_unlock(&queue->lock);
+    pthread_cond_signal(&queue->cond);
+
+    return OMX_ErrorNone;
+}
+
+void* SF_Queue_Dequeue(
+    SF_Queue*      queue
+    )
+{
+    void* data;
+    OMX_U32   offset;
+
+    if (queue == NULL)
+        return NULL;
+    /* SF_Queue is empty */
+    if (queue->count == 0)
+        return NULL;
+    pthread_mutex_lock(&queue->lock);
+    offset = queue->front * queue->itemSize;
+    data   = (void*)&queue->buffer[offset];
+    queue->front++;
+    queue->front %= queue->size;
+    queue->count--;
+    pthread_mutex_unlock(&queue->lock);
+    return data;
+}
+
+void* SF_Queue_Dequeue_Block(
+    SF_Queue*      queue
+    )
+{
+    void* data;
+    OMX_U32   offset;
+
+    if (queue == NULL)
+        return NULL;
+    pthread_mutex_lock(&queue->lock);
+    /* SF_Queue is empty */
+    while (queue->count == 0){
+        pthread_cond_wait(&queue->cond,&queue->lock);
+    }
+
+    offset = queue->front * queue->itemSize;
+    data   = (void*)&queue->buffer[offset];
+    queue->front++;
+    queue->front %= queue->size;
+    queue->count--;
+    pthread_mutex_unlock(&queue->lock);
+    return data;
+}
+
+void SF_Queue_Flush(
+    SF_Queue*      queue
+    )
+{
+    if (queue == NULL)
+        return;
+    pthread_mutex_lock(&queue->lock);
+    queue->count = 0;
+    queue->front = 0;
+    queue->rear  = 0;
+    pthread_mutex_unlock(&queue->lock);
+    return;
+}
+
+void* SF_Queue_Peek(
+    SF_Queue*      queue
+    )
+{
+    OMX_U32      offset;
+    void*       temp;
+
+    if (queue == NULL)
+        return NULL;
+    /* SF_Queue is empty */
+    if (queue->count == 0)
+        return NULL;
+    pthread_mutex_lock(&queue->lock);
+    offset = queue->front * queue->itemSize;
+    temp = (void*)&queue->buffer[offset];
+    pthread_mutex_unlock(&queue->lock);
+    return  temp;
+}
+
+OMX_U32   SF_Queue_Get_Cnt(
+    SF_Queue*      queue
+    )
+{
+    OMX_U32      cnt;
+
+    if (queue == NULL)
+        return 0;
+    pthread_mutex_lock(&queue->lock);
+    cnt = queue->count;
+    pthread_mutex_unlock(&queue->lock);
+    return cnt;
+}
+
+SF_Queue* SF_Queue_Copy(
+    SF_Queue*  dstQ,
+    SF_Queue*  srcQ
+    )
+{
+    SF_Queue*   queue = NULL;
+    OMX_U32   bufferSize;
+
+    if (dstQ == NULL) {
+        if ((queue=(SF_Queue *)malloc(sizeof(SF_Queue))) == NULL)
+            return NULL;
+        memset((void*)queue, 0x00, sizeof(SF_Queue));
+    }
+    else {
+        queue = dstQ;
+    }
+
+    bufferSize      = srcQ->size * srcQ->itemSize;
+    queue->size     = srcQ->size;
+    queue->itemSize = srcQ->itemSize;
+    queue->count    = srcQ->count;
+    queue->front    = srcQ->front;
+    queue->rear     = srcQ->rear;
+    if (queue->buffer) {
+        free(queue->buffer);
+    }
+    queue->buffer   = (OMX_U8*)malloc(bufferSize);
+
+    memcpy(queue->buffer, srcQ->buffer, bufferSize);
+
+    return queue;
+}

+ 38 - 0
omx-il/component/helper/sf_queue.h

@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ */
+#ifndef SF_QUEUE_H
+#define SF_QUEUE_H
+
+#include <stdint.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <time.h>
+#include <pthread.h>
+#include "OMX_Types.h"
+#include "OMX_Core.h"
+
+typedef struct {
+    OMX_U8*      buffer;
+    OMX_U32      size;
+    OMX_U32      itemSize;
+    OMX_U32      count;
+    OMX_U32      front;
+    OMX_U32      rear;
+    pthread_mutex_t    lock;
+    pthread_cond_t     cond;
+} SF_Queue;
+
+
+SF_Queue* SF_Queue_Create(OMX_U32 itemCount, OMX_U32 itemSize);
+void SF_Queue_Destroy(SF_Queue* queue);
+OMX_ERRORTYPE SF_Queue_Enqueue(SF_Queue* queue, void* data);
+void* SF_Queue_Dequeue(SF_Queue* queue);
+void* SF_Queue_Dequeue_Block(SF_Queue* queue);
+void SF_Queue_Flush(SF_Queue* queue);
+void* SF_Queue_Peek(SF_Queue* queue);
+OMX_U32   SF_Queue_Get_Cnt(SF_Queue* queue);
+SF_Queue* SF_Queue_Copy(SF_Queue* dstQ, SF_Queue* srcQ);
+
+#endif //SF_QUEUE_H

+ 103 - 0
omx-il/component/helper/sf_semaphore.c

@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ */
+#include "sf_semaphore.h"
+#include "SF_OMX_Core.h"
+
+OMX_ERRORTYPE SF_SemaphoreCreate(OMX_HANDLETYPE *semaphoreHandle)
+{
+    sem_t *sema;
+
+    sema = (sem_t *)malloc(sizeof(sem_t));
+    if (!sema)
+        return OMX_ErrorInsufficientResources;
+
+    if (sem_init(sema, 0, 0) != 0) {
+        free(sema);
+        return OMX_ErrorUndefined;
+    }
+
+    *semaphoreHandle = (OMX_HANDLETYPE)sema;
+
+    LOG(SF_LOG_INFO,"SF_SemaphoreCreate %p\r\n", sema);
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE SF_SemaphoreTerminate(OMX_HANDLETYPE semaphoreHandle)
+{
+    sem_t *sema = (sem_t *)semaphoreHandle;
+
+    if (sema == NULL)
+        return OMX_ErrorBadParameter;
+
+    if (sem_destroy(sema) != 0)
+        return OMX_ErrorUndefined;
+
+    free(sema);
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE SF_SemaphoreWait(OMX_HANDLETYPE semaphoreHandle)
+{
+    LOG(SF_LOG_INFO,"SF_SemaphoreWait %p\r\n", semaphoreHandle);
+    sem_t *sema = (sem_t *)semaphoreHandle;
+
+    FunctionIn();
+
+    if (sema == NULL)
+        return OMX_ErrorBadParameter;
+
+    if (sem_wait(sema) != 0)
+        return OMX_ErrorUndefined;
+
+    FunctionOut();
+
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE SF_SemaphorePost(OMX_HANDLETYPE semaphoreHandle)
+{
+    sem_t *sema = (sem_t *)semaphoreHandle;
+
+    FunctionIn();
+
+    if (sema == NULL)
+        return OMX_ErrorBadParameter;
+
+    if (sem_post(sema) != 0)
+        return OMX_ErrorUndefined;
+
+    FunctionOut();
+
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE SF_Set_SemaphoreCount(OMX_HANDLETYPE semaphoreHandle, OMX_S32 val)
+{
+    sem_t *sema = (sem_t *)semaphoreHandle;
+
+    if (sema == NULL)
+        return OMX_ErrorBadParameter;
+
+    if (sem_init(sema, 0, val) != 0)
+        return OMX_ErrorUndefined;
+
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE SF_Get_SemaphoreCount(OMX_HANDLETYPE semaphoreHandle, OMX_S32 *val)
+{
+    sem_t *sema = (sem_t *)semaphoreHandle;
+    int semaVal = 0;
+
+    if (sema == NULL)
+        return OMX_ErrorBadParameter;
+
+    if (sem_getvalue(sema, &semaVal) != 0)
+        return OMX_ErrorUndefined;
+
+    *val = (OMX_S32)semaVal;
+
+    return OMX_ErrorNone;
+}

+ 23 - 0
omx-il/component/helper/sf_semaphore.h

@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ */
+#ifndef SF_SEMAPHORE_H
+#define SF_SEMAPHORE_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include "OMX_Types.h"
+#include "OMX_Core.h"
+
+OMX_ERRORTYPE SF_SemaphoreCreate(OMX_HANDLETYPE *semaphoreHandle);
+OMX_ERRORTYPE SF_SemaphoreTerminate(OMX_HANDLETYPE semaphoreHandle);
+OMX_ERRORTYPE SF_SemaphoreWait(OMX_HANDLETYPE semaphoreHandle);
+OMX_ERRORTYPE SF_SemaphorePost(OMX_HANDLETYPE semaphoreHandle);
+OMX_ERRORTYPE SF_Set_SemaphoreCount(OMX_HANDLETYPE semaphoreHandle, OMX_S32 val);
+OMX_ERRORTYPE SF_Get_SemaphoreCount(OMX_HANDLETYPE semaphoreHandle, OMX_S32 *val);
+
+#endif //SF_SEMAPHORE_H

+ 68 - 0
omx-il/component/helper/sf_thread.c

@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ */
+#include "sf_thread.h"
+#include "SF_OMX_Core.h"
+
+OMX_ERRORTYPE CreateThread(THREAD_HANDLE_TYPE **threadHandle, OMX_PTR function_name, OMX_PTR argument)
+{
+    FunctionIn();
+
+    int result = 0;
+    int detach_ret = 0;
+    THREAD_HANDLE_TYPE *thread;
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    thread = malloc(sizeof(THREAD_HANDLE_TYPE));
+    memset(thread, 0, sizeof(THREAD_HANDLE_TYPE));
+
+    pthread_attr_init(&thread->attr);
+    if (thread->stack_size != 0)
+        pthread_attr_setstacksize(&thread->attr, thread->stack_size);
+
+    /* set priority */
+    if (thread->schedparam.sched_priority != 0)
+        pthread_attr_setschedparam(&thread->attr, &thread->schedparam);
+
+    detach_ret = pthread_attr_setdetachstate(&thread->attr, PTHREAD_CREATE_JOINABLE);
+    if (detach_ret != 0)
+    {
+        free(thread);
+        *threadHandle = NULL;
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    result = pthread_create(&thread->pthread, &thread->attr, function_name, (void *)argument);
+    /* pthread_setschedparam(thread->pthread, SCHED_RR, &thread->schedparam); */
+
+    switch (result)
+    {
+    case 0:
+        *threadHandle = thread;
+        ret = OMX_ErrorNone;
+        break;
+    case EAGAIN:
+        free(thread);
+        *threadHandle = NULL;
+        ret = OMX_ErrorInsufficientResources;
+        break;
+    default:
+        free(thread);
+        *threadHandle = NULL;
+        ret = OMX_ErrorUndefined;
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+void ThreadExit(void *value_ptr)
+{
+    pthread_exit(value_ptr);
+    return;
+}

+ 28 - 0
omx-il/component/helper/sf_thread.h

@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ */
+#ifndef SF_THREAD_H
+#define SF_THREAD_H
+
+#include <stdint.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <time.h>
+#include <pthread.h>
+#include "OMX_Types.h"
+#include "OMX_Core.h"
+
+typedef struct _THREAD_HANDLE_TYPE
+{
+    pthread_t          pthread;
+    pthread_attr_t     attr;
+    struct sched_param schedparam;
+    int                stack_size;
+} THREAD_HANDLE_TYPE;
+
+
+OMX_ERRORTYPE CreateThread(THREAD_HANDLE_TYPE **threadHandle, OMX_PTR function_name, OMX_PTR argument);
+void ThreadExit(void *value_ptr);
+
+#endif //SF_THREAD_H

+ 590 - 0
omx-il/component/image/common/SF_OMX_mjpeg_common.c

@@ -0,0 +1,590 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 StarFive Technology Co., Ltd.
+ */
+#include "SF_OMX_mjpeg_common.h"
+
+static void sf_get_component_functions(SF_CODAJ12_FUNCTIONS *funcs, OMX_PTR *sohandle);
+
+OMX_ERRORTYPE GetStateMjpegCommon(OMX_IN OMX_HANDLETYPE hComponent, OMX_OUT OMX_STATETYPE *pState)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+    FunctionOut();
+    return ret;
+}
+
+OMX_ERRORTYPE InitMjpegStructorCommon(SF_OMX_COMPONENT *pSfOMXComponent)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    char *strDebugLevel = NULL;
+    int debugLevel = 0;
+    SF_CODAJ12_IMPLEMEMT *pSfCodaj12Implement = NULL;
+
+    FunctionIn();
+    if (pSfOMXComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pSfOMXComponent->pOMXComponent = malloc(sizeof(OMX_COMPONENTTYPE));
+    if (pSfOMXComponent->pOMXComponent == NULL)
+    {
+        ret = OMX_ErrorInsufficientResources;
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        goto ERROR;
+    }
+    memset(pSfOMXComponent->pOMXComponent, 0, sizeof(OMX_COMPONENTTYPE));
+
+    pSfOMXComponent->soHandle = dlopen(pSfOMXComponent->libName, RTLD_NOW);
+    if (pSfOMXComponent->soHandle == NULL)
+    {
+        ret = OMX_ErrorInsufficientResources;
+        LOG(SF_LOG_ERR, "could not open %s, error: %s\r\n", pSfOMXComponent->libName, dlerror());
+        goto ERROR;
+    }
+
+    pSfOMXComponent->componentImpl = malloc(sizeof(SF_CODAJ12_IMPLEMEMT));
+    if (pSfOMXComponent->componentImpl == NULL)
+    {
+        ret = OMX_ErrorInsufficientResources;
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        goto ERROR;
+    }
+    memset(pSfOMXComponent->componentImpl, 0, sizeof(SF_CODAJ12_IMPLEMEMT));
+
+    pSfCodaj12Implement = (SF_CODAJ12_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    pSfCodaj12Implement->functions = malloc(sizeof(SF_CODAJ12_FUNCTIONS));
+    pSfCodaj12Implement->currentState = OMX_StateLoaded;
+    pSfCodaj12Implement->frameFormat = DEFAULT_FRAME_FORMAT;
+    if (pSfCodaj12Implement->functions == NULL)
+    {
+        ret = OMX_ErrorInsufficientResources;
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        goto ERROR;
+    }
+    memset(pSfCodaj12Implement->functions, 0, sizeof(SF_CODAJ12_FUNCTIONS));
+    sf_get_component_functions(pSfCodaj12Implement->functions, pSfOMXComponent->soHandle);
+
+    // Init JPU log
+    if (pSfCodaj12Implement->functions->SetMaxLogLevel)
+    {
+        strDebugLevel = getenv("JPU_DEBUG");
+        if (strDebugLevel)
+        {
+            debugLevel = atoi(strDebugLevel);
+            if (debugLevel >=0)
+            {
+                pSfCodaj12Implement->functions->SetMaxLogLevel(debugLevel);
+            }
+        }
+    }
+
+    if (strstr(pSfOMXComponent->componentName, "OMX.sf.video_decoder") != NULL)
+    {
+        pSfCodaj12Implement->config = malloc(sizeof(DecConfigParam));
+        if (pSfCodaj12Implement->config == NULL)
+        {
+            ret = OMX_ErrorInsufficientResources;
+            LOG(SF_LOG_ERR, "malloc fail\r\n");
+            goto ERROR;
+        }
+        memset(pSfCodaj12Implement->config, 0, sizeof(DecConfigParam));
+    }
+    else
+    {
+        ret = OMX_ErrorBadParameter;
+        LOG(SF_LOG_ERR, "unknown component!\r\n");
+        goto ERROR;
+    }
+
+    pSfOMXComponent->pOMXComponent->pComponentPrivate = pSfOMXComponent;
+
+    pSfCodaj12Implement->sInputMessageQueue = msgget(IPC_PRIVATE, 0666 | IPC_CREAT);
+    if (pSfCodaj12Implement->sInputMessageQueue < 0)
+    {
+        LOG(SF_LOG_ERR, "get ipc_id error");
+        return OMX_ErrorInsufficientResources;
+    }
+    pSfCodaj12Implement->sOutputMessageQueue = msgget(IPC_PRIVATE, 0666 | IPC_CREAT);
+    if (pSfCodaj12Implement->sOutputMessageQueue < 0)
+    {
+        LOG(SF_LOG_ERR, "get ipc_id error");
+        return OMX_ErrorInsufficientResources;
+    }
+    pSfCodaj12Implement->sBufferDoneQueue = msgget(IPC_PRIVATE, 0666 | IPC_CREAT);
+    if (pSfCodaj12Implement->sBufferDoneQueue < 0)
+    {
+        LOG(SF_LOG_ERR, "get ipc_id error");
+        return OMX_ErrorInsufficientResources;
+    }
+
+    for (int i = 0; i < 2; i++)
+    {
+        OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = &pSfOMXComponent->portDefinition[i];
+
+        // OMX_IMAGE_PARAM_PORTFORMATTYPE * imagePortFormat = &pSfOMXComponent->MJPEGComponent[i];
+        // memset(&imagePortFormat, 0, sizeof(OMX_IMAGE_PARAM_PORTFORMATTYPE));
+        // INIT_SET_SIZE_VERSION(imagePortFormat, OMX_PARAM_PORTDEFINITIONTYPE);
+        // imagePortFormat->nPortIndex = i;
+        // imagePortFormat->nIndex = 0; //TODO
+        // imagePortFormat->eCompressionFormat = OMX_IMAGE_CodingJPEG;
+        // imagePortFormat->eColorFormat = OMX_COLOR_FormatUnused;  //TODO
+
+        INIT_SET_SIZE_VERSION(pPortDefinition, OMX_PARAM_PORTDEFINITIONTYPE);
+
+        pPortDefinition->nPortIndex = i;
+        pPortDefinition->nBufferCountActual = (i == 0 ? CODAJ12_INPUT_BUF_NUMBER : CODAJ12_OUTPUT_BUF_NUMBER);
+        pPortDefinition->nBufferCountMin = (i == 0 ? CODAJ12_INPUT_BUF_NUMBER : CODAJ12_OUTPUT_BUF_NUMBER);
+        pPortDefinition->nBufferSize = (i == 0 ? DEFAULT_MJPEG_INPUT_BUFFER_SIZE : DEFAULT_MJPEG_OUTPUT_BUFFER_SIZE);
+        pPortDefinition->eDomain = OMX_PortDomainVideo;
+
+        // pPortDefinition->format.image.nFrameWidth = DEFAULT_FRAME_WIDTH;
+        // pPortDefinition->format.image.nFrameHeight = DEFAULT_FRAME_HEIGHT;
+        // pPortDefinition->format.image.nStride = DEFAULT_FRAME_WIDTH;
+        // pPortDefinition->format.image.nSliceHeight = DEFAULT_FRAME_HEIGHT;
+        // pPortDefinition->format.image.eCompressionFormat = OMX_IMAGE_CodingUnused;
+        // pPortDefinition->format.image.cMIMEType = malloc(OMX_MAX_STRINGNAME_SIZE);
+
+        // if (pPortDefinition->format.image.cMIMEType == NULL)
+        // {
+        //     ret = OMX_ErrorInsufficientResources;
+        //     free(pPortDefinition->format.image.cMIMEType);
+        //     pPortDefinition->format.image.cMIMEType = NULL;
+        //     LOG(SF_LOG_ERR, "malloc fail\r\n");
+        //     goto ERROR;
+        // }
+        // memset(pPortDefinition->format.image.cMIMEType, 0, OMX_MAX_STRINGNAME_SIZE);
+        // pPortDefinition->format.image.pNativeRender = 0;
+        // pPortDefinition->format.image.bFlagErrorConcealment = OMX_FALSE;
+        // pPortDefinition->format.image.eColorFormat = OMX_COLOR_FormatUnused;
+
+        pPortDefinition->format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
+        pPortDefinition->format.video.nFrameHeight = DEFAULT_FRAME_HEIGHT;
+        pPortDefinition->format.video.nStride = DEFAULT_FRAME_WIDTH;
+        pPortDefinition->format.video.nSliceHeight = DEFAULT_FRAME_HEIGHT;
+        pPortDefinition->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+        pPortDefinition->format.video.cMIMEType = malloc(OMX_MAX_STRINGNAME_SIZE);
+        pPortDefinition->format.video.xFramerate = 30;
+        if (pPortDefinition->format.video.cMIMEType == NULL)
+        {
+            ret = OMX_ErrorInsufficientResources;
+            free(pPortDefinition->format.video.cMIMEType);
+            pPortDefinition->format.video.cMIMEType = NULL;
+            LOG(SF_LOG_ERR, "malloc fail\r\n");
+            goto ERROR;
+        }
+        memset(pPortDefinition->format.video.cMIMEType, 0, OMX_MAX_STRINGNAME_SIZE);
+        pPortDefinition->format.video.pNativeRender = 0;
+        pPortDefinition->format.video.bFlagErrorConcealment = OMX_FALSE;
+        pPortDefinition->format.video.eColorFormat = OMX_COLOR_FormatUnused;
+
+        pPortDefinition->bEnabled = OMX_TRUE;
+
+        pPortDefinition->eDir = (i == 0 ? OMX_DirInput : OMX_DirOutput);
+    }
+
+    // strcpy(pSfOMXComponent->portDefinition[1].format.image.cMIMEType, "JPEG");
+    // pSfOMXComponent->portDefinition[1].format.image.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+    strcpy(pSfOMXComponent->portDefinition[1].format.video.cMIMEType, "JPEG");
+    pSfOMXComponent->portDefinition[1].format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+
+    memset(pSfOMXComponent->pBufferArray, 0, sizeof(pSfOMXComponent->pBufferArray));
+    pSfOMXComponent->memory_optimization = OMX_TRUE;
+
+    FunctionOut();
+EXIT:
+    return ret;
+ERROR:
+    if (pSfOMXComponent->pOMXComponent)
+    {
+        free(pSfOMXComponent->pOMXComponent);
+        pSfOMXComponent->pOMXComponent = NULL;
+    }
+
+    return ret;
+}
+
+static void sf_get_component_functions(SF_CODAJ12_FUNCTIONS *funcs, OMX_PTR *sohandle)
+{
+    FunctionIn();
+    funcs->JPU_Init = dlsym(sohandle, "JPU_Init");
+    funcs->JPU_DecOpen = dlsym(sohandle, "JPU_DecOpen");
+    funcs->JPU_DecGetInitialInfo = dlsym(sohandle, "JPU_DecGetInitialInfo");
+    funcs->JPU_DecRegisterFrameBuffer2 = dlsym(sohandle, "JPU_DecRegisterFrameBuffer2");
+    funcs->JPU_DecRegisterFrameBuffer = dlsym(sohandle, "JPU_DecRegisterFrameBuffer");
+    funcs->JPU_DecGiveCommand = dlsym(sohandle, "JPU_DecGiveCommand");
+    funcs->JPU_DecStartOneFrameBySerialNum = dlsym(sohandle, "JPU_DecStartOneFrameBySerialNum");
+    funcs->JPU_DecGetOutputInfo = dlsym(sohandle, "JPU_DecGetOutputInfo");
+    funcs->JPU_SWReset = dlsym(sohandle, "JPU_SWReset");
+    funcs->JPU_DecSetRdPtrEx = dlsym(sohandle, "JPU_DecSetRdPtrEx");
+    funcs->JPU_DecClose = dlsym(sohandle, "JPU_DecClose");
+    funcs->JPU_WaitInterrupt = dlsym(sohandle, "JPU_WaitInterrupt");
+    funcs->JPU_GetFrameBufPool = dlsym(sohandle, "JPU_GetFrameBufPool");
+    funcs->JPU_ClrStatus = dlsym(sohandle, "JPU_ClrStatus");
+    funcs->JPU_DeInit = dlsym(sohandle, "JPU_DeInit");
+    funcs->BSFeederBuffer_SetData = dlsym(sohandle, "BSFeederBuffer_SetData");
+    funcs->BitstreamFeeder_SetData = dlsym(sohandle, "BitstreamFeeder_SetData");
+    funcs->BitstreamFeeder_Create = dlsym(sohandle, "BitstreamFeeder_Create");
+    funcs->BitstreamFeeder_Act = dlsym(sohandle, "BitstreamFeeder_Act");
+    funcs->BitstreamFeeder_Destroy = dlsym(sohandle, "BitstreamFeeder_Destroy");
+    funcs->jdi_allocate_dma_memory = dlsym(sohandle, "jdi_allocate_dma_memory");
+    funcs->jdi_free_dma_memory = dlsym(sohandle, "jdi_free_dma_memory");
+    funcs->AllocateOneFrameBuffer = dlsym(sohandle, "AllocateOneFrameBuffer");
+    funcs->FreeFrameBuffer = dlsym(sohandle, "FreeFrameBuffer");
+    funcs->GetFrameBuffer = dlsym(sohandle, "GetFrameBuffer");
+    funcs->GetFrameBufferCount = dlsym(sohandle, "GetFrameBufferCount");
+    funcs->UpdateFrameBuffers = dlsym(sohandle, "UpdateFrameBuffers");
+    funcs->SetMaxLogLevel = dlsym(sohandle, "SetMaxLogLevel");
+    funcs->AttachOneFrameBuffer = dlsym(sohandle, "AttachOneFrameBuffer");
+    FunctionOut();
+}
+
+OMX_BOOL AttachOutputBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U8* pBuffer, OMX_U32 nSizeBytes)
+{
+    SF_CODAJ12_IMPLEMEMT *pSfCodaj12Implement = pSfOMXComponent->componentImpl;
+    Int32 instIdx = pSfCodaj12Implement->instIdx;
+    JpgDecOpenParam *decOP = &pSfCodaj12Implement->decOP;
+    DecConfigParam *decConfig = pSfCodaj12Implement->config;
+    JpgDecInitialInfo *initialInfo = &pSfCodaj12Implement->initialInfo;
+    FrameBuffer *pFrameBuf = pSfCodaj12Implement->frameBuf;
+    JpgDecHandle handle = pSfCodaj12Implement->handle;
+
+    Uint32 framebufWidth = 0, framebufHeight = 0, framebufStride = 0;
+    Uint32 decodingWidth, decodingHeight;
+    BOOL scalerOn = FALSE;
+    Uint32 bitDepth = 0;
+    FrameFormat subsample;
+    Uint32 temp;
+    OMX_U8 *virtAddr = NULL;
+    Uint32 bufferIndex;
+    JpgRet jpgret;
+
+    FunctionIn();
+    if (initialInfo->sourceFormat == FORMAT_420 || initialInfo->sourceFormat == FORMAT_422)
+        framebufWidth = JPU_CEIL(16, initialInfo->picWidth);
+    else
+        framebufWidth = JPU_CEIL(8, initialInfo->picWidth);
+
+    if (initialInfo->sourceFormat == FORMAT_420 || initialInfo->sourceFormat == FORMAT_440)
+        framebufHeight = JPU_CEIL(16, initialInfo->picHeight);
+    else
+        framebufHeight = JPU_CEIL(8, initialInfo->picHeight);
+
+    if (framebufWidth == 0 || framebufHeight == 0)
+    {
+        LOG(SF_LOG_WARN, "width or height == 0, use port parameters\r\n");
+        for (int i = 0; i < OMX_PORT_MAX; i ++)
+        {
+            OMX_PARAM_PORTDEFINITIONTYPE *pPort = &pSfOMXComponent->portDefinition[i];
+            framebufWidth = pPort->format.video.nFrameWidth;
+            framebufHeight = pPort->format.video.nFrameHeight;
+            if (framebufWidth > 0 && framebufHeight > 0)
+            {
+                LOG(SF_LOG_INFO, "Use port: %d\r\n", i);
+                break;
+            }
+        }
+        if (framebufWidth == 0 || framebufHeight == 0)
+        {
+            LOG(SF_LOG_ERR, "Can not get frame size\r\n");
+            return OMX_FALSE;
+        }
+    }
+    LOG(SF_LOG_DEBUG, "framebufWidth: %d, framebufHeight: %d\r\n", framebufWidth, framebufHeight);
+
+    decodingWidth = framebufWidth >> decConfig->iHorScaleMode;
+    decodingHeight = framebufHeight >> decConfig->iVerScaleMode;
+    if (decOP->packedFormat != PACKED_FORMAT_NONE && decOP->packedFormat != PACKED_FORMAT_444)
+    {
+        // When packed format, scale-down resolution should be multiple of 2.
+        decodingWidth = JPU_CEIL(2, decodingWidth);
+    }
+
+    subsample = pSfCodaj12Implement->frameFormat;
+    temp = decodingWidth;
+    decodingWidth = (decConfig->rotation == 90 || decConfig->rotation == 270) ? decodingHeight : decodingWidth;
+    decodingHeight = (decConfig->rotation == 90 || decConfig->rotation == 270) ? temp : decodingHeight;
+    if (decConfig->roiEnable == TRUE)
+    {
+        decodingWidth = framebufWidth = initialInfo->roiFrameWidth;
+        decodingHeight = framebufHeight = initialInfo->roiFrameHeight;
+    }
+
+    LOG(SF_LOG_DEBUG, "decodingWidth: %d, decodingHeight: %d\n", decodingWidth, decodingHeight);
+
+    if (decOP->rotation != 0 || decOP->mirror != MIRDIR_NONE)
+    {
+        if (decOP->outputFormat != FORMAT_MAX && decOP->outputFormat != initialInfo->sourceFormat)
+        {
+            LOG(SF_LOG_ERR, "The rotator cannot work with the format converter together.\n");
+            return OMX_FALSE;
+        }
+    }
+
+    LOG(SF_LOG_INFO, "<INSTANCE %d>\n", instIdx);
+    LOG(SF_LOG_INFO, "SOURCE PICTURE SIZE : W(%d) H(%d)\n", initialInfo->picWidth, initialInfo->picHeight);
+    LOG(SF_LOG_INFO, "SUBSAMPLE           : %d\n", subsample);
+
+    bitDepth = initialInfo->bitDepth;
+    scalerOn = (BOOL)(decConfig->iHorScaleMode || decConfig->iVerScaleMode);
+    // may be handle == NULL on ffmpeg case
+    if (bitDepth == 0)
+    {
+        bitDepth = 8;
+    }
+    LOG(SF_LOG_DEBUG, "AllocateOneFrameBuffer\r\n");
+    LOG_APPEND(SF_LOG_DEBUG, "instIdx = %d subsample = %d chromaInterleave = %d packedFormat = %d rotation = %d\r\n",
+                instIdx, subsample, decOP->chromaInterleave, decOP->packedFormat, decConfig->rotation);
+    LOG_APPEND(SF_LOG_DEBUG, "scalerOn = %d decodingWidth = %d decodingHeight = %d bitDepth = %d\r\n",
+                scalerOn, decodingWidth, decodingHeight, bitDepth);
+    if (pSfCodaj12Implement->functions->AttachOneFrameBuffer(instIdx, subsample, decOP->chromaInterleave,
+        decOP->packedFormat, decConfig->rotation,
+        scalerOn, decodingWidth, decodingHeight, bitDepth, pBuffer, nSizeBytes, &bufferIndex) == OMX_FALSE)
+    {
+        LOG(SF_LOG_ERR, "Fail to attach FrameBuffer\r\n");
+        return OMX_FALSE;
+    }
+
+    LOG(SF_LOG_INFO, "Allocate frame buffer %p, index = %d\r\n", virtAddr, bufferIndex);
+
+    //Register frame buffer
+    FRAME_BUF *pFrame = pSfCodaj12Implement->functions->GetFrameBuffer(instIdx, bufferIndex);
+    memcpy(&pSfCodaj12Implement->frame[bufferIndex], pFrame, sizeof(FRAME_BUF));
+    pFrameBuf[bufferIndex].bufY = pFrame->vbY.phys_addr;
+    pFrameBuf[bufferIndex].bufCb = pFrame->vbCb.phys_addr;
+    if (decOP->chromaInterleave == CBCR_SEPARATED)
+        pFrameBuf[bufferIndex].bufCr = pFrame->vbCr.phys_addr;
+    pFrameBuf[bufferIndex].stride = pFrame->strideY;
+    pFrameBuf[bufferIndex].strideC = pFrame->strideC;
+    pFrameBuf[bufferIndex].endian = decOP->frameEndian;
+    pFrameBuf[bufferIndex].format = (FrameFormat)pFrame->Format;
+    framebufStride = pFrameBuf[bufferIndex].stride;
+
+    // may be handle == NULL on ffmpeg case
+    jpgret = pSfCodaj12Implement->functions->JPU_DecRegisterFrameBuffer2(handle, &pFrameBuf[bufferIndex], framebufStride);
+    LOG(SF_LOG_DEBUG, "JPU_DecRegisterFrameBuffer2 ret = %d\r\n", jpgret);
+    FunctionOut();
+    return OMX_TRUE;
+
+}
+OMX_U8 *AllocateOutputBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U32 nSizeBytes)
+{
+    SF_CODAJ12_IMPLEMEMT *pSfCodaj12Implement = pSfOMXComponent->componentImpl;
+    Int32 instIdx = pSfCodaj12Implement->instIdx;
+    JpgDecOpenParam *decOP = &pSfCodaj12Implement->decOP;
+    DecConfigParam *decConfig = pSfCodaj12Implement->config;
+    JpgDecInitialInfo *initialInfo = &pSfCodaj12Implement->initialInfo;
+    FrameBuffer *pFrameBuf = pSfCodaj12Implement->frameBuf;
+    JpgDecHandle handle = pSfCodaj12Implement->handle;
+
+    Uint32 framebufWidth = 0, framebufHeight = 0, framebufStride = 0;
+    Uint32 decodingWidth, decodingHeight;
+    BOOL scalerOn = FALSE;
+    Uint32 bitDepth = 0;
+    FrameFormat subsample;
+    Uint32 temp;
+    OMX_U8 *virtAddr;
+    Uint32 bufferIndex;
+    JpgRet jpgret;
+
+    CbCrInterLeave chromaInterleave;
+    PackedFormat packedFormat;
+    FunctionIn();
+
+    if (initialInfo->sourceFormat == FORMAT_420 || initialInfo->sourceFormat == FORMAT_422)
+        framebufWidth = JPU_CEIL(16, initialInfo->picWidth);
+    else
+        framebufWidth = JPU_CEIL(8, initialInfo->picWidth);
+
+    if (initialInfo->sourceFormat == FORMAT_420 || initialInfo->sourceFormat == FORMAT_440)
+        framebufHeight = JPU_CEIL(16, initialInfo->picHeight);
+    else
+        framebufHeight = JPU_CEIL(8, initialInfo->picHeight);
+
+    if (framebufWidth == 0 || framebufHeight == 0)
+    {
+        LOG(SF_LOG_WARN, "width or height == 0, use port parameters\r\n");
+        for (int i = 0; i < OMX_PORT_MAX; i ++)
+        {
+            OMX_PARAM_PORTDEFINITIONTYPE *pPort = &pSfOMXComponent->portDefinition[i];
+            framebufWidth = pPort->format.video.nFrameWidth;
+            framebufHeight = pPort->format.video.nFrameHeight;
+            if (framebufWidth > 0 && framebufHeight > 0)
+            {
+                LOG(SF_LOG_INFO, "Use port: %d\r\n", i);
+                break;
+            }
+        }
+
+        if (initialInfo->sourceFormat == FORMAT_420 || initialInfo->sourceFormat == FORMAT_422)
+            framebufWidth = JPU_CEIL(16, framebufWidth);
+        else
+            framebufWidth = JPU_CEIL(8, framebufWidth);
+
+        if (initialInfo->sourceFormat == FORMAT_420 || initialInfo->sourceFormat == FORMAT_440)
+            framebufHeight = JPU_CEIL(16, framebufHeight);
+        else
+            framebufHeight = JPU_CEIL(8, framebufHeight);
+
+        if (framebufWidth == 0 || framebufHeight == 0)
+        {
+            LOG(SF_LOG_ERR, "Can not get frame size\r\n");
+            return NULL;
+        }
+    }
+    LOG(SF_LOG_DEBUG, "framebufWidth: %d, framebufHeight: %d\r\n", framebufWidth, framebufHeight);
+
+    decodingWidth = framebufWidth >> decConfig->iHorScaleMode;
+    decodingHeight = framebufHeight >> decConfig->iVerScaleMode;
+    if (decOP->packedFormat != PACKED_FORMAT_NONE && decOP->packedFormat != PACKED_FORMAT_444)
+    {
+        // When packed format, scale-down resolution should be multiple of 2.
+        decodingWidth = JPU_CEIL(2, decodingWidth);
+    }
+
+    subsample = pSfCodaj12Implement->frameFormat;
+    temp = decodingWidth;
+    decodingWidth = (decConfig->rotation == 90 || decConfig->rotation == 270) ? decodingHeight : decodingWidth;
+    decodingHeight = (decConfig->rotation == 90 || decConfig->rotation == 270) ? temp : decodingHeight;
+    if (decConfig->roiEnable == TRUE)
+    {
+        decodingWidth = framebufWidth = initialInfo->roiFrameWidth;
+        decodingHeight = framebufHeight = initialInfo->roiFrameHeight;
+    }
+
+    LOG(SF_LOG_DEBUG, "decodingWidth: %d, decodingHeight: %d\n", decodingWidth, decodingHeight);
+
+    if (decOP->rotation != 0 || decOP->mirror != MIRDIR_NONE)
+    {
+        if (decOP->outputFormat != FORMAT_MAX && decOP->outputFormat != initialInfo->sourceFormat)
+        {
+            LOG(SF_LOG_ERR, "The rotator cannot work with the format converter together.\n");
+            return NULL;
+        }
+    }
+
+    LOG(SF_LOG_INFO, "<INSTANCE %d>\n", instIdx);
+    LOG(SF_LOG_INFO, "SOURCE PICTURE SIZE : W(%d) H(%d)\n", initialInfo->picWidth, initialInfo->picHeight);
+    LOG(SF_LOG_INFO, "SUBSAMPLE           : %d\n", subsample);
+
+    bitDepth = initialInfo->bitDepth;
+    scalerOn = (BOOL)(decConfig->iHorScaleMode || decConfig->iVerScaleMode);
+    // may be handle == NULL on ffmpeg case
+    if (bitDepth == 0)
+    {
+        bitDepth = 8;
+    }
+    if (handle == NULL)
+    {
+        LOG(SF_LOG_INFO, "JPU not open yet, use default\r\n");
+        chromaInterleave = decConfig->cbcrInterleave;
+        packedFormat = decConfig->packedFormat;
+    }
+    else
+    {
+        chromaInterleave = decOP->chromaInterleave;
+        packedFormat = decOP->packedFormat;
+    }
+    LOG(SF_LOG_DEBUG, "AllocateOneFrameBuffer\r\n");
+    LOG_APPEND(SF_LOG_DEBUG, "instIdx = %d subsample = %d chromaInterleave = %d packedFormat = %d rotation = %d\r\n",
+                instIdx, subsample, chromaInterleave, packedFormat, decConfig->rotation);
+    LOG_APPEND(SF_LOG_DEBUG, "scalerOn = %d decodingWidth = %d decodingHeight = %d bitDepth = %d\r\n",
+                scalerOn, decodingWidth, decodingHeight, bitDepth);
+    virtAddr = (OMX_U8 *)pSfCodaj12Implement->functions->AllocateOneFrameBuffer
+        (instIdx, subsample, chromaInterleave, packedFormat, decConfig->rotation,
+        scalerOn, decodingWidth, decodingHeight, bitDepth, &bufferIndex);
+    if (virtAddr == NULL)
+    {
+        LOG(SF_LOG_ERR, "Failed to AllocateOneFrameBuffer()\n");
+        return NULL;
+    }
+    LOG(SF_LOG_INFO, "Allocate frame buffer %p, index = %d\r\n", virtAddr, bufferIndex);
+
+    //Register frame buffer
+    FRAME_BUF *pFrame = pSfCodaj12Implement->functions->GetFrameBuffer(instIdx, bufferIndex);
+    memcpy(&pSfCodaj12Implement->frame[bufferIndex], pFrame, sizeof(FRAME_BUF));
+    pFrameBuf[bufferIndex].bufY = pFrame->vbY.phys_addr;
+    pFrameBuf[bufferIndex].bufCb = pFrame->vbCb.phys_addr;
+    if (decOP->chromaInterleave == CBCR_SEPARATED)
+        pFrameBuf[bufferIndex].bufCr = pFrame->vbCr.phys_addr;
+    pFrameBuf[bufferIndex].stride = pFrame->strideY;
+    pFrameBuf[bufferIndex].strideC = pFrame->strideC;
+    pFrameBuf[bufferIndex].endian = decOP->frameEndian;
+    pFrameBuf[bufferIndex].format = (FrameFormat)pFrame->Format;
+    framebufStride = pFrameBuf[bufferIndex].stride;
+
+    // may be handle == NULL on ffmpeg case
+    jpgret = pSfCodaj12Implement->functions->JPU_DecRegisterFrameBuffer2(handle, &pFrameBuf[bufferIndex], framebufStride);
+    LOG(SF_LOG_DEBUG, "JPU_DecRegisterFrameBuffer2 ret = %d\r\n", jpgret);
+    FunctionOut();
+    return virtAddr;
+}
+
+void CodaJ12FlushBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U32 nPortNumber)
+{
+    SF_CODAJ12_IMPLEMEMT *pSfCodaj12Implement = pSfOMXComponent->componentImpl;
+    Message data;
+    OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL;
+
+    FunctionIn();
+    switch (nPortNumber)
+    {
+    case OMX_INPUT_PORT_INDEX:
+        while (OMX_TRUE)
+        {
+            if (msgrcv(pSfCodaj12Implement->sInputMessageQueue, (void *)&data, BUFSIZ, 0, IPC_NOWAIT) < 0)
+            {
+                if (msgrcv(pSfCodaj12Implement->sBufferDoneQueue,  (void *)&data, BUFSIZ, 0, IPC_NOWAIT) < 0)
+                {
+                    LOG(SF_LOG_INFO, "No more buffer in input port\r\n");
+                    break;
+                }
+            }
+
+            pOMXBuffer = data.pBuffer;
+            LOG(SF_LOG_INFO, "Flush Buffer %p\r\n", pOMXBuffer);
+            if (pOMXBuffer != NULL)
+            {
+                pOMXBuffer->nFilledLen = 0;
+                pOMXBuffer->nFlags = OMX_BUFFERFLAG_EOS;
+                pSfOMXComponent->callbacks->EmptyBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pOMXBuffer);
+            }
+        }
+        break;
+    case OMX_OUTPUT_PORT_INDEX:
+        for(int i = 0; i < MCA_MAX_INDEX; i++){
+            pOMXBuffer = pSfCodaj12Implement->mesCacheArr[i].pBuffer;
+            LOG(SF_LOG_INFO, "Flush Buffer %p\r\n", pOMXBuffer);
+            if (pOMXBuffer != NULL)
+            {
+                pOMXBuffer->nFilledLen = 0;
+                pOMXBuffer->nFlags = OMX_BUFFERFLAG_EOS;
+                pSfOMXComponent->callbacks->FillBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pOMXBuffer);
+            }
+        }
+        while (OMX_TRUE)
+        {
+            if (msgrcv(pSfCodaj12Implement->sOutputMessageQueue, (void *)&data, BUFSIZ, 0, IPC_NOWAIT) < 0)
+            {
+                LOG(SF_LOG_INFO, "No more buffer in output port\r\n");
+                break;
+            }
+
+            pOMXBuffer = data.pBuffer;
+            LOG(SF_LOG_INFO, "Flush Buffer %p\r\n", pOMXBuffer);
+            if (pOMXBuffer != NULL)
+            {
+                pOMXBuffer->nFilledLen = 0;
+                pOMXBuffer->nFlags = OMX_BUFFERFLAG_EOS;
+                pSfOMXComponent->callbacks->FillBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pOMXBuffer);
+            }
+        }
+        break;
+    default:
+        break;
+    }
+    FunctionOut();
+}

+ 143 - 0
omx-il/component/image/common/SF_OMX_mjpeg_common.h

@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 StarFive Technology Co., Ltd.
+ */
+#ifndef SF_OMX_MJPEG_COMMON
+#define SF_OMX_MJPEG_COMMON
+
+#include "OMX_Component.h"
+#include "OMX_Image.h"
+#include "OMX_Index.h"
+#include "OMX_IndexExt.h"
+#include "SF_OMX_Core.h"
+#include "sf_thread.h"
+#include "codaj12/jpuapi/jpuapi.h"
+#include "codaj12/jpuapi/jpuapifunc.h"
+#include "codaj12/sample/main_helper.h"
+#include <sys/queue.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+#include <pthread.h>
+#include <errno.h>
+
+#define INIT_SET_SIZE_VERSION(_struct_, _structType_) \
+    do                                                \
+    {                                                 \
+        memset((_struct_), 0, sizeof(_structType_));  \
+        (_struct_)->nSize = sizeof(_structType_);     \
+        (_struct_)->nVersion.s.nVersionMajor = 1;     \
+        (_struct_)->nVersion.s.nVersionMinor = 18;    \
+        (_struct_)->nVersion.s.nRevision = 1;         \
+        (_struct_)->nVersion.s.nStep = 0;             \
+    } while (0)
+
+#define DEFAULT_FRAME_WIDTH 1920
+#define DEFAULT_FRAME_HEIGHT 1080
+#define DEFAULT_MJPEG_INPUT_BUFFER_SIZE (DEFAULT_FRAME_WIDTH * DEFAULT_FRAME_HEIGHT * 3)
+#define DEFAULT_MJPEG_OUTPUT_BUFFER_SIZE (DEFAULT_FRAME_WIDTH * DEFAULT_FRAME_HEIGHT * 3)
+#define NUM_FRAME_BUF MAX_FRAME
+#define DEFAULT_FRAME_FORMAT FORMAT_420
+
+#define CODAJ12_OUTPUT_BUF_NUMBER 4
+#define CODAJ12_INPUT_BUF_NUMBER 1
+
+#define MCA_MAX_INDEX 1
+
+typedef struct _SF_CODAJ12_FUNCTIONS
+{
+    JpgRet (*JPU_Init)(void);
+    JpgRet (*JPU_DecOpen)(JpgDecHandle *pHandle, JpgDecOpenParam *pop);
+    JpgRet (*JPU_DecGetInitialInfo)(JpgDecHandle handle, JpgDecInitialInfo *info);
+    JpgRet (*JPU_DecRegisterFrameBuffer2)(JpgDecHandle handle, FrameBuffer *bufArray, int stride);
+    JpgRet (*JPU_DecRegisterFrameBuffer)(JpgDecHandle handle, FrameBuffer * bufArray, int num, int stride);
+    JpgRet (*JPU_DecGiveCommand)(JpgDecHandle handle, JpgCommand cmd, void *param);
+    JpgRet (*JPU_DecStartOneFrameBySerialNum)(JpgDecHandle handle, JpgDecParam *param,int bufferIndex);
+    JpgRet (*JPU_DecGetOutputInfo)(JpgDecHandle handle, JpgDecOutputInfo *info);
+    JpgRet (*JPU_SWReset)(JpgHandle handle);
+    JpgRet (*JPU_DecSetRdPtrEx)(JpgDecHandle handle, PhysicalAddress addr, BOOL updateWrPtr);
+    JpgRet (*JPU_DecClose)(JpgDecHandle handle);
+    Int32 (*JPU_WaitInterrupt)(JpgHandle handle, int timeout);
+    FrameBuffer *(*JPU_GetFrameBufPool)(JpgDecHandle handle);
+    void (*JPU_ClrStatus)(JpgHandle handle, Uint32 val);
+    void (*JPU_DeInit)(void);
+
+    void (*BSFeederBuffer_SetData)(void *feeder, char *address, Uint32 size);
+    Uint32 (*BitstreamFeeder_SetData)(BSFeeder feeder, void *data, Uint32 size);
+    BSFeeder (*BitstreamFeeder_Create)(const char *path, FeedingMethod method, EndianMode endian);
+    Uint32 (*BitstreamFeeder_Act)(BSFeeder feeder, JpgDecHandle handle, jpu_buffer_t *bsBuffer);
+    BOOL(*BitstreamFeeder_Destroy)
+    (BSFeeder feeder);
+
+    int (*jdi_allocate_dma_memory)(jpu_buffer_t *vb);
+    void (*jdi_free_dma_memory)(jpu_buffer_t *vb);
+
+    void *(*AllocateOneFrameBuffer)
+    // (Uint32 instIdx, Uint32 size, Uint32 *bufferIndex);
+    (Uint32 instIdx, FrameFormat subsample, CbCrInterLeave cbcrIntlv,
+     PackedFormat packed, Uint32 rotation, BOOL scalerOn, Uint32 width, Uint32 height, Uint32 bitDepth, Uint32 *bufferIndex);
+    void (*FreeFrameBuffer)(int instIdx);
+    FRAME_BUF *(*GetFrameBuffer)(int instIdx, int idx);
+    Uint32 (*GetFrameBufferCount)(int instIdx);
+    BOOL (*AttachOneFrameBuffer)(Uint32 instIdx, FrameFormat subsample, CbCrInterLeave cbcrIntlv, PackedFormat packed,
+                         Uint32 rotation, BOOL scalerOn, Uint32 width, Uint32 height, Uint32 bitDepth,
+                         void *virtAddress, Uint32 size, Uint32 *bufferIndex);
+    BOOL (*UpdateFrameBuffers)(Uint32 instIdx, Uint32 num, FRAME_BUF *frameBuf);
+
+    // JPU Log
+    void (*SetMaxLogLevel)(int level);
+} SF_CODAJ12_FUNCTIONS;
+
+typedef struct Message
+{
+    long msg_type;
+    OMX_U32 msg_flag;
+    OMX_BUFFERHEADERTYPE *pBuffer;
+} Message;
+
+typedef struct _SF_CODAJ12_IMPLEMEMT
+{
+    DecConfigParam *config;
+    SF_CODAJ12_FUNCTIONS *functions;
+    BSFeeder feeder;
+    jpu_buffer_t vbStream;
+    JpgDecOpenParam decOP;
+    JpgDecHandle handle;
+    JpgDecInitialInfo initialInfo;
+    Int32 instIdx;
+    FrameBuffer frameBuf[NUM_FRAME_BUF];
+    FRAME_BUF frame[NUM_FRAME_BUF];
+    OMX_S32 sInputMessageQueue;
+    OMX_S32 sOutputMessageQueue;
+    OMX_S32 sBufferDoneQueue;
+    Message mesCacheArr[MCA_MAX_INDEX];
+    THREAD_HANDLE_TYPE *pProcessThread;
+    OMX_BOOL bThreadRunning;
+    OMX_STATETYPE currentState;
+    FrameFormat frameFormat;
+    OMX_BOOL allocBufFlag;
+} SF_CODAJ12_IMPLEMEMT;
+
+enum port_index
+{
+    OMX_INPUT_PORT_INDEX = 0,
+    OMX_OUTPUT_PORT_INDEX = 1,
+    OMX_PORT_MAX = 2,
+};
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+OMX_ERRORTYPE GetStateMjpegCommon(OMX_IN OMX_HANDLETYPE hComponent, OMX_OUT OMX_STATETYPE *pState);
+OMX_ERRORTYPE InitMjpegStructorCommon(SF_OMX_COMPONENT *hComponent);
+OMX_BOOL AttachOutputBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U8* pBuffer, OMX_U32 nSizeBytes);
+OMX_U8* AllocateOutputBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U32 nSizeBytes);
+void ThreadExit(void *value_ptr);
+void CodaJ12FlushBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U32 nPortNumber);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 1607 - 0
omx-il/component/image/dec/SF_OMX_Mjpeg_decoder.c

@@ -0,0 +1,1607 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 StarFive Technology Co., Ltd.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include "SF_OMX_mjpeg_common.h"
+#include "SF_OMX_Core.h"
+#include <sys/prctl.h>
+
+extern OMX_TICKS gInitTimeStamp;
+#define TEMP_DEBUG 1
+#define NUM_OF_PORTS 2
+
+static OMX_ERRORTYPE SF_OMX_EmptyThisBuffer(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_BOOL bSendNULL = OMX_FALSE;
+    OMX_BOOL bSendMessage = OMX_TRUE;
+    FunctionIn();
+
+    if (hComponent == NULL || pBuffer == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = (SF_OMX_COMPONENT *)pOMXComponent->pComponentPrivate;
+    SF_CODAJ12_IMPLEMEMT *pSfCodaj12Implement = (SF_CODAJ12_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+
+    LOG(SF_LOG_DEBUG, "nFilledLen = %d, nFlags = %d, header = %p, pBuffer = %p\r\n", pBuffer->nFilledLen, pBuffer->nFlags, pBuffer, pBuffer->pBuffer);
+
+    if (pBuffer->nFilledLen == 0 || (pBuffer->nFlags & 0x1) == 0x1)
+    {
+        bSendNULL = OMX_TRUE;
+    }
+    else
+    {
+        bSendNULL = OMX_FALSE;
+    }
+
+    if (pBuffer->pBuffer == NULL)
+    {
+        bSendMessage = OMX_FALSE;
+    }
+    else
+    {
+        bSendMessage = OMX_TRUE;
+    }
+
+    Message data;
+    data.msg_type = 1;
+    data.msg_flag = 0;
+    if (bSendMessage)
+    {
+        data.pBuffer = pBuffer;
+        if (msgsnd(pSfCodaj12Implement->sInputMessageQueue, (void *)&data, sizeof(data) - sizeof(data.msg_type), 0) == -1)
+        {
+            LOG(SF_LOG_ERR, "msgsnd failed\n");
+        }
+    }
+    if (bSendNULL)
+    {
+        data.pBuffer = NULL;
+        if (msgsnd(pSfCodaj12Implement->sInputMessageQueue, (void *)&data, sizeof(data) - sizeof(data.msg_type), 0) == -1)
+        {
+            LOG(SF_LOG_ERR, "msgsnd failed\n");
+        }
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+int MCAIndex = 0;
+int dataCount = 0;
+
+static OMX_ERRORTYPE SF_OMX_FillThisBuffer(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    FunctionIn();
+
+    if (hComponent == NULL || pBuffer == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = (SF_OMX_COMPONENT *)pOMXComponent->pComponentPrivate;
+    SF_CODAJ12_IMPLEMEMT *pSfCodaj12Implement = (SF_CODAJ12_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    LOG(SF_LOG_DEBUG, "nFilledLen = %d, nFlags = %d, header = %p, pBuffer = %p\r\n", pBuffer->nFilledLen, pBuffer->nFlags, pBuffer, pBuffer->pBuffer);
+    // if (pSfCodaj12Implement->functions->Queue_Enqueue(&pSfCodaj12Implement->decodeBufferQueue, (void *)pBuffer->pBuffer) == FALSE)
+    // {
+    //     return OMX_ErrorInsufficientResources;
+    // }
+    Message data,outputData;
+    data.msg_type = 1;
+    data.msg_flag = 0;
+    data.pBuffer = pBuffer;
+
+    // TODO start:
+    // Temporary store one buff here to prevent the buff from being refill too soon.
+    // It is a workaround for issue and should be fixed further.
+    MCAIndex = (dataCount)%MCA_MAX_INDEX;
+    if(dataCount++ < MCA_MAX_INDEX)
+    {
+        pSfCodaj12Implement->mesCacheArr[MCAIndex] = data;
+        FunctionOut();
+        return ret;
+    }
+    else
+    {
+        outputData = pSfCodaj12Implement->mesCacheArr[MCAIndex];
+        pSfCodaj12Implement->mesCacheArr[MCAIndex] = data;
+    }
+    // TODO end
+
+    LOG(SF_LOG_DEBUG, "Send to message queue\r\n");
+    if (msgsnd(pSfCodaj12Implement->sOutputMessageQueue, (void *)&outputData, sizeof(data) - sizeof(data.msg_type), 0) == -1)
+    {
+        LOG(SF_LOG_ERR, "msgsnd failed\n");
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_U64 nOutBufIndex = 0;
+
+static OMX_ERRORTYPE SF_OMX_UseBuffer(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
+    OMX_IN OMX_U32 nPortIndex,
+    OMX_IN OMX_PTR pAppPrivate,
+    OMX_IN OMX_U32 nSizeBytes,
+    OMX_IN OMX_U8 *pBuffer)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    SF_CODAJ12_IMPLEMEMT *pSfCodaj12Implement = pSfOMXComponent->componentImpl;
+    FunctionIn();
+
+    if (hComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    if (AttachOutputBuffer(pSfOMXComponent, pBuffer, nSizeBytes) == OMX_FALSE)
+    {
+        LOG(SF_LOG_ERR, "Failed to attach dma buffer\r\n");
+        return OMX_ErrorInsufficientResources;
+    }
+    OMX_BUFFERHEADERTYPE *temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)malloc(sizeof(OMX_BUFFERHEADERTYPE));
+    if (temp_bufferHeader == NULL)
+    {
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        return OMX_ErrorInsufficientResources;
+    }
+    memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE));
+    temp_bufferHeader->nAllocLen = nSizeBytes;
+    temp_bufferHeader->pAppPrivate = pAppPrivate;
+    temp_bufferHeader->pBuffer = pBuffer;
+    *ppBufferHdr = temp_bufferHeader;
+    if (nPortIndex == 1)
+    {
+        temp_bufferHeader->pOutputPortPrivate = (OMX_PTR)nOutBufIndex;
+        nOutBufIndex ++;
+    }
+    LOG(SF_LOG_DEBUG, "pBuffer address = %p, nOutBufIndex = %d\r\n", temp_bufferHeader->pBuffer, (OMX_U64)temp_bufferHeader->pOutputPortPrivate);
+
+    pSfCodaj12Implement->allocBufFlag = OMX_FALSE;
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_AllocateBuffer(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
+    OMX_IN OMX_U32 nPortIndex,
+    OMX_IN OMX_PTR pAppPrivate,
+    OMX_IN OMX_U32 nSizeBytes)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    SF_CODAJ12_IMPLEMEMT *pSfCodaj12Implement = pSfOMXComponent->componentImpl;
+
+    FunctionIn();
+    if (nSizeBytes == 0)
+    {
+        LOG(SF_LOG_ERR, "nSizeBytes = %d\r\n", nSizeBytes);
+        return OMX_ErrorBadParameter;
+    }
+    OMX_BUFFERHEADERTYPE *temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)malloc(sizeof(OMX_BUFFERHEADERTYPE));
+    if (temp_bufferHeader == NULL)
+    {
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        return OMX_ErrorInsufficientResources;
+    }
+    memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE));
+
+
+    temp_bufferHeader->nAllocLen = nSizeBytes;
+    temp_bufferHeader->pAppPrivate = pAppPrivate;
+    if (nPortIndex == 1)
+    {
+        temp_bufferHeader->pBuffer = AllocateOutputBuffer(pSfOMXComponent, nSizeBytes);
+        temp_bufferHeader->pOutputPortPrivate = (OMX_PTR)nOutBufIndex;
+        nOutBufIndex ++;
+        pSfCodaj12Implement->allocBufFlag = OMX_TRUE;
+        // temp_bufferHeader->nFilledLen = nSizeBytes;
+    }
+    else if (nPortIndex == 0)
+    {
+        jpu_buffer_t *vbStream = &pSfCodaj12Implement->vbStream;
+        vbStream->size = (nSizeBytes == 0) ? STREAM_BUF_SIZE : nSizeBytes;
+        vbStream->size = (vbStream->size + 1023) & ~1023; // ceil128(size)
+        if (pSfCodaj12Implement->functions->jdi_allocate_dma_memory(vbStream) < 0)
+        {
+            LOG(SF_LOG_ERR, "fail to allocate bitstream buffer\r\n");
+            return OMX_ErrorInsufficientResources;
+        }
+        temp_bufferHeader->pBuffer = (OMX_U8 *)vbStream->virt_addr;
+        temp_bufferHeader->pInputPortPrivate = (void *)vbStream->phys_addr;
+    }
+
+    if (temp_bufferHeader->pBuffer == NULL)
+    {
+        free(temp_bufferHeader);
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        return OMX_ErrorInsufficientResources;
+    }
+    *ppBuffer = temp_bufferHeader;
+    LOG(SF_LOG_INFO, "nPortIndex = %d, header = %p, pBuffer address = %p, nFilledLen = %d, nSizeBytes = %d\r\n",
+            nPortIndex, temp_bufferHeader, temp_bufferHeader->pBuffer, temp_bufferHeader->nFilledLen, nSizeBytes);
+    FunctionOut();
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_GetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE nParamIndex,
+    OMX_INOUT OMX_PTR ComponentParameterStructure)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+
+    FunctionIn();
+    if (hComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (ComponentParameterStructure == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    LOG(SF_LOG_INFO, "Get parameter on index %X\r\n", nParamIndex);
+    switch ((OMX_U32)nParamIndex)
+    {
+    case OMX_IndexParamImageInit:
+    case OMX_IndexParamVideoInit:
+    {
+        OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure;
+        portParam->nPorts = NUM_OF_PORTS;
+        portParam->nStartPortNumber = OMX_INPUT_PORT_INDEX;
+        break;
+    }
+
+    case OMX_IndexParamImagePortFormat:
+    {
+        OMX_IMAGE_PARAM_PORTFORMATTYPE *portFormat = (OMX_IMAGE_PARAM_PORTFORMATTYPE *)ComponentParameterStructure;
+        OMX_U32 index = portFormat->nIndex;
+        switch (index)
+        {
+        case OMX_INPUT_PORT_INDEX:
+            portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
+            portFormat->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+        default:
+            if (index > 0)
+            {
+                ret = OMX_ErrorNoMore;
+            }
+        }
+        break;
+    }
+
+    case OMX_IndexParamPortDefinition:
+    {
+        OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
+        OMX_U32 portIndex = pPortDefinition->nPortIndex;
+        OMX_PARAM_PORTDEFINITIONTYPE *pSrcDefinition = &pSfOMXComponent->portDefinition[portIndex];
+
+        LOG(SF_LOG_DEBUG, "Get parameter port %X\r\n",portIndex);
+        LOG_APPEND(SF_LOG_DEBUG, "width = %d, height = %d\r\n", pSrcDefinition->format.video.nFrameWidth, pSrcDefinition->format.video.nFrameHeight);
+        LOG_APPEND(SF_LOG_DEBUG, "eColorFormat = %d\r\n", pSrcDefinition->format.video.eColorFormat);
+        LOG_APPEND(SF_LOG_DEBUG, "xFramerate = %d\r\n", pSrcDefinition->format.video.xFramerate);
+        LOG_APPEND(SF_LOG_DEBUG, "bufferSize = %d\r\n",pSrcDefinition->nBufferSize);
+        LOG_APPEND(SF_LOG_DEBUG, "Buffer count = %d\r\n", pSrcDefinition->nBufferCountActual);
+
+        memcpy(pPortDefinition, pSrcDefinition, pPortDefinition->nSize);
+        break;
+    }
+
+    case OMX_IndexParamVideoPortFormat:
+    {
+        OMX_VIDEO_PARAM_PORTFORMATTYPE *portFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure;
+        OMX_U32 index = portFormat->nIndex;
+        portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
+        portFormat->xFramerate = 30;
+        LOG(SF_LOG_DEBUG, "Get video format at port %d index %d\r\n",portFormat->nPortIndex, index);
+        switch (index)
+        {
+        case 0:
+            portFormat->eColorFormat = OMX_COLOR_FormatYUV420Planar;
+            break;
+        case 1:
+            portFormat->eColorFormat = OMX_COLOR_FormatYUV422Planar;
+            break;
+        case 2:
+            portFormat->eColorFormat = OMX_COLOR_FormatYUV444Interleaved;
+            break;
+        case 3:
+            portFormat->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; //NV12
+            break;
+        case 4:
+            portFormat->eColorFormat = OMX_COLOR_FormatYVU420SemiPlanar; //NV21
+            break;
+        default:
+            if (index > 0)
+            {
+                ret = OMX_ErrorNoMore;
+            }
+        }
+        break;
+    }
+    default:
+    {
+        ret = OMX_ErrorUnsupportedIndex;
+        break;
+    }
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+static OMX_ERRORTYPE SF_OMX_SetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE nIndex,
+    OMX_IN OMX_PTR ComponentParameterStructure)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+    if (hComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (ComponentParameterStructure == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    LOG(SF_LOG_INFO, "Set parameter on index %X\r\n", nIndex);
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    SF_CODAJ12_IMPLEMEMT *pSfMjpegImplement = (SF_CODAJ12_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+
+    if (pSfOMXComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    switch ((OMX_U32)nIndex)
+    {
+    case OMX_IndexParamPortDefinition:
+    {
+        OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition =
+            (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
+        OMX_PARAM_PORTDEFINITIONTYPE *pInputPort = &pSfOMXComponent->portDefinition[0];
+        OMX_PARAM_PORTDEFINITIONTYPE *pOutputPort = &pSfOMXComponent->portDefinition[1];
+        DecConfigParam *decConfig = pSfMjpegImplement->config;
+
+        OMX_U32 portIndex = pPortDefinition->nPortIndex;
+        OMX_U32 width = pPortDefinition->format.video.nFrameWidth;
+        OMX_U32 height = pPortDefinition->format.video.nFrameHeight;
+        LOG(SF_LOG_INFO, "Set parameter on port %d\r\n", pPortDefinition->nPortIndex);
+        LOG_APPEND(SF_LOG_DEBUG, "width = %d, height = %d\r\n",width, height);
+        LOG_APPEND(SF_LOG_DEBUG, "eColorFormat = %d\r\n", pPortDefinition->format.video.eColorFormat);
+        LOG_APPEND(SF_LOG_DEBUG, "xFramerate = %d\r\n", pPortDefinition->format.video.xFramerate);
+        LOG_APPEND(SF_LOG_DEBUG, "bufferSize = %d\r\n",pPortDefinition->nBufferSize);
+        LOG_APPEND(SF_LOG_DEBUG, "Buffer count = %d\r\n", pPortDefinition->nBufferCountActual);
+        if (portIndex == (OMX_U32)OMX_INPUT_PORT_INDEX)
+        {
+            memcpy(&pSfOMXComponent->portDefinition[portIndex], pPortDefinition, pPortDefinition->nSize);
+            pInputPort->format.video.nStride = width;
+            pInputPort->format.video.nSliceHeight = height;
+            pInputPort->nBufferSize = width * height * 2;
+        }
+        else if (portIndex == (OMX_U32)(OMX_OUTPUT_PORT_INDEX))
+        {
+            memcpy(&pSfOMXComponent->portDefinition[portIndex], pPortDefinition, pPortDefinition->nSize);
+
+            /*
+              Some client may set '0' or '1' to output port, in this case use input port parameters
+            */
+            if (width <= 1)
+            {
+                width = pInputPort->format.video.nFrameWidth;
+            }
+            if (height <= 1)
+            {
+                height = pInputPort->format.video.nFrameHeight;
+            }
+            if (width > 0 && height > 0)
+            {
+                int scalew = pInputPort->format.video.nFrameWidth / width;
+                int scaleh = pInputPort->format.video.nFrameHeight / height;
+                if (scalew > 8 || scaleh > 8 || scalew < 1 || scaleh < 1)
+                {
+                    int nInputWidth = pInputPort->format.video.nFrameWidth;
+                    int nInputHeight = pInputPort->format.video.nFrameHeight;
+                    LOG(SF_LOG_WARN, "Scaling should be 1 to 1/8 (down-scaling only)! Use input parameter. "
+                                     "OutPut[%d, %d]. Input[%d, %d]\r\n",
+                        width, height, nInputWidth, nInputHeight);
+                    width = nInputWidth;
+                    height = nInputHeight;
+                }
+
+                pOutputPort->format.video.nFrameWidth = width;
+                pOutputPort->format.video.nFrameHeight = height;
+                pOutputPort->format.video.nStride = width;
+                pOutputPort->format.video.nSliceHeight = height;
+                switch (pOutputPort->format.video.eColorFormat)
+                {
+                    case OMX_COLOR_FormatYUV420Planar:
+                        decConfig->cbcrInterleave = CBCR_SEPARATED;
+                        decConfig->packedFormat = PACKED_FORMAT_NONE;
+                        pSfMjpegImplement->frameFormat = FORMAT_420;
+                        pOutputPort->nBufferSize = (width * height * 3) / 2;
+                        break;
+                    case OMX_COLOR_FormatYUV420SemiPlanar: //NV12
+                        decConfig->cbcrInterleave = CBCR_INTERLEAVE;
+                        decConfig->packedFormat = PACKED_FORMAT_NONE;
+                        pSfMjpegImplement->frameFormat = FORMAT_420;
+                        pOutputPort->nBufferSize = (width * height * 3) / 2;
+                        break;
+                    case OMX_COLOR_FormatYVU420SemiPlanar: //NV21
+                        decConfig->cbcrInterleave = CRCB_INTERLEAVE;
+                        decConfig->packedFormat = PACKED_FORMAT_NONE;
+                        pSfMjpegImplement->frameFormat = FORMAT_420;
+                        pOutputPort->nBufferSize = (width * height * 3) / 2;
+                        break;
+                    case OMX_COLOR_FormatYUV422Planar:
+                        decConfig->cbcrInterleave = CBCR_SEPARATED;
+                        decConfig->packedFormat = PACKED_FORMAT_NONE;
+                        pSfMjpegImplement->frameFormat = FORMAT_422;
+                        pOutputPort->nBufferSize = width * height * 2;
+                        break;
+                    case OMX_COLOR_FormatYUV422SemiPlanar: //NV16
+                        decConfig->cbcrInterleave = CBCR_INTERLEAVE;
+                        decConfig->packedFormat = PACKED_FORMAT_NONE;
+                        pSfMjpegImplement->frameFormat = FORMAT_422;
+                        pOutputPort->nBufferSize = width * height * 2;
+                        break;
+                    case OMX_COLOR_FormatYVU422SemiPlanar: //NV61
+                        decConfig->cbcrInterleave = CRCB_INTERLEAVE;
+                        decConfig->packedFormat = PACKED_FORMAT_NONE;
+                        pSfMjpegImplement->frameFormat = FORMAT_422;
+                        pOutputPort->nBufferSize = width * height * 2;
+                        break;
+                    case OMX_COLOR_FormatYCbYCr: //YUYV
+                        decConfig->cbcrInterleave = CBCR_SEPARATED;
+                        decConfig->packedFormat   = PACKED_FORMAT_422_YUYV;
+                        pSfMjpegImplement->frameFormat = FORMAT_422;
+                        pOutputPort->nBufferSize = width * height * 2;
+                        break;
+                    case OMX_COLOR_FormatYCrYCb: //YVYU
+                        decConfig->cbcrInterleave = CBCR_SEPARATED;
+                        decConfig->packedFormat   = PACKED_FORMAT_422_YVYU;
+                        pSfMjpegImplement->frameFormat = FORMAT_422;
+                        pOutputPort->nBufferSize = width * height * 2;
+                        break;
+                    case OMX_COLOR_FormatCbYCrY: //UYVY
+                        decConfig->cbcrInterleave = CBCR_SEPARATED;
+                        decConfig->packedFormat   = PACKED_FORMAT_422_UYVY;
+                        pSfMjpegImplement->frameFormat = FORMAT_422;
+                        pOutputPort->nBufferSize = width * height * 2;
+                        break;
+                    case OMX_COLOR_FormatCrYCbY: //VYUY
+                        decConfig->cbcrInterleave = CBCR_SEPARATED;
+                        decConfig->packedFormat   = PACKED_FORMAT_422_VYUY;
+                        pSfMjpegImplement->frameFormat = FORMAT_422;
+                        pOutputPort->nBufferSize = width * height * 2;
+                        break;
+                    case OMX_COLOR_FormatYUV444Planar: //I444
+                        decConfig->cbcrInterleave = CBCR_SEPARATED;
+                        decConfig->packedFormat   = PACKED_FORMAT_NONE;
+                        pSfMjpegImplement->frameFormat = FORMAT_444;
+                        pOutputPort->nBufferSize = width * height * 3;
+                        break;
+                    case OMX_COLOR_FormatYUV444Interleaved: //YUV444PACKED
+                        decConfig->cbcrInterleave = CBCR_SEPARATED;
+                        decConfig->packedFormat   = PACKED_FORMAT_444;
+                        pSfMjpegImplement->frameFormat = FORMAT_444;
+                        pOutputPort->nBufferSize = width * height * 3;
+                        break;
+                    default:
+                        pOutputPort->nBufferSize = width * height * 4;
+                        break;
+                }
+            }
+        }
+        else
+        {
+            ret = OMX_ErrorNoMore;
+        }
+        break;
+    }
+    case OMX_IndexParamVideoPortFormat:
+    {
+        OMX_VIDEO_PARAM_PORTFORMATTYPE *portFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure;
+        OMX_U32 nPortIndex = portFormat->nPortIndex;
+        OMX_PARAM_PORTDEFINITIONTYPE *pPort = &pSfOMXComponent->portDefinition[nPortIndex];
+        DecConfigParam *decConfig = pSfMjpegImplement->config;
+        LOG(SF_LOG_DEBUG, "Set video format to port %d color %d\r\n", portFormat->nPortIndex, portFormat->eColorFormat);
+        switch (portFormat->eColorFormat)
+        {
+        case OMX_COLOR_FormatYUV420Planar:
+            decConfig->cbcrInterleave = CBCR_SEPARATED;
+            decConfig->packedFormat = PACKED_FORMAT_NONE;
+            pSfMjpegImplement->frameFormat = FORMAT_420;
+            break;
+        case OMX_COLOR_FormatYUV420SemiPlanar: //NV12
+            decConfig->cbcrInterleave = CBCR_INTERLEAVE;
+            decConfig->packedFormat = PACKED_FORMAT_NONE;
+            pSfMjpegImplement->frameFormat = FORMAT_420;
+            break;
+        case OMX_COLOR_FormatYVU420SemiPlanar: //NV21
+            decConfig->cbcrInterleave = CRCB_INTERLEAVE;
+            decConfig->packedFormat = PACKED_FORMAT_NONE;
+            pSfMjpegImplement->frameFormat = FORMAT_420;
+            break;
+        case OMX_COLOR_FormatYUV422Planar:
+            decConfig->cbcrInterleave = CBCR_SEPARATED;
+            decConfig->packedFormat = PACKED_FORMAT_NONE;
+            pSfMjpegImplement->frameFormat = FORMAT_422;
+            break;
+        case OMX_COLOR_FormatYUV422SemiPlanar: //NV16
+            decConfig->cbcrInterleave = CBCR_INTERLEAVE;
+            decConfig->packedFormat = PACKED_FORMAT_NONE;
+            pSfMjpegImplement->frameFormat = FORMAT_422;
+            break;
+        case OMX_COLOR_FormatYVU422SemiPlanar: //NV61
+            decConfig->cbcrInterleave = CRCB_INTERLEAVE;
+            decConfig->packedFormat = PACKED_FORMAT_NONE;
+            pSfMjpegImplement->frameFormat = FORMAT_422;
+            break;
+        case OMX_COLOR_FormatYCbYCr: //YUYV
+            decConfig->cbcrInterleave = CBCR_SEPARATED;
+            decConfig->packedFormat   = PACKED_FORMAT_422_YUYV;
+            pSfMjpegImplement->frameFormat = FORMAT_422;
+            break;
+        case OMX_COLOR_FormatYCrYCb: //YVYU
+            decConfig->cbcrInterleave = CBCR_SEPARATED;
+            decConfig->packedFormat   = PACKED_FORMAT_422_YVYU;
+            pSfMjpegImplement->frameFormat = FORMAT_422;
+            break;
+        case OMX_COLOR_FormatCbYCrY: //UYVY
+            decConfig->cbcrInterleave = CBCR_SEPARATED;
+            decConfig->packedFormat   = PACKED_FORMAT_422_UYVY;
+            pSfMjpegImplement->frameFormat = FORMAT_422;
+            break;
+        case OMX_COLOR_FormatCrYCbY: //VYUY
+            decConfig->cbcrInterleave = CBCR_SEPARATED;
+            decConfig->packedFormat   = PACKED_FORMAT_422_VYUY;
+            pSfMjpegImplement->frameFormat = FORMAT_422;
+            break;
+        case OMX_COLOR_FormatYUV444Planar: //I444
+            decConfig->cbcrInterleave = CBCR_SEPARATED;
+            decConfig->packedFormat   = PACKED_FORMAT_NONE;
+            pSfMjpegImplement->frameFormat = FORMAT_444;
+            break;
+        case OMX_COLOR_FormatYUV444Interleaved: //YUV444PACKED
+            decConfig->cbcrInterleave = CBCR_SEPARATED;
+            decConfig->packedFormat   = PACKED_FORMAT_444;
+            pSfMjpegImplement->frameFormat = FORMAT_444;
+            pPort->format.video.eColorFormat = portFormat->eColorFormat;
+            break;
+        default:
+            ret = OMX_ErrorNotImplemented;
+            break;
+        }
+        if(!ret)
+            pPort->format.video.eColorFormat = portFormat->eColorFormat;
+        break;
+    }
+    case OMX_IndexParamImageInit:
+    case OMX_IndexParamVideoInit:
+    {
+        OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure;
+        portParam->nPorts           = 2;
+        portParam->nStartPortNumber = 0;
+        break;
+    }
+
+    case OMX_IndexParamImagePortFormat:
+        break;
+
+    default:
+        ret = OMX_ErrorUnsupportedIndex;
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_GetConfig(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE nIndex,
+    OMX_PTR pComponentConfigStructure)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+    if (hComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pComponentConfigStructure == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    LOG(SF_LOG_INFO, "Get config on index %X\r\n", nIndex);
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    SF_CODAJ12_IMPLEMEMT *pSfMjpegImplement = (SF_CODAJ12_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+
+    switch ((OMX_U32)nIndex)
+    {
+    case OMX_IndexConfigCommonOutputCrop:
+    {
+        OMX_CONFIG_RECTTYPE *rectParam = (OMX_CONFIG_RECTTYPE *)pComponentConfigStructure;
+        DecConfigParam *decConfig = pSfMjpegImplement->config;
+        if(rectParam->nPortIndex == (OMX_U32)(OMX_OUTPUT_PORT_INDEX))
+        {
+            rectParam->nLeft = decConfig->roiOffsetX;
+            rectParam->nTop = decConfig->roiOffsetY;
+            rectParam->nWidth = decConfig->roiWidth;
+            rectParam->nHeight = decConfig->roiHeight;
+            LOG(SF_LOG_INFO, "Get OutputCrop left %d top %d width %d height %d \r\n",
+                decConfig->roiOffsetX, decConfig->roiOffsetY, decConfig->roiWidth, decConfig->roiHeight);
+        }
+        else
+        {
+            LOG(SF_LOG_WARN, "Only output port support OutputCrop param\r\n");
+            ret = OMX_ErrorBadParameter;
+        }
+        break;
+    }
+
+    case OMX_IndexConfigCommonRotate:
+    {
+        OMX_CONFIG_ROTATIONTYPE *rotatParam = (OMX_CONFIG_ROTATIONTYPE *)pComponentConfigStructure;
+        DecConfigParam *decConfig = pSfMjpegImplement->config;
+        if(rotatParam->nPortIndex == (OMX_U32)(OMX_OUTPUT_PORT_INDEX))
+        {
+            rotatParam->nRotation = decConfig->rotation;
+            LOG(SF_LOG_INFO, "Get Rotation %d \r\n", decConfig->rotation);
+        }
+        else
+        {
+            LOG(SF_LOG_WARN, "Only output port support Rotation config\r\n");
+            ret = OMX_ErrorBadParameter;
+        }
+        break;
+    }
+
+    case OMX_IndexConfigCommonMirror:
+    {
+        OMX_CONFIG_MIRRORTYPE *mirrParam = (OMX_CONFIG_MIRRORTYPE *)pComponentConfigStructure;
+        DecConfigParam *decConfig = pSfMjpegImplement->config;
+        if(mirrParam->nPortIndex == (OMX_U32)(OMX_OUTPUT_PORT_INDEX))
+        {
+            mirrParam->eMirror = decConfig->mirror;
+            LOG(SF_LOG_INFO, "Get Mirror %d \r\n", decConfig->mirror);
+        }
+        else
+        {
+            LOG(SF_LOG_WARN, "Only output port support Mirror config\r\n");
+            ret = OMX_ErrorBadParameter;
+        }
+        break;
+    }
+
+    case OMX_IndexConfigCommonScale:
+    {
+        OMX_CONFIG_SCALEFACTORTYPE *scaleParam = (OMX_CONFIG_SCALEFACTORTYPE *)pComponentConfigStructure;
+        DecConfigParam *decConfig = pSfMjpegImplement->config;
+        if(scaleParam->nPortIndex == (OMX_U32)(OMX_OUTPUT_PORT_INDEX))
+        {
+            /* In Q16 format */
+            scaleParam->xWidth = (1 << 16) >> decConfig->iHorScaleMode;
+            scaleParam->xHeight = (1 << 16) >> decConfig->iVerScaleMode;
+            LOG(SF_LOG_INFO, "Get scale  %d(Q16),%d(Q16) \r\n", scaleParam->xWidth, scaleParam->xHeight);
+        }
+        else
+        {
+            LOG(SF_LOG_WARN, "Only output port support Scale config\r\n");
+            ret = OMX_ErrorBadParameter;
+        }
+        break;
+    }
+
+    default:
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_SetConfig(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE nIndex,
+    OMX_PTR pComponentConfigStructure)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+    if (hComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pComponentConfigStructure == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    LOG(SF_LOG_INFO, "Set config on index %X\r\n", nIndex);
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    SF_CODAJ12_IMPLEMEMT *pSfMjpegImplement = (SF_CODAJ12_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+
+    switch ((OMX_U32)nIndex)
+    {
+    case OMX_IndexConfigCommonOutputCrop:
+    {
+        OMX_CONFIG_RECTTYPE *rectParam = (OMX_CONFIG_RECTTYPE *)pComponentConfigStructure;
+        DecConfigParam *decConfig = pSfMjpegImplement->config;
+        if(rectParam->nPortIndex == (OMX_U32)(OMX_OUTPUT_PORT_INDEX))
+        {
+            decConfig->roiOffsetX = rectParam->nLeft;
+            decConfig->roiOffsetY = rectParam->nTop;
+            decConfig->roiWidth = rectParam->nWidth;
+            decConfig->roiHeight = rectParam->nHeight;
+            decConfig->roiEnable = OMX_TRUE;
+            LOG(SF_LOG_INFO, "Set OutputCrop left %d top %d width %d height %d \r\n",
+                decConfig->roiOffsetX, decConfig->roiOffsetY, decConfig->roiWidth, decConfig->roiHeight);
+        }
+        else
+        {
+            LOG(SF_LOG_WARN, "Only support set OutputCrop config to output port\r\n");
+            ret = OMX_ErrorBadParameter;
+        }
+        break;
+    }
+
+    case OMX_IndexConfigCommonRotate:
+    {
+        OMX_CONFIG_ROTATIONTYPE *rotatParam = (OMX_CONFIG_ROTATIONTYPE *)pComponentConfigStructure;
+        DecConfigParam *decConfig = pSfMjpegImplement->config;
+        if(rotatParam->nPortIndex == (OMX_U32)(OMX_OUTPUT_PORT_INDEX))
+        {
+            decConfig->rotation = rotatParam->nRotation;
+            LOG(SF_LOG_INFO, "Set Rotation %d to output port\r\n", decConfig->rotation);
+        }
+        else
+        {
+            LOG(SF_LOG_WARN, "Only support set Rotation config to output port\r\n");
+            ret = OMX_ErrorBadParameter;
+        }
+        break;
+    }
+
+    case OMX_IndexConfigCommonMirror:
+    {
+        OMX_CONFIG_MIRRORTYPE *mirrParam = (OMX_CONFIG_MIRRORTYPE *)pComponentConfigStructure;
+        DecConfigParam *decConfig = pSfMjpegImplement->config;
+        if(mirrParam->nPortIndex == (OMX_U32)(OMX_OUTPUT_PORT_INDEX))
+        {
+            decConfig->mirror = mirrParam->eMirror;
+            LOG(SF_LOG_INFO, "Set Mirror %d \r\n", decConfig->mirror);
+        }
+        else
+        {
+            LOG(SF_LOG_WARN, "Only output port support Mirror config\r\n");
+            ret = OMX_ErrorBadParameter;
+        }
+        break;
+    }
+
+    case OMX_IndexConfigCommonScale:
+    {
+        OMX_CONFIG_SCALEFACTORTYPE *scaleParam = (OMX_CONFIG_SCALEFACTORTYPE *)pComponentConfigStructure;
+        DecConfigParam *decConfig = pSfMjpegImplement->config;
+        OMX_U32 x;
+        if(scaleParam->nPortIndex == (OMX_U32)(OMX_OUTPUT_PORT_INDEX))
+        {
+            /* In Q16 format */
+            x = (1 << 16) / (scaleParam->xWidth);
+            if(x >= 8)
+                decConfig->iHorScaleMode = 3;
+            else if(x >= 4)
+                decConfig->iHorScaleMode = 2;
+            else if(x >= 2)
+                decConfig->iHorScaleMode = 1;
+            else
+                decConfig->iHorScaleMode = 0;
+
+            x = (1 << 16) / (scaleParam->xHeight);
+            if(x >= 8)
+                decConfig->iVerScaleMode = 3;
+            else if(x >= 4)
+                decConfig->iVerScaleMode = 2;
+            else if(x >= 2)
+                decConfig->iVerScaleMode = 1;
+            else
+                decConfig->iVerScaleMode = 0;
+
+            LOG(SF_LOG_INFO, "Set scale H 1/%d, V 1/%d \r\n", 1 << decConfig->iHorScaleMode, 1 << scaleParam->xHeight);
+        }
+        else
+        {
+            LOG(SF_LOG_WARN, "Only output port support Scale config\r\n");
+            ret = OMX_ErrorBadParameter;
+        }
+        break;
+    }
+
+    default:
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE InitDecoder(SF_OMX_COMPONENT *pSfOMXComponent)
+{
+    FunctionIn();
+    SF_CODAJ12_IMPLEMEMT *pSfCodaj12Implement = pSfOMXComponent->componentImpl;
+    JpgRet ret = JPG_RET_SUCCESS;
+    DecConfigParam *decConfig = pSfCodaj12Implement->config;
+    jpu_buffer_t *vbStream = &pSfCodaj12Implement->vbStream;
+
+    ret = pSfCodaj12Implement->functions->JPU_Init();
+    if (ret != JPG_RET_SUCCESS && ret != JPG_RET_CALLED_BEFORE)
+    {
+        LOG(SF_LOG_ERR, "JPU_Init failed Error code is 0x%x \r\n", ret);
+        return ret;
+    }
+
+    decConfig->feedingMode = FEEDING_METHOD_BUFFER;
+    LOG(SF_LOG_DEBUG, "feedingMode = %d, StreamEndian = %d\r\n", decConfig->feedingMode, decConfig->StreamEndian);
+    if ((pSfCodaj12Implement->feeder = pSfCodaj12Implement->functions->BitstreamFeeder_Create(decConfig->bitstreamFileName, decConfig->feedingMode, (EndianMode)decConfig->StreamEndian)) == NULL)
+    {
+        return OMX_ErrorResourcesLost;
+    }
+
+    FunctionOut();
+    return OMX_ErrorNone;
+
+    pSfCodaj12Implement->functions->FreeFrameBuffer(pSfCodaj12Implement->instIdx);
+
+    pSfCodaj12Implement->functions->jdi_free_dma_memory(vbStream);
+
+    pSfCodaj12Implement->functions->JPU_DeInit();
+    FunctionOut();
+    return OMX_ErrorHardware;
+}
+
+
+static OMX_BOOL FillBufferDone(SF_OMX_COMPONENT *pSfOMXComponent, OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    struct timeval tv;
+    static OMX_U32 dec_cnt = 0;
+    OMX_U32 fps = 0;
+    OMX_U64 diff_time = 0; // ms
+    static struct timeval tv_old = {0};
+
+    FunctionIn();
+
+    gettimeofday(&tv, NULL);
+    if (gInitTimeStamp == 0)
+    {
+        gInitTimeStamp = tv.tv_sec * 1000000 + tv.tv_usec;
+    }
+    pBuffer->nTimeStamp = tv.tv_sec * 1000000 + tv.tv_usec - gInitTimeStamp;
+
+    if (dec_cnt == 0) {
+        tv_old = tv;
+    }
+    if (dec_cnt++ >= 50) {
+        diff_time = (tv.tv_sec - tv_old.tv_sec) * 1000 + (tv.tv_usec - tv_old.tv_usec) / 1000;
+        fps = 1000  * (dec_cnt - 1) / diff_time;
+        dec_cnt = 0;
+        LOG(SF_LOG_WARN, "Decoding fps: %d \r\n", fps);
+    }
+
+    LOG(SF_LOG_PERF, "OMX finish one buffer, header = %p, address = %p, size = %d, nTimeStamp = %d, nFlags = %X\r\n",
+            pBuffer, pBuffer->pBuffer, pBuffer->nFilledLen, pBuffer->nTimeStamp, pBuffer->nFlags);
+    // Following comment store data loal
+    // {
+    //     FILE *fb = fopen("./out.bcp", "ab+");
+    //     LOG(SF_LOG_INFO, "%p %d\r\n", pBuffer->pBuffer, pBuffer->nFilledLen);
+    //     fwrite(pBuffer->pBuffer, 1, pBuffer->nFilledLen, fb);
+    //     fclose(fb);
+    // }
+    pSfOMXComponent->callbacks->FillBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pBuffer);
+    FunctionOut();
+    return OMX_TRUE;
+}
+static OMX_BOOL EmptyBufferDone(SF_OMX_COMPONENT *pSfOMXComponent)
+{
+    SF_CODAJ12_IMPLEMEMT *pSfCodaj12Implement = pSfOMXComponent->componentImpl;
+    OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL;
+    Message data;
+    ssize_t ret;
+
+    FunctionIn();
+    LOG(SF_LOG_INFO, "Wait for done used buffer\r\n");
+    ret = msgrcv(pSfCodaj12Implement->sBufferDoneQueue, (void *)&data, BUFSIZ, 0, IPC_NOWAIT);
+    if (ret < 0)
+    {
+        LOG(SF_LOG_ERR, "msgrcv failed ret = %x\r\n", ret);
+        return OMX_FALSE;
+    }
+    // switch (ret)
+    // {
+    // case ENOMSG:
+    //     LOG(SF_LOG_INFO, "msgrcv no message\n");
+    //     return OMX_TRUE;
+    // default:
+    //     LOG(SF_LOG_ERR, "msgrcv failed ret = %x\r\n", ret);
+    //     return OMX_FALSE;
+    // }
+
+    pOMXBuffer = data.pBuffer;
+    //TODO: input/output Buffer done
+    LOG(SF_LOG_DEBUG, "EmptyBufferDone IN\r\n");
+    pSfOMXComponent->callbacks->EmptyBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pOMXBuffer);
+    LOG(SF_LOG_DEBUG, "EmptyBufferDone OUT\r\n");
+
+    FunctionOut();
+    return OMX_TRUE;
+}
+
+static OMX_U32 FeedData(SF_OMX_COMPONENT *pSfOMXComponent)
+{
+    FunctionIn();
+    SF_CODAJ12_IMPLEMEMT *pSfCodaj12Implement = pSfOMXComponent->componentImpl;
+    BSFeeder feeder = pSfCodaj12Implement->feeder;
+    JpgDecHandle handle = pSfCodaj12Implement->handle;
+    jpu_buffer_t *vbStream = &pSfCodaj12Implement->vbStream;
+    OMX_U32 nFilledLen = 0;
+
+    OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL;
+    Message data;
+    LOG(SF_LOG_INFO, "Wait for input buffer\r\n");
+    if (msgrcv(pSfCodaj12Implement->sInputMessageQueue, (void *)&data, BUFSIZ, 0, 0) == -1)
+    {
+        LOG(SF_LOG_ERR, "msgrcv failed\n");
+        return 0;
+    }
+    pOMXBuffer = data.pBuffer;
+    // if (pOMXBuffer == NULL || data.msg_flag == OMX_BUFFERFLAG_EOS)
+    // {
+    //     return 0;
+    // }
+
+    if (pOMXBuffer != NULL)
+    {
+        if (pOMXBuffer->pBuffer != NULL && pOMXBuffer->nFilledLen > 0)
+        {
+            nFilledLen = pOMXBuffer->nFilledLen;
+            LOG(SF_LOG_INFO, "Address = %p, size = %d\r\n", pOMXBuffer->pBuffer, nFilledLen);
+            pSfCodaj12Implement->functions->BitstreamFeeder_SetData(feeder, pOMXBuffer->pBuffer, nFilledLen);
+            pSfCodaj12Implement->functions->BitstreamFeeder_Act(feeder, handle, vbStream);
+        }
+        LOG(SF_LOG_INFO, "Send %p to sBufferDoneQueue\r\n", pOMXBuffer);
+        if (msgsnd(pSfCodaj12Implement->sBufferDoneQueue, (void *)&data, sizeof(data) - sizeof(data.msg_type), 0) == -1)
+        {
+            LOG(SF_LOG_ERR, "msgsnd failed\n");
+            return 0;
+        }
+    }
+
+    // LOG(SF_LOG_DEBUG, "EmptyBufferDone IN\r\n");
+    // pSfOMXComponent->callbacks->EmptyBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pOMXBuffer);
+    // LOG(SF_LOG_DEBUG, "EmptyBufferDone OUT\r\n");
+
+    // if (pOMXBuffer->nFlags & 0x1 == 0x1)
+    // {
+    //     pSfCodaj12Implement->bThreadRunning = OMX_FALSE;
+    // }
+    FunctionOut();
+    return nFilledLen;
+}
+
+static OMX_ERRORTYPE WaitForOutputBufferReady(SF_OMX_COMPONENT *pSfOMXComponent,OMX_BUFFERHEADERTYPE **ppOMXBuffer)
+{
+    FunctionIn();
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    SF_CODAJ12_IMPLEMEMT *pSfCodaj12Implement = pSfOMXComponent->componentImpl;
+    OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL;
+    Message data;
+    LOG(SF_LOG_INFO, "Wait for output buffer\r\n");
+    if (msgrcv(pSfCodaj12Implement->sOutputMessageQueue, (void *)&data, BUFSIZ, 0, 0) == -1)
+    {
+        LOG(SF_LOG_ERR, "msgrcv failed\n");
+        return OMX_ErrorInsufficientResources;
+    }
+    pOMXBuffer = data.pBuffer;
+    // if (pOMXBuffer == NULL || data.msg_flag == OMX_BUFFERFLAG_EOS)
+    if (pOMXBuffer == NULL)
+    {
+        LOG(SF_LOG_INFO, "Buffer end flag detected! \r\n");
+        pSfCodaj12Implement->bThreadRunning = OMX_FALSE;
+        ret = OMX_ErrorNoMore;
+    }
+    *ppOMXBuffer = pOMXBuffer;
+    FunctionOut();
+    return ret;
+}
+
+static void ProcessThread(void *args)
+{
+    SF_OMX_COMPONENT *pSfOMXComponent = (SF_OMX_COMPONENT *)args;
+    SF_CODAJ12_IMPLEMEMT *pSfCodaj12Implement = pSfOMXComponent->componentImpl;
+    jpu_buffer_t *vbStream = &pSfCodaj12Implement->vbStream;
+    JpgDecInitialInfo *initialInfo = &pSfCodaj12Implement->initialInfo;
+
+    JpgDecOpenParam *decOP = &pSfCodaj12Implement->decOP;
+    DecConfigParam *decConfig = pSfCodaj12Implement->config;
+
+    JpgDecHandle handle;
+    Int32 frameIdx = 0;
+    JpgDecParam decParam = {0};
+    JpgDecOutputInfo outputInfo = {0};
+    Int32 int_reason = 0;
+    Int32 instIdx;
+    JpgRet ret = JPG_RET_SUCCESS;
+
+    FunctionIn();
+    prctl(PR_SET_NAME, pSfOMXComponent->componentName);
+    LOG(SF_LOG_INFO, "vbStream phys_addr = %x, size = %d, virt_addr = %x\r\n", vbStream->phys_addr, vbStream->size, vbStream->virt_addr);
+    decOP->streamEndian = decConfig->StreamEndian;
+    decOP->frameEndian = decConfig->FrameEndian;
+    decOP->bitstreamBuffer = vbStream->phys_addr;
+    decOP->bitstreamBufferSize = vbStream->size;
+    //set virtual address mapped of physical address
+    decOP->pBitStream = (BYTE *)vbStream->virt_addr; //lint !e511
+    decOP->chromaInterleave = decConfig->cbcrInterleave;
+    decOP->packedFormat = decConfig->packedFormat;
+    decOP->roiEnable = decConfig->roiEnable;
+    decOP->roiOffsetX = decConfig->roiOffsetX;
+    decOP->roiOffsetY = decConfig->roiOffsetY;
+    decOP->roiWidth = decConfig->roiWidth;
+    decOP->roiHeight = decConfig->roiHeight;
+    decOP->rotation = decConfig->rotation;
+    decOP->mirror = decConfig->mirror;
+    decOP->pixelJustification = decConfig->pixelJustification;
+    decOP->outputFormat = pSfCodaj12Implement->frameFormat; //decConfig->subsample;
+    decOP->intrEnableBit = ((1 << INT_JPU_DONE) | (1 << INT_JPU_ERROR) | (1 << INT_JPU_BIT_BUF_EMPTY));
+
+    LOG(SF_LOG_DEBUG, "streamEndian = %x\r\n", decOP->streamEndian);
+    LOG_APPEND(SF_LOG_DEBUG, "frameEndian = %x\r\n", decOP->frameEndian);
+    LOG_APPEND(SF_LOG_DEBUG, "bitstreamBuffer = %x\r\n", decOP->bitstreamBuffer);
+    LOG_APPEND(SF_LOG_DEBUG, "bitstreamBufferSize = %x\r\n", decOP->bitstreamBufferSize);
+    LOG_APPEND(SF_LOG_DEBUG, "pBitStream = %x\r\n", decOP->pBitStream);
+    LOG_APPEND(SF_LOG_DEBUG, "chromaInterleave = %x\r\n", decOP->chromaInterleave);
+    LOG_APPEND(SF_LOG_DEBUG, "packedFormat = %x\r\n", decOP->packedFormat);
+    LOG_APPEND(SF_LOG_DEBUG, "roiEnable = %x\r\n", decOP->roiEnable);
+    LOG_APPEND(SF_LOG_DEBUG, "roiOffsetX = %x\r\n", decOP->roiOffsetX);
+    LOG_APPEND(SF_LOG_DEBUG, "roiOffsetY = %x\r\n", decOP->roiOffsetY);
+    LOG_APPEND(SF_LOG_DEBUG, "roiWidth = %x\r\n", decOP->roiWidth);
+    LOG_APPEND(SF_LOG_DEBUG, "roiHeight = %x\r\n", decOP->roiHeight);
+    LOG_APPEND(SF_LOG_DEBUG, "rotation = %x\r\n", decOP->rotation);
+    LOG_APPEND(SF_LOG_DEBUG, "mirror = %x\r\n", decOP->mirror);
+    LOG_APPEND(SF_LOG_DEBUG, "pixelJustification = %x\r\n", decOP->pixelJustification);
+    LOG_APPEND(SF_LOG_DEBUG, "outputFormat = %x\r\n", decOP->outputFormat);
+    LOG_APPEND(SF_LOG_DEBUG, "intrEnableBit = %x\r\n", decOP->intrEnableBit);
+
+    ret = pSfCodaj12Implement->functions->JPU_DecOpen(&handle, decOP);
+    if (ret != JPG_RET_SUCCESS)
+    {
+        LOG(SF_LOG_ERR, "JPU_DecOpen failed Error code is 0x%x \r\n", ret);
+        return;
+    }
+    pSfCodaj12Implement->handle = handle;
+    instIdx = pSfCodaj12Implement->instIdx = pSfCodaj12Implement->handle->instIndex;
+
+    do
+    {
+        OMX_U32 size = FeedData(pSfOMXComponent);
+        if (size <= 0)
+        {
+            LOG(SF_LOG_INFO, "FeedData = %d, end thread\r\n", size);
+            pSfCodaj12Implement->bThreadRunning = OMX_FALSE;
+        }
+
+        if ((ret = pSfCodaj12Implement->functions->JPU_DecGetInitialInfo(handle, initialInfo)) != JPG_RET_SUCCESS)
+        {
+            if (JPG_RET_BIT_EMPTY == ret)
+            {
+                LOG(SF_LOG_INFO, "<%s:%d> BITSTREAM EMPTY\n", __FUNCTION__, __LINE__);
+                continue;
+            }
+            else
+            {
+                LOG(SF_LOG_ERR, "JPU_DecGetInitialInfo failed Error code is 0x%x, inst=%d \n", ret, instIdx);
+                return;
+            }
+        }
+    } while (JPG_RET_SUCCESS != ret);
+    //TODO:Set output info
+    OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = &pSfOMXComponent->portDefinition[OMX_OUTPUT_PORT_INDEX];
+    LOG(SF_LOG_DEBUG, "picWidth = %d, picHeight = %d\r\n", initialInfo->picWidth, initialInfo->picHeight);
+    pPortDefinition->format.video.nFrameWidth = initialInfo->picWidth;
+    pPortDefinition->format.video.nFrameHeight = initialInfo->picHeight;
+    pPortDefinition->format.video.nStride = initialInfo->picWidth;
+    pPortDefinition->format.video.nSliceHeight = initialInfo->picHeight;
+    pPortDefinition->format.video.eCompressionFormat = OMX_IMAGE_CodingUnused;
+    switch (pSfCodaj12Implement->frameFormat)
+    {
+    case FORMAT_400:
+    case FORMAT_420:
+        pPortDefinition->nBufferSize = initialInfo->picWidth * initialInfo->picHeight * 3 / 2;
+        break;
+    case FORMAT_422:
+    case FORMAT_440:
+        pPortDefinition->nBufferSize = initialInfo->picWidth * initialInfo->picHeight * 2;
+        break;
+    case FORMAT_444:
+    case FORMAT_MAX:
+        pPortDefinition->nBufferSize = initialInfo->picWidth * initialInfo->picHeight * 3;
+        break;
+    default:
+        pPortDefinition->nBufferSize = initialInfo->picWidth * initialInfo->picHeight * 4;
+        break;
+    }
+    LOG(SF_LOG_DEBUG, "Output buffer size = %d\r\n", pPortDefinition->nBufferSize);
+    if (pPortDefinition->nBufferCountActual < initialInfo->minFrameBufferCount)
+    {
+        pPortDefinition->nBufferCountActual = initialInfo->minFrameBufferCount;
+    }
+    if (pPortDefinition->nBufferCountMin < initialInfo->minFrameBufferCount)
+    {
+        pPortDefinition->nBufferCountMin = initialInfo->minFrameBufferCount;
+    }
+
+    LOG(SF_LOG_DEBUG, "OMX_EventPortSettingsChanged IN\r\n");
+    pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, OMX_EventPortSettingsChanged,
+                                             1, OMX_IndexParamPortDefinition, NULL);
+    LOG(SF_LOG_DEBUG, "OMX_EventPortSettingsChanged OUT\r\n");
+    LOG(SF_LOG_INFO, "Wait for out buffers ready\r\n");
+    OMX_U32 nTimeout = 100;
+    OMX_U32 nBufferNumber = pSfOMXComponent->portDefinition[OMX_OUTPUT_PORT_INDEX].nBufferCountActual;
+    while (OMX_TRUE)
+    {
+        // LOG(SF_LOG_INFO, "GetFrameBufferCount addr = %p\r\n", pSfCodaj12Implement->functions->GetFrameBufferCount);
+        nBufferNumber = pSfOMXComponent->portDefinition[OMX_OUTPUT_PORT_INDEX].nBufferCountActual;
+        OMX_U32 number = pSfCodaj12Implement->functions->GetFrameBufferCount(instIdx);
+        OMX_S32 oldNumber = -1;
+        if (number < nBufferNumber)
+        {
+            if (oldNumber < number)
+            {
+                LOG(SF_LOG_INFO, "Wait for output buffer %d/%d\r\n", number, initialInfo->minFrameBufferCount);
+                oldNumber = number;
+            }
+            usleep(50 * 1000);
+            nTimeout --;
+            if (nTimeout < 0)
+            {
+                LOG(SF_LOG_ERR, "No buffers found on output port\r\n");
+                LOG(SF_LOG_DEBUG, "OMX_EventBufferFlag IN\r\n");
+                pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, OMX_EventBufferFlag,
+                                             1, 1, NULL);
+                LOG(SF_LOG_DEBUG, "OMX_EventBufferFlag OUT\r\n");
+                return;
+            }
+        }
+        else
+        {
+            break;
+        }
+    }
+
+    FRAME_BUF *pFrame = pSfCodaj12Implement->frame;
+    LOG(SF_LOG_INFO, "Update and regist %d FrameBuffers\r\n", nBufferNumber);
+    LOG(SF_LOG_DEBUG, "%20s%20s%20s%20s\r\n", "virtAddr", "Y", "CB", "CR");
+    for (int i = 0; i < nBufferNumber; i ++)
+    {
+        LOG_APPEND(SF_LOG_DEBUG, "%20lX%20lX%20lX%20lX\r\n", pFrame[i].vbY.virt_addr,
+            pFrame[i].vbY.phys_addr, pFrame[i].vbCb.phys_addr, pFrame[i].vbCr.phys_addr);
+    }
+
+    // ffmpeg: may register frame buffer append
+    if (pSfCodaj12Implement->functions->JPU_GetFrameBufPool(pSfCodaj12Implement->handle) == NULL)
+    {
+        JpgRet ret = JPG_RET_SUCCESS;
+        pSfCodaj12Implement->functions->UpdateFrameBuffers(instIdx, nBufferNumber, pFrame);
+        ret = pSfCodaj12Implement->functions->JPU_DecRegisterFrameBuffer(pSfCodaj12Implement->handle, pSfCodaj12Implement->frameBuf,
+                                        nBufferNumber, pSfCodaj12Implement->frameBuf[0].stride);
+        if (ret != JPG_RET_SUCCESS)
+        {
+            LOG(SF_LOG_ERR, "JPU_DecRegisterFrameBuffer fail ret = %d\r\n", ret);
+            pSfCodaj12Implement->bThreadRunning = OMX_FALSE;
+        }
+    }
+
+    pSfCodaj12Implement->functions->JPU_DecGiveCommand(handle, SET_JPG_SCALE_HOR, &(decConfig->iHorScaleMode));
+    pSfCodaj12Implement->functions->JPU_DecGiveCommand(handle, SET_JPG_SCALE_VER, &(decConfig->iVerScaleMode));
+
+    /* LOG HEADER */
+    LOG(SF_LOG_INFO, "I   F    FB_INDEX  FRAME_START  ECS_START  CONSUME   RD_PTR   WR_PTR      CYCLE\n");
+    LOG(SF_LOG_INFO, "-------------------------------------------------------------------------------\n");
+
+    while (pSfCodaj12Implement->bThreadRunning)
+    {
+        OMX_BUFFERHEADERTYPE *pBuffer;
+
+        if (WaitForOutputBufferReady(pSfOMXComponent,&pBuffer) != OMX_ErrorNone)
+        {
+            continue;
+        }
+
+        LOG(SF_LOG_INFO, "pBuffer->pOutputPortPrivate:%d\r\n", (OMX_U64)(pBuffer->pOutputPortPrivate));
+        ret = pSfCodaj12Implement->functions->JPU_DecStartOneFrameBySerialNum(handle, &decParam,(OMX_U64)(pBuffer->pOutputPortPrivate));
+        if (ret != JPG_RET_SUCCESS && ret != JPG_RET_EOS)
+        {
+            if (ret == JPG_RET_BIT_EMPTY)
+            {
+                LOG(SF_LOG_INFO, "BITSTREAM NOT ENOUGH.............\n");
+                OMX_U32 size = FeedData(pSfOMXComponent);
+                if (size <= 0)
+                {
+                    LOG(SF_LOG_INFO, "FeedData = %d, end thread\r\n", size);
+                    pSfCodaj12Implement->bThreadRunning = OMX_FALSE;
+                }
+                continue;
+            }
+
+            LOG(SF_LOG_ERR, "JPU_DecStartOneFrameBySerialNum failed Error code is 0x%x \n", ret);
+            return;
+        }
+        if (ret == JPG_RET_EOS)
+        {
+            pSfCodaj12Implement->functions->JPU_DecGetOutputInfo(handle, &outputInfo);
+            break;
+        }
+
+        while (1)
+        {
+            if ((int_reason = pSfCodaj12Implement->functions->JPU_WaitInterrupt(handle, JPU_INTERRUPT_TIMEOUT_MS)) == -1)
+            {
+                LOG(SF_LOG_ERR, "Error : timeout happened\n");
+                pSfCodaj12Implement->functions->JPU_SWReset(handle);
+                break;
+            }
+
+            if (int_reason & ((1 << INT_JPU_DONE) | (1 << INT_JPU_ERROR) | (1 << INT_JPU_SLICE_DONE)))
+            {
+                // Do no clear INT_JPU_DONE and INT_JPU_ERROR interrupt. these will be cleared in JPU_DecGetOutputInfo.
+                LOG(SF_LOG_INFO, "\tINSTANCE #%d int_reason: %08x\n", handle->instIndex, int_reason);
+                break;
+            }
+
+            // if (int_reason & (1 << INT_JPU_BIT_BUF_EMPTY))
+            // {
+            //     if (decConfig->feedingMode != FEEDING_METHOD_FRAME_SIZE)
+            //     {
+            //         pSfCodaj12Implement->functions->BitstreamFeeder_Act(feeder, handle, &vbStream);
+            //     }
+            //     pSfCodaj12Implement->functions->JPU_ClrStatus(handle, (1 << INT_JPU_BIT_BUF_EMPTY));
+            // }
+        }
+        //LOG(SF_LOG_INFO, "\t<->INSTANCE #%d JPU_WaitInterrupt\n", handle->instIndex);
+        EmptyBufferDone(pSfOMXComponent);
+        if ((ret = pSfCodaj12Implement->functions->JPU_DecGetOutputInfo(handle, &outputInfo)) != JPG_RET_SUCCESS)
+        {
+            LOG(SF_LOG_ERR, "JPU_DecGetOutputInfo failed Error code is 0x%x \n", ret);
+            return;
+        }
+
+        switch (pSfCodaj12Implement->frameFormat)
+        {
+        case FORMAT_420:
+            pBuffer->nFilledLen = outputInfo.decPicWidth * outputInfo.decPicHeight * 3 / 2;
+            break;
+        case FORMAT_422:
+            pBuffer->nFilledLen = outputInfo.decPicWidth * outputInfo.decPicHeight * 2;
+            break;
+        case FORMAT_444:
+            pBuffer->nFilledLen = outputInfo.decPicWidth * outputInfo.decPicHeight * 3;
+            break;
+        default:
+            LOG(SF_LOG_ERR, "Unsupported format: %d\r\n", pSfCodaj12Implement->frameFormat);
+            break;
+        }
+
+        LOG(SF_LOG_DEBUG, "decPicSize = [%d %d], pBuffer = %p\r\n",
+            outputInfo.decPicWidth, outputInfo.decPicHeight, pBuffer->pBuffer);
+        // AdjustFrame(pBuffer, outputInfo.decPicWidth, outputInfo.decPicHeight, nDestStride, nDestHeight);
+        FillBufferDone(pSfOMXComponent, pBuffer);
+        // LOG(SF_LOG_DEBUG, "FillBufferDone IN\r\n");
+        // Following comment store data loal
+        // {
+        //     FILE *fb = fopen("./out.bcp", "ab+");
+        //     LOG(SF_LOG_INFO, "%p %d\r\n", pBuffer->pBuffer, pBuffer->nFilledLen);
+        //     fwrite(pBuffer->pBuffer, 1, pBuffer->nFilledLen, fb);
+        //     fclose(fb);
+        // }
+        // pSfOMXComponent->callbacks->FillBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pBuffer);
+        // LOG(SF_LOG_DEBUG, "FillBufferDone OUT\r\n");
+        if (outputInfo.numOfErrMBs)
+        {
+            Int32 errRstIdx, errPosX, errPosY;
+            errRstIdx = (outputInfo.numOfErrMBs & 0x0F000000) >> 24;
+            errPosX = (outputInfo.numOfErrMBs & 0x00FFF000) >> 12;
+            errPosY = (outputInfo.numOfErrMBs & 0x00000FFF);
+            LOG(SF_LOG_ERR, "Error restart Idx : %d, MCU x:%d, y:%d, in Frame : %d \n", errRstIdx, errPosX, errPosY, frameIdx);
+        }
+
+        // if (pSfCodaj12Implement->bThreadRunning == OMX_FALSE)
+        // {
+        //     break;
+        // }
+        pSfCodaj12Implement->functions->JPU_DecSetRdPtrEx(handle, vbStream->phys_addr, TRUE);
+        OMX_U32 size = FeedData(pSfOMXComponent);
+        if (size <= 0)
+        {
+            LOG(SF_LOG_INFO, "FeedData = %d, end thread\r\n", size);
+            pSfCodaj12Implement->bThreadRunning = OMX_FALSE;
+        }
+    }
+    LOG(SF_LOG_DEBUG, "OMX_EventBufferFlag IN\r\n");
+    pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, OMX_EventBufferFlag,
+                                    1, 1, NULL);
+    LOG(SF_LOG_DEBUG, "OMX_EventBufferFlag OUT\r\n");
+    CodaJ12FlushBuffer(pSfOMXComponent, OMX_INPUT_PORT_INDEX);
+    CodaJ12FlushBuffer(pSfOMXComponent, OMX_OUTPUT_PORT_INDEX);
+    pSfCodaj12Implement->currentState = OMX_StateIdle;
+    FunctionOut();
+    ThreadExit(NULL);
+}
+
+static OMX_ERRORTYPE SF_OMX_SendCommand(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_COMMANDTYPE Cmd,
+    OMX_IN OMX_U32 nParam,
+    OMX_IN OMX_PTR pCmdData)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    SF_CODAJ12_IMPLEMEMT *pSfCodaj12Implement = pSfOMXComponent->componentImpl;
+
+    FunctionIn();
+    if (hComponent == NULL || pSfOMXComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    LOG(SF_LOG_INFO, "cmd = %X, nParam = %X\r\n", Cmd, nParam);
+    switch (Cmd)
+    {
+    case OMX_CommandStateSet:
+        pSfOMXComponent->state = nParam;
+        LOG(SF_LOG_INFO, "OMX dest state = %X, current state = %X\r\n", nParam, pSfCodaj12Implement->currentState);
+        switch (nParam)
+        {
+        case OMX_StateLoaded:
+            break;
+        case OMX_StateIdle:
+            switch (pSfCodaj12Implement->currentState)
+            {
+                case OMX_StateExecuting:
+                {
+                    Message data;
+                    data.msg_type = 1;
+                    data.msg_flag = OMX_BUFFERFLAG_EOS;
+                    data.pBuffer = NULL;
+                    LOG(SF_LOG_DEBUG, "Send to message queue\r\n");
+                    if (msgsnd(pSfCodaj12Implement->sOutputMessageQueue, (void *)&data, sizeof(data) - sizeof(data.msg_type), 0) == -1)
+                    {
+                        LOG(SF_LOG_ERR, "msgsnd failed\n");
+                    }
+                    if (msgsnd(pSfCodaj12Implement->sInputMessageQueue, (void *)&data, sizeof(data) - sizeof(data.msg_type), 0) == -1)
+                    {
+                        LOG(SF_LOG_ERR, "msgsnd failed\n");
+                    }
+                    pSfCodaj12Implement->currentState = OMX_StateIdle;
+                    break;
+                }
+                case OMX_StateIdle:
+                    break;
+                case OMX_StateLoaded:
+                    // InitDecoder(pSfOMXComponent);
+                    pSfCodaj12Implement->currentState = OMX_StateIdle;
+                    break;
+                default:
+                    LOG(SF_LOG_ERR, "Can't go to state %d from %d\r\n",pSfCodaj12Implement->currentState, nParam);
+                    return OMX_ErrorBadParameter;
+                    break;
+            }
+            break;
+        case OMX_StateExecuting:
+            switch (pSfCodaj12Implement->currentState)
+            {
+            case OMX_StateIdle:
+                pSfCodaj12Implement->bThreadRunning = OMX_TRUE;
+                CreateThread(&pSfCodaj12Implement->pProcessThread, ProcessThread, (void *)pSfOMXComponent);
+                pSfCodaj12Implement->currentState = OMX_StateExecuting;
+                break;
+            case OMX_StateExecuting:
+                break;
+            case OMX_StateLoaded:
+            default:
+                LOG(SF_LOG_ERR, "Can't go to state %d from %d\r\n",pSfCodaj12Implement->currentState, nParam);
+                return OMX_ErrorBadParameter;
+                break;
+            }
+            break;
+        default:
+            ret = OMX_ErrorIncorrectStateTransition;
+            break;
+        }
+        pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
+                                                 OMX_EventCmdComplete, OMX_CommandStateSet, nParam, NULL);
+
+        break;
+    case OMX_CommandFlush:
+    {
+        OMX_U32 nPort = nParam;
+        CodaJ12FlushBuffer(pSfOMXComponent, nPort);
+        pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
+                                                 OMX_EventCmdComplete, OMX_CommandFlush, nParam, NULL);
+    }
+    case OMX_CommandPortDisable:
+        pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
+                                                 OMX_EventCmdComplete, OMX_CommandPortDisable, nParam, NULL);
+        break;
+    case OMX_CommandPortEnable:
+        pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
+                                                 OMX_EventCmdComplete, OMX_CommandPortEnable, nParam, NULL);
+    default:
+        break;
+    }
+    //TODO
+EXIT:
+    FunctionOut();
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_GetState(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_OUT OMX_STATETYPE *pState)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    SF_CODAJ12_IMPLEMEMT *pSfCodaj12Implement = pSfOMXComponent->componentImpl;
+    FunctionIn();
+    *pState = pSfCodaj12Implement->currentState;
+    FunctionOut();
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_FreeBuffer(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_U32 nPortIndex,
+    OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    FunctionIn();
+    //TODO
+    FunctionOut();
+    return ret;
+}
+
+
+static OMX_ERRORTYPE SF_OMX_ComponentConstructor(SF_OMX_COMPONENT *pSfOMXComponent)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    SF_CODAJ12_IMPLEMEMT *pSfCodaj12Implement;
+    FunctionIn();
+
+    ret = InitMjpegStructorCommon(pSfOMXComponent);
+    if (ret != OMX_ErrorNone)
+    {
+        goto EXIT;
+    }
+
+    pSfOMXComponent->pOMXComponent->UseBuffer = &SF_OMX_UseBuffer;
+    pSfOMXComponent->pOMXComponent->AllocateBuffer = &SF_OMX_AllocateBuffer;
+    pSfOMXComponent->pOMXComponent->EmptyThisBuffer = &SF_OMX_EmptyThisBuffer;
+    pSfOMXComponent->pOMXComponent->FillThisBuffer = &SF_OMX_FillThisBuffer;
+    pSfOMXComponent->pOMXComponent->FreeBuffer = &SF_OMX_FreeBuffer;
+    // pSfOMXComponent->pOMXComponent->ComponentTunnelRequest = &SF_OMX_ComponentTunnelRequest;
+    pSfOMXComponent->pOMXComponent->GetParameter = &SF_OMX_GetParameter;
+    pSfOMXComponent->pOMXComponent->SetParameter = &SF_OMX_SetParameter;
+    pSfOMXComponent->pOMXComponent->GetConfig = &SF_OMX_GetConfig;
+    pSfOMXComponent->pOMXComponent->SetConfig = &SF_OMX_SetConfig;
+    pSfOMXComponent->pOMXComponent->SendCommand = &SF_OMX_SendCommand;
+    pSfOMXComponent->pOMXComponent->GetState = &SF_OMX_GetState;
+    // pSfOMXComponent->pOMXComponent->GetExtensionIndex = &SF_OMX_GetExtensionIndex;
+    // pSfOMXComponent->pOMXComponent->ComponentRoleEnum = &SF_OMX_ComponentRoleEnum;
+    // pSfOMXComponent->pOMXComponent->ComponentDeInit = &SF_OMX_ComponentDeInit;
+    pSfCodaj12Implement = pSfOMXComponent->componentImpl;
+    pSfCodaj12Implement->currentState = OMX_StateLoaded;
+    InitDecoder(pSfOMXComponent);
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_ComponentClear(SF_OMX_COMPONENT *pSfOMXComponent)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    SF_CODAJ12_IMPLEMEMT *pSfCodaj12Implement = pSfOMXComponent->componentImpl;
+    jpu_buffer_t *vbStream = &pSfCodaj12Implement->vbStream;
+    JpgDecHandle handle = pSfCodaj12Implement->handle;
+    FunctionIn();
+
+    if (pSfCodaj12Implement->functions->JPU_DecClose(handle) != JPG_RET_SUCCESS)
+    {
+        LOG(SF_LOG_ERR, "\nDec End\r\n");
+        ret = OMX_ErrorHardware;
+    }
+    pSfCodaj12Implement->functions->BitstreamFeeder_Destroy(pSfCodaj12Implement->feeder);
+
+
+    if(pSfCodaj12Implement->allocBufFlag == OMX_TRUE)
+    {
+        pSfCodaj12Implement->functions->FreeFrameBuffer(pSfCodaj12Implement->instIdx);
+    }
+    pSfCodaj12Implement->functions->jdi_free_dma_memory(vbStream);
+    pSfCodaj12Implement->functions->JPU_DeInit();
+    // TODO
+    // MjpegClearCommon(hComponent);
+
+    FunctionOut();
+
+    return ret;
+}
+
+//TODO happer
+SF_OMX_COMPONENT sf_dec_decoder_mjpeg = {
+    .componentName = "OMX.sf.video_decoder.mjpeg",
+    .libName = "libcodadec.so",
+    .pOMXComponent = NULL,
+    .SF_OMX_ComponentConstructor = SF_OMX_ComponentConstructor,
+    .SF_OMX_ComponentClear = SF_OMX_ComponentClear,
+    // .functions = NULL,
+    // .bitFormat = STD_HEVC,
+    .componentImpl = NULL,
+    .fwPath = "/lib/firmware/chagall.bin",
+    .componentRule = "video_decoder.mjpeg"};

+ 2415 - 0
omx-il/component/video/wave4/SF_OMX_Wave420L_encoder.c

@@ -0,0 +1,2415 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include "SF_OMX_Wave420L_encoder.h"
+#include "SF_OMX_Core.h"
+#include <sys/prctl.h>
+
+#define STREAM_READ_ALL_SIZE            (0)
+#define WAVE420L_CONFIG_FILE "/lib/firmware/encoder_defconfig.cfg"
+#define OMX_Command_StopThread OMX_CommandMax
+
+static OMX_BOOL EmptyBufferDone(SF_OMX_COMPONENT *pSfOMXComponent, OMX_BUFFERHEADERTYPE *pBuffer);
+static OMX_BOOL FillBufferDone(SF_OMX_COMPONENT *pSfOMXComponent, OMX_BUFFERHEADERTYPE *pBuffer);
+static void FlushBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U32 nPortNumber);
+static void CmdThread(void *args);
+static void EncoderThread(void *args);
+
+
+static void sf_get_component_functions(SF_W420L_FUNCTIONS *funcs, OMX_PTR *sohandle)
+{
+    FunctionIn();
+    funcs->VPU_GetProductId = dlsym(sohandle, "VPU_GetProductId");
+    funcs->VPU_GetVersionInfo = dlsym(sohandle, "VPU_GetVersionInfo");
+    funcs->VPU_InitWithBitcode = dlsym(sohandle, "VPU_InitWithBitcode");
+    funcs->VPU_DeInit = dlsym(sohandle, "VPU_DeInit");
+    funcs->GetEncOpenParam = dlsym(sohandle, "GetEncOpenParam");
+    funcs->GetEncOpenParamDefault = dlsym(sohandle, "GetEncOpenParamDefault");
+    funcs->VPU_EncOpen = dlsym(sohandle, "VPU_EncOpen");
+    funcs->VPU_EncClose = dlsym(sohandle, "VPU_EncClose");
+    funcs->VPU_GetFrameBufSize = dlsym(sohandle, "VPU_GetFrameBufSize");
+    funcs->VPU_EncRegisterFrameBuffer = dlsym(sohandle, "VPU_EncRegisterFrameBuffer");
+    funcs->VPU_EncAllocateFrameBuffer = dlsym(sohandle, "VPU_EncAllocateFrameBuffer");
+    funcs->VPU_EncGiveCommand = dlsym(sohandle, "VPU_EncGiveCommand");
+    funcs->VPU_EncGetInitialInfo = dlsym(sohandle, "VPU_EncGetInitialInfo");
+    funcs->VPU_SWReset = dlsym(sohandle, "VPU_SWReset");
+    funcs->VPU_EncStartOneFrame = dlsym(sohandle, "VPU_EncStartOneFrame");
+    funcs->VPU_WaitInterrupt = dlsym(sohandle, "VPU_WaitInterrupt");
+    funcs->VPU_ClearInterrupt = dlsym(sohandle, "VPU_ClearInterrupt");
+    funcs->VPU_EncGetOutputInfo = dlsym(sohandle, "VPU_EncGetOutputInfo");
+    funcs->vdi_allocate_dma_memory = dlsym(sohandle, "vdi_allocate_dma_memory");
+    funcs->vdi_free_dma_memory = dlsym(sohandle, "vdi_free_dma_memory");
+    funcs->YuvFeeder_Create = dlsym(sohandle, "YuvFeeder_Create");
+    funcs->YuvFeeder_Feed = dlsym(sohandle, "YuvFeeder_Feed");
+    funcs->YuvFeeder_Destroy = dlsym(sohandle, "YuvFeeder_Destroy");
+    funcs->BufferStreamReader_Create = dlsym(sohandle, "BufferStreamReader_Create");
+    funcs->BufferStreamReader_Act = dlsym(sohandle, "BufferStreamReader_Act");
+    funcs->BufferStreamReader_Destroy = dlsym(sohandle, "BufferStreamReader_Destroy");
+    funcs->Comparator_Create = dlsym(sohandle, "Comparator_Create");
+    funcs->Comparator_Destroy = dlsym(sohandle, "Comparator_Destroy");
+    funcs->Comparator_CheckEOF = dlsym(sohandle, "Comparator_CheckEOF");
+    funcs->DisplayEncodedInformation = dlsym(sohandle, "DisplayEncodedInformation");
+    funcs->PrintVpuVersionInfo = dlsym(sohandle, "PrintVpuVersionInfo");
+    funcs->CalcStride = dlsym(sohandle, "CalcStride");
+    funcs->GetPackedFormat = dlsym(sohandle, "GetPackedFormat");
+    funcs->LoadFirmware = dlsym(sohandle, "LoadFirmware");
+    funcs->SetMaxLogLevel = dlsym(sohandle, "SetMaxLogLevel");
+    funcs->EnterLock = dlsym(sohandle, "EnterLock");
+    funcs->LeaveLock = dlsym(sohandle, "LeaveLock");
+    funcs->PrintVpuStatus = dlsym(sohandle, "PrintVpuStatus");
+    FunctionOut();
+}
+
+OMX_ERRORTYPE WaveOmxInit(SF_OMX_COMPONENT *pSfOMXComponent)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    char *strDebugLevel = NULL;
+    int debugLevel = 0;
+    SF_WAVE420L_IMPLEMEMT *pImp = NULL;
+
+    FunctionIn();
+    if (pSfOMXComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pSfOMXComponent->pOMXComponent = malloc(sizeof(OMX_COMPONENTTYPE));
+    if (pSfOMXComponent->pOMXComponent == NULL)
+    {
+        ret = OMX_ErrorInsufficientResources;
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        goto ERROR;
+    }
+    memset(pSfOMXComponent->pOMXComponent, 0, sizeof(OMX_COMPONENTTYPE));
+
+    pSfOMXComponent->soHandle = dlopen(pSfOMXComponent->libName, RTLD_NOW);
+    if (pSfOMXComponent->soHandle == NULL)
+    {
+        ret = OMX_ErrorInsufficientResources;
+        LOG(SF_LOG_ERR, "could not open %s, error: %s\r\n", pSfOMXComponent->libName, dlerror());
+        goto ERROR;
+    }
+
+    pSfOMXComponent->componentImpl = malloc(sizeof(SF_WAVE420L_IMPLEMEMT));
+    if (pSfOMXComponent->componentImpl == NULL)
+    {
+        ret = OMX_ErrorInsufficientResources;
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        goto ERROR;
+    }
+    memset(pSfOMXComponent->componentImpl, 0, sizeof(SF_WAVE420L_IMPLEMEMT));
+
+    pImp = (SF_WAVE420L_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    pImp->functions = malloc(sizeof(SF_W420L_FUNCTIONS));
+
+    //pImp->frameFormat = DEFAULT_FRAME_FORMAT;
+    if (pImp->functions == NULL)
+    {
+        ret = OMX_ErrorInsufficientResources;
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        goto ERROR;
+    }
+    memset(pImp->functions, 0, sizeof(SF_W420L_FUNCTIONS));
+    sf_get_component_functions(pImp->functions, pSfOMXComponent->soHandle);
+
+    // Init Vpu log
+    if (pImp->functions->SetMaxLogLevel)
+    {
+        strDebugLevel = getenv("VPU_DEBUG");
+        if (strDebugLevel)
+        {
+            debugLevel = atoi(strDebugLevel);
+        }else{
+            debugLevel = 0;
+        }
+        if (debugLevel >=0)
+        {
+            pImp->functions->SetMaxLogLevel(debugLevel);
+        }
+    }
+
+    pSfOMXComponent->pOMXComponent->pComponentPrivate = pSfOMXComponent;
+
+    pImp->EmptyQueue = SF_Queue_Create(ENC_SRC_BUF_NUM, sizeof(OMX_BUFFERHEADERTYPE*));
+    if (NULL == pImp->EmptyQueue)
+    {
+        LOG(SF_LOG_ERR, "create EmptyQueue error");
+        return OMX_ErrorInsufficientResources;
+    }
+    pImp->FillQueue = SF_Queue_Create(ENC_SRC_BUF_NUM, sizeof(OMX_BUFFERHEADERTYPE*));
+    if (NULL == pImp->FillQueue)
+    {
+        LOG(SF_LOG_ERR, "create FillQueue error");
+        return OMX_ErrorInsufficientResources;
+    }
+    pImp->CmdQueue = SF_Queue_Create(ENC_SRC_BUF_NUM, sizeof(SF_OMX_CMD));
+    if (NULL == pImp->CmdQueue)
+    {
+        LOG(SF_LOG_ERR, "create CmdQueue error");
+        return OMX_ErrorInsufficientResources;
+    }
+    pImp->pauseQ = SF_Queue_Create(20, sizeof(OMX_BUFFERHEADERTYPE*));
+    if (NULL == pImp->pauseQ)
+    {
+        LOG(SF_LOG_ERR, "create pauseQ error");
+        return OMX_ErrorInsufficientResources;
+    }
+
+    for (int i = 0; i < OMX_PORT_MAX; i++)
+    {
+        OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = &pSfOMXComponent->portDefinition[i];
+        OMX_VIDEO_PARAM_HEVCTYPE *pHEVCComponent = &pImp->HEVCComponent[i];
+
+        INIT_SET_SIZE_VERSION(pPortDefinition, OMX_PARAM_PORTDEFINITIONTYPE);
+        INIT_SET_SIZE_VERSION(pHEVCComponent, OMX_VIDEO_PARAM_HEVCTYPE);
+
+        pPortDefinition->nPortIndex = i;
+        pPortDefinition->nBufferCountActual = (i == 0 ? WAVE_DEFAULT_INPUT_BUF_NUMBER : WAVE_DEFAULT_OUTPUT_BUF_NUMBER);
+        pPortDefinition->nBufferCountMin = (i == 0 ? WAVE_DEFAULT_INPUT_BUF_NUMBER : WAVE_DEFAULT_OUTPUT_BUF_NUMBER);
+        pPortDefinition->nBufferSize = (i == 0 ? DEFAULT_MJPEG_INPUT_BUFFER_SIZE : DEFAULT_MJPEG_OUTPUT_BUFFER_SIZE);
+        pPortDefinition->eDomain = OMX_PortDomainVideo;
+
+        pPortDefinition->format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
+        pPortDefinition->format.video.nFrameHeight = DEFAULT_FRAME_HEIGHT;
+        pPortDefinition->format.video.nStride = DEFAULT_FRAME_WIDTH;
+        pPortDefinition->format.video.nSliceHeight = DEFAULT_FRAME_HEIGHT;
+        pPortDefinition->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+        pPortDefinition->format.video.xFramerate = DEFAULT_FRAMERATE;
+
+        pPortDefinition->format.video.pNativeRender = 0;
+        pPortDefinition->format.video.bFlagErrorConcealment = OMX_FALSE;
+        pPortDefinition->format.video.eColorFormat = OMX_COLOR_FormatUnused;
+
+        pPortDefinition->bEnabled = OMX_TRUE;
+        pPortDefinition->eDir = (i == 0 ? OMX_DirInput : OMX_DirOutput);
+
+        pHEVCComponent->nPortIndex = i;
+        pHEVCComponent->nKeyFrameInterval = DEFAULT_GOP;
+        pHEVCComponent->eProfile = OMX_VIDEO_HEVCProfileMain;
+        pSfOMXComponent->assignedBufferNum[i] = 0;
+    }
+
+    pSfOMXComponent->portDefinition[OMX_INPUT_PORT_INDEX].format.video.cMIMEType = "raw/video";
+    pSfOMXComponent->portDefinition[OMX_OUTPUT_PORT_INDEX].format.video.cMIMEType = "video/H265";
+
+    pSfOMXComponent->portDefinition[OMX_INPUT_PORT_INDEX].format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
+
+    memset(pSfOMXComponent->pBufferArray, 0, sizeof(pSfOMXComponent->pBufferArray));
+    pSfOMXComponent->memory_optimization = OMX_TRUE;
+
+    /* Set componentVersion */
+    pSfOMXComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pSfOMXComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pSfOMXComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
+    pSfOMXComponent->componentVersion.s.nStep         = STEP_NUMBER;
+    /* Set specVersion */
+    pSfOMXComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pSfOMXComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pSfOMXComponent->specVersion.s.nRevision     = REVISION_NUMBER;
+    pSfOMXComponent->specVersion.s.nStep         = STEP_NUMBER;
+
+    memset(pSfOMXComponent->markType, 0, sizeof(pSfOMXComponent->markType));
+    pSfOMXComponent->propagateMarkType.hMarkTargetComponent = NULL;
+    pSfOMXComponent->propagateMarkType.pMarkData = NULL;
+
+    for (int i = 0; i < 2; i++)
+    {
+        ret = SF_SemaphoreCreate(&pSfOMXComponent->portSemaphore[i]);
+        if (ret)
+            goto ERROR;
+        ret = SF_SemaphoreCreate(&pSfOMXComponent->portUnloadSemaphore[i]);
+        if (ret)
+            goto ERROR;
+    }
+
+    ret = SF_SemaphoreCreate(&pImp->pauseSemaphore);
+    if (ret)
+        goto ERROR;
+
+    CreateThread(&pImp->pCmdThread, CmdThread, (void *)pSfOMXComponent);
+    pImp->bCmdRunning = OMX_TRUE;
+    pImp->tmpFramerate = 25;
+
+    FunctionOut();
+EXIT:
+    return ret;
+ERROR:
+    for (int i = 0; i < 2; i++)
+    {
+        SF_SemaphoreTerminate(pSfOMXComponent->portSemaphore[i]);
+        SF_SemaphoreTerminate(pSfOMXComponent->portUnloadSemaphore[i]);
+    }
+
+    SF_SemaphoreTerminate(pImp->pauseSemaphore);
+
+    if (pSfOMXComponent->pOMXComponent)
+    {
+        free(pSfOMXComponent->pOMXComponent);
+        pSfOMXComponent->pOMXComponent = NULL;
+    }
+
+    return ret;
+}
+
+static OMX_ERRORTYPE InitEncoder(SF_OMX_COMPONENT *pSfOMXComponent)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    SF_WAVE420L_IMPLEMEMT *pImp = (SF_WAVE420L_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    TestEncConfig   *pEncConfig = &pImp->encConfig;
+    Int32 productId;
+    Uint32 BitCodesizeInWord;
+    Uint16* pusBitCode;
+
+    FunctionIn();
+
+    pEncConfig->stdMode       = STD_HEVC;
+    pEncConfig->frame_endian  = VPU_FRAME_ENDIAN;
+    pEncConfig->stream_endian = VPU_STREAM_ENDIAN;
+    pEncConfig->source_endian = VPU_SOURCE_ENDIAN;
+    pEncConfig->mapType       = COMPRESSED_FRAME_MAP;
+
+    pEncConfig->coreIdx       = 0;
+    pEncConfig->picWidth      = DEFAULT_FRAME_WIDTH;
+    pEncConfig->picHeight     = DEFAULT_FRAME_HEIGHT;
+    pEncConfig->cbcrInterleave = OMX_FALSE;
+    pEncConfig->nv21          = OMX_FALSE;
+    pEncConfig->srcFormat     = FORMAT_420;
+    pEncConfig->packedFormat  = NOT_PACKED;
+    pEncConfig->yuv_mode      = NOT_PACKED;
+    strcpy(pEncConfig->cfgFileName, WAVE420L_CONFIG_FILE);
+
+    //Wave420L not support
+    pEncConfig->rotAngle      = 0;
+    pEncConfig->mirDir        = 0;
+    pEncConfig->srcFormat3p4b = 0;
+    pEncConfig->ringBufferEnable = 0;
+
+
+    productId = Warp_VPU_GetProductId(pImp, pEncConfig->coreIdx);
+
+    LOG(SF_LOG_INFO, "product ID = %d FW PATH = %s\r\n", productId, pSfOMXComponent->fwPath);
+    if (Warp_LoadFirmware(pImp, productId, (Uint8**)&pusBitCode, &BitCodesizeInWord, pSfOMXComponent->fwPath) < 0) {
+        LOG(SF_LOG_ERR, "%s:%d Failed to load firmware: %s\r\n", __FUNCTION__, __LINE__, pSfOMXComponent->fwPath);
+        return OMX_ErrorInsufficientResources;
+    }
+
+    ret = Warp_VPU_InitWithBitcode(pImp, pEncConfig->coreIdx, (const Uint16*)pusBitCode, BitCodesizeInWord);
+    if (ret)
+    {
+        LOG(SF_LOG_ERR, "Failed to boot up VPU with bit code\r\n");
+        free(pusBitCode);
+        return OMX_ErrorInsufficientResources;
+    }
+
+    Warp_PrintVpuVersionInfo(pImp, pEncConfig->coreIdx);
+
+    return ret;
+    FunctionOut();
+}
+
+static void CmdThread(void *args)
+{
+    SF_OMX_COMPONENT *pSfOMXComponent = (SF_OMX_COMPONENT *)args;
+    SF_WAVE420L_IMPLEMEMT *pImp = (SF_WAVE420L_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL;
+    OMX_BUFFERHEADERTYPE **ppBuffer = NULL;
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_STATETYPE comCurrentState;
+    OMX_U32 i = 0, cnt = 0;
+    SF_OMX_CMD *pCmd;
+    void *pNull = NULL;
+    void *ThreadRet;
+
+    while(1){
+        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+        pCmd = (SF_OMX_CMD*)SF_Queue_Dequeue_Block(pImp->CmdQueue);
+        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+        pthread_testcancel();
+        pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
+
+        if(pCmd->Cmd == OMX_Command_StopThread)
+            break;
+
+        switch (pCmd->Cmd)
+        {
+        case OMX_CommandStateSet:
+            LOG(SF_LOG_INFO, "OMX dest state = %X\r\n", pCmd->nParam);
+
+            comCurrentState = pSfOMXComponent->state;
+
+            if (comCurrentState == pCmd->nParam)
+            {
+                LOG(SF_LOG_DEBUG, "same state %d\r\n", pCmd->nParam);
+                pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
+                                                    OMX_EventError, OMX_ErrorSameState, pCmd->nParam, NULL);
+                break;
+            }
+
+            ret = OMX_ErrorNone;
+
+            switch (pCmd->nParam)
+            {
+            case OMX_StateInvalid:
+                switch (comCurrentState)
+                {
+                case OMX_StateExecuting:
+                    pImp->bThreadRunning = 0;
+                    // enqueue null mean encoder thread cycle end
+                    SF_Queue_Enqueue(pImp->EmptyQueue, &pNull);
+                    SF_Queue_Enqueue(pImp->FillQueue, &pNull);
+                    pthread_join(pImp->pProcessThread->pthread, &ThreadRet);
+                case OMX_StateIdle:
+                case OMX_StatePause:
+                case OMX_StateLoaded:
+                case OMX_StateWaitForResources:
+                default:
+                    pSfOMXComponent->state = OMX_StateInvalid;
+                    break;
+                }
+                ret = OMX_ErrorInvalidState;
+                break;
+
+            case OMX_StateLoaded:
+                switch (comCurrentState)
+                {
+                case OMX_StateWaitForResources:
+                    break;
+                case OMX_StateIdle:
+                    Warp_VPU_DeInit(pImp, pImp->coreIdx);
+                    for (i = 0; i < 2; i++)
+                    {
+                        if (pSfOMXComponent->portDefinition[i].bEnabled){
+                            LOG(SF_LOG_INFO,"unload SemaphoreWait \r\n");
+                            SF_SemaphoreWait(pSfOMXComponent->portUnloadSemaphore[i]);
+                            LOG(SF_LOG_INFO,"unload SemaphoreWait out\r\n");
+                        }
+                    }
+                    break;
+                default:
+                    ret = OMX_ErrorIncorrectStateTransition;
+                    break;
+                }
+                break;
+            case OMX_StateIdle:
+                if (comCurrentState == OMX_StatePause)
+                {
+                    comCurrentState = pSfOMXComponent->stateBeforePause;
+                }
+                switch (comCurrentState)
+                {
+                case OMX_StateLoaded:
+                    InitEncoder(pSfOMXComponent);
+                    for (i = 0; i < 2; i++)
+                    {
+                        if (pSfOMXComponent->portDefinition[i].bEnabled){
+                            LOG(SF_LOG_INFO,"SemaphoreWait \r\n");
+                            SF_SemaphoreWait(pSfOMXComponent->portSemaphore[i]);
+                            LOG(SF_LOG_INFO,"SemaphoreWait out\r\n");
+                        }
+                    }
+                    break;
+                case OMX_StateExecuting:
+                    pImp->bThreadRunning = 0;
+                    // enqueue null mean encoder thread cycle end
+                    SF_Queue_Enqueue(pImp->EmptyQueue, &pNull);
+                    SF_Queue_Enqueue(pImp->FillQueue, &pNull);
+                    pthread_join(pImp->pProcessThread->pthread, &ThreadRet);
+                    LOG(SF_LOG_INFO, "Encoder thread end %ld\r\n", (Uint64)ThreadRet);
+                    FlushBuffer(pSfOMXComponent,OMX_INPUT_PORT_INDEX);
+                    FlushBuffer(pSfOMXComponent,OMX_OUTPUT_PORT_INDEX);
+                    SF_Queue_Flush(pImp->EmptyQueue);
+                    SF_Queue_Flush(pImp->FillQueue);
+                    break;
+                case OMX_StateIdle:
+                    pImp->bPause = OMX_FALSE;
+                    break;
+                default:
+                    ret = OMX_ErrorIncorrectStateTransition;
+                    break;
+                }
+                break;
+
+            case OMX_StateWaitForResources:
+                switch (comCurrentState)
+                {
+                case OMX_StateLoaded:
+                    break;
+                default:
+                    ret = OMX_ErrorIncorrectStateTransition;
+                    break;
+                }
+                break;
+
+            case OMX_StateExecuting:
+                if (comCurrentState == OMX_StatePause)
+                {
+                    comCurrentState = pSfOMXComponent->stateBeforePause;
+                }
+                switch (comCurrentState)
+                {
+                case OMX_StateIdle:
+                    pImp->bThreadRunning = OMX_TRUE;
+                    pImp->bPause = OMX_FALSE;
+                    pImp->tmpCounter = 0;
+                    CreateThread(&pImp->pProcessThread, EncoderThread, (void *)pSfOMXComponent);
+                    break;
+                case OMX_StateExecuting:
+                    pImp->bPause = OMX_FALSE;
+                    SF_SemaphorePost(pImp->pauseSemaphore);
+                    break;
+                default:
+                    ret = OMX_ErrorIncorrectStateTransition;
+                    break;
+                }
+                break;
+
+            case OMX_StatePause:
+                switch (comCurrentState)
+                {
+                case OMX_StateIdle:
+                case OMX_StateExecuting:
+                    pImp->bPause = OMX_TRUE;
+                    pSfOMXComponent->stateBeforePause = comCurrentState;
+                    break;
+                default:
+                    ret = OMX_ErrorIncorrectStateTransition;
+                    break;
+                }
+                break;
+
+            default:
+                ret = OMX_ErrorIncorrectStateTransition;
+                break;
+            }
+
+            if (ret == OMX_ErrorNone)
+            {
+                pSfOMXComponent->state = pCmd->nParam;
+                pSfOMXComponent->traningState = OMX_TransStateInvalid;
+                pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
+                                                    OMX_EventCmdComplete, OMX_CommandStateSet, pCmd->nParam, NULL);
+                LOG(SF_LOG_DEBUG, "complete cmd StateSet %d\r\n", pCmd->nParam);
+
+                if (pSfOMXComponent->state == OMX_StateExecuting)
+                {
+                    ppBuffer = SF_Queue_Dequeue(pImp->pauseQ);
+                    while (ppBuffer)
+                    {
+                        pOMXBuffer = *ppBuffer;
+                        pSfOMXComponent->callbacks->FillBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pOMXBuffer);
+                        ppBuffer = SF_Queue_Dequeue(pImp->pauseQ);
+                    }
+                }
+            }
+            else
+            {
+                pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
+                                                    OMX_EventError, ret, 0, NULL);
+                LOG(SF_LOG_DEBUG, "Can't go to state %d from %d, ret %X \r\n",pSfOMXComponent->state, pCmd->nParam, ret);
+            }
+            break;
+
+        case OMX_CommandFlush:
+        {
+            LOG(SF_LOG_INFO, "flush port %d\r\n", pCmd->nParam);
+            OMX_U32 nPort = pCmd->nParam;
+            cnt = (pCmd->nParam == OMX_ALL) ? 2 : 1;
+
+            for (i = 0; i < cnt; i++) {
+                if (pCmd->nParam == OMX_ALL)
+                    nPort = i;
+                else
+                    nPort = pCmd->nParam;
+
+                if (nPort == 0)
+                {
+                    FlushBuffer(pSfOMXComponent, nPort);
+                    pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
+                                                    OMX_EventCmdComplete, OMX_CommandFlush, nPort, NULL);
+                }
+                else
+                {
+                    FlushBuffer(pSfOMXComponent, nPort);
+                    if (pSfOMXComponent->state == OMX_StatePause)
+                    {
+                        ppBuffer = SF_Queue_Dequeue(pImp->pauseQ);
+                        while (ppBuffer)
+                        {
+                            pOMXBuffer = *ppBuffer;
+                            pSfOMXComponent->callbacks->FillBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pOMXBuffer);
+                            ppBuffer = SF_Queue_Dequeue(pImp->pauseQ);
+                        }
+                    }
+                    pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
+                                                    OMX_EventCmdComplete, OMX_CommandFlush, nPort, NULL);
+                }
+            }
+        }
+        break;
+
+        case OMX_CommandPortDisable:
+        {
+            LOG(SF_LOG_INFO, "disable port %d\r\n", pCmd->nParam);
+            OMX_U32 nPort;
+            cnt = (pCmd->nParam == OMX_ALL) ? 2 : 1;
+
+            for (i = 0; i < cnt; i++) {
+                if (pCmd->nParam == OMX_ALL)
+                    nPort = i;
+                else
+                    nPort = pCmd->nParam;
+
+                FlushBuffer(pSfOMXComponent, nPort);
+            }
+
+            for (i = 0; i < cnt; i++) {
+                if (pCmd->nParam == OMX_ALL)
+                    nPort = i;
+                else
+                    nPort = pCmd->nParam;
+
+                if (pSfOMXComponent->state != OMX_StateLoaded)
+                    SF_SemaphoreWait(pSfOMXComponent->portUnloadSemaphore[nPort]);
+                pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
+                                                    OMX_EventCmdComplete, OMX_CommandPortDisable, nPort, NULL);
+            }
+        }
+        break;
+
+        case OMX_CommandPortEnable:
+        {
+            LOG(SF_LOG_INFO, "enable port %d\r\n", pCmd->nParam);
+            OMX_U32 nPort;
+            cnt = (pCmd->nParam == OMX_ALL) ? 2 : 1;
+
+            for (i = 0; i < cnt; i++) {
+                if (pCmd->nParam == OMX_ALL)
+                    nPort = i;
+                else
+                    nPort = pCmd->nParam;
+
+                if ((pSfOMXComponent->state != OMX_StateLoaded) &&
+                        (pSfOMXComponent->state != OMX_StateWaitForResources))
+                    SF_SemaphoreWait(pSfOMXComponent->portSemaphore[nPort]);
+                pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
+                                                    OMX_EventCmdComplete, OMX_CommandPortEnable, nPort, NULL);
+            }
+        }
+        break;
+
+        case OMX_CommandMarkBuffer:
+        {
+            LOG(SF_LOG_INFO, "set mark %d\r\n", pCmd->nParam);
+            OMX_U32 nPort;
+            nPort = pCmd->nParam;
+            pSfOMXComponent->markType[nPort].hMarkTargetComponent =
+                                ((OMX_MARKTYPE *)pCmd->pCmdData)->hMarkTargetComponent;
+            pSfOMXComponent->markType[nPort].pMarkData =
+                                ((OMX_MARKTYPE *)pCmd->pCmdData)->pMarkData;
+        }
+        break;
+
+        default:
+            break;
+        }
+    }
+
+    pthread_exit(NULL);
+}
+
+static void EncoderThread(void *args)
+{
+    SF_OMX_COMPONENT *pSfOMXComponent = (SF_OMX_COMPONENT *)args;
+    SF_WAVE420L_IMPLEMEMT *pImp = (SF_WAVE420L_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    TestEncConfig   *pEncConfig = &pImp->encConfig;
+    EncOpenParam    *pEncOP = &pImp->encOP;
+    EncHandle       *pHandle = &pImp->handle;
+    EncInitialInfo  *pInitialInfo = &pImp->initialInfo;
+    EncOutputInfo       outputInfo;
+    FrameBufferAllocInfo fbAllocInfo;
+    FrameBufferFormat   srcFrameFormat;
+    EncParam            encParam;
+    EncHeaderParam encHeaderParam;
+    YuvInfo        yuvFeederInfo;
+    OMX_BUFFERHEADERTYPE *pOutputBuffer;
+    OMX_BUFFERHEADERTYPE *pInputBuffer;
+    BitstreamReader bsReader = NULL;
+    SecAxiUse secAxiUse;
+    Comparator comparatorBitStream  = NULL;//todo use comparator
+    Int32 srcFrameWidth, srcFrameHeight, srcFrameStride;
+    Int32 framebufStride = 0, framebufWidth = 0, framebufHeight = 0, FrameBufSize = 0;
+    Int32 regFrameBufCount;
+    Int32 productId, instIdx, coreIdx, mapType;
+    Int32 i, ret, bsBufferCount, bsQueueIndex = 0;
+    Int32 srcFrameIdx = 0, frameIdx = 0;
+    Int32 timeoutCount = 0, int_reason = 0;
+    Uint32 interruptTimeout = VPU_ENC_TIMEOUT;
+    Uint32 geteos = 0;
+    Uint32 size;
+    void* yuvFeeder = NULL;
+
+    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+
+    instIdx = pEncConfig->instNum;
+    coreIdx = pEncConfig->coreIdx;
+
+    productId = Warp_VPU_GetProductId(pImp, coreIdx);
+
+    pEncOP->bitstreamFormat = pEncConfig->stdMode;
+    mapType = (pEncConfig->mapType & 0x0f);
+
+    //Warp_GetEncOpenParamDefault(pImp, pEncOP, pEncConfig);
+    if (strlen(pEncConfig->cfgFileName) != 0) {
+        Warp_GetEncOpenParam(pImp, pEncOP, pEncConfig, NULL);
+    }
+    else {
+        Warp_GetEncOpenParamDefault(pImp, pEncOP, pEncConfig);
+    }
+
+    //if modify encop should be here
+
+    srcFrameWidth  = ((pEncOP->picWidth+7)&~7);        // width = 8-aligned (CU unit)
+    srcFrameHeight = ((pEncOP->picHeight+7)&~7);       // height = 8-aligned (CU unit)
+    srcFrameStride = ((pEncOP->picWidth+31)&~31);      // stride should be a 32-aligned.
+
+    if (pEncConfig->packedFormat >= 1)
+        pEncConfig->srcFormat = FORMAT_422;
+
+    if (pEncConfig->srcFormat == FORMAT_422 && pEncConfig->packedFormat >= PACKED_YUYV) {
+        Int32 p10bits = pEncConfig->srcFormat3p4b == 0 ? 16 : 32;
+        Int32 packedFormat =
+            pImp->functions->GetPackedFormat(pEncOP->srcBitDepth, pEncConfig->packedFormat, p10bits, 1);
+
+        if (packedFormat == -1) {
+            LOG(SF_LOG_ERR, "fail to GetPackedFormat\n" );
+            goto ERR_ENC_INIT;
+        }
+        pEncOP->srcFormat = packedFormat;
+        srcFrameFormat  = (FrameBufferFormat)packedFormat;
+        pEncOP->nv21      = 0;
+        pEncOP->cbcrInterleave = 0;
+    }
+    else {
+        pEncOP->srcFormat    = pEncConfig->srcFormat;
+        srcFrameFormat     = (FrameBufferFormat)pEncConfig->srcFormat;
+        pEncOP->nv21         = pEncConfig->nv21;
+    }
+    pEncOP->packedFormat = pEncConfig->packedFormat;
+
+    framebufWidth  = (pEncOP->picWidth  +7)&~7;
+    framebufHeight = (pEncOP->picHeight +7)&~7;
+
+    bsBufferCount = DEFAULT_BS_BUFF;
+    for (i=0; i<bsBufferCount; i++ ) {
+        pImp->vbStream[i].size = framebufWidth * framebufWidth *2;
+        if (Warp_vdi_allocate_dma_memory(pImp, coreIdx, &pImp->vbStream[i]) < 0) {
+            LOG(SF_LOG_ERR, "fail to allocate bitstream buffer\n" );
+            goto ERR_ENC_INIT;
+        }
+        LOG(SF_LOG_DEBUG, "STREAM_BUF=0x%x STREAM_BUF_SIZE=%d(0x%x)\n",pImp->vbStream[i].phys_addr, pImp->vbStream[i].size, pImp->vbStream[i].size);
+    }
+
+    pSfOMXComponent->portDefinition[OMX_OUTPUT_PORT_INDEX].format.video.nStride = framebufWidth;
+    pSfOMXComponent->portDefinition[OMX_OUTPUT_PORT_INDEX].format.video.nSliceHeight = framebufHeight;
+    pSfOMXComponent->portDefinition[OMX_OUTPUT_PORT_INDEX].nBufferSize = framebufWidth * framebufHeight * 2;
+    LOG(SF_LOG_DEBUG, "OMX_EventPortSettingsChanged IN\r\n");
+    pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, OMX_EventPortSettingsChanged,
+                                             OMX_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition, NULL);
+    LOG(SF_LOG_DEBUG, "OMX_EventPortSettingsChanged OUT\r\n");
+
+    pEncOP->bitstreamBuffer = pImp->vbStream[0].phys_addr;
+    pEncOP->bitstreamBufferSize = pImp->vbStream[0].size;//* bsBufferCount;//
+
+    pEncOP->ringBufferEnable =  pEncConfig->ringBufferEnable;
+    pEncOP->cbcrInterleave = pEncConfig->cbcrInterleave;
+    pEncOP->frameEndian   = pEncConfig->frame_endian;
+    pEncOP->streamEndian  = pEncConfig->stream_endian;
+    pEncOP->sourceEndian  = pEncConfig->source_endian;
+
+    pEncOP->lineBufIntEn  =  pEncConfig->lineBufIntEn;
+    pEncOP->coreIdx       = coreIdx;
+    pEncOP->cbcrOrder     = CBCR_ORDER_NORMAL;
+    // host can set useLongTerm to 1 or 0 directly
+    pEncOP->EncStdParam.hevcParam.useLongTerm =
+            (pEncConfig->useAsLongtermPeriod > 0 && pEncConfig->refLongtermPeriod > 0) ? 1 : 0;
+
+    /* set framerate and bitrate */
+    /* If xFramerate value from user is stored in Q16 format, should convert into integer */
+    if(pSfOMXComponent->portDefinition[0].format.video.xFramerate > (1 << 16))
+    {
+        pEncOP->frameRateInfo = pSfOMXComponent->portDefinition[0].format.video.xFramerate >> 16;
+    }
+    else
+    {
+        pEncOP->frameRateInfo = pSfOMXComponent->portDefinition[0].format.video.xFramerate;
+    }
+
+    if(pSfOMXComponent->portDefinition[1].format.video.nBitrate)
+    {
+        pEncOP->rcEnable = 1;
+        pEncOP->bitRate = pSfOMXComponent->portDefinition[1].format.video.nBitrate;
+    }
+    else if(pEncOP->rcEnable == 1)
+    {
+        pSfOMXComponent->portDefinition[1].format.video.nBitrate = pEncOP->bitRate;
+    }
+
+    ret = Warp_VPU_EncOpen(pImp, pHandle, pEncOP);
+    if (ret) {
+        LOG(SF_LOG_ERR, "VPU_EncOpen failed Error code is 0x%x \n", ret );
+        goto ERR_ENC_INIT;
+    }
+
+    ret = Warp_VPU_EncGetInitialInfo(pImp, *pHandle, pInitialInfo);
+    if (ret) {
+        LOG(SF_LOG_ERR, "VPU_EncGetInitialInfo failed Error code is 0x%x \n", ret );
+        goto ERR_ENC_OPEN;
+    }
+
+    LOG(SF_LOG_INFO, "* Enc InitialInfo =>\n instance #%d, \n minframeBuffercount: %u\n minSrcBufferCount: %d\n",
+            instIdx, pInitialInfo->minFrameBufferCount, pInitialInfo->minSrcFrameCount);
+    LOG(SF_LOG_INFO, " picWidth: %u\n picHeight: %u\n ",pEncOP->picWidth, pEncOP->picHeight);
+
+    //create comparator here
+
+    secAxiUse.u.wave4.useEncImdEnable  = (pEncConfig->secondary_axi & 0x1)?TRUE:FALSE;  //USE_IMD_INTERNAL_BUF
+    secAxiUse.u.wave4.useEncRdoEnable  = (pEncConfig->secondary_axi & 0x2)?TRUE:FALSE;  //USE_RDO_INTERNAL_BUF
+    secAxiUse.u.wave4.useEncLfEnable   = (pEncConfig->secondary_axi & 0x4)?TRUE:FALSE;  //USE_LF_INTERNAL_BUF
+    Warp_VPU_EncGiveCommand(pImp, *pHandle, SET_SEC_AXI, &secAxiUse);
+
+    /* Allocate framebuffers for recon. */
+    framebufStride = Warp_CalcStride(pImp, framebufWidth, framebufHeight,
+            (FrameBufferFormat)pEncOP->srcFormat, pEncOP->cbcrInterleave, (TiledMapType)mapType, FALSE);
+    FrameBufSize   = Warp_VPU_GetFrameBufSize(pImp, coreIdx, framebufStride,
+            framebufHeight, (TiledMapType)mapType, pEncOP->srcFormat, pEncOP->cbcrInterleave, NULL);
+
+    regFrameBufCount = pInitialInfo->minFrameBufferCount;
+    for (i = 0; i < regFrameBufCount; i++) {
+        pImp->vbReconFrameBuf[i].size = FrameBufSize;
+        if (Warp_vdi_allocate_dma_memory(pImp,coreIdx, &pImp->vbReconFrameBuf[i]) < 0) {
+            LOG(SF_LOG_ERR, "SF_LOG_fail to allocate recon buffer\n" );
+            goto ERR_ENC_OPEN;
+        }
+        pImp->fbRecon[i].bufY  = pImp->vbReconFrameBuf[i].phys_addr;
+        pImp->fbRecon[i].bufCb = (PhysicalAddress)-1;
+        pImp->fbRecon[i].bufCr = (PhysicalAddress)-1;
+        pImp->fbRecon[i].size  = FrameBufSize;
+        pImp->fbRecon[i].updateFbInfo = TRUE;
+        LOG(SF_LOG_DEBUG, "Recon_BUF=0x%x Recon_BUF_SIZE=%d(0x%x)\n",pImp->vbReconFrameBuf[i].phys_addr, pImp->vbReconFrameBuf[i].size, pImp->vbReconFrameBuf[i].size);
+    }
+
+    ret = Warp_VPU_EncRegisterFrameBuffer(pImp, *pHandle, pImp->fbRecon,
+                regFrameBufCount, framebufStride, framebufHeight, mapType);
+    if(ret) {
+        LOG(SF_LOG_ERR, "VPU_EncRegisterFrameBuffer failed Error code is 0x%x \n", ret );
+        goto ERR_ENC_OPEN;
+    }
+
+
+    fbAllocInfo.mapType = LINEAR_FRAME_MAP;
+
+    srcFrameStride = Warp_CalcStride(pImp, srcFrameWidth, srcFrameHeight, (FrameBufferFormat)srcFrameFormat,
+                                            pEncOP->cbcrInterleave, (TiledMapType)fbAllocInfo.mapType, FALSE);
+    FrameBufSize   = Warp_VPU_GetFrameBufSize(pImp, coreIdx, srcFrameStride, srcFrameHeight,
+                                            (TiledMapType)fbAllocInfo.mapType, srcFrameFormat, pEncOP->cbcrInterleave, NULL);
+
+    fbAllocInfo.format = (FrameBufferFormat)srcFrameFormat;
+    fbAllocInfo.cbcrInterleave = pEncOP->cbcrInterleave;
+    fbAllocInfo.stride = srcFrameStride;
+    fbAllocInfo.height = srcFrameHeight;
+    fbAllocInfo.endian = pEncOP->sourceEndian;
+    fbAllocInfo.type   = FB_TYPE_PPU;
+    fbAllocInfo.num    = pInitialInfo->minSrcFrameCount + EXTRA_SRC_BUFFER_NUM;
+    fbAllocInfo.nv21   = pEncOP->nv21;
+
+    LOG(SF_LOG_INFO, "Allocated source framebuffers : %d, size : %d\n", fbAllocInfo.num, FrameBufSize);
+    for (i = 0; i < fbAllocInfo.num; i++) {
+        pImp->vbSourceFrameBuf[i].size = FrameBufSize;
+        if (Warp_vdi_allocate_dma_memory(pImp, coreIdx, &pImp->vbSourceFrameBuf[i]) < 0)
+        {
+            LOG(SF_LOG_ERR, "fail to allocate frame buffer\n" );
+            goto ERR_ENC_OPEN;
+        }
+        pImp->fbSrc[i].bufY  = pImp->vbSourceFrameBuf[i].phys_addr;
+        pImp->fbSrc[i].bufCb = (PhysicalAddress)-1;
+        pImp->fbSrc[i].bufCr = (PhysicalAddress)-1;
+        pImp->fbSrc[i].size  = FrameBufSize;
+        pImp->fbSrc[i].updateFbInfo = TRUE;
+        LOG(SF_LOG_DEBUG, "Source_BUF=0x%x Source_BUF_SIZE=%d(0x%x)\n",pImp->vbSourceFrameBuf[i].phys_addr, pImp->vbSourceFrameBuf[i].size, pImp->vbSourceFrameBuf[i].size);
+    }
+
+    ret = Warp_VPU_EncAllocateFrameBuffer(pImp, *pHandle, fbAllocInfo, pImp->fbSrc);
+    if (ret) {
+        LOG(SF_LOG_ERR, "VPU_EncAllocateFrameBuffer fail to allocate source frame buffer is 0x%x \n", ret );
+        goto ERR_ENC_OPEN;
+    }
+
+    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+    pthread_testcancel();
+    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
+
+    memset(&encParam, 0x00, sizeof(EncParam));
+    encParam.skipPicture        = 0;
+    encParam.quantParam         = pEncConfig->picQpY;
+    encParam.skipPicture        = 0;
+    encParam.forcePicQpEnable   = 0;
+    encParam.forcePicQpI        = 0;
+    encParam.forcePicQpP        = 0;
+    encParam.forcePicQpB        = 0;
+    encParam.forcePicTypeEnable = 0;
+    encParam.forcePicType       = 0;
+    encParam.codeOption.implicitHeaderEncode = 1;      // FW will encode header data implicitly when changing the header syntaxes
+    encParam.codeOption.encodeAUD   = pEncConfig->encAUD;
+    encParam.codeOption.encodeEOS   = 0;
+
+    memset(&encHeaderParam, 0x00, sizeof(EncHeaderParam));
+    encHeaderParam.buf = pEncOP->bitstreamBuffer;
+    encHeaderParam.size = pEncOP->bitstreamBufferSize;
+
+    encHeaderParam.headerType = CODEOPT_ENC_VPS | CODEOPT_ENC_SPS | CODEOPT_ENC_PPS;
+    ret = Warp_VPU_EncGiveCommand(pImp, *pHandle, ENC_PUT_VIDEO_HEADER, &encHeaderParam);
+    if (ret) {
+        LOG(SF_LOG_ERR, "VPU_EncGiveCommand ( ENC_PUT_VIDEO_HEADER ) for VPS/SPS/PPS failed Error Reason code : 0x%x \n", ret);
+        goto ERR_ENC_OPEN;
+    }
+    if (encHeaderParam.size == 0) {
+        LOG(SF_LOG_ERR, "encHeaderParam.size=0\n");
+        goto ERR_ENC_OPEN;
+    }
+
+    bsReader = Warp_BufferStreamReader_Create(pImp, pEncOP->ringBufferEnable, (EndianMode)pEncOP->streamEndian, pHandle);
+
+    pOutputBuffer = *(OMX_BUFFERHEADERTYPE**)SF_Queue_Dequeue_Block(pImp->FillQueue);
+
+    if(pOutputBuffer == NULL){
+        pImp->bThreadRunning = 0;
+        goto ERR_ENC_OPEN;
+    }
+
+    LOG(SF_LOG_DEBUG, "get output buff %p index %d\r\n", pOutputBuffer->pBuffer,
+                        ((SF_OMX_BUF_INFO*)pOutputBuffer->pOutputPortPrivate)->index);
+
+    Warp_EnterLock(pImp, coreIdx);
+    size = Warp_BufferStreamReader_Act(pImp, bsReader, encHeaderParam.buf,
+                pEncOP->bitstreamBufferSize, encHeaderParam.size, pOutputBuffer->pBuffer, comparatorBitStream);
+    Warp_LeaveLock(pImp, coreIdx);
+    if (size == 0) {
+        LOG(SF_LOG_ERR, "fill header size 0, end\n");
+        goto ERR_ENC_OPEN;
+    }
+    pOutputBuffer->nFilledLen = size;
+    pOutputBuffer->nFlags = OMX_BUFFERFLAG_CODECCONFIG;
+    FillBufferDone(pSfOMXComponent, pOutputBuffer);
+
+    memset(&yuvFeederInfo,   0x00, sizeof(YuvInfo));
+    yuvFeederInfo.cbcrInterleave = pEncConfig->cbcrInterleave;
+    yuvFeederInfo.nv21           = pEncConfig->nv21;
+    yuvFeederInfo.packedFormat   = pEncConfig->packedFormat;
+    yuvFeederInfo.srcFormat      = pEncOP->srcFormat;
+    yuvFeederInfo.srcPlanar      = TRUE;
+    yuvFeederInfo.srcStride      = srcFrameStride;
+    yuvFeederInfo.srcHeight      = srcFrameHeight;
+    yuvFeeder = Warp_YuvFeeder_Create(pImp, SOURCE_YUV_WITH_BUFFER, NULL, yuvFeederInfo);
+    if ( yuvFeeder == NULL ) {
+        LOG(SF_LOG_ERR, "YuvFeeder_Create error");
+        goto ERR_ENC_OPEN;
+    }
+
+    LOG(SF_LOG_INFO, "Enc Start :\n");
+    Warp_DisplayEncodedInformation(pImp, *pHandle, STD_HEVC, 0, NULL, 0, 0);
+
+    while(1){
+        if(!pImp->bThreadRunning){
+            LOG(SF_LOG_DEBUG,"encoder thread end\n");
+            break;
+        }
+
+        if(pImp->bPause){
+            LOG(SF_LOG_DEBUG,"in pause\n");
+            SF_SemaphoreWait(pImp->pauseSemaphore);
+            LOG(SF_LOG_DEBUG,"out pause\n");
+        }
+
+        pInputBuffer = *(OMX_BUFFERHEADERTYPE**)SF_Queue_Dequeue_Block(pImp->EmptyQueue);
+
+        if(pInputBuffer == NULL){
+            pImp->bThreadRunning = 0;
+            LOG(SF_LOG_DEBUG, "null input buffer,end\n");
+            break;
+        }
+        if(!pInputBuffer->nFilledLen){
+            LOG(SF_LOG_DEBUG, "end of stream,end\n");
+            pImp->bThreadRunning = 0;
+            EmptyBufferDone(pSfOMXComponent, pInputBuffer);
+            pOutputBuffer = *(OMX_BUFFERHEADERTYPE**)SF_Queue_Dequeue_Block(pImp->FillQueue);
+            pOutputBuffer->nFilledLen = 0;
+            pOutputBuffer->nFlags = OMX_BUFFERFLAG_EOS;
+            FillBufferDone(pSfOMXComponent, pOutputBuffer);
+            break;
+        }else if(pInputBuffer->nFlags == OMX_BUFFERFLAG_EOS){
+            LOG(SF_LOG_DEBUG, "end of stream,end\n");
+            //encParam.srcEndFlag = 1;
+            geteos = 1;
+        }
+
+        LOG(SF_LOG_DEBUG, "get input buff %p index %d\r\n", pInputBuffer->pBuffer,
+                            ((SF_OMX_BUF_INFO*)pInputBuffer->pInputPortPrivate)->index);
+
+        srcFrameIdx = (frameIdx%fbAllocInfo.num);
+        encParam.srcIdx = srcFrameIdx;
+        ret = Warp_YuvFeeder_Feed(pImp, yuvFeeder, coreIdx, &pImp->fbSrc[srcFrameIdx], pEncOP->picWidth, pEncOP->picHeight, pInputBuffer->pBuffer);
+        LOG(SF_LOG_DEBUG,"feed src %p size %ld fbSrcIdx %d ret %d\n",pInputBuffer->pBuffer, pInputBuffer->nFilledLen, srcFrameIdx, ret);
+        if ( ret == 0 ) {
+            encParam.srcEndFlag = 1;            // when there is no more source image to be encoded, srcEndFlag should be set 1. because of encoding delay for WAVE420
+        }
+
+        EmptyBufferDone(pSfOMXComponent, pInputBuffer);
+
+        if ( encParam.srcEndFlag != 1) {
+            pImp->fbSrc[srcFrameIdx].srcBufState = SRC_BUFFER_USE_ENCODE;
+            encParam.sourceFrame = &pImp->fbSrc[srcFrameIdx];
+            encParam.sourceFrame->sourceLBurstEn = 0;///???
+        }
+
+        bsQueueIndex = (bsQueueIndex+1)%bsBufferCount;
+        encParam.picStreamBufferAddr = pImp->vbStream[bsQueueIndex].phys_addr;   // can set the newly allocated buffer.
+        encParam.picStreamBufferSize = pEncOP->bitstreamBufferSize;
+
+        if (pEncConfig->useAsLongtermPeriod > 0 && pEncConfig->refLongtermPeriod > 0) {
+            encParam.useCurSrcAsLongtermPic = (frameIdx % pEncConfig->useAsLongtermPeriod) == 0 ? 1 : 0;
+            encParam.useLongtermRef         = (frameIdx % pEncConfig->refLongtermPeriod)   == 0 ? 1 : 0;
+        }
+
+        // Start encoding a frame.
+        frameIdx++;
+
+        LOG(SF_LOG_DEBUG, "vpu start one frame\r\n");
+        ret = Warp_VPU_EncStartOneFrame(pImp,*pHandle, &encParam);
+        if(ret) {
+            LOG(SF_LOG_ERR,  "VPU_EncStartOneFrame failed Error code is 0x%x \n", ret );
+            Warp_LeaveLock(pImp, coreIdx);
+            goto ERR_ENC_OPEN;
+        }
+
+        timeoutCount = 0;
+
+        while(1){
+            int_reason = Warp_VPU_WaitInterrupt(pImp, coreIdx, VPU_WAIT_TIME_OUT);
+
+            if (int_reason == -1) {
+                if (interruptTimeout > 0 && timeoutCount*VPU_WAIT_TIME_OUT > interruptTimeout) {
+                    LOG(SF_LOG_ERR, "Error : encoder timeout happened\n");
+                    Warp_PrintVpuStatus(pImp, coreIdx, productId);
+                    Warp_VPU_SWReset(pImp, coreIdx, SW_RESET_SAFETY, *pHandle);
+                    break;
+                }
+                int_reason = 0;
+                timeoutCount++;
+            }
+
+            if (int_reason & (1<<INT_BIT_BIT_BUF_FULL)) {
+                LOG(SF_LOG_WARN,"INT_BIT_BIT_BUF_FULL \n");
+                pOutputBuffer = *(OMX_BUFFERHEADERTYPE**)SF_Queue_Dequeue_Block(pImp->FillQueue);
+
+                if(pOutputBuffer == NULL){
+                    pImp->bThreadRunning = 0;
+                    LOG(SF_LOG_DEBUG, "null output buffer,end\n");
+                    goto ERR_ENC_OPEN;
+                }
+
+                LOG(SF_LOG_DEBUG, "get output buff %p index %d\r\n", pOutputBuffer->pBuffer,
+                                    ((SF_OMX_BUF_INFO*)pOutputBuffer->pOutputPortPrivate)->index);
+                size = Warp_BufferStreamReader_Act(pImp, bsReader, pEncOP->bitstreamBuffer, pEncOP->bitstreamBufferSize, STREAM_READ_ALL_SIZE, pOutputBuffer->pBuffer, comparatorBitStream);
+                if (size == 0) {
+                    LOG(SF_LOG_ERR, "BufferStreamReader acc err \r\n");
+                    goto ERR_ENC_OPEN;
+                }
+                pOutputBuffer->nFilledLen = size;
+                pOutputBuffer->nFlags = 0;
+                if (geteos)
+                {
+                    pOutputBuffer->nFlags |= OMX_BUFFERFLAG_EOS;
+                    geteos = 0;
+                }
+                FillBufferDone(pSfOMXComponent, pOutputBuffer);
+            }
+
+            if (int_reason) {
+                Warp_VPU_ClearInterrupt(pImp, coreIdx);
+                if (int_reason & (1<<INT_WAVE_ENC_PIC)) {
+                    break;
+                }
+            }
+
+        }
+
+        ret = Warp_VPU_EncGetOutputInfo(pImp, *pHandle, &outputInfo);
+        if (ret ) {
+            LOG(SF_LOG_ERR, "VPU_EncGetOutputInfo failed Error code is 0x%x \n", ret );
+            if (ret == RETCODE_STREAM_BUF_FULL) {
+                LOG(SF_LOG_ERR, "RETCODE_STREAM_BUF_FULL\n");
+                continue;
+            }
+            else if ( ret == RETCODE_MEMORY_ACCESS_VIOLATION || ret == RETCODE_CP0_EXCEPTION || ret == RETCODE_ACCESS_VIOLATION_HW)
+            {
+                Warp_EnterLock(pImp, coreIdx);
+                Warp_PrintVpuStatus(pImp, coreIdx, productId);
+                Warp_VPU_SWReset(pImp,coreIdx, SW_RESET_SAFETY, *pHandle);
+                Warp_LeaveLock(pImp, coreIdx);
+            } else {
+                Warp_EnterLock(pImp, coreIdx);
+                Warp_PrintVpuStatus(pImp, coreIdx, productId);
+                Warp_VPU_SWReset(pImp, coreIdx, SW_RESET_SAFETY, *pHandle);
+                Warp_LeaveLock(pImp, coreIdx);
+            }
+            LOG(SF_LOG_ERR, "something err \r\n");
+            goto ERR_ENC_OPEN;
+        }
+
+        Warp_DisplayEncodedInformation(pImp, *pHandle, STD_HEVC, 0, &outputInfo, encParam.srcEndFlag , srcFrameIdx);
+
+        if (outputInfo.bitstreamWrapAround == 1) {
+            LOG(SF_LOG_WARN, "Warnning!! BitStream buffer wrap arounded. prepare more large buffer \n", ret );
+        }
+        if (outputInfo.bitstreamSize == 0 && outputInfo.reconFrameIndex >= 0) {
+            LOG(SF_LOG_ERR, "ERROR!!! bitstreamsize = 0 \n");
+        }
+
+        if (pEncOP->lineBufIntEn == 0) {
+            if (outputInfo.wrPtr < outputInfo.rdPtr)
+            {
+                LOG(SF_LOG_ERR, "wrptr < rdptr\n");
+                goto ERR_ENC_OPEN;
+            }
+        }
+
+        if ( outputInfo.bitstreamSize ) {
+            pOutputBuffer = *(OMX_BUFFERHEADERTYPE**)SF_Queue_Dequeue_Block(pImp->FillQueue);
+
+            if(pOutputBuffer == NULL){
+                pImp->bThreadRunning = 0;
+                LOG(SF_LOG_DEBUG, "null output buffer,end\n");
+                goto ERR_ENC_OPEN;
+            }
+
+            LOG(SF_LOG_DEBUG, "get output buff %p index %d\r\n", pOutputBuffer->pBuffer,
+                                    ((SF_OMX_BUF_INFO*)pOutputBuffer->pOutputPortPrivate)->index);
+            Warp_EnterLock(pImp, coreIdx);
+            size = Warp_BufferStreamReader_Act(pImp, bsReader, outputInfo.bitstreamBuffer, pEncOP->bitstreamBufferSize,
+                                    outputInfo.bitstreamSize, pOutputBuffer->pBuffer,comparatorBitStream);
+            Warp_LeaveLock(pImp, coreIdx);
+            if (size == 0) {
+                LOG(SF_LOG_ERR, "BufferStreamReader acc err \r\n");
+                goto ERR_ENC_OPEN;
+            }
+            pOutputBuffer->nFilledLen = size;
+            pOutputBuffer->nFlags = OMX_BUFFERFLAG_ENDOFFRAME;
+            if (outputInfo.reconFrameIndex == -1)
+                pOutputBuffer->nFlags |= OMX_BUFFERFLAG_EOS;
+            FillBufferDone(pSfOMXComponent, pOutputBuffer);
+        }
+
+        if (outputInfo.reconFrameIndex == -1)       // end of encoding
+        {
+            LOG(SF_LOG_DEBUG, "end of coding\n");
+            break;
+        }
+
+    }
+
+ERR_ENC_OPEN:
+    FlushBuffer(pSfOMXComponent,OMX_INPUT_PORT_INDEX);
+    FlushBuffer(pSfOMXComponent,OMX_OUTPUT_PORT_INDEX);
+    for (i = 0; i < regFrameBufCount; i++) {
+        if (pImp->vbReconFrameBuf[i].size > 0) {
+            Warp_vdi_free_dma_memory(pImp, coreIdx, &pImp->vbReconFrameBuf[i]);
+        }
+    }
+    for (i = 0; i < fbAllocInfo.num; i++) {
+        if (pImp->vbSourceFrameBuf[i].size > 0) {
+            Warp_vdi_free_dma_memory(pImp, coreIdx, &pImp->vbSourceFrameBuf[i]);
+        }
+    }
+    Warp_VPU_EncClose(pImp, *pHandle);
+    LOG(SF_LOG_DEBUG,"close vpu \r\n");
+ERR_ENC_INIT:
+    for (i=0; i< bsBufferCount ; i++) {
+        if (pImp->vbStream[i].size){
+            Warp_vdi_free_dma_memory(pImp, coreIdx, &pImp->vbStream[i]);
+        }
+    }
+
+    pthread_exit(NULL);
+}
+
+static OMX_ERRORTYPE SF_OMX_ComponentTunnelRequest(
+    OMX_IN OMX_HANDLETYPE hComp,
+    OMX_IN OMX_U32        nPort,
+    OMX_IN OMX_HANDLETYPE hTunneledComp,
+    OMX_IN OMX_U32        nTunneledPort,
+    OMX_INOUT OMX_TUNNELSETUPTYPE *pTunnelSetup)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    (void) hComp;
+    (void) nPort;
+    (void) hTunneledComp;
+    (void) nTunneledPort;
+    (void) pTunnelSetup;
+    ret = OMX_ErrorTunnelingUnsupported;
+    goto EXIT;
+EXIT:
+    return ret;
+}
+
+static void FlushBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U32 nPortNumber)
+{
+    SF_WAVE420L_IMPLEMEMT *pImp = (SF_WAVE420L_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL;
+    OMX_BUFFERHEADERTYPE **ppBuffer = NULL;
+
+    FunctionIn();
+    switch (nPortNumber)
+    {
+    case OMX_INPUT_PORT_INDEX:
+        while (OMX_TRUE)
+        {
+            ppBuffer = SF_Queue_Dequeue(pImp->EmptyQueue);
+            if (NULL == ppBuffer)
+            {
+                LOG(SF_LOG_INFO, "No more buffer in input port\r\n");
+                break;
+            }
+            pOMXBuffer = *ppBuffer;
+            if(!pOMXBuffer)
+                continue;
+            LOG(SF_LOG_INFO, "Flush Buffer %p\r\n", pOMXBuffer);
+            pOMXBuffer->nFlags = OMX_BUFFERFLAG_EOS;
+            EmptyBufferDone(pSfOMXComponent, pOMXBuffer);
+        }
+        break;
+    case OMX_OUTPUT_PORT_INDEX:
+        while (OMX_TRUE)
+        {
+            ppBuffer = SF_Queue_Dequeue(pImp->FillQueue);
+            if (NULL == ppBuffer)
+            {
+                LOG(SF_LOG_INFO, "No more buffer in output port\r\n");
+                break;
+            }
+            pOMXBuffer = *ppBuffer;
+            if(!pOMXBuffer)
+                continue;
+            LOG(SF_LOG_INFO, "Flush Buffer %p\r\n", pOMXBuffer);
+            pOMXBuffer->nFilledLen = 0;
+            pOMXBuffer->nFlags = OMX_BUFFERFLAG_EOS;
+            FillBufferDone(pSfOMXComponent, pOMXBuffer);
+        }
+        break;
+    default:
+        break;
+    }
+    FunctionOut();
+}
+
+static OMX_ERRORTYPE SF_OMX_EmptyThisBuffer(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    FunctionIn();
+
+    if (hComponent == NULL || pBuffer == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = (SF_OMX_COMPONENT *)pOMXComponent->pComponentPrivate;
+    SF_WAVE420L_IMPLEMEMT *pImp = (SF_WAVE420L_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+
+    LOG(SF_LOG_DEBUG, "bufheader %p nFilledLen = %d, nFlags = %d, pBuffer = %p\r\n", pBuffer, pBuffer->nFilledLen, pBuffer->nFlags, pBuffer->pBuffer);
+
+    if (!pSfOMXComponent->portDefinition[OMX_INPUT_PORT_INDEX].bEnabled)
+    {
+        LOG(SF_LOG_INFO, "feed buffer when input port stop\r\n");
+        return OMX_ErrorIncorrectStateOperation;
+    }
+
+    if (pBuffer->nInputPortIndex != OMX_INPUT_PORT_INDEX)
+    {
+        LOG(SF_LOG_INFO, "Incorrect nInputPortIndex %d\r\n", pBuffer->nInputPortIndex);
+        return OMX_ErrorBadPortIndex;
+    }
+
+    ret = SF_Queue_Enqueue(pImp->EmptyQueue, &pBuffer);
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_FillThisBuffer(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    FunctionIn();
+
+    if (hComponent == NULL || pBuffer == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = (SF_OMX_COMPONENT *)pOMXComponent->pComponentPrivate;
+    SF_WAVE420L_IMPLEMEMT *pImp = (SF_WAVE420L_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    LOG(SF_LOG_DEBUG, "bufheader %p nFilledLen = %d, nFlags = %d, pBuffer = %p\r\n", pBuffer, pBuffer->nFilledLen, pBuffer->nFlags, pBuffer->pBuffer);
+
+    if (!pSfOMXComponent->portDefinition[OMX_OUTPUT_PORT_INDEX].bEnabled)
+    {
+        LOG(SF_LOG_INFO, "feed buffer when output port stop\r\n");
+        return OMX_ErrorIncorrectStateOperation;
+    }
+
+    if (pBuffer->nOutputPortIndex != OMX_OUTPUT_PORT_INDEX)
+    {
+        LOG(SF_LOG_INFO, "Incorrect nOutputPortIndex %d\r\n", pBuffer->nOutputPortIndex);
+        return OMX_ErrorBadPortIndex;
+    }
+
+    ret = SF_Queue_Enqueue(pImp->FillQueue, &pBuffer);
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_UseBuffer(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
+    OMX_IN OMX_U32 nPortIndex,
+    OMX_IN OMX_PTR pAppPrivate,
+    OMX_IN OMX_U32 nSizeBytes,
+    OMX_IN OMX_U8 *pBuffer)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_BUFFERHEADERTYPE *temp_bufferHeader;
+    SF_OMX_BUF_INFO *pBufInfo;
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    OMX_U32 i;
+
+    FunctionIn();
+
+    temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)malloc(sizeof(OMX_BUFFERHEADERTYPE));
+    if (temp_bufferHeader == NULL)
+    {
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        return OMX_ErrorInsufficientResources;
+    }
+    pBufInfo = (SF_OMX_BUF_INFO *)malloc(sizeof(SF_OMX_BUF_INFO));
+    if (pBufInfo == NULL)
+    {
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        free(temp_bufferHeader);
+        return OMX_ErrorInsufficientResources;
+    }
+    memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE));
+    temp_bufferHeader->nAllocLen = nSizeBytes;
+    temp_bufferHeader->pAppPrivate = pAppPrivate;
+    temp_bufferHeader->pBuffer = pBuffer;
+    temp_bufferHeader->nSize = sizeof(OMX_BUFFERHEADERTYPE);
+    memcpy(&(temp_bufferHeader->nVersion), &(pSfOMXComponent->componentVersion), sizeof(OMX_VERSIONTYPE));
+
+    if(nPortIndex == OMX_INPUT_PORT_INDEX)
+    {
+        for (i = 0; i < MAX_BUFF_NUM; i++)
+        {
+            if (!pSfOMXComponent->pBufferArray[OMX_INPUT_PORT_INDEX][i])
+            {
+                pBufInfo->type = SF_BUFFER_DMA_EXTERNAL;
+                pBufInfo->index = i;
+                temp_bufferHeader->pInputPortPrivate = (OMX_PTR)pBufInfo;
+                temp_bufferHeader->nInputPortIndex = OMX_INPUT_PORT_INDEX;
+                pSfOMXComponent->pBufferArray[OMX_INPUT_PORT_INDEX][i] = temp_bufferHeader;
+                pSfOMXComponent->assignedBufferNum[OMX_INPUT_PORT_INDEX] ++;
+
+                if (pSfOMXComponent->assignedBufferNum[OMX_INPUT_PORT_INDEX] ==
+                        pSfOMXComponent->portDefinition[OMX_INPUT_PORT_INDEX].nBufferCountActual)
+                {
+                    pSfOMXComponent->portDefinition[OMX_INPUT_PORT_INDEX].bPopulated = OMX_TRUE;
+                    SF_SemaphorePost(pSfOMXComponent->portSemaphore[OMX_INPUT_PORT_INDEX]);
+                }
+                break;
+            }
+        }
+        if (i == MAX_BUFF_NUM){
+            LOG(SF_LOG_ERR, "buffer array full\r\n");
+            free(temp_bufferHeader);
+            free(pBufInfo);
+            ret = OMX_ErrorInsufficientResources;
+        }
+    }
+    else if(nPortIndex == OMX_OUTPUT_PORT_INDEX)
+    {
+        for (i = 0; i < MAX_BUFF_NUM; i++)
+        {
+            if (!pSfOMXComponent->pBufferArray[OMX_OUTPUT_PORT_INDEX][i])
+            {
+                pBufInfo->type = SF_BUFFER_DMA_EXTERNAL;
+                pBufInfo->index = i;
+                temp_bufferHeader->pOutputPortPrivate = (OMX_PTR)pBufInfo;
+                temp_bufferHeader->nOutputPortIndex = OMX_OUTPUT_PORT_INDEX;
+                pSfOMXComponent->pBufferArray[OMX_OUTPUT_PORT_INDEX][i] = temp_bufferHeader;
+                pSfOMXComponent->assignedBufferNum[OMX_OUTPUT_PORT_INDEX] ++;
+
+                if (pSfOMXComponent->assignedBufferNum[OMX_OUTPUT_PORT_INDEX] ==
+                        pSfOMXComponent->portDefinition[OMX_OUTPUT_PORT_INDEX].nBufferCountActual)
+                {
+                    pSfOMXComponent->portDefinition[OMX_OUTPUT_PORT_INDEX].bPopulated = OMX_TRUE;
+                    SF_SemaphorePost(pSfOMXComponent->portSemaphore[OMX_OUTPUT_PORT_INDEX]);
+                }
+                break;
+            }
+        }
+        if (i == MAX_BUFF_NUM){
+            LOG(SF_LOG_ERR, "buffer array full\r\n");
+            free(temp_bufferHeader);
+            free(pBufInfo);
+            ret = OMX_ErrorInsufficientResources;
+        }
+    }
+
+    *ppBufferHdr = temp_bufferHeader;
+
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_BOOL FillBufferDone(SF_OMX_COMPONENT *pSfOMXComponent, OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    SF_WAVE420L_IMPLEMEMT *pImp = (SF_WAVE420L_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    FunctionIn();
+
+    pBuffer->nTimeStamp = (pImp->tmpCounter*1000000)/pImp->tmpFramerate;
+    pImp->tmpCounter++;
+
+    LOG(SF_LOG_PERF, "OMX finish one buffer, address = %p, size = %d, nTimeStamp = %d, nFlags = %X\r\n",
+            pBuffer->pBuffer, pBuffer->nFilledLen, pBuffer->nTimeStamp, pBuffer->nFlags);
+
+    if (pSfOMXComponent->propagateMarkType.hMarkTargetComponent != NULL) {
+        LOG(SF_LOG_INFO, "Component propagate mark to output port\r\n");
+        pBuffer->hMarkTargetComponent = pSfOMXComponent->propagateMarkType.hMarkTargetComponent;
+        pBuffer->pMarkData = pSfOMXComponent->propagateMarkType.pMarkData;
+        pSfOMXComponent->propagateMarkType.hMarkTargetComponent = NULL;
+        pSfOMXComponent->propagateMarkType.pMarkData = NULL;
+    }
+
+    if (pSfOMXComponent->state == OMX_StatePause)
+    {
+        LOG(SF_LOG_INFO, "tmp store buf when pause\r\n");
+        SF_Queue_Enqueue(pImp->pauseQ, &pBuffer);
+    }
+    else{
+        if (pBuffer->nFlags & OMX_BUFFERFLAG_EOS)
+        {
+            pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, OMX_EventBufferFlag,
+                                                 OMX_OUTPUT_PORT_INDEX, pBuffer->nFlags, NULL);
+        }
+        pSfOMXComponent->callbacks->FillBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pBuffer);
+    }
+
+
+    FunctionOut();
+    return OMX_TRUE;
+}
+
+static OMX_BOOL EmptyBufferDone(SF_OMX_COMPONENT *pSfOMXComponent, OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    FunctionIn();
+    LOG(SF_LOG_DEBUG, "EmptyBufferDone IN\r\n");
+    LOG(SF_LOG_PERF, "OMX empty one buffer, address = %p, size = %d, nTimeStamp = %d, nFlags = %X\r\n",
+        pBuffer->pBuffer, pBuffer->nFilledLen, pBuffer->nTimeStamp, pBuffer->nFlags);
+
+    if (pSfOMXComponent->markType[OMX_INPUT_PORT_INDEX].hMarkTargetComponent != NULL)
+    {
+        LOG(SF_LOG_INFO, "set Component mark %p\r\n", pSfOMXComponent->markType[OMX_INPUT_PORT_INDEX].hMarkTargetComponent);
+        pBuffer->hMarkTargetComponent      = pSfOMXComponent->markType[OMX_INPUT_PORT_INDEX].hMarkTargetComponent;
+        pBuffer->pMarkData                 = pSfOMXComponent->markType[OMX_INPUT_PORT_INDEX].pMarkData;
+        pSfOMXComponent->markType[OMX_INPUT_PORT_INDEX].hMarkTargetComponent = NULL;
+        pSfOMXComponent->markType[OMX_INPUT_PORT_INDEX].pMarkData = NULL;
+    }
+
+    if (pBuffer->hMarkTargetComponent != NULL)
+    {
+        if (pBuffer->hMarkTargetComponent == pSfOMXComponent->pOMXComponent)
+        {
+            LOG(SF_LOG_INFO, "Component mark hit\r\n");
+            pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent,
+                pSfOMXComponent->pAppData,
+                OMX_EventMark,
+                0, 0, pBuffer->pMarkData);
+        } else {
+            LOG(SF_LOG_INFO, "Component propagate mark from input port\r\n");
+            pSfOMXComponent->propagateMarkType.hMarkTargetComponent = pBuffer->hMarkTargetComponent;
+            pSfOMXComponent->propagateMarkType.pMarkData = pBuffer->pMarkData;
+        }
+    }
+
+    pSfOMXComponent->callbacks->EmptyBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pBuffer);
+    LOG(SF_LOG_DEBUG, "EmptyBufferDone OUT\r\n");
+
+    FunctionOut();
+    return OMX_TRUE;
+}
+
+static OMX_ERRORTYPE SF_OMX_AllocateBuffer(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
+    OMX_IN OMX_U32 nPortIndex,
+    OMX_IN OMX_PTR pAppPrivate,
+    OMX_IN OMX_U32 nSizeBytes)
+{
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_BUFFERHEADERTYPE *temp_bufferHeader;
+    SF_OMX_BUF_INFO *pBufInfo;
+    OMX_U32 i;
+
+    FunctionIn();
+    if (nSizeBytes == 0)
+    {
+        LOG(SF_LOG_ERR, "nSizeBytes = %d\r\n", nSizeBytes);
+        return OMX_ErrorBadParameter;
+    }
+    temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)malloc(sizeof(OMX_BUFFERHEADERTYPE));
+    if (temp_bufferHeader == NULL)
+    {
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        return OMX_ErrorInsufficientResources;
+    }
+    memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE));
+    pBufInfo = (SF_OMX_BUF_INFO *)malloc(sizeof(SF_OMX_BUF_INFO));
+    if (pBufInfo == NULL)
+    {
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        free(temp_bufferHeader);
+        return OMX_ErrorInsufficientResources;
+    }
+
+    temp_bufferHeader->nAllocLen = nSizeBytes;
+    temp_bufferHeader->pAppPrivate = pAppPrivate;
+    temp_bufferHeader->nSize = sizeof(OMX_BUFFERHEADERTYPE);
+    memcpy(&(temp_bufferHeader->nVersion), &(pSfOMXComponent->componentVersion), sizeof(OMX_VERSIONTYPE));
+
+    if (nPortIndex == OMX_OUTPUT_PORT_INDEX)
+    {
+        for (i = 0; i < MAX_BUFF_NUM; i++)
+        {
+            if (!pSfOMXComponent->pBufferArray[OMX_OUTPUT_PORT_INDEX][i])
+            {
+                temp_bufferHeader->pBuffer = malloc(nSizeBytes);
+                memset(temp_bufferHeader->pBuffer, 0, nSizeBytes);
+                temp_bufferHeader->nOutputPortIndex = OMX_OUTPUT_PORT_INDEX;
+                pBufInfo->type = SF_BUFFER_NOMAL;
+                pBufInfo->index = i;
+                temp_bufferHeader->pOutputPortPrivate = (void*)pBufInfo;
+                LOG(SF_LOG_PERF, "alloc normal output buffer %d \r\n", i);
+
+                pSfOMXComponent->pBufferArray[OMX_OUTPUT_PORT_INDEX][i] = temp_bufferHeader;
+                pSfOMXComponent->assignedBufferNum[OMX_OUTPUT_PORT_INDEX]++;
+
+                if (pSfOMXComponent->assignedBufferNum[OMX_OUTPUT_PORT_INDEX] ==
+                        pSfOMXComponent->portDefinition[OMX_OUTPUT_PORT_INDEX].nBufferCountActual)
+                {
+                    pSfOMXComponent->portDefinition[OMX_OUTPUT_PORT_INDEX].bPopulated = OMX_TRUE;
+                    SF_SemaphorePost(pSfOMXComponent->portSemaphore[OMX_OUTPUT_PORT_INDEX]);
+                }
+                break;
+            }
+        }
+        if (i == MAX_BUFF_NUM){
+            LOG(SF_LOG_ERR, "buffer array full\r\n");
+            temp_bufferHeader->pBuffer = NULL;
+        }
+    }
+    else if (nPortIndex == OMX_INPUT_PORT_INDEX)
+    {
+        for (i = 0; i < MAX_BUFF_NUM; i++)
+        {
+            if (!pSfOMXComponent->pBufferArray[OMX_INPUT_PORT_INDEX][i])
+            {
+                temp_bufferHeader->pBuffer = malloc(nSizeBytes);
+                memset(temp_bufferHeader->pBuffer, 0, nSizeBytes);
+                temp_bufferHeader->nInputPortIndex = OMX_INPUT_PORT_INDEX;
+                pBufInfo->type = SF_BUFFER_NOMAL;
+                pBufInfo->index = i;
+                temp_bufferHeader->pInputPortPrivate = (void*)pBufInfo;
+                LOG(SF_LOG_PERF, "alloc normal intput buffer %d \r\n", i);
+
+                pSfOMXComponent->pBufferArray[OMX_INPUT_PORT_INDEX][i] = temp_bufferHeader;
+                pSfOMXComponent->assignedBufferNum[OMX_INPUT_PORT_INDEX]++;
+
+                if (pSfOMXComponent->assignedBufferNum[OMX_INPUT_PORT_INDEX] ==
+                        pSfOMXComponent->portDefinition[OMX_INPUT_PORT_INDEX].nBufferCountActual)
+                {
+                    pSfOMXComponent->portDefinition[OMX_INPUT_PORT_INDEX].bPopulated = OMX_TRUE;
+                    SF_SemaphorePost(pSfOMXComponent->portSemaphore[OMX_INPUT_PORT_INDEX]);
+                }
+                break;
+            }
+        }
+        if (i == MAX_BUFF_NUM){
+            LOG(SF_LOG_ERR, "buffer array full\r\n");
+            temp_bufferHeader->pBuffer = NULL;
+        }
+    }
+
+    if (temp_bufferHeader->pBuffer == NULL)
+    {
+        free(pBufInfo);
+        free(temp_bufferHeader);
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        return OMX_ErrorInsufficientResources;
+    }
+
+    *ppBuffer = temp_bufferHeader;
+    LOG(SF_LOG_INFO, "nPortIndex = %d, buffheader %p Buffer address = %p, nFilledLen = %d, nSizeBytes = %d\r\n",
+            nPortIndex, temp_bufferHeader, temp_bufferHeader->pBuffer, temp_bufferHeader->nFilledLen, nSizeBytes);
+    FunctionOut();
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_FreeBuffer(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_U32 nPortIndex,
+    OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr)
+{
+    SF_OMX_BUF_INFO *pBufInfo;
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+
+    FunctionIn();
+
+    if(pBufferHdr == NULL)
+        return OMX_ErrorBadParameter;
+    if(nPortIndex >= OMX_PORT_MAX)
+        return OMX_ErrorBadParameter;
+
+    if(nPortIndex == OMX_INPUT_PORT_INDEX)
+        pBufInfo = pBufferHdr->pInputPortPrivate;
+    else if(nPortIndex == OMX_OUTPUT_PORT_INDEX)
+        pBufInfo = pBufferHdr->pOutputPortPrivate;
+
+    LOG(SF_LOG_INFO, "free header %p pBuffer address = %p on port %d\r\n",
+                                            pBufferHdr, pBufferHdr->pBuffer, nPortIndex);
+
+    if ((pSfOMXComponent->traningState != OMX_TransStateIdleToLoaded) &&
+            (pSfOMXComponent->portDefinition[nPortIndex].bEnabled))
+    {
+        LOG(SF_LOG_INFO, "port Unpopulated\r\n");
+        pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
+                                                    OMX_EventError, OMX_ErrorPortUnpopulated, nPortIndex, NULL);
+    }
+
+    if(pBufInfo->type == SF_BUFFER_NOMAL)
+    {
+        if(pBufferHdr->pBuffer)
+            free(pBufferHdr->pBuffer);
+    }
+
+    pSfOMXComponent->pBufferArray[nPortIndex][pBufInfo->index] = NULL;
+    pSfOMXComponent->assignedBufferNum[nPortIndex]--;
+    LOG(SF_LOG_INFO, "remain %d buff port %d assgin\r\n",pSfOMXComponent->assignedBufferNum[nPortIndex], nPortIndex);
+
+    free(pBufferHdr);
+    free(pBufInfo);
+
+    if (pSfOMXComponent->assignedBufferNum[nPortIndex] == 0) {
+        LOG(SF_LOG_INFO, "unloadedResource signal set\r\n");
+        SF_SemaphorePost(pSfOMXComponent->portUnloadSemaphore[nPortIndex]);
+        pSfOMXComponent->portDefinition[nPortIndex].bPopulated = OMX_FALSE;
+    }
+
+    FunctionOut();
+    return OMX_ErrorNone;
+}
+
+static OMX_ERRORTYPE SF_OMX_GetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE nParamIndex,
+    OMX_INOUT OMX_PTR ComponentParameterStructure)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    SF_WAVE420L_IMPLEMEMT *pImp = (SF_WAVE420L_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    OMX_PARAM_PORTDEFINITIONTYPE *pOutputPort = &pSfOMXComponent->portDefinition[OMX_OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if (hComponent == NULL || ComponentParameterStructure == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    LOG(SF_LOG_INFO, "Get parameter on index %X\r\n", nParamIndex);
+    switch ((OMX_U32)nParamIndex)
+    {
+
+    case OMX_IndexParamVideoInit:
+    {
+        OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure;
+        portParam->nPorts           = OMX_PORT_MAX;
+        portParam->nStartPortNumber = OMX_INPUT_PORT_INDEX;
+        break;
+    }
+
+    case OMX_IndexParamAudioInit:
+    case OMX_IndexParamImageInit:
+    case OMX_IndexParamOtherInit:
+    {
+        OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure;
+        portParam->nPorts           = 0;
+        portParam->nStartPortNumber = 0;
+        break;
+    }
+
+    case OMX_IndexParamVideoPortFormat:
+    {
+        OMX_VIDEO_PARAM_PORTFORMATTYPE *portFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure;
+        OMX_U32 index = portFormat->nIndex;
+        LOG(SF_LOG_INFO, "Get video port format at index %d\r\n", index);
+        portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
+        portFormat->xFramerate = 30;
+        switch (index)
+        {
+        case 0:
+            portFormat->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+            break;
+        case 1:
+            portFormat->eColorFormat = OMX_COLOR_FormatYUV420Planar;
+            break;
+        case 2:
+            portFormat->eColorFormat = OMX_COLOR_FormatYVU420SemiPlanar;
+            break;
+        default:
+            if (index > 0)
+            {
+                ret = OMX_ErrorNoMore;
+            }
+            break;
+        }
+        break;
+    }
+
+    case OMX_IndexParamVideoBitrate:
+    {
+        OMX_VIDEO_PARAM_BITRATETYPE     *videoRateControl = (OMX_VIDEO_PARAM_BITRATETYPE *)ComponentParameterStructure;
+        OMX_U32                          portIndex = videoRateControl->nPortIndex;
+        if ((portIndex != OMX_OUTPUT_PORT_INDEX)) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+        else
+        {
+            videoRateControl->nTargetBitrate = pOutputPort->format.video.nBitrate;
+        }
+        LOG(SF_LOG_INFO, "Get nTargetBitrate = %u on port %d\r\n",videoRateControl->nTargetBitrate, videoRateControl->nPortIndex);
+        break;
+    }
+
+    case OMX_IndexParamVideoQuantization:
+        break;
+
+    case OMX_IndexParamPortDefinition:
+    {
+        OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
+        OMX_U32 portIndex = pPortDefinition->nPortIndex;
+
+        if (portIndex < OMX_PORT_MAX)
+        {
+            memcpy(pPortDefinition, &pSfOMXComponent->portDefinition[portIndex], pPortDefinition->nSize);
+            LOG(SF_LOG_DEBUG, "Get parameter port %X\r\n",portIndex);
+            LOG_APPEND(SF_LOG_DEBUG, "width = %d, height = %d\r\n", pPortDefinition->format.video.nFrameWidth, pPortDefinition->format.video.nFrameHeight);
+            LOG_APPEND(SF_LOG_DEBUG, "eColorFormat = %d\r\n", pPortDefinition->format.video.eColorFormat);
+            LOG_APPEND(SF_LOG_DEBUG, "xFramerate = %d\r\n", pPortDefinition->format.video.xFramerate);
+            LOG_APPEND(SF_LOG_DEBUG, "bufferSize = %d\r\n",pPortDefinition->nBufferSize);
+            LOG_APPEND(SF_LOG_DEBUG, "Buffer count = %d\r\n", pPortDefinition->nBufferCountActual);
+        }
+        else
+        {
+            LOG(SF_LOG_INFO,"Bad port index %d\r\n",portIndex);
+            ret = OMX_ErrorBadPortIndex;
+        }
+        break;
+    }
+
+    case OMX_IndexParamVideoIntraRefresh:
+        break;
+
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)ComponentParameterStructure;
+        strcpy((OMX_STRING)(pComponentRole->cRole), pSfOMXComponent->componentRule);
+        break;
+    }
+
+    case OMX_IndexParamVideoAvc:
+        break;
+
+    case OMX_IndexParamVideoHevc:
+    {
+        OMX_VIDEO_PARAM_HEVCTYPE *pDstHEVCComponent = (OMX_VIDEO_PARAM_HEVCTYPE *)ComponentParameterStructure;
+        OMX_U32 nPortIndex = pDstHEVCComponent->nPortIndex;
+        OMX_VIDEO_PARAM_HEVCTYPE *pSrcHEVCComponent = &pImp->HEVCComponent[nPortIndex];
+
+        LOG(SF_LOG_INFO, "Get nKeyFrameInterval = %d on port %d\r\n", pSrcHEVCComponent->nKeyFrameInterval, nPortIndex);
+        memcpy(pDstHEVCComponent, pSrcHEVCComponent, sizeof(OMX_VIDEO_PARAM_HEVCTYPE));
+        break;
+    }
+
+    case OMX_IndexParamVideoProfileLevelQuerySupported:
+        break;
+
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)ComponentParameterStructure;
+        LOG(SF_LOG_INFO, "Get ProfileLevel on port %d\r\n", pParam->nPortIndex);
+        if (pParam->nPortIndex == OMX_OUTPUT_PORT_INDEX)
+        {
+            //TODO
+            pParam->eProfile = OMX_VIDEO_HEVCProfileMain;
+            pParam->eLevel = OMX_VIDEO_HEVCMainTierLevel5;
+            LOG(SF_LOG_INFO, "eProfile = OMX_VIDEO_HEVCProfileMain\r\n");
+        }
+        break;
+    }
+
+    case OMX_IndexParamCompBufferSupplier:
+    {
+        OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE *)ComponentParameterStructure;
+        OMX_U32 portIndex = bufferSupplier->nPortIndex;
+        if (portIndex >= OMX_PORT_MAX)
+            ret = OMX_ErrorBadPortIndex;
+        break;
+    }
+
+    default:
+    {
+        ret = OMX_ErrorUnsupportedIndex;
+        break;
+    }
+
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_SetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE nIndex,
+    OMX_IN OMX_PTR ComponentParameterStructure)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+    if (hComponent == NULL || ComponentParameterStructure == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    SF_WAVE420L_IMPLEMEMT *pImp = (SF_WAVE420L_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    OMX_PARAM_PORTDEFINITIONTYPE *pInputPort = &pSfOMXComponent->portDefinition[OMX_INPUT_PORT_INDEX];
+    OMX_PARAM_PORTDEFINITIONTYPE *pOutputPort = &pSfOMXComponent->portDefinition[OMX_OUTPUT_PORT_INDEX];
+
+    if (pSfOMXComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    LOG(SF_LOG_INFO, "Set parameter on index %X\r\n", nIndex);
+
+    switch ((OMX_U32)nIndex)
+    {
+    case OMX_IndexParamPortDefinition:
+    {
+        OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
+        OMX_U32 portIndex = pPortDefinition->nPortIndex;
+        OMX_U32 width = pPortDefinition->format.video.nFrameWidth;
+        OMX_U32 height = pPortDefinition->format.video.nFrameHeight;
+        OMX_U32 nBitrate = pPortDefinition->format.video.nBitrate;
+        OMX_U32 xFramerate = pPortDefinition->format.video.xFramerate;
+        OMX_U32 bufFrameWidth, bufFrameHeight, bufFrameStride;
+        OMX_U32 nBufferCountActual = pPortDefinition->nBufferCountActual;
+        LOG(SF_LOG_INFO, "Set width = %d, height = %d, xFramerate = %d, nBitrate = %d, nBufferCountActual = %d on port %d\r\n",
+            width, height, xFramerate, nBitrate, nBufferCountActual, portIndex);
+        OMX_COLOR_FORMATTYPE eColorFormat = pPortDefinition->format.video.eColorFormat;
+
+        if (xFramerate == 0)
+        {
+            LOG(SF_LOG_ERR, "Fail to set xFramerate = %d\r\n", xFramerate);
+            return OMX_ErrorBadParameter;
+        }
+        pImp->tmpFramerate = xFramerate;
+        if (portIndex == OMX_INPUT_PORT_INDEX)
+        {
+            switch (eColorFormat)
+            {
+            case OMX_COLOR_FormatYUV420Planar:
+                pImp->encConfig.cbcrInterleave = OMX_FALSE;
+                pImp->encConfig.nv21 = OMX_FALSE;
+                pImp->encConfig.srcFormat = FORMAT_420;
+                pImp->encConfig.packedFormat = NOT_PACKED;
+                break;
+            case OMX_COLOR_FormatYUV420SemiPlanar:
+                pImp->encConfig.cbcrInterleave = OMX_TRUE;
+                pImp->encConfig.nv21 = OMX_FALSE;
+                pImp->encConfig.srcFormat = FORMAT_420;
+                pImp->encConfig.packedFormat = NOT_PACKED;
+                break;
+            case OMX_COLOR_FormatYVU420SemiPlanar:
+                pImp->encConfig.cbcrInterleave = OMX_TRUE;
+                pImp->encConfig.nv21 = OMX_TRUE;
+                pImp->encConfig.srcFormat = FORMAT_420;
+                pImp->encConfig.packedFormat = NOT_PACKED;
+                break;
+            default:
+                ret = OMX_ErrorBadParameter;
+                break;
+            }
+            if(ret)
+                return ret;
+
+            memcpy(pInputPort, pPortDefinition, pPortDefinition->nSize);
+            pImp->encConfig.picWidth = width;
+            pImp->encConfig.picHeight = height;
+            bufFrameWidth  = ((width+7)&~7);        // width = 8-aligned (CU unit)
+            bufFrameHeight = ((height+7)&~7);       // height = 8-aligned (CU unit)
+            bufFrameStride = Warp_CalcStride(pImp, bufFrameWidth, bufFrameHeight, pImp->encConfig.srcFormat,
+                    pImp->encConfig.cbcrInterleave, LINEAR_FRAME_MAP, FALSE);
+
+            pInputPort->nBufferSize = Warp_VPU_GetFrameBufSize(pImp, pImp->coreIdx, bufFrameStride, bufFrameHeight,
+                    LINEAR_FRAME_MAP, pImp->encConfig.srcFormat, pImp->encConfig.cbcrInterleave, NULL);
+
+            LOG(SF_LOG_INFO, "alloc buff size %d on port %d\r\n",
+                    pInputPort->nBufferSize, portIndex);
+        }
+        else if (portIndex == OMX_OUTPUT_PORT_INDEX)
+        {
+            memcpy(pOutputPort, pPortDefinition, pPortDefinition->nSize);
+            pOutputPort->format.video.nStride = width;
+            pOutputPort->format.video.nSliceHeight = height;
+            pOutputPort->nBufferSize = width * height * 2;
+        }
+        else
+        {
+            LOG(SF_LOG_INFO,"Bad port index %d\r\n",portIndex);
+            ret = OMX_ErrorBadPortIndex;
+        }
+        break;
+    }
+
+    case OMX_IndexParamVideoPortFormat:
+    {
+        OMX_VIDEO_PARAM_PORTFORMATTYPE *portFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure;
+        OMX_COLOR_FORMATTYPE eColorFormat = portFormat->eColorFormat;
+        OMX_U32 nPortIndex = portFormat->nPortIndex;
+        OMX_PARAM_PORTDEFINITIONTYPE *pPort = &pSfOMXComponent->portDefinition[nPortIndex];
+        LOG(SF_LOG_INFO, "Set eColorFormat to %d\r\n", eColorFormat);
+
+        if (nPortIndex >= OMX_PORT_MAX)
+            return OMX_ErrorBadPortIndex;
+
+        pPort = &pSfOMXComponent->portDefinition[nPortIndex];
+
+        switch (eColorFormat)
+        {
+        case OMX_COLOR_FormatYUV420Planar:
+            pImp->encConfig.cbcrInterleave = OMX_FALSE;
+            pImp->encConfig.nv21 = OMX_FALSE;
+            pImp->encConfig.srcFormat = FORMAT_420;
+            pImp->encConfig.packedFormat = NOT_PACKED;
+            break;
+        case OMX_COLOR_FormatYUV420SemiPlanar:
+            pImp->encConfig.cbcrInterleave = OMX_TRUE;
+            pImp->encConfig.nv21 = OMX_FALSE;
+            pImp->encConfig.srcFormat = FORMAT_420;
+            pImp->encConfig.packedFormat = NOT_PACKED;
+            break;
+        case OMX_COLOR_FormatYVU420SemiPlanar:
+            pImp->encConfig.cbcrInterleave = OMX_TRUE;
+            pImp->encConfig.nv21 = OMX_TRUE;
+            pImp->encConfig.srcFormat = FORMAT_420;
+            pImp->encConfig.packedFormat = NOT_PACKED;
+            break;
+        default:
+            ret = OMX_ErrorBadParameter;
+            break;
+        }
+        if(!ret){
+            pPort->format.video.eColorFormat = eColorFormat;
+        }
+        break;
+    }
+
+    case OMX_IndexParamVideoBitrate:
+    {
+        OMX_VIDEO_PARAM_BITRATETYPE     *videoRateControl = (OMX_VIDEO_PARAM_BITRATETYPE *)ComponentParameterStructure;
+        OMX_U32                          portIndex = videoRateControl->nPortIndex;
+
+        LOG(SF_LOG_INFO, "Set nTargetBitrate = %u on port %d\r\n",videoRateControl->nTargetBitrate, portIndex);
+
+        if ((portIndex != 1)) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+        else
+        {
+            pOutputPort->format.video.nBitrate = videoRateControl->nTargetBitrate;
+        }
+        ret = OMX_ErrorNone;
+        break;
+    }
+
+    case OMX_IndexConfigVideoAVCIntraPeriod:
+    {
+        break;
+    }
+
+    case OMX_IndexParamVideoAvc:
+    {
+        break;
+    }
+
+    case OMX_IndexParamVideoHevc:
+    {
+        OMX_VIDEO_PARAM_HEVCTYPE *pSrcHEVCComponent= (OMX_VIDEO_PARAM_HEVCTYPE *)ComponentParameterStructure;
+        OMX_U32 nPortIndex = pSrcHEVCComponent->nPortIndex;
+        OMX_VIDEO_PARAM_HEVCTYPE *pDstHEVCComponent = &pImp->HEVCComponent[nPortIndex];
+        OMX_U32 nKeyFrameInterval = pSrcHEVCComponent->nKeyFrameInterval;
+
+        LOG(SF_LOG_INFO, "Set nKeyFrameInterval = %d on port %d\r\n", nKeyFrameInterval, nPortIndex);
+        if (nKeyFrameInterval == 1)
+        {
+            LOG(SF_LOG_ERR, "Set nKeyFrameInterval = %d not supported!\r\n", nKeyFrameInterval);
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+        memcpy(pDstHEVCComponent, pSrcHEVCComponent, sizeof(OMX_VIDEO_PARAM_HEVCTYPE));
+        break;
+    }
+
+    case OMX_IndexParamStandardComponentRole:
+    {
+        if ((pSfOMXComponent->state != OMX_StateLoaded) &&
+                (pSfOMXComponent->state != OMX_StateWaitForResources)) {
+            ret = OMX_ErrorIncorrectStateOperation;
+        }
+        break;
+    }
+
+    case OMX_IndexParamCompBufferSupplier:
+    {
+        OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE *)ComponentParameterStructure;
+        OMX_U32 portIndex = bufferSupplier->nPortIndex;
+        if (portIndex >= OMX_PORT_MAX)
+            ret = OMX_ErrorBadPortIndex;
+        break;
+    }
+
+    case OMX_IndexParamVideoQuantization:
+    case OMX_IndexParamVideoIntraRefresh:
+        break;
+
+    default:
+        ret = OMX_ErrorUnsupportedIndex;
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_SendCommand(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_COMMANDTYPE Cmd,
+    OMX_IN OMX_U32 nParam,
+    OMX_IN OMX_PTR pCmdData)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    SF_WAVE420L_IMPLEMEMT *pImp = (SF_WAVE420L_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    OMX_STATETYPE comCurrentState;
+    SF_OMX_CMD cmd;
+
+    FunctionIn();
+    if (hComponent == NULL || pSfOMXComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    LOG(SF_LOG_INFO, "cmd = %X, nParam = %X\r\n", Cmd, nParam);
+
+    comCurrentState = pSfOMXComponent->state;
+
+    if (comCurrentState == OMX_StateInvalid) {
+        return OMX_ErrorInvalidState;
+    }
+
+    switch (Cmd)
+    {
+    case OMX_CommandStateSet:
+    {
+        if ((nParam == OMX_StateLoaded) &&
+            (pSfOMXComponent->state == OMX_StateIdle))
+        {
+            pSfOMXComponent->traningState = OMX_TransStateIdleToLoaded;
+        }
+        else if ((nParam == OMX_StateIdle) &&
+            (pSfOMXComponent->state == OMX_StateLoaded))
+        {
+            pSfOMXComponent->traningState = OMX_TransStateLoadedToIdle;
+        }
+    }
+    break;
+
+    case OMX_CommandFlush:
+    {
+        if (nParam >= 2 && nParam != OMX_ALL)
+            return OMX_ErrorBadPortIndex;
+    }
+    break;
+
+    case OMX_CommandMarkBuffer:
+    {
+        if (nParam >= 2)
+            return OMX_ErrorBadPortIndex;
+        if ((pSfOMXComponent->state != OMX_StateExecuting) &&
+            (pSfOMXComponent->state != OMX_StatePause))
+            return OMX_ErrorIncorrectStateOperation;
+    }
+    break;
+
+    case OMX_CommandPortDisable:
+    {
+        if (nParam >= 2 && nParam != OMX_ALL)
+            return OMX_ErrorBadPortIndex;
+
+        if (nParam == OMX_ALL)
+        {
+            for (int i = 0; i < 2; i++)
+            {
+                if(pSfOMXComponent->portDefinition[i].bEnabled == OMX_FALSE)
+                    return OMX_ErrorIncorrectStateOperation;
+            }
+            for (int i = 0; i < 2; i++)
+            {
+                pSfOMXComponent->portDefinition[i].bEnabled = OMX_FALSE;
+            }
+        }
+        else
+        {
+            if (pSfOMXComponent->portDefinition[nParam].bEnabled == OMX_FALSE)
+                return OMX_ErrorIncorrectStateOperation;
+            pSfOMXComponent->portDefinition[nParam].bEnabled = OMX_FALSE;
+        }
+    }
+    break;
+
+    case OMX_CommandPortEnable:
+    {
+        if (nParam >= 2 && nParam != OMX_ALL)
+            return OMX_ErrorBadPortIndex;
+
+        if (nParam == OMX_ALL)
+        {
+            for (int i = 0; i < 2; i++)
+            {
+                if(pSfOMXComponent->portDefinition[i].bEnabled == OMX_TRUE)
+                    return OMX_ErrorIncorrectStateOperation;
+            }
+            for (int i = 0; i < 2; i++)
+            {
+                pSfOMXComponent->portDefinition[i].bEnabled = OMX_TRUE;
+            }
+        }
+        else
+        {
+            if (pSfOMXComponent->portDefinition[nParam].bEnabled == OMX_TRUE)
+                return OMX_ErrorIncorrectStateOperation;
+            pSfOMXComponent->portDefinition[nParam].bEnabled = OMX_TRUE;
+        }
+    }
+    break;
+
+    default:
+    break;
+    }
+
+    cmd.Cmd = Cmd;
+    cmd.nParam = nParam;
+    cmd.pCmdData = pCmdData;
+
+    ret = SF_Queue_Enqueue(pImp->CmdQueue, &cmd);
+
+EXIT:
+    FunctionOut();
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_GetState(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_OUT OMX_STATETYPE *pState)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+
+    FunctionIn();
+    *pState = pSfOMXComponent->state;
+    FunctionOut();
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_GetConfig(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE nIndex,
+    OMX_PTR pComponentConfigStructure)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if (hComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    switch (nIndex)
+    {
+    case OMX_IndexConfigVideoBitrate:
+        break;
+    case OMX_IndexConfigVideoFramerate:
+        break;
+    default:
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_SetConfig(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE nIndex,
+    OMX_PTR pComponentConfigStructure)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if (hComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    switch ((OMX_U32)nIndex)
+    {
+    case OMX_IndexConfigVideoBitrate:
+        break;
+    case OMX_IndexConfigVideoFramerate:
+        break;
+    case OMX_IndexConfigVideoIntraVOPRefresh:
+        break;
+    default:
+
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_GetComponentVersion(
+    OMX_IN  OMX_HANDLETYPE   hComponent,
+    OMX_OUT OMX_STRING       pComponentName,
+    OMX_OUT OMX_VERSIONTYPE *pComponentVersion,
+    OMX_OUT OMX_VERSIONTYPE *pSpecVersion,
+    OMX_OUT OMX_UUIDTYPE    *pComponentUUID)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE *pOMXComponent = NULL;
+    SF_OMX_COMPONENT *pSfOMXComponent = NULL;
+    OMX_U32 compUUID[4];
+
+    FunctionIn();
+
+    /* check parameters */
+    if (hComponent     == NULL ||
+        pComponentName == NULL || pComponentVersion == NULL ||
+        pSpecVersion   == NULL || pComponentUUID    == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pSfOMXComponent = (SF_OMX_COMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pSfOMXComponent->state == OMX_StateInvalid) {
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    strcpy(pComponentName, pSfOMXComponent->componentName);
+    memcpy(pComponentVersion, &(pSfOMXComponent->componentVersion), sizeof(OMX_VERSIONTYPE));
+    memcpy(pSpecVersion, &(pSfOMXComponent->specVersion), sizeof(OMX_VERSIONTYPE));
+
+    /* Fill UUID with handle address, PID and UID.
+     * This should guarantee uiniqness */
+    compUUID[0] = (OMX_U32)pOMXComponent;
+    compUUID[1] = (OMX_U32)pOMXComponent;
+    compUUID[2] = (OMX_U32)pOMXComponent;
+    compUUID[3] = (OMX_U32)pOMXComponent;
+    //compUUID[1] = getpid();
+    //compUUID[2] = getuid();
+    memcpy(*pComponentUUID, compUUID, 4 * sizeof(*compUUID));
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_U32 nInstance = 0;
+
+static OMX_ERRORTYPE SF_OMX_ComponentConstructor(SF_OMX_COMPONENT *pSfOMXComponent)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if (nInstance >= MAX_NUM_INSTANCE)
+    {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    nInstance++;
+
+    ret = WaveOmxInit(pSfOMXComponent);
+    if (ret != OMX_ErrorNone)
+    {
+        nInstance--;
+        goto EXIT;
+    }
+
+    pSfOMXComponent->pOMXComponent->UseBuffer = &SF_OMX_UseBuffer;
+    pSfOMXComponent->pOMXComponent->AllocateBuffer = &SF_OMX_AllocateBuffer;
+    pSfOMXComponent->pOMXComponent->EmptyThisBuffer = &SF_OMX_EmptyThisBuffer;
+    pSfOMXComponent->pOMXComponent->FillThisBuffer = &SF_OMX_FillThisBuffer;
+    pSfOMXComponent->pOMXComponent->FreeBuffer = &SF_OMX_FreeBuffer;
+    pSfOMXComponent->pOMXComponent->ComponentTunnelRequest = &SF_OMX_ComponentTunnelRequest;
+    pSfOMXComponent->pOMXComponent->GetParameter = &SF_OMX_GetParameter;
+    pSfOMXComponent->pOMXComponent->SetParameter = &SF_OMX_SetParameter;
+    pSfOMXComponent->pOMXComponent->GetConfig = &SF_OMX_GetConfig;
+    pSfOMXComponent->pOMXComponent->SetConfig = &SF_OMX_SetConfig;
+    pSfOMXComponent->pOMXComponent->SendCommand = &SF_OMX_SendCommand;
+    pSfOMXComponent->pOMXComponent->GetState = &SF_OMX_GetState;
+    pSfOMXComponent->pOMXComponent->GetComponentVersion = &SF_OMX_GetComponentVersion;
+    // pSfOMXComponent->pOMXComponent->GetExtensionIndex = &SF_OMX_GetExtensionIndex;
+    // pSfOMXComponent->pOMXComponent->ComponentRoleEnum = &SF_OMX_ComponentRoleEnum;
+    // pSfOMXComponent->pOMXComponent->ComponentDeInit = &SF_OMX_ComponentDeInit;
+
+    //InitEncoder(pSfOMXComponent);
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_ComponentClear(SF_OMX_COMPONENT *pSfOMXComponent)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    SF_WAVE420L_IMPLEMEMT *pImp = (SF_WAVE420L_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    SF_OMX_CMD cmd;
+    void *pNull = NULL;
+    void *ThreadRet = NULL;
+
+    FunctionIn();
+
+    if(pImp->bThreadRunning)
+    {
+        pImp->bThreadRunning = 0;
+        /* enqueue null mean encoder thread cycle end */
+        SF_Queue_Enqueue(pImp->EmptyQueue, &pNull);
+        SF_Queue_Enqueue(pImp->FillQueue, &pNull);
+        pthread_join(pImp->pProcessThread->pthread, &ThreadRet);
+        LOG(SF_LOG_INFO, "Encoder thread end %ld\r\n", (Uint64)ThreadRet);
+        SF_Queue_Flush(pImp->EmptyQueue);
+        SF_Queue_Flush(pImp->FillQueue);
+        SF_Queue_Destroy(pImp->EmptyQueue);
+        SF_Queue_Destroy(pImp->FillQueue);
+    }
+
+    pImp->bCmdRunning = 0;
+    /* enqueue OMX_Command_StopThread mean cmd thread cycle end */
+    cmd.Cmd = OMX_Command_StopThread;
+    SF_Queue_Enqueue(pImp->CmdQueue, &cmd);
+    pthread_cancel(pImp->pCmdThread->pthread);
+	pthread_join(pImp->pCmdThread->pthread, &ThreadRet);
+    LOG(SF_LOG_INFO, "Cmd thread end %ld\r\n", (Uint64)ThreadRet);
+    SF_Queue_Destroy(pImp->CmdQueue);
+    SF_Queue_Destroy(pImp->pauseQ);
+
+    //Warp_VPU_DeInit(pImp, pImp->coreIdx);
+
+    nInstance--;
+
+    FunctionOut();
+
+    return ret;
+}
+
+SF_OMX_COMPONENT sf_enc_encoder_h265 = {
+    .componentName = "OMX.sf.video_encoder.hevc",
+    .libName = "libsfenc.so",
+    .pOMXComponent = NULL,
+    .SF_OMX_ComponentConstructor = SF_OMX_ComponentConstructor,
+    .SF_OMX_ComponentClear = SF_OMX_ComponentClear,
+    // .bitFormat = STD_HEVC,
+    .componentImpl = NULL,
+    .fwPath = "/lib/firmware/monet.bin",
+    .componentRule = "video_encoder.hevc"};

+ 268 - 0
omx-il/component/video/wave4/SF_OMX_Wave420L_encoder.h

@@ -0,0 +1,268 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ */
+#ifndef SF_OMX_WAVE4_ENC
+#define SF_OMX_WAVE4_ENC
+
+
+#include "OMX_Component.h"
+#include "OMX_Video.h"
+#include "OMX_Index.h"
+#include "OMX_IndexExt.h"
+#include "SF_OMX_Core.h"
+#include <sys/queue.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+#include <pthread.h>
+#include <errno.h>
+
+#include "sf_queue.h"
+#include "sf_thread.h"
+#include "sf_semaphore.h"
+#include "wave420l/sample/helper/main_helper.h"
+#include "wave420l/vpuapi/vpuapi.h"
+
+
+#define INIT_SET_SIZE_VERSION(_struct_, _structType_) \
+    do                                                \
+    {                                                 \
+        memset((_struct_), 0, sizeof(_structType_));  \
+        (_struct_)->nSize = sizeof(_structType_);     \
+        (_struct_)->nVersion.s.nVersionMajor = 1;     \
+        (_struct_)->nVersion.s.nVersionMinor = 18;    \
+        (_struct_)->nVersion.s.nRevision = 1;         \
+        (_struct_)->nVersion.s.nStep = 0;             \
+    } while (0)
+
+#define NUM_OF_PORTS 2
+
+#define DEFAULT_FRAME_WIDTH 1920
+#define DEFAULT_FRAME_HEIGHT 1080
+#define DEFAULT_MJPEG_INPUT_BUFFER_SIZE (DEFAULT_FRAME_WIDTH * DEFAULT_FRAME_HEIGHT * 3)
+#define DEFAULT_MJPEG_OUTPUT_BUFFER_SIZE (DEFAULT_FRAME_WIDTH * DEFAULT_FRAME_HEIGHT * 3)
+#define DEFAULT_FRAMERATE 30
+#define DEFAULT_GOP 30
+#define DEFAULT_FRAME_FORMAT FORMAT_420
+
+#define WAVE_DEFAULT_INPUT_BUF_NUMBER 8
+#define WAVE_DEFAULT_OUTPUT_BUF_NUMBER 8
+#define DEFAULT_BS_BUFF 1
+
+typedef struct _SF_W420L_FUNCTIONS
+{
+    Int32 (*VPU_GetProductId)(Int32 coreIdx);
+    RetCode (*VPU_GetVersionInfo)(Uint32 coreIdx, Uint32 *versionInfo, Uint32 *revision, Uint32 *productId);
+    RetCode (*VPU_InitWithBitcode)(Uint32 coreIdx, const Uint16* code, Uint32 size);
+    RetCode (*VPU_DeInit)(Uint32 coreIdx);
+    Int32 (*GetEncOpenParam)(EncOpenParam *pEncOP, TestEncConfig *pEncConfig, ENC_CFG *pEncCfg);
+    Int32 (*GetEncOpenParamDefault)(EncOpenParam *pEncOP, TestEncConfig *pEncConfig);
+    RetCode (*VPU_EncOpen)(EncHandle* pHandle, EncOpenParam * pop);
+    RetCode (*VPU_EncClose)(EncHandle handle);
+    Int32 (*VPU_GetFrameBufSize)(Int32 coreIdx, Int32 stride, Int32 height, Int32 mapType, Int32 format, Int32 interleave, DRAMConfig *pDramCfg);
+    RetCode (*VPU_EncRegisterFrameBuffer)(EncHandle handle, FrameBuffer* bufArray, Int32 num, Int32 stride, Int32 height, Int32 mapType);
+    RetCode (*VPU_EncAllocateFrameBuffer)(EncHandle handle, FrameBufferAllocInfo info, FrameBuffer *frameBuffer);
+    RetCode (*VPU_EncGiveCommand)(EncHandle handle, CodecCommand cmd, void* param);
+    RetCode (*VPU_EncGetInitialInfo)(EncHandle handle, EncInitialInfo * info);
+    RetCode (*VPU_SWReset)(Uint32 coreIdx, SWResetMode resetMode, void *pendingInst);
+    RetCode (*VPU_EncStartOneFrame)(EncHandle handle, EncParam * param);
+    Int32 (*VPU_WaitInterrupt)(Uint32 coreIdx, Int32 timeout);
+    void (*VPU_ClearInterrupt)(Uint32 coreIdx);
+    RetCode (*VPU_EncGetOutputInfo)(EncHandle handle, EncOutputInfo* info);
+
+    int (*vdi_allocate_dma_memory)(unsigned long core_idx, vpu_buffer_t *vb);
+    void (*vdi_free_dma_memory)(unsigned long core_idx, vpu_buffer_t *vb);
+
+    YuvFeeder (*YuvFeeder_Create)(Uint32 type, const char* srcFilePath, YuvInfo yuvInfo);
+    BOOL (*YuvFeeder_Feed)(YuvFeeder feeder, Uint32 coreIdx, FrameBuffer* fb, size_t picWidth, size_t picHeight, void* arg);
+    BOOL (*YuvFeeder_Destroy)(YuvFeeder feeder);
+    BitstreamReader (*BufferStreamReader_Create)(Uint32 type, EndianMode endian, EncHandle* handle);
+    BOOL (*BufferStreamReader_Act)(BitstreamReader reader, PhysicalAddress bitstreamBuffer, Uint32 bitstreamBufferSize, Uint32 streamReadSize, Uint8* pBuffer,Comparator comparator);
+    BOOL (*BufferStreamReader_Destroy)(BitstreamReader reader);
+    Comparator (*Comparator_Create)(Uint32 type, char* goldenPath, ...);
+    BOOL (*Comparator_Destroy)(Comparator  comp);
+    BOOL (*Comparator_CheckEOF)(Comparator  comp);
+
+    void (*DisplayEncodedInformation)(EncHandle handle, CodStd codec, Uint32 frameNo, EncOutputInfo* encodedInfo, ...);
+    void (*PrintVpuVersionInfo)(Uint32 core_idx);
+    Int32 (*CalcStride)(Uint32 width, Uint32 height, FrameBufferFormat format, BOOL cbcrInterleave, TiledMapType mapType, BOOL isVP9);
+    Int32 (*GetPackedFormat) (Int32 srcBitDepth, Int32 packedType, Int32 p10bits,Int32 msb);
+    Int32 (*LoadFirmware)(Int32 productId, Uint8** retFirmware, Uint32* retSizeInWord, const char* path);
+
+    void (*SetMaxLogLevel)(int level);
+    RetCode (*EnterLock)(Uint32 coreIdx);
+    RetCode (*LeaveLock)(Uint32 coreIdx);
+    void (*PrintVpuStatus)(Uint32 coreIdx, Uint32 productId);
+}SF_W420L_FUNCTIONS;
+
+
+typedef struct Message
+{
+    long msg_type;
+    OMX_U32 msg_flag;
+    OMX_BUFFERHEADERTYPE *pBuffer;
+} Message;
+
+typedef struct SF_OMX_CMD
+{
+    OMX_COMMANDTYPE Cmd;
+    OMX_U32 nParam;
+    OMX_PTR pCmdData;
+}SF_OMX_CMD;
+
+enum port_index
+{
+    OMX_INPUT_PORT_INDEX = 0,
+    OMX_OUTPUT_PORT_INDEX = 1,
+    OMX_PORT_MAX = 2,
+};
+
+typedef struct _SF_WAVE420L_IMPLEMEMT
+{
+    EncHandle           handle;
+    SF_W420L_FUNCTIONS *functions;
+    BSFeeder            feeder;
+    vpu_buffer_t        vbSourceFrameBuf[ENC_SRC_BUF_NUM];
+    vpu_buffer_t        vbReconFrameBuf[MAX_REG_FRAME];
+    vpu_buffer_t        vbStream[MAX_REG_FRAME];
+    FrameBuffer         fbSrc[ENC_SRC_BUF_NUM];
+    FrameBuffer         fbRecon[MAX_REG_FRAME];
+    Int32               regFrameBufCount;
+    Int32               bsBufferCount;
+    EncOpenParam        encOP;
+    TestEncConfig       encConfig;
+    EncInitialInfo      initialInfo;
+    EncOutputInfo       outputInfo;
+    Int32               instIdx;
+    Int32               coreIdx;
+    Uint32              tmpFramerate;
+    Uint64              tmpCounter;
+    SF_Queue            *EmptyQueue;
+    SF_Queue            *FillQueue;
+    SF_Queue            *CmdQueue;
+    SF_Queue            *pauseQ;
+    OMX_HANDLETYPE      pauseSemaphore;
+    OMX_VIDEO_PARAM_HEVCTYPE HEVCComponent[2];
+
+    THREAD_HANDLE_TYPE *pProcessThread;
+    THREAD_HANDLE_TYPE *pCmdThread;
+    OMX_BOOL bThreadRunning;
+    OMX_BOOL bCmdRunning;
+    OMX_BOOL bPause;
+    OMX_STATETYPE currentState;
+} SF_WAVE420L_IMPLEMEMT;
+
+
+/* Warper functions marco */
+#define Warp_VPU_GetProductId(Implement, coreIdx) \
+    Implement->functions->VPU_GetProductId(coreIdx)
+
+#define Warp_VPU_GetVersionInfo(Implement, coreIdx, pVersionInfo, pRevision, pProductId) \
+    Implement->functions->VPU_GetVersionInfo(coreIdx, pVersionInfo, pRevision, pProductId)
+
+#define Warp_VPU_InitWithBitcode(Implement, coreIdx, pCode, size) \
+    Implement->functions->VPU_InitWithBitcode(coreIdx, pCode, size)
+
+#define Warp_VPU_DeInit(Implement, coreIdx) \
+    Implement->functions->VPU_DeInit(coreIdx)
+
+#define Warp_GetEncOpenParam(Implement, pEncOP, pEncConfig, pEncCfg) \
+    Implement->functions->GetEncOpenParam(pEncOP, pEncConfig, pEncCfg)
+
+#define Warp_GetEncOpenParamDefault(Implement, pEncOP, pEncConfig) \
+    Implement->functions->GetEncOpenParamDefault(pEncOP, pEncConfig)
+
+#define Warp_VPU_EncOpen(Implement, pHandle, pop) \
+    Implement->functions->VPU_EncOpen(pHandle, pop)
+
+#define Warp_VPU_EncClose(Implement, handle) \
+    Implement->functions->VPU_EncClose(handle)
+
+#define Warp_VPU_GetFrameBufSize(Implement, coreIdx, stride, height, mapType, format, interleave, pDramCfg) \
+    Implement->functions->VPU_GetFrameBufSize(coreIdx, stride, height, mapType, format, interleave, pDramCfg)
+
+#define Warp_VPU_EncRegisterFrameBuffer(Implement, handle, bufArray, num, stride, height, mapType)\
+    Implement->functions->VPU_EncRegisterFrameBuffer(handle, bufArray, num, stride, height, mapType)
+
+#define Warp_VPU_EncAllocateFrameBuffer(Implement, handle, info, pframeBuffer) \
+    Implement->functions->VPU_EncAllocateFrameBuffer(handle, info, pframeBuffer)
+
+#define Warp_VPU_EncGiveCommand(Implement, handle, cmd, param) \
+    Implement->functions->VPU_EncGiveCommand(handle, cmd, param)
+
+#define Warp_VPU_EncGetInitialInfo(Implement, handle, pInfo) \
+    Implement->functions->VPU_EncGetInitialInfo(handle, pInfo)
+
+#define Warp_VPU_SWReset(Implement, coreIdx, resetMode, pendingInst) \
+    Implement->functions->VPU_SWReset(coreIdx, resetMode, pendingInst)
+
+#define Warp_VPU_EncStartOneFrame(Implement, handle, param) \
+    Implement->functions->VPU_EncStartOneFrame(handle, param)
+
+#define Warp_VPU_WaitInterrupt(Implement, coreIdx, timeout) \
+    Implement->functions->VPU_WaitInterrupt(coreIdx, timeout)
+
+#define Warp_VPU_ClearInterrupt(Implement, coreIdx) \
+    Implement->functions->VPU_ClearInterrupt(coreIdx)
+
+#define Warp_VPU_EncGetOutputInfo(Implement, handle, info) \
+    Implement->functions->VPU_EncGetOutputInfo(handle, info)
+
+#define Warp_vdi_allocate_dma_memory(Implement, core_idx, vb) \
+    Implement->functions->vdi_allocate_dma_memory(core_idx, vb)
+
+#define Warp_vdi_free_dma_memory(Implement, core_idx, vb) \
+    Implement->functions->vdi_free_dma_memory(core_idx, vb)
+
+#define Warp_YuvFeeder_Create(Implement, type, srcFilePath, yuvInfo) \
+    Implement->functions->YuvFeeder_Create(type, srcFilePath, yuvInfo)
+
+#define Warp_YuvFeeder_Feed(Implement, feeder, coreIdx, fb, picWidth, picHeight, arg) \
+    Implement->functions->YuvFeeder_Feed(feeder, coreIdx, fb, picWidth, picHeight, arg)
+
+#define Warp_YuvFeeder_Destroy(Implement, feeder) \
+    Implement->functions->YuvFeeder_Destroy(feeder)
+
+#define Warp_BufferStreamReader_Create(Implement, type, endian, handle) \
+    Implement->functions->BufferStreamReader_Create(type, endian, handle)
+
+#define Warp_BufferStreamReader_Act(Implement, reader, bitstreamBuffer, bitstreamBufferSize, streamReadSize, pBuffer, comparator) \
+    Implement->functions->BufferStreamReader_Act(reader, bitstreamBuffer, bitstreamBufferSize, streamReadSize, pBuffer, comparator)
+
+#define Warp_BufferStreamReader_Destroy(Implement, reader) \
+    Implement->functions->BufferStreamReader_Destroy(reader)
+
+#define Warp_Comparator_Create(Implement, type, goldenPath, ...) \
+    Implement->functions->Comparator_Create(type, goldenPath, __VA_ARGS__)
+
+#define Warp_Comparator_Destroy(Implement, comp) \
+    Implement->functions->Comparator_Destroy(comp)
+
+#define Warp_Comparator_CheckEOF(Implement, comp) \
+    Implement->functions->Comparator_CheckEOF(comp)
+
+#define Warp_DisplayEncodedInformation(Implement, handle, codec, frameNo, encodedInfo, ...) \
+    Implement->functions->DisplayEncodedInformation(handle, codec, frameNo, encodedInfo, __VA_ARGS__)
+
+#define Warp_PrintVpuVersionInfo(Implement, core_idx) \
+    Implement->functions->PrintVpuVersionInfo(core_idx)
+
+#define Warp_CalcStride(Implement, width, height, format, cbcrInterleave, mapType, isVP9) \
+    Implement->functions->CalcStride(width, height, format, cbcrInterleave, mapType, isVP9)
+
+#define Warp_LoadFirmware(Implement, productId, retFirmware, retSizeInWord, path) \
+    Implement->functions->LoadFirmware(productId, retFirmware, retSizeInWord, path)
+
+#define Warp_SetMaxLogLevel(Implement, level) \
+    Implement->functions->SetMaxLogLevel(level)
+
+#define Warp_EnterLock(Implement, coreIdx) \
+    Implement->functions->EnterLock(coreIdx)
+
+#define Warp_LeaveLock(Implement, coreIdx) \
+    Implement->functions->LeaveLock(coreIdx)
+
+#define Warp_PrintVpuStatus(Implement, coreIdx, productId) \
+    Implement->functions->PrintVpuStatus(coreIdx, productId)
+
+#endif //SF_OMX_WAVE4_ENC

+ 561 - 0
omx-il/component/video/wave5/common/SF_OMX_video_common.c

@@ -0,0 +1,561 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 StarFive Technology Co., Ltd.
+ */
+#include "SF_OMX_video_common.h"
+
+extern SF_OMX_COMPONENT *sf_omx_component_list[];
+static void sf_get_component_functions(SF_COMPONENT_FUNCTIONS *funcs, OMX_PTR *sohandle);
+
+OMX_ERRORTYPE GetStateCommon(OMX_IN OMX_HANDLETYPE hComponent, OMX_OUT OMX_STATETYPE *pState)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE *pOMXComponent = NULL;
+    SF_OMX_COMPONENT *pSfOMXComponent = NULL;
+    ComponentState state;
+    OMX_STATETYPE comState;
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = NULL;
+    FunctionIn();
+    if (hComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    comState = pSfOMXComponent->state;
+    state = pSfVideoImplement->functions->ComponentGetState(pSfVideoImplement->hSFComponentExecoder);
+    LOG(SF_LOG_INFO, "state = %d\r\n", state);
+
+    switch (state)
+    {
+    case COMPONENT_STATE_CREATED:
+        if (comState == OMX_StateLoaded)
+        {
+            *pState = OMX_StateLoaded;
+        }else{
+            *pState = OMX_StateIdle;
+        }
+        break;
+    case COMPONENT_STATE_NONE:
+    case COMPONENT_STATE_TERMINATED:
+        *pState = OMX_StateLoaded;
+        break;
+    case COMPONENT_STATE_PREPARED:
+    case COMPONENT_STATE_EXECUTED:
+        if (comState == OMX_StateIdle || comState == OMX_StateExecuting || comState == OMX_StatePause)
+        {
+            *pState = comState;
+        }
+        break;
+    default:
+        LOG(SF_LOG_WARN, "unknown state:%d \r\n", state);
+        ret = OMX_ErrorUndefined;
+        break;
+    }
+EXIT:
+    FunctionOut();
+    return ret;
+}
+
+OMX_ERRORTYPE ComponentClearCommon(SF_OMX_COMPONENT *pSfOMXComponent)
+{
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+
+    pSfVideoImplement->functions->ComponentRelease(pSfVideoImplement->hSFComponentExecoder);
+    pSfVideoImplement->functions->ComponentDestroy(pSfVideoImplement->hSFComponentExecoder, NULL);
+    pSfVideoImplement->functions->DeInitLog();
+    dlclose(pSfOMXComponent->soHandle);
+    free(pSfVideoImplement->functions);
+    free(pSfVideoImplement->testConfig);
+    free(pSfVideoImplement->config);
+    free(pSfVideoImplement->lsnCtx);
+    free(pSfOMXComponent->pOMXComponent);
+    for (int i = 0; i < 2; i++)
+    {
+        OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = &pSfOMXComponent->portDefinition[i];
+        free(pPortDefinition->format.video.cMIMEType);
+    }
+    return OMX_ErrorNone;
+}
+
+BOOL CheckEncTestConfig(TestEncConfig *testConfig)
+{
+    FunctionIn();
+    if ((testConfig->compareType & (1 << MODE_SAVE_ENCODED)) && testConfig->bitstreamFileName[0] == 0)
+    {
+        testConfig->compareType &= ~(1 << MODE_SAVE_ENCODED);
+        LOG(SF_LOG_ERR, "You want to Save bitstream data. Set the path\r\n");
+        return FALSE;
+    }
+
+    if ((testConfig->compareType & (1 << MODE_COMP_ENCODED)) && testConfig->ref_stream_path[0] == 0)
+    {
+        testConfig->compareType &= ~(1 << MODE_COMP_ENCODED);
+        LOG(SF_LOG_ERR, "You want to Compare bitstream data. Set the path\r\n");
+        return FALSE;
+    }
+
+    FunctionOut();
+    return TRUE;
+}
+
+BOOL CheckDecTestConfig(TestDecConfig *testConfig)
+{
+    BOOL isValidParameters = TRUE;
+
+    /* Check parameters */
+    if (testConfig->skipMode < 0 || testConfig->skipMode == 3 || testConfig->skipMode > 4)
+    {
+        LOG(SF_LOG_WARN, "Invalid skip mode: %d\n", testConfig->skipMode);
+        isValidParameters = FALSE;
+    }
+    if ((FORMAT_422 < testConfig->wtlFormat && testConfig->wtlFormat <= FORMAT_400) ||
+        testConfig->wtlFormat < FORMAT_420 || testConfig->wtlFormat >= FORMAT_MAX)
+    {
+        LOG(SF_LOG_WARN, "Invalid WTL format(%d)\n", testConfig->wtlFormat);
+        isValidParameters = FALSE;
+    }
+    if (isValidParameters == TRUE && (testConfig->scaleDownWidth > 0 || testConfig->scaleDownHeight > 0))
+    {
+    }
+    if (testConfig->renderType < RENDER_DEVICE_NULL || testConfig->renderType >= RENDER_DEVICE_MAX)
+    {
+        LOG(SF_LOG_WARN, "unknown render device type(%d)\n", testConfig->renderType);
+        isValidParameters = FALSE;
+    }
+    if (testConfig->thumbnailMode == TRUE && testConfig->skipMode != 0)
+    {
+        LOG(SF_LOG_WARN, "Turn off thumbnail mode or skip mode\n");
+        isValidParameters = FALSE;
+    }
+
+    return isValidParameters;
+}
+
+OMX_ERRORTYPE InitComponentStructorCommon(SF_OMX_COMPONENT *pSfOMXComponent)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    char *strDebugLevel = NULL;
+    int debugLevel = 0;
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = NULL;
+
+    FunctionIn();
+    if (pSfOMXComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pSfOMXComponent->pOMXComponent = malloc(sizeof(OMX_COMPONENTTYPE));
+    if (pSfOMXComponent->pOMXComponent == NULL)
+    {
+        ret = OMX_ErrorInsufficientResources;
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        goto ERROR;
+    }
+    memset(pSfOMXComponent->pOMXComponent, 0, sizeof(OMX_COMPONENTTYPE));
+    pSfOMXComponent->soHandle = dlopen(pSfOMXComponent->libName, RTLD_NOW);
+    if (pSfOMXComponent->soHandle == NULL)
+    {
+        ret = OMX_ErrorInsufficientResources;
+        LOG(SF_LOG_ERR, "could not open %s\r\n", pSfOMXComponent->libName);
+        goto ERROR;
+    }
+
+    pSfOMXComponent->componentImpl = malloc(sizeof(SF_WAVE5_IMPLEMEMT));
+    if (pSfOMXComponent->componentImpl == NULL)
+    {
+        ret = OMX_ErrorInsufficientResources;
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        goto ERROR;
+    }
+    pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    memset(pSfVideoImplement, 0, sizeof(SF_WAVE5_IMPLEMEMT));
+
+    pSfVideoImplement->functions = malloc(sizeof(SF_COMPONENT_FUNCTIONS));
+    if (pSfVideoImplement->functions == NULL)
+    {
+        ret = OMX_ErrorInsufficientResources;
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        goto ERROR;
+    }
+    memset(pSfVideoImplement->functions, 0, sizeof(SF_COMPONENT_FUNCTIONS));
+    sf_get_component_functions(pSfVideoImplement->functions, pSfOMXComponent->soHandle);
+
+    // Init VPU log
+    if (pSfVideoImplement->functions->InitLog && pSfVideoImplement->functions->SetMaxLogLevel)
+    {
+        pSfVideoImplement->functions->InitLog();
+        strDebugLevel = getenv("VPU_DEBUG");
+        if (strDebugLevel)
+        {
+            debugLevel = atoi(strDebugLevel);
+            if (debugLevel >=0)
+            {
+                pSfVideoImplement->functions->SetMaxLogLevel(debugLevel);
+            }
+        }
+    }
+
+    if (strstr(pSfOMXComponent->componentName, "sf.video_encoder") != NULL)
+    {
+        pSfVideoImplement->testConfig = malloc(sizeof(TestEncConfig));
+        if (pSfVideoImplement->testConfig == NULL)
+        {
+            ret = OMX_ErrorInsufficientResources;
+            LOG(SF_LOG_ERR, "malloc fail\r\n");
+            goto ERROR;
+        }
+        pSfVideoImplement->lsnCtx = malloc(sizeof(EncListenerContext));
+        if (pSfVideoImplement->lsnCtx == NULL)
+        {
+            ret = OMX_ErrorInsufficientResources;
+            LOG(SF_LOG_ERR, "malloc fail\r\n");
+            goto ERROR;
+        }
+        memset(pSfVideoImplement->testConfig, 0, sizeof(TestEncConfig));
+        memset(pSfVideoImplement->lsnCtx, 0, sizeof(EncListenerContext));
+        pSfVideoImplement->functions->SetDefaultEncTestConfig(pSfVideoImplement->testConfig);
+    }
+    else if (strstr(pSfOMXComponent->componentName, "sf.video_decoder") != NULL)
+    {
+        pSfVideoImplement->testConfig = malloc(sizeof(TestDecConfig));
+        if (pSfVideoImplement->testConfig == NULL)
+        {
+            ret = OMX_ErrorInsufficientResources;
+            LOG(SF_LOG_ERR, "malloc fail\r\n");
+            goto ERROR;
+        }
+        pSfVideoImplement->lsnCtx = malloc(sizeof(DecListenerContext));
+        if (pSfVideoImplement->lsnCtx == NULL)
+        {
+            ret = OMX_ErrorInsufficientResources;
+            LOG(SF_LOG_ERR, "malloc fail\r\n");
+            goto ERROR;
+        }
+        memset(pSfVideoImplement->testConfig, 0, sizeof(TestDecConfig));
+        memset(pSfVideoImplement->lsnCtx, 0, sizeof(DecListenerContext));
+        pSfVideoImplement->functions->SetDefaultDecTestConfig(pSfVideoImplement->testConfig);
+    }
+    else
+    {
+        ret = OMX_ErrorBadParameter;
+        LOG(SF_LOG_ERR, "unknown component!\r\n");
+        goto ERROR;
+    }
+
+    if (strstr(pSfOMXComponent->componentName, "avc") != NULL)
+    {
+        pSfVideoImplement->bitFormat = STD_AVC;
+    }
+    else if (strstr(pSfOMXComponent->componentName, "hevc") != NULL)
+    {
+        pSfVideoImplement->bitFormat = STD_HEVC;
+    }
+    else
+    {
+        ret = OMX_ErrorBadParameter;
+        LOG(SF_LOG_ERR, "unknown format!\r\n");
+        goto ERROR;
+    }
+
+    pSfVideoImplement->config = malloc(sizeof(CNMComponentConfig));
+    if (pSfVideoImplement->config == NULL)
+    {
+        ret = OMX_ErrorInsufficientResources;
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        goto ERROR;
+    }
+    memset(pSfVideoImplement->config, 0, sizeof(CNMComponentConfig));
+
+    pSfOMXComponent->pOMXComponent->pComponentPrivate = pSfOMXComponent;
+    for (int i = 0; i < 2; i++)
+    {
+        OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = &pSfOMXComponent->portDefinition[i];
+        OMX_VIDEO_PARAM_AVCTYPE *pAVCComponent = &pSfVideoImplement->AVCComponent[i];
+        OMX_VIDEO_PARAM_HEVCTYPE *pHEVCComponent = &pSfVideoImplement->HEVCComponent[i];
+        INIT_SET_SIZE_VERSION(pPortDefinition, OMX_PARAM_PORTDEFINITIONTYPE);
+        INIT_SET_SIZE_VERSION(pAVCComponent, OMX_VIDEO_PARAM_AVCTYPE);
+        INIT_SET_SIZE_VERSION(pHEVCComponent, OMX_VIDEO_PARAM_HEVCTYPE);
+        pPortDefinition->nPortIndex = i;
+        pPortDefinition->nBufferCountActual = VPU_OUTPUT_BUF_NUMBER;
+        pPortDefinition->nBufferCountMin = VPU_OUTPUT_BUF_NUMBER;
+        pPortDefinition->nBufferSize = 0;
+        pPortDefinition->eDomain = OMX_PortDomainVideo;
+        pPortDefinition->format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
+        pPortDefinition->format.video.nFrameHeight = DEFAULT_FRAME_HEIGHT;
+        pPortDefinition->format.video.nStride = DEFAULT_FRAME_WIDTH;
+        pPortDefinition->format.video.nSliceHeight = DEFAULT_FRAME_HEIGHT;
+        pPortDefinition->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+        pPortDefinition->format.video.cMIMEType = malloc(OMX_MAX_STRINGNAME_SIZE);
+        pPortDefinition->format.video.xFramerate = 30;
+        if (pPortDefinition->format.video.cMIMEType == NULL)
+        {
+            ret = OMX_ErrorInsufficientResources;
+            free(pPortDefinition->format.video.cMIMEType);
+            pPortDefinition->format.video.cMIMEType = NULL;
+            LOG(SF_LOG_ERR, "malloc fail\r\n");
+            goto ERROR;
+        }
+        memset(pPortDefinition->format.video.cMIMEType, 0, OMX_MAX_STRINGNAME_SIZE);
+        pPortDefinition->format.video.pNativeRender = 0;
+        pPortDefinition->format.video.bFlagErrorConcealment = OMX_FALSE;
+        pPortDefinition->format.video.eColorFormat = OMX_COLOR_FormatUnused;
+        pPortDefinition->bEnabled = OMX_TRUE;
+
+        pAVCComponent->nPortIndex = i;
+        pAVCComponent->nPFrames = 30;
+        pAVCComponent->eProfile = OMX_VIDEO_AVCProfileHigh;
+        pHEVCComponent->nPortIndex = i;
+        pHEVCComponent->nKeyFrameInterval = 30;
+        pHEVCComponent->eProfile = OMX_VIDEO_HEVCProfileMain;
+        pSfOMXComponent->assignedBufferNum[i] = 0;
+    }
+
+    pSfOMXComponent->portDefinition[0].eDir = OMX_DirInput;
+    pSfOMXComponent->portDefinition[0].nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
+    pSfOMXComponent->portDefinition[0].nBufferCountActual = VPU_INPUT_BUF_NUMBER;
+    pSfOMXComponent->portDefinition[0].nBufferCountMin = VPU_INPUT_BUF_NUMBER;
+
+    strcpy(pSfOMXComponent->portDefinition[1].format.video.cMIMEType, "raw/video");
+    pSfOMXComponent->portDefinition[1].format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+    pSfOMXComponent->portDefinition[1].eDir = OMX_DirOutput;
+    pSfOMXComponent->portDefinition[1].nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
+    pSfOMXComponent->portDefinition[1].nBufferCountActual = VPU_OUTPUT_BUF_NUMBER;
+    pSfOMXComponent->portDefinition[1].nBufferCountMin = VPU_OUTPUT_BUF_NUMBER;
+
+    /* Set componentVersion */
+    pSfOMXComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pSfOMXComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pSfOMXComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
+    pSfOMXComponent->componentVersion.s.nStep         = STEP_NUMBER;
+    /* Set specVersion */
+    pSfOMXComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pSfOMXComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pSfOMXComponent->specVersion.s.nRevision     = REVISION_NUMBER;
+    pSfOMXComponent->specVersion.s.nStep         = STEP_NUMBER;
+    /* Input port */
+
+    memset(pSfOMXComponent->pBufferArray, 0, sizeof(pSfOMXComponent->pBufferArray));
+    pSfOMXComponent->memory_optimization = OMX_FALSE;
+
+    memset(pSfOMXComponent->markType, 0, sizeof(pSfOMXComponent->markType));
+    pSfOMXComponent->propagateMarkType.hMarkTargetComponent = NULL;
+    pSfOMXComponent->propagateMarkType.pMarkData = NULL;
+
+    for (int i = 0; i < 2; i++)
+    {
+        ret = SF_SemaphoreCreate(&pSfOMXComponent->portSemaphore[i]);
+        if (ret)
+            goto ERROR;
+        ret = SF_SemaphoreCreate(&pSfOMXComponent->portUnloadSemaphore[i]);
+        if (ret)
+            goto ERROR;
+    }
+
+    FunctionOut();
+EXIT:
+    return ret;
+ERROR:
+    for (int i = 0; i < 2; i++)
+    {
+        SF_SemaphoreTerminate(pSfOMXComponent->portSemaphore[i]);
+        SF_SemaphoreTerminate(pSfOMXComponent->portUnloadSemaphore[i]);
+    }
+    if (pSfOMXComponent->pOMXComponent)
+    {
+        free(pSfOMXComponent->pOMXComponent);
+        pSfOMXComponent->pOMXComponent = NULL;
+    }
+    if (pSfVideoImplement)
+    {
+        if (pSfVideoImplement->functions)
+        {
+            free(pSfVideoImplement->functions);
+            pSfVideoImplement->functions = NULL;
+        }
+        if (pSfVideoImplement->testConfig)
+        {
+            free(pSfVideoImplement->testConfig);
+            pSfVideoImplement->testConfig = NULL;
+        }
+        if (pSfVideoImplement->lsnCtx)
+        {
+            free(pSfVideoImplement->lsnCtx);
+            pSfVideoImplement->lsnCtx = NULL;
+        }
+        if (pSfVideoImplement->config)
+        {
+            free(pSfVideoImplement->config);
+            pSfVideoImplement->config = NULL;
+        }
+        free(pSfVideoImplement);
+        pSfVideoImplement = NULL;
+    }
+    return ret;
+}
+
+OMX_ERRORTYPE FlushBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U32 nPort)
+{
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+
+    FunctionIn();
+    if (nPort == 0)
+    {
+        ComponentImpl *pFeederComponent = (ComponentImpl *)(pSfVideoImplement->hSFComponentFeeder);
+        if (pFeederComponent)
+        {
+            OMX_U32 inputQueueCount = pSfVideoImplement->functions->Queue_Get_Cnt(pFeederComponent->srcPort.inputQ);
+            LOG(SF_LOG_PERF, "Flush %d buffers on inputPort\r\n", inputQueueCount);
+            if (inputQueueCount > 0)
+            {
+                PortContainerExternal *input = NULL;
+                while ((input = (PortContainerExternal*)pSfVideoImplement->functions->ComponentPortGetData(&pFeederComponent->srcPort)) != NULL)
+                {
+                    if (strstr(pSfOMXComponent->componentName, "sf.video_decoder") != NULL)
+                    {
+                        pSfVideoImplement->functions->ComponentNotifyListeners(pFeederComponent, COMPONENT_EVENT_DEC_EMPTY_BUFFER_DONE, (void *)input);
+                    }
+                    else if (strstr(pSfOMXComponent->componentName, "sf.video_encoder") != NULL)
+                    {
+                        pSfVideoImplement->functions->ComponentNotifyListeners(pFeederComponent, COMPONENT_EVENT_ENC_EMPTY_BUFFER_DONE, (void *)input);
+                    }
+                }
+            }
+        }
+    }
+    else if (nPort == 1)
+    {
+        ComponentImpl *pRendererComponent = (ComponentImpl *)(pSfVideoImplement->hSFComponentRender);
+        if (pRendererComponent)
+        {
+            OMX_U32 OutputQueueCount = pSfVideoImplement->functions->Queue_Get_Cnt(pRendererComponent->sinkPort.inputQ);
+            LOG(SF_LOG_PERF, "Flush %d buffers on outputPort\r\n", OutputQueueCount);
+            if (OutputQueueCount > 0)
+            {
+                PortContainerExternal *output = NULL;
+                while ((output = (PortContainerExternal*)pSfVideoImplement->functions->ComponentPortGetData(&pRendererComponent->sinkPort)) != NULL)
+                {
+                    output->nFlags = 0x1;
+                    output->nFilledLen = 0;
+                    if (strstr(pSfOMXComponent->componentName, "sf.video_decoder") != NULL)
+                    {
+                        pSfVideoImplement->functions->ComponentNotifyListeners(pRendererComponent, COMPONENT_EVENT_DEC_FILL_BUFFER_DONE, (void *)output);
+                    }
+                    else if (strstr(pSfOMXComponent->componentName, "sf.video_encoder") != NULL)
+                    {
+                        pSfVideoImplement->functions->ComponentNotifyListeners(pRendererComponent, COMPONENT_EVENT_ENC_FILL_BUFFER_DONE, (void *)output);
+                    }
+                }
+            }
+        }
+    }
+    FunctionOut();
+    return OMX_ErrorNone;
+}
+
+static void sf_get_component_functions(SF_COMPONENT_FUNCTIONS *funcs, OMX_PTR *sohandle)
+{
+    FunctionIn();
+    funcs->ComponentCreate = dlsym(sohandle, "ComponentCreate");
+    funcs->ComponentExecute = dlsym(sohandle, "ComponentExecute");
+    funcs->ComponentGetParameter = dlsym(sohandle, "ComponentGetParameter");
+    funcs->ComponentGetState = dlsym(sohandle, "ComponentGetState");
+    funcs->ComponentNotifyListeners = dlsym(sohandle, "ComponentNotifyListeners");
+    funcs->ComponentPortCreate = dlsym(sohandle, "ComponentPortCreate");
+    funcs->ComponentPortDestroy = dlsym(sohandle, "ComponentPortDestroy");
+    funcs->ComponentPortFlush = dlsym(sohandle, "ComponentPortFlush");
+    funcs->ComponentPortGetData = dlsym(sohandle, "ComponentPortGetData");
+    funcs->ComponentPortPeekData = dlsym(sohandle, "ComponentPortPeekData");
+    funcs->ComponentPortSetData = dlsym(sohandle, "ComponentPortSetData");
+    funcs->ComponentPortWaitReadyStatus = dlsym(sohandle, "ComponentPortWaitReadyStatus");
+    funcs->ComponentRelease = dlsym(sohandle, "ComponentRelease");
+    funcs->ComponentSetParameter = dlsym(sohandle, "ComponentSetParameter");
+    funcs->ComponentStop = dlsym(sohandle, "ComponentStop");
+    funcs->ComponentSetupTunnel = dlsym(sohandle, "ComponentSetupTunnel");
+    funcs->ComponentWait = dlsym(sohandle, "ComponentWait");
+    funcs->WaitBeforeComponentPortGetData = dlsym(sohandle, "WaitBeforeComponentPortGetData");
+    funcs->ComponentChangeState = dlsym(sohandle, "ComponentChangeState");
+    funcs->ComponentDestroy = dlsym(sohandle, "ComponentDestroy");
+    funcs->ComponentRegisterListener = dlsym(sohandle, "ComponentRegisterListener");
+    funcs->ComponentPortHasInputData = dlsym(sohandle, "ComponentPortHasInputData");
+    funcs->ComponentPortGetSize = dlsym(sohandle, "ComponentPortGetSize");
+    funcs->ComponentParamReturnTest = dlsym(sohandle, "ComponentParamReturnTest");
+    //Listener
+    funcs->SetupDecListenerContext = dlsym(sohandle, "SetupDecListenerContext");
+    funcs->SetupEncListenerContext = dlsym(sohandle, "SetupEncListenerContext");
+    funcs->ClearDecListenerContext = dlsym(sohandle, "ClearDecListenerContext");
+    funcs->HandleDecCompleteSeqEvent = dlsym(sohandle, "HandleDecCompleteSeqEvent");
+    funcs->HandleDecRegisterFbEvent = dlsym(sohandle, "HandleDecRegisterFbEvent");
+    funcs->HandleDecGetOutputEvent = dlsym(sohandle, "HandleDecGetOutputEvent");
+    funcs->HandleDecCloseEvent = dlsym(sohandle, "HandleDecCloseEvent");
+    funcs->ClearEncListenerContext = dlsym(sohandle, "ClearEncListenerContext");
+    funcs->HandleEncFullEvent = dlsym(sohandle, "HandleEncFullEvent");
+    funcs->HandleEncGetOutputEvent = dlsym(sohandle, "HandleEncGetOutputEvent");
+    funcs->HandleEncCompleteSeqEvent = dlsym(sohandle, "HandleEncCompleteSeqEvent");
+    funcs->HandleEncGetEncCloseEvent = dlsym(sohandle, "HandleEncGetEncCloseEvent");
+    funcs->EncoderListener = dlsym(sohandle, "EncoderListener");
+    funcs->DecoderListener = dlsym(sohandle, "DecoderListener");
+    // Helper
+    funcs->SetDefaultEncTestConfig = dlsym(sohandle, "SetDefaultEncTestConfig");
+    funcs->SetDefaultDecTestConfig = dlsym(sohandle, "SetDefaultDecTestConfig");
+    funcs->LoadFirmware = dlsym(sohandle, "LoadFirmware");
+    funcs->SetupEncoderOpenParam = dlsym(sohandle, "SetupEncoderOpenParam");
+    funcs->SetUpDecoderOpenParam = dlsym(sohandle, "SetUpDecoderOpenParam");
+    // VPU
+    funcs->VPU_GetProductId = dlsym(sohandle, "VPU_GetProductId");
+    funcs->Queue_Enqueue = dlsym(sohandle, "Queue_Enqueue");
+    funcs->Queue_Get_Cnt = dlsym(sohandle, "Queue_Get_Cnt");
+    funcs->VPU_DecClrDispFlag = dlsym(sohandle, "VPU_DecClrDispFlag");
+    funcs->VPU_DecGetFrameBuffer = dlsym(sohandle, "VPU_DecGetFrameBuffer");
+    funcs->Render_DecClrDispFlag = dlsym(sohandle, "Render_DecClrDispFlag");
+    // VPU Log
+    funcs->InitLog = dlsym(sohandle, "InitLog");
+    funcs->DeInitLog = dlsym(sohandle, "DeInitLog");
+    funcs->SetMaxLogLevel = dlsym(sohandle, "SetMaxLogLevel");
+    funcs->GetMaxLogLevel = dlsym(sohandle, "GetMaxLogLevel");
+
+    //Renderer
+    funcs->AllocateFrameBuffer2 = dlsym(sohandle, "AllocateFrameBuffer2");
+    funcs->AttachDMABuffer = dlsym(sohandle, "AttachDMABuffer");
+    funcs->SetRenderTotalBufferNumber = dlsym(sohandle, "SetRenderTotalBufferNumber");
+    funcs->SetFeederTotalBufferNumber = dlsym(sohandle, "SetFeederTotalBufferNumber");
+    funcs->WaitForExecoderReady = dlsym(sohandle, "WaitForExecoderReady");
+    FunctionOut();
+}
+
+SF_OMX_COMPONENT *GetSFOMXComponrntByComponent(Component *pComponent)
+{
+    SF_OMX_COMPONENT *pSfOMXComponent = NULL;
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = NULL;
+    int size = GetNumberOfComponent();
+
+    FunctionIn();
+    for (int i = 0; i < size; i++)
+    {
+        pSfOMXComponent = sf_omx_component_list[i];
+        if (pSfOMXComponent == NULL)
+        {
+            continue;
+        }
+        pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+        if (pSfVideoImplement == NULL)
+        {
+            continue;
+        }
+        if (pSfVideoImplement->hSFComponentExecoder == pComponent || pSfVideoImplement->hSFComponentFeeder == pComponent || pSfVideoImplement->hSFComponentRender == pComponent)
+        {
+            break;
+        }
+    }
+
+    if (pSfOMXComponent == NULL)
+    {
+        LOG(SF_LOG_ERR, "Could not get SfOMXComponent buy %p\r\n", pComponent);
+    }
+    FunctionOut();
+
+    return pSfOMXComponent;
+}

+ 143 - 0
omx-il/component/video/wave5/common/SF_OMX_video_common.h

@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 StarFive Technology Co., Ltd.
+ */
+#ifndef SF_OMX_VIDEO_COMMON
+#define SF_OMX_VIDEO_COMMON
+
+#include "OMX_Component.h"
+#include "OMX_Video.h"
+#include "OMX_VideoExt.h"
+#include "OMX_Index.h"
+#include "OMX_IndexExt.h"
+#include "SF_OMX_Core.h"
+#include "sf_queue.h"
+#include "sf_thread.h"
+#include "sf_semaphore.h"
+#include "wave511/sample_v2/component/component.h"
+#include "wave511/sample_v2/component_encoder/encoder_listener.h"
+#include "wave511/sample_v2/component_decoder/decoder_listener.h"
+
+#define INIT_SET_SIZE_VERSION(_struct_, _structType_) \
+    do                                                \
+    {                                                 \
+        memset((_struct_), 0, sizeof(_structType_));  \
+        (_struct_)->nSize = sizeof(_structType_);     \
+        (_struct_)->nVersion.s.nVersionMajor = 1;     \
+        (_struct_)->nVersion.s.nVersionMinor = 18;    \
+        (_struct_)->nVersion.s.nRevision = 1;         \
+        (_struct_)->nVersion.s.nStep = 0;             \
+    } while (0)
+
+#define DEFAULT_FRAME_WIDTH 3840
+#define DEFAULT_FRAME_HEIGHT 2160
+#define DEFAULT_VIDEO_INPUT_BUFFER_SIZE (DEFAULT_FRAME_WIDTH * DEFAULT_FRAME_HEIGHT) / 2
+#define DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE (DEFAULT_FRAME_WIDTH * DEFAULT_FRAME_HEIGHT * 3) / 2
+#define MAX_INDEX 1
+
+typedef struct _SF_COMPONENT_FUNCTIONS
+{
+    Component (*ComponentCreate)(const char *componentName, CNMComponentConfig *componentParam);
+    BOOL(*ComponentSetupTunnel)(Component fromComponent, Component toComponent);
+    ComponentState (*ComponentExecute)(Component component);
+    Int32 (*ComponentWait)(Component component);
+    void (*ComponentStop)(Component component);
+    void (*ComponentRelease)(Component component);
+    BOOL(*ComponentChangeState)(Component component, Uint32 state);
+    BOOL(*ComponentDestroy)(Component component, BOOL *ret);
+    CNMComponentParamRet (*ComponentGetParameter)(Component from, Component to, GetParameterCMD commandType, void *data);
+    CNMComponentParamRet (*ComponentSetParameter)(Component from, Component to, SetParameterCMD commandType, void *data);
+    void (*ComponentNotifyListeners)(Component component, Uint64 event, void *data);
+    BOOL(*ComponentRegisterListener)(Component component, Uint64 events, ComponentListenerFunc func, void *context);
+    void (*ComponentPortCreate)(Port *port, Component owner, Uint32 depth, Uint32 size);
+    void (*ComponentPortSetData)(Port *port, PortContainer *portData);
+    PortContainer *(*ComponentPortPeekData)(Port *port);
+    PortContainer *(*ComponentPortGetData)(Port *port);
+    void *(*WaitBeforeComponentPortGetData)(Port *port);
+    void (*ComponentPortWaitReadyStatus)(Port *port);
+    void (*ComponentPortDestroy)(Port *port);
+    BOOL(*ComponentPortHasInputData)(Port *port);
+    Uint32 (*ComponentPortGetSize)(Port *port);
+    void (*ComponentPortFlush)(Component component);
+    ComponentState (*ComponentGetState)(Component component);
+    BOOL(*ComponentParamReturnTest)(CNMComponentParamRet ret, BOOL *retry);
+    // Listener
+    BOOL(*SetupDecListenerContext)(DecListenerContext *ctx, CNMComponentConfig *config, Component renderer);
+    BOOL(*SetupEncListenerContext)(EncListenerContext *ctx, CNMComponentConfig *config);
+    void (*ClearDecListenerContext)(DecListenerContext *ctx);
+    void (*HandleDecCompleteSeqEvent)(Component com, CNMComListenerDecCompleteSeq *param, DecListenerContext *ctx);
+    void (*HandleDecRegisterFbEvent)(Component com, CNMComListenerDecRegisterFb *param, DecListenerContext *ctx);
+    void (*HandleDecGetOutputEvent)(Component com, CNMComListenerDecDone *param, DecListenerContext *ctx);
+    void (*HandleDecCloseEvent)(Component com, CNMComListenerDecClose *param, DecListenerContext *ctx);
+    void (*ClearEncListenerContext)(EncListenerContext *ctx);
+    void (*HandleEncFullEvent)(Component com, CNMComListenerEncFull *param, EncListenerContext *ctx);
+    void (*HandleEncGetOutputEvent)(Component com, CNMComListenerEncDone *param, EncListenerContext *ctx);
+    void (*HandleEncCompleteSeqEvent)(Component com, CNMComListenerEncCompleteSeq *param, EncListenerContext *ctx);
+    void (*HandleEncGetEncCloseEvent)(Component com, CNMComListenerEncClose *param, EncListenerContext *ctx);
+    void (*EncoderListener)(Component com, Uint64 event, void *data, void *context);
+    void (*DecoderListener)(Component com, Uint64 event, void *data, void *context);
+    // Helper
+    void (*SetDefaultEncTestConfig)(TestEncConfig *testConfig);
+    void (*SetDefaultDecTestConfig)(TestDecConfig *testConfig);
+    Int32 (*LoadFirmware)(Int32 productId, Uint8 **retFirmware, Uint32 *retSizeInWord, const char *path);
+    BOOL(*SetupEncoderOpenParam)(EncOpenParam *param, TestEncConfig *config, ENC_CFG *encCfg);
+    RetCode (*SetUpDecoderOpenParam)(DecOpenParam *param, TestDecConfig *config);
+    // VPU
+    int (*VPU_GetProductId)(int coreIdx);
+    BOOL(*Queue_Enqueue)(Queue *queue, void *data);
+    Uint32 (*Queue_Get_Cnt)(Queue *queue);
+    RetCode (*VPU_DecClrDispFlag)(DecHandle handle, int index);
+    RetCode (*VPU_DecGetFrameBuffer)(DecHandle handle, int frameIdx, FrameBuffer* frameBuf);
+    void (*Render_DecClrDispFlag)(void *context, int index);
+    // VPU Log
+    int (*InitLog)(void);
+    void (*DeInitLog)(void);
+    void (*SetMaxLogLevel)(int level);
+    int (*GetMaxLogLevel)(void);
+    // FrameBuffer
+    void* (*AllocateFrameBuffer2)(ComponentImpl* com, Uint32 size);
+    BOOL (*AttachDMABuffer)(ComponentImpl* com, Uint64 virtAddress, Uint32 size);
+    void (*SetRenderTotalBufferNumber)(ComponentImpl* com, Uint32 number);
+    void (*SetFeederTotalBufferNumber)(ComponentImpl* com, Uint32 number);
+    void (*WaitForExecoderReady)(ComponentImpl *com);
+} SF_COMPONENT_FUNCTIONS;
+
+typedef struct _SF_WAVE5_IMPLEMEMT
+{
+    SF_COMPONENT_FUNCTIONS *functions;
+    Component *hSFComponentExecoder;
+    Component *hSFComponentFeeder;
+    Component *hSFComponentRender;
+    void *testConfig;
+    CNMComponentConfig *config;
+    void *lsnCtx;
+    Uint16 *pusBitCode;
+    CodStd bitFormat;
+    OMX_BOOL rev_eos;
+    SF_Queue *CmdQueue;
+    SF_Queue *pauseQ;
+    THREAD_HANDLE_TYPE *pCmdThread;
+    OMX_BOOL bCmdRunning;
+    OMX_U64 frame_array[MAX_INDEX];
+    OMX_U32 frame_array_index;
+    OMX_VIDEO_PARAM_AVCTYPE AVCComponent[2];
+    OMX_VIDEO_PARAM_HEVCTYPE HEVCComponent[2];
+}SF_WAVE5_IMPLEMEMT;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+    BOOL CheckEncTestConfig(TestEncConfig *testConfig);
+    BOOL CheckDecTestConfig(TestDecConfig *testConfig);
+    OMX_ERRORTYPE GetStateCommon(OMX_IN OMX_HANDLETYPE hComponent, OMX_OUT OMX_STATETYPE *pState);
+    OMX_ERRORTYPE InitComponentStructorCommon(SF_OMX_COMPONENT *hComponent);
+    OMX_ERRORTYPE ComponentClearCommon(SF_OMX_COMPONENT *hComponent);
+    OMX_ERRORTYPE FlushBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U32 nPort);
+    SF_OMX_COMPONENT *GetSFOMXComponrntByComponent(Component *pComponent);
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 1934 - 0
omx-il/component/video/wave5/dec/SF_OMX_Vdec_decoder.c

@@ -0,0 +1,1934 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 StarFive Technology Co., Ltd.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "SF_OMX_video_common.h"
+#include "SF_OMX_Core.h"
+
+#define DEC_StopThread OMX_CommandMax
+
+extern OMX_TICKS gInitTimeStamp;
+
+typedef struct DEC_CMD
+{
+    OMX_COMMANDTYPE Cmd;
+    OMX_U32 nParam;
+    OMX_PTR pCmdData;
+}DEC_CMD;
+
+static char* Event2Str(unsigned long event)
+{
+    char *event_str = NULL;
+    switch (event)
+    {
+    case COMPONENT_EVENT_DEC_OPEN:
+        event_str = "COMPONENT_EVENT_DEC_OPEN";
+        break;
+    case COMPONENT_EVENT_DEC_ISSUE_SEQ:
+        event_str = "COMPONENT_EVENT_DEC_ISSUE_SEQ";
+        break;
+    case COMPONENT_EVENT_DEC_COMPLETE_SEQ:
+        event_str = "COMPONENT_EVENT_DEC_COMPLETE_SEQ";
+        break;
+    case COMPONENT_EVENT_DEC_REGISTER_FB:
+        event_str = "COMPONENT_EVENT_DEC_REGISTER_FB";
+        break;
+    case COMPONENT_EVENT_DEC_READY_ONE_FRAME:
+        event_str = "COMPONENT_EVENT_DEC_READY_ONE_FRAME";
+        break;
+    case COMPONENT_EVENT_DEC_START_ONE_FRAME:
+        event_str = "COMPONENT_EVENT_DEC_START_ONE_FRAME";
+        break;
+    case COMPONENT_EVENT_DEC_INTERRUPT:
+        event_str = "COMPONENT_EVENT_DEC_INTERRUPT";
+        break;
+    case COMPONENT_EVENT_DEC_GET_OUTPUT_INFO:
+        event_str = "COMPONENT_EVENT_DEC_GET_OUTPUT_INFO";
+        break;
+    case COMPONENT_EVENT_DEC_DECODED_ALL:
+        event_str = "COMPONENT_EVENT_DEC_DECODED_ALL";
+        break;
+    case COMPONENT_EVENT_DEC_CLOSE:
+        event_str = "COMPONENT_EVENT_DEC_CLOSE";
+        break;
+    case COMPONENT_EVENT_DEC_RESET_DONE:
+        event_str = "COMPONENT_EVENT_DEC_RESET_DONE";
+        break;
+    case COMPONENT_EVENT_DEC_EMPTY_BUFFER_DONE:
+        event_str = "COMPONENT_EVENT_DEC_EMPTY_BUFFER_DONE";
+        break;
+    case COMPONENT_EVENT_DEC_FILL_BUFFER_DONE:
+        event_str = "COMPONENT_EVENT_DEC_FILL_BUFFER_DONE";
+        break;
+    case COMPONENT_EVENT_DEC_ALL:
+        event_str = "COMPONENT_EVENT_DEC_ALL";
+        break;
+    }
+    return event_str;
+}
+
+static void OnEventArrived(Component com, unsigned long event, void *data, void *context)
+{
+    PortContainerExternal *pPortContainerExternal = (PortContainerExternal *)data;
+    OMX_BUFFERHEADERTYPE *pOMXBuffer;
+    SF_OMX_BUF_INFO *pBufInfo;
+    static OMX_U32 dec_cnt = 0;
+    static struct timeval tv_old = {0};
+    OMX_U32 fps = 0;
+    OMX_U64 diff_time = 0; // ms
+    FunctionIn();
+    SF_OMX_COMPONENT *pSfOMXComponent = (SF_OMX_COMPONENT*)context;
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+
+    char *event_str = Event2Str(event);
+
+    LOG(SF_LOG_INFO, "event=%lX %s\r\n", event, event_str);
+    switch (event)
+    {
+    case COMPONENT_EVENT_DEC_EMPTY_BUFFER_DONE:
+        pOMXBuffer = (OMX_BUFFERHEADERTYPE *)pPortContainerExternal->pAppPrivate;
+        if (pOMXBuffer == NULL)
+        {
+            LOG(SF_LOG_WARN, "Could not find omx buffer by address\r\n");
+            return;
+        }
+        LOG(SF_LOG_INFO, "Empty done h %p b %p\r\n", pOMXBuffer, pOMXBuffer->pBuffer);
+
+        if (pSfOMXComponent->markType[0].hMarkTargetComponent != NULL)
+        {
+            LOG(SF_LOG_INFO, "set Component mark %p\r\n", pSfOMXComponent->markType[0].hMarkTargetComponent);
+            pOMXBuffer->hMarkTargetComponent      = pSfOMXComponent->markType[0].hMarkTargetComponent;
+            pOMXBuffer->pMarkData                 = pSfOMXComponent->markType[0].pMarkData;
+            pSfOMXComponent->markType[0].hMarkTargetComponent = NULL;
+            pSfOMXComponent->markType[0].pMarkData = NULL;
+        }
+
+        if (pOMXBuffer->hMarkTargetComponent != NULL)
+        {
+            if (pOMXBuffer->hMarkTargetComponent == pSfOMXComponent->pOMXComponent)
+            {
+                LOG(SF_LOG_INFO, "Component mark hit\r\n");
+                pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent,
+                    pSfOMXComponent->pAppData,
+                    OMX_EventMark,
+                    0, 0, pOMXBuffer->pMarkData);
+            } else {
+                LOG(SF_LOG_INFO, "Component propagate mark from input port\r\n");
+                pSfOMXComponent->propagateMarkType.hMarkTargetComponent = pOMXBuffer->hMarkTargetComponent;
+                pSfOMXComponent->propagateMarkType.pMarkData = pOMXBuffer->pMarkData;
+            }
+        }
+
+        pSfOMXComponent->callbacks->EmptyBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pOMXBuffer);
+        break;
+    case COMPONENT_EVENT_DEC_FILL_BUFFER_DONE:
+    {
+        struct timeval tv;
+
+        pOMXBuffer = (OMX_BUFFERHEADERTYPE *)pPortContainerExternal->pAppPrivate;
+        if (pOMXBuffer == NULL)
+        {
+            LOG(SF_LOG_WARN, "Could not find omx buffer by address\r\n");
+            return;
+        }
+        gettimeofday(&tv, NULL);
+        if (gInitTimeStamp == 0)
+        {
+            gInitTimeStamp = tv.tv_sec * 1000000 + tv.tv_usec;
+        }
+        pOMXBuffer->nFilledLen = pPortContainerExternal->nFilledLen;
+        pOMXBuffer->nTimeStamp = tv.tv_sec * 1000000 + tv.tv_usec - gInitTimeStamp;
+
+        pBufInfo = pOMXBuffer->pOutputPortPrivate;
+#if 0
+        {
+            FILE *fb = fopen("./out.bcp", "ab+");
+            LOG(SF_LOG_INFO, "%p %d\r\n", pOMXBuffer->pBuffer, pOMXBuffer->nFilledLen);
+            fwrite(pOMXBuffer->pBuffer, 1, pOMXBuffer->nFilledLen, fb);
+            fclose(fb);
+        }
+#endif
+
+        // Following is to print the decoding fps
+        if (dec_cnt == 0) {
+            tv_old = tv;
+        }
+        if (dec_cnt++ >= 50) {
+            diff_time = (tv.tv_sec - tv_old.tv_sec) * 1000 + (tv.tv_usec - tv_old.tv_usec) / 1000;
+            fps = 1000  * (dec_cnt - 1) / diff_time;
+            dec_cnt = 0;
+            LOG(SF_LOG_WARN, "Decoding fps: %d \r\n", fps);
+        }
+        if (pPortContainerExternal->nFlags & 0x1)
+            pOMXBuffer->nFlags |= OMX_BUFFERFLAG_EOS;
+
+        LOG(SF_LOG_PERF, "OMX finish one buffer, address = %p, size = %d, nTimeStamp = %d, nFlags = %X\r\n",
+            pOMXBuffer->pBuffer, pOMXBuffer->nFilledLen, pOMXBuffer->nTimeStamp, pOMXBuffer->nFlags);
+        LOG(SF_LOG_INFO, "indexFrameDisplay = %d, OMXBuferFlag = %d, OMXBufferAddr = %p\r\n",
+                        pPortContainerExternal->index, pBufInfo->index, pOMXBuffer->pBuffer);
+        ComponentImpl *pRendererComponent = (ComponentImpl *)pSfVideoImplement->hSFComponentRender;
+        LOG(SF_LOG_PERF, "output queue count=%d/%d\r\n", pSfVideoImplement->functions->Queue_Get_Cnt(pRendererComponent->sinkPort.inputQ),
+                                                    pSfOMXComponent->portDefinition[1].nBufferCountActual);
+
+        if (pSfOMXComponent->propagateMarkType.hMarkTargetComponent != NULL) {
+            LOG(SF_LOG_INFO, "Component propagate mark to output port\r\n");
+            pOMXBuffer->hMarkTargetComponent = pSfOMXComponent->propagateMarkType.hMarkTargetComponent;
+            pOMXBuffer->pMarkData = pSfOMXComponent->propagateMarkType.pMarkData;
+            pSfOMXComponent->propagateMarkType.hMarkTargetComponent = NULL;
+            pSfOMXComponent->propagateMarkType.pMarkData = NULL;
+        }
+
+        if (pSfOMXComponent->state == OMX_StatePause)
+        {
+            LOG(SF_LOG_INFO, "tmp store buf when pause\r\n");
+            SF_Queue_Enqueue(pSfVideoImplement->pauseQ, &pOMXBuffer);
+        }
+        else{
+            pSfOMXComponent->callbacks->FillBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pOMXBuffer);
+        }
+    }
+    break;
+    case COMPONENT_EVENT_DEC_REGISTER_FB:
+    {
+        /*The width and height vpu return will align to 16, eg: 1080 will be 1088. so check scale value at first.*/
+        TestDecConfig *testConfig = (TestDecConfig *)pSfVideoImplement->testConfig;
+        OMX_U32 nWidth = testConfig->scaleDownWidth;
+        OMX_U32 nHeight = testConfig->scaleDownHeight;
+        if (nWidth <= 0 || nHeight <= 0)
+        {
+            /*If scale value not set, then get value from vpu*/
+            FrameBuffer *frameBuffer = (FrameBuffer *)data;
+            nWidth = frameBuffer->width;
+            nHeight = frameBuffer->height;
+        }
+
+        LOG(SF_LOG_INFO, "Get Output width = %d, height = %d\r\n", nWidth, nHeight);
+        pSfOMXComponent->portDefinition[1].format.video.nFrameWidth = nWidth;
+        pSfOMXComponent->portDefinition[1].format.video.nFrameHeight = nHeight;
+        pSfOMXComponent->portDefinition[1].format.video.nStride = nWidth;
+        pSfOMXComponent->portDefinition[1].format.video.nSliceHeight = nHeight;
+
+        /*Caculate buffer size by eColorFormat*/
+        switch (pSfOMXComponent->portDefinition[1].format.video.eColorFormat)
+        {
+        case OMX_COLOR_FormatYUV420Planar:
+        case OMX_COLOR_FormatYUV420SemiPlanar:
+        case OMX_COLOR_FormatYVU420SemiPlanar:
+            if (nWidth && nHeight) {
+                pSfOMXComponent->portDefinition[1].nBufferSize = (nWidth * nHeight * 3) / 2;
+            }
+            break;
+        default:
+            if (nWidth && nHeight) {
+                pSfOMXComponent->portDefinition[1].nBufferSize = nWidth * nHeight * 2;
+            }
+            break;
+        }
+        pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, OMX_EventPortSettingsChanged,
+                                                 1, OMX_IndexParamPortDefinition, NULL);
+    }
+    break;
+    case COMPONENT_EVENT_TERMINATED:
+    break;
+    case COMPONENT_EVENT_DEC_DECODED_ALL:
+        pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, OMX_EventBufferFlag,
+                                                 1, 1, NULL);
+    default:
+        break;
+    }
+    FunctionOut();
+}
+
+static OMX_ERRORTYPE SF_OMX_EmptyThisBuffer(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    FunctionIn();
+
+    if (hComponent == NULL || pBuffer == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+
+    ComponentImpl *pFeederComponent = (ComponentImpl *)pSfVideoImplement->hSFComponentFeeder;
+
+    if (!pSfOMXComponent->portDefinition[0].bEnabled)
+    {
+        LOG(SF_LOG_INFO, "feed buffer when input port stop\r\n");
+        return OMX_ErrorIncorrectStateOperation;
+    }
+
+    if (pBuffer->nInputPortIndex != 0)
+    {
+        LOG(SF_LOG_INFO, "Incorrect nInputPortIndex %d\r\n", pBuffer->nInputPortIndex);
+        return OMX_ErrorBadPortIndex;
+    }
+
+    PortContainerExternal *pPortContainerExternal = malloc(sizeof(PortContainerExternal));
+    if (pPortContainerExternal == NULL)
+    {
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        return OMX_ErrorInsufficientResources;
+    }
+    memset(pPortContainerExternal, 0, sizeof(PortContainerExternal));
+    pPortContainerExternal->pBuffer = pBuffer->pBuffer;
+    pPortContainerExternal->nFilledLen = pBuffer->nFilledLen;
+    pPortContainerExternal->nFlags = pBuffer->nFlags;
+    pPortContainerExternal->pAppPrivate = (void*)pBuffer;
+
+    if (pSfVideoImplement->functions->Queue_Enqueue(pFeederComponent->srcPort.inputQ, (void *)pPortContainerExternal) != OMX_TRUE)
+    {
+        LOG(SF_LOG_ERR, "%p:%p FAIL\r\n", pFeederComponent->srcPort.inputQ, pPortContainerExternal);
+        free(pPortContainerExternal);
+        return OMX_ErrorInsufficientResources;
+    }
+    LOG(SF_LOG_PERF, "input queue count=%d/%d\r\n", pSfVideoImplement->functions->Queue_Get_Cnt(pFeederComponent->srcPort.inputQ),
+                                                    pSfOMXComponent->portDefinition[0].nBufferCountActual);
+    LOG(SF_LOG_INFO, "input buffer address = %p, size = %d, flag = %x\r\n", pBuffer->pBuffer, pBuffer->nFilledLen, pBuffer->nFlags);
+
+    if (pBuffer->nFlags & OMX_BUFFERFLAG_EOS)
+    {
+        pSfVideoImplement->rev_eos = OMX_TRUE;
+    }
+
+    free(pPortContainerExternal);
+
+    pFeederComponent->pause = OMX_FALSE;
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_FillThisBuffer(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    FunctionIn();
+
+    if (hComponent == NULL || pBuffer == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = (SF_OMX_COMPONENT *)pOMXComponent->pComponentPrivate;
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    SF_OMX_BUF_INFO *pBufInfo = (SF_OMX_BUF_INFO *)pBuffer->pOutputPortPrivate;
+    ComponentImpl *pRendererComponent = (ComponentImpl *)pSfVideoImplement->hSFComponentRender;
+
+    if (!pSfOMXComponent->portDefinition[1].bEnabled)
+    {
+        LOG(SF_LOG_INFO, "feed buffer when output port stop\r\n");
+        return OMX_ErrorIncorrectStateOperation;
+    }
+
+    if (pBuffer->nOutputPortIndex != 1)
+    {
+        LOG(SF_LOG_INFO, "Incorrect nOutputPortIndex %d\r\n", pBuffer->nOutputPortIndex);
+        return OMX_ErrorBadPortIndex;
+    }
+
+    PortContainerExternal *pPortContainerExternal = malloc(sizeof(PortContainerExternal));
+    if (pPortContainerExternal == NULL)
+    {
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        return OMX_ErrorInsufficientResources;
+    }
+    memset(pPortContainerExternal, 0, sizeof(PortContainerExternal));
+    pPortContainerExternal->pBuffer = pBuffer->pBuffer;
+    pPortContainerExternal->nFilledLen = pBuffer->nAllocLen;
+    pPortContainerExternal->pAppPrivate = (void*)pBuffer;
+
+    if (gInitTimeStamp != 0)
+    {
+        int clear = pSfVideoImplement->frame_array[pSfVideoImplement->frame_array_index];
+        pSfVideoImplement->functions->Render_DecClrDispFlag(pRendererComponent->context, clear);
+        pSfVideoImplement->frame_array[pSfVideoImplement->frame_array_index] = pBufInfo->index;
+        LOG(SF_LOG_INFO, "store display flag: %d, clear display flag: %d\r\n",
+                            pSfVideoImplement->frame_array[pSfVideoImplement->frame_array_index], clear);
+        pSfVideoImplement->frame_array_index ++;
+    }
+
+    if (pSfVideoImplement->frame_array_index == MAX_INDEX) pSfVideoImplement->frame_array_index = 0;
+    if (pSfVideoImplement->functions->Queue_Enqueue(pRendererComponent->sinkPort.inputQ, (void *)pPortContainerExternal) == FALSE)
+    {
+        LOG(SF_LOG_ERR, "%p:%p FAIL\r\n", pRendererComponent->sinkPort.inputQ, pPortContainerExternal);
+        free(pPortContainerExternal);
+        return OMX_ErrorInsufficientResources;
+    }
+    LOG(SF_LOG_PERF, "output queue count=%d/%d\r\n", pSfVideoImplement->functions->Queue_Get_Cnt(pRendererComponent->sinkPort.inputQ),
+                                                    pSfOMXComponent->portDefinition[1].nBufferCountActual);
+    free(pPortContainerExternal);
+    pRendererComponent->pause = OMX_FALSE;
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+
+static OMX_ERRORTYPE SF_OMX_UseBuffer(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
+    OMX_IN OMX_U32 nPortIndex,
+    OMX_IN OMX_PTR pAppPrivate,
+    OMX_IN OMX_U32 nSizeBytes,
+    OMX_IN OMX_U8 *pBuffer)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    ComponentImpl *pComponentRender = (ComponentImpl *)pSfVideoImplement->hSFComponentRender;
+    OMX_U32 i;
+
+    FunctionIn();
+
+    if (hComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    OMX_BUFFERHEADERTYPE *temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)malloc(sizeof(OMX_BUFFERHEADERTYPE));
+    if (temp_bufferHeader == NULL)
+    {
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        return OMX_ErrorInsufficientResources;
+    }
+    memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE));
+
+    SF_OMX_BUF_INFO *pBufInfo = (SF_OMX_BUF_INFO *)malloc(sizeof(SF_OMX_BUF_INFO));
+    if (pBufInfo == NULL)
+    {
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        free(temp_bufferHeader);
+        return OMX_ErrorInsufficientResources;
+    }
+
+    temp_bufferHeader->nAllocLen = nSizeBytes;
+    temp_bufferHeader->pAppPrivate = pAppPrivate;
+    temp_bufferHeader->pBuffer = pBuffer;
+    temp_bufferHeader->nSize = sizeof(OMX_BUFFERHEADERTYPE);
+    memcpy(&(temp_bufferHeader->nVersion), &(pSfOMXComponent->componentVersion), sizeof(OMX_VERSIONTYPE));
+    *ppBufferHdr = temp_bufferHeader;
+
+    if (nPortIndex == 1)
+    {
+        for (i = 0; i < MAX_BUFF_NUM; i++)
+        {
+            if (!pSfOMXComponent->pBufferArray[1][i])
+            {
+                if ((!pComponentRender) || (!pSfOMXComponent->memory_optimization)
+                                || (pSfVideoImplement->functions->AttachDMABuffer(pComponentRender, (Uint64)pBuffer, nSizeBytes) == FALSE))
+                {
+                    LOG(SF_LOG_INFO, "Failed to attach dma buffer, no memory optimization\r\n");
+                    pSfOMXComponent->memory_optimization = OMX_FALSE;
+                }
+
+                pBufInfo->type = SF_BUFFER_DMA_EXTERNAL;
+                pBufInfo->index = i;
+                temp_bufferHeader->pOutputPortPrivate = (OMX_PTR)pBufInfo;
+                temp_bufferHeader->nOutputPortIndex = 1;
+                pSfOMXComponent->pBufferArray[1][i] = temp_bufferHeader;
+                pSfOMXComponent->assignedBufferNum[1] ++;
+
+                if (pSfOMXComponent->assignedBufferNum[1] == pSfOMXComponent->portDefinition[1].nBufferCountActual)
+                {
+                    pSfOMXComponent->portDefinition[1].bPopulated = OMX_TRUE;
+                    SF_SemaphorePost(pSfOMXComponent->portSemaphore[1]);
+                }
+                break;
+            }
+        }
+        if (i == MAX_BUFF_NUM){
+            LOG(SF_LOG_ERR, "buffer array full\r\n");
+            free(temp_bufferHeader);
+            free(pBufInfo);
+            ret = OMX_ErrorInsufficientResources;
+        }
+    }
+    else if (nPortIndex == 0)
+    {
+        for (i = 0; i < MAX_BUFF_NUM; i++)
+        {
+            if (!pSfOMXComponent->pBufferArray[0][i])
+            {
+                pBufInfo->type = SF_BUFFER_DMA_EXTERNAL;
+                pBufInfo->index = i;
+                temp_bufferHeader->pInputPortPrivate = (OMX_PTR)pBufInfo;
+                temp_bufferHeader->nInputPortIndex = 0;
+                pSfOMXComponent->pBufferArray[0][i] = temp_bufferHeader;
+                pSfOMXComponent->assignedBufferNum[0] ++;
+
+                if (pSfOMXComponent->assignedBufferNum[0] == pSfOMXComponent->portDefinition[0].nBufferCountActual)
+                {
+                    pSfOMXComponent->portDefinition[0].bPopulated = OMX_TRUE;
+                    SF_SemaphorePost(pSfOMXComponent->portSemaphore[0]);
+                }
+                break;
+            }
+        }
+        if (i == MAX_BUFF_NUM){
+            LOG(SF_LOG_ERR, "buffer array full\r\n");
+            free(temp_bufferHeader);
+            free(pBufInfo);
+            ret = OMX_ErrorInsufficientResources;
+        }
+    }
+
+    LOG(SF_LOG_INFO, "header %p pBuffer address = %p on port %d\r\n", temp_bufferHeader, temp_bufferHeader->pBuffer, nPortIndex);
+EXIT:
+    FunctionOut();
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_AllocateBuffer(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
+    OMX_IN OMX_U32 nPortIndex,
+    OMX_IN OMX_PTR pAppPrivate,
+    OMX_IN OMX_U32 nSizeBytes)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    ComponentImpl *pComponentRender = (ComponentImpl *)pSfVideoImplement->hSFComponentRender;
+    OMX_U32 i;
+
+    FunctionIn();
+    if (nSizeBytes == 0)
+    {
+        LOG(SF_LOG_WARN, "nSizeBytes = %d, use default buffer size\r\n", nSizeBytes);
+        nSizeBytes = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
+    }
+
+    OMX_BUFFERHEADERTYPE *temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)malloc(sizeof(OMX_BUFFERHEADERTYPE));
+    if (temp_bufferHeader == NULL)
+    {
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        return OMX_ErrorInsufficientResources;
+    }
+    memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE));
+
+    SF_OMX_BUF_INFO *pBufInfo = (SF_OMX_BUF_INFO *)malloc(sizeof(SF_OMX_BUF_INFO));
+    if (pBufInfo == NULL)
+    {
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        free(temp_bufferHeader);
+        return OMX_ErrorInsufficientResources;
+    }
+
+    temp_bufferHeader->nAllocLen = nSizeBytes;
+    temp_bufferHeader->pAppPrivate = pAppPrivate;
+    temp_bufferHeader->nSize = sizeof(OMX_BUFFERHEADERTYPE);
+    memcpy(&(temp_bufferHeader->nVersion), &(pSfOMXComponent->componentVersion), sizeof(OMX_VERSIONTYPE));
+    if (nPortIndex == 1)
+    {
+        for (i = 0; i < MAX_BUFF_NUM; i++)
+        {
+            if (!pSfOMXComponent->pBufferArray[1][i])
+            {
+                // Alloc DMA memory first
+                if (pSfOMXComponent->memory_optimization)
+                {
+                    temp_bufferHeader->pBuffer = pSfVideoImplement->functions->AllocateFrameBuffer2(pComponentRender, nSizeBytes);
+                }
+                // DMA Memory alloc fail, goto normal alloc
+                if (temp_bufferHeader->pBuffer == NULL)
+                {
+                    pSfOMXComponent->memory_optimization = OMX_FALSE;
+                    temp_bufferHeader->pBuffer = malloc(nSizeBytes);
+                    memset(temp_bufferHeader->pBuffer, 0, nSizeBytes);
+                    pBufInfo->type = SF_BUFFER_NOMAL;
+                    LOG(SF_LOG_PERF, "Use normal buffer\r\n");
+                }
+                else
+                {
+                    pBufInfo->type = SF_BUFFER_DMA;
+                    LOG(SF_LOG_PERF, "Use DMA buffer\r\n");
+                }
+                pBufInfo->index = i;
+                temp_bufferHeader->pOutputPortPrivate = (OMX_PTR)pBufInfo;
+                temp_bufferHeader->nOutputPortIndex = 1;
+                pSfOMXComponent->pBufferArray[1][i] = temp_bufferHeader;
+                pSfOMXComponent->assignedBufferNum[1] ++;
+
+                if (pSfOMXComponent->assignedBufferNum[1] == pSfOMXComponent->portDefinition[1].nBufferCountActual)
+                {
+                    pSfOMXComponent->portDefinition[1].bPopulated = OMX_TRUE;
+                    SF_SemaphorePost(pSfOMXComponent->portSemaphore[1]);
+                }
+                break;
+            }
+        }
+        if (i == MAX_BUFF_NUM){
+            LOG(SF_LOG_ERR, "buffer array full\r\n");
+            temp_bufferHeader->pBuffer = NULL;
+        }
+    }
+    else if (nPortIndex == 0)
+    {
+        for (i = 0; i < MAX_BUFF_NUM; i++)
+        {
+            if (!pSfOMXComponent->pBufferArray[0][i])
+            {
+                temp_bufferHeader->pBuffer = malloc(nSizeBytes);
+                memset(temp_bufferHeader->pBuffer, 0, nSizeBytes);
+
+                pBufInfo->type = SF_BUFFER_NOMAL;
+                pBufInfo->index = i;
+                temp_bufferHeader->pInputPortPrivate = (OMX_PTR)pBufInfo;
+                temp_bufferHeader->nInputPortIndex = 0;
+                pSfOMXComponent->pBufferArray[0][i] = temp_bufferHeader;
+                pSfOMXComponent->assignedBufferNum[0] ++;
+
+                if (pSfOMXComponent->assignedBufferNum[0] == pSfOMXComponent->portDefinition[0].nBufferCountActual)
+                {
+                    pSfOMXComponent->portDefinition[0].bPopulated = OMX_TRUE;
+                    SF_SemaphorePost(pSfOMXComponent->portSemaphore[0]);
+                }
+                break;
+            }
+        }
+        if (i == MAX_BUFF_NUM){
+            LOG(SF_LOG_ERR, "buffer array full\r\n");
+            temp_bufferHeader->pBuffer = NULL;
+        }
+    }
+
+    if (temp_bufferHeader->pBuffer == NULL)
+    {
+        free(temp_bufferHeader);
+        free(pBufInfo);
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        return OMX_ErrorInsufficientResources;
+    }
+    *ppBuffer = temp_bufferHeader;
+    LOG(SF_LOG_INFO, "header %p pBuffer address = %p on port %d\r\n", temp_bufferHeader, temp_bufferHeader->pBuffer, nPortIndex);
+
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_GetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE nParamIndex,
+    OMX_INOUT OMX_PTR ComponentParameterStructure)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    FunctionIn();
+    LOG(SF_LOG_INFO, "Get parameter on index %X\r\n", nParamIndex);
+    if (hComponent == NULL || ComponentParameterStructure == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    switch ((OMX_U32)nParamIndex)
+    {
+    case OMX_IndexParamVideoInit:
+    {
+        OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure;
+        portParam->nPorts           = 2;
+        portParam->nStartPortNumber = 0;
+    }
+    break;
+    case OMX_IndexParamAudioInit:
+    case OMX_IndexParamImageInit:
+    case OMX_IndexParamOtherInit:
+    {
+        OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure;
+        portParam->nPorts           = 0;
+        portParam->nStartPortNumber = 0;
+    }
+    break;
+    case OMX_IndexParamVideoPortFormat:
+    {
+        OMX_VIDEO_PARAM_PORTFORMATTYPE *portFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure;
+        OMX_U32 index = portFormat->nIndex;
+        switch (index)
+        {
+        case 0:
+            portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
+            portFormat->eColorFormat = OMX_COLOR_FormatYUV420Planar;
+            portFormat->xFramerate = 30;
+            break;
+        case 1:
+            portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
+            portFormat->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+            portFormat->xFramerate = 30;
+            break;
+        case 2:
+            portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
+            portFormat->eColorFormat = OMX_COLOR_FormatYVU420SemiPlanar;
+            portFormat->xFramerate = 30;
+            break;
+        default:
+            if (index > 0)
+            {
+                ret = OMX_ErrorNoMore;
+            }
+            break;
+        }
+    }
+
+    break;
+    case OMX_IndexParamVideoBitrate:
+        break;
+    case OMX_IndexParamVideoQuantization:
+
+        break;
+    case OMX_IndexParamPortDefinition:{
+        OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
+        OMX_U32 portIndex = pPortDefinition->nPortIndex;
+        OMX_PARAM_PORTDEFINITIONTYPE *pSrcDefinition;
+        if (portIndex < 2)
+        {
+            pSrcDefinition = &pSfOMXComponent->portDefinition[portIndex];
+            LOG(SF_LOG_INFO, "Get parameter width = %d, height = %d from port %X\r\n",
+                pSrcDefinition->format.video.nFrameWidth, pSrcDefinition->format.video.nFrameHeight, portIndex);
+            memcpy(pPortDefinition, pSrcDefinition, pPortDefinition->nSize);
+        }
+        else
+        {
+            LOG(SF_LOG_INFO,"Bad port index %d\r\n",portIndex);
+            ret = OMX_ErrorBadPortIndex;
+        }
+    }
+        break;
+
+    case OMX_IndexParamVideoIntraRefresh:
+
+        break;
+
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)ComponentParameterStructure;
+        strcpy((OMX_STRING)(pComponentRole->cRole), pSfOMXComponent->componentRule);
+    }
+        break;
+
+    case OMX_IndexParamVideoAvc:
+        break;
+    case OMX_IndexParamVideoHevc:
+        break;
+    case OMX_IndexParamVideoProfileLevelQuerySupported:
+        break;
+    case OMX_IndexParamCompBufferSupplier:
+    {
+        OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE *)ComponentParameterStructure;
+        OMX_U32 portIndex = bufferSupplier->nPortIndex;
+        if (portIndex >= 2)
+            ret = OMX_ErrorBadPortIndex;
+    }
+        break;
+
+    default:
+        ret = OMX_ErrorUnsupportedIndex;
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_SetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE nIndex,
+    OMX_IN OMX_PTR ComponentParameterStructure)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+    if (hComponent == NULL || ComponentParameterStructure == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+
+    if (pSfOMXComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    TestDecConfig *testConfig = pSfVideoImplement->testConfig;
+    LOG(SF_LOG_INFO, "Set parameter on index %X\r\n", nIndex);
+    switch ((OMX_U32)nIndex)
+    {
+    case OMX_IndexParamVideoPortFormat:
+    {
+        OMX_VIDEO_PARAM_PORTFORMATTYPE *portFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure;
+        OMX_U32 nPortIndex = portFormat->nPortIndex;
+        TestDecConfig *pTestDecConfig = (TestDecConfig *)pSfVideoImplement->testConfig;
+        OMX_PARAM_PORTDEFINITIONTYPE *pPort = &pSfOMXComponent->portDefinition[nPortIndex];
+        LOG(SF_LOG_DEBUG, "Set video format to port %d color %d\r\n", portFormat->nPortIndex, portFormat->eColorFormat);
+        switch (portFormat->eColorFormat)
+        {
+             case OMX_COLOR_FormatYUV420Planar: //I420
+                pTestDecConfig->cbcrInterleave = FALSE;
+                pTestDecConfig->nv21 = FALSE;
+                pPort->format.video.eColorFormat = portFormat->eColorFormat;
+                break;
+            case OMX_COLOR_FormatYUV420SemiPlanar: //NV12
+                pTestDecConfig->cbcrInterleave = TRUE;
+                pTestDecConfig->nv21 = FALSE;
+                pPort->format.video.eColorFormat = portFormat->eColorFormat;
+                break;
+            case OMX_COLOR_FormatYVU420SemiPlanar: //NV21
+                pTestDecConfig->cbcrInterleave = TRUE;
+                pTestDecConfig->nv21 = TRUE;
+                pPort->format.video.eColorFormat = portFormat->eColorFormat;
+                break;
+            default:
+                LOG(SF_LOG_ERR, "Error to set parameter: %d, only nv12 nv21 i420 supported\r\n", portFormat->eColorFormat);
+                return OMX_ErrorBadParameter;
+                break;
+        }
+        break;
+    }
+    case OMX_IndexParamVideoBitrate:
+        break;
+    case OMX_IndexParamVideoQuantization:
+
+        break;
+    break;
+    case OMX_IndexParamPortDefinition:
+    {
+        OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
+        OMX_PARAM_PORTDEFINITIONTYPE *pInputPort = &pSfOMXComponent->portDefinition[0];
+        OMX_PARAM_PORTDEFINITIONTYPE *pOutputPort = &pSfOMXComponent->portDefinition[1];
+        TestDecConfig *pTestDecConfig = (TestDecConfig *)pSfVideoImplement->testConfig;
+        OMX_U32 portIndex = pPortDefinition->nPortIndex;
+        OMX_U32 width = pPortDefinition->format.video.nFrameWidth;
+        OMX_U32 height = pPortDefinition->format.video.nFrameHeight;
+        LOG(SF_LOG_INFO, "Set width = %d, height = %d on port %d\r\n", width, height, pPortDefinition->nPortIndex);
+
+        if (portIndex == 0)
+        {
+            if (pPortDefinition->nBufferCountActual != pInputPort->nBufferCountActual)
+            {
+                LOG(SF_LOG_INFO, "Set input buffer count = %d\r\n", pPortDefinition->nBufferCountActual);
+                ComponentImpl *pFeederComponent = (ComponentImpl *)pSfVideoImplement->hSFComponentFeeder;
+                if (pFeederComponent)
+                {
+                    pSfVideoImplement->functions->ComponentPortDestroy(&pFeederComponent->srcPort);
+                    pSfVideoImplement->functions->ComponentPortCreate(&pFeederComponent->srcPort, pSfVideoImplement->hSFComponentFeeder,
+                                                                        pPortDefinition->nBufferCountActual, sizeof(PortContainerExternal));
+                }
+            }
+
+            memcpy(&pSfOMXComponent->portDefinition[portIndex], pPortDefinition, pPortDefinition->nSize);
+
+            pInputPort->format.video.nStride = width;
+            pInputPort->format.video.nSliceHeight = height;
+            pInputPort->nBufferSize = width * height * 2;
+        }
+        else if (portIndex == 1)
+        {
+            if (pPortDefinition->nBufferCountActual != pOutputPort->nBufferCountActual)
+            {
+                LOG(SF_LOG_INFO, "Set output buffer count = %d\r\n", pPortDefinition->nBufferCountActual);
+                ComponentImpl *pRenderComponent = (ComponentImpl *)pSfVideoImplement->hSFComponentRender;
+                if (pRenderComponent)
+                {
+                    pSfVideoImplement->functions->SetRenderTotalBufferNumber(pRenderComponent, pPortDefinition->nBufferCountActual);
+                    pSfVideoImplement->functions->ComponentPortDestroy(&pRenderComponent->sinkPort);
+                    pSfVideoImplement->functions->ComponentPortCreate(&pRenderComponent->sinkPort, pSfVideoImplement->hSFComponentRender,
+                                                                        pPortDefinition->nBufferCountActual, sizeof(PortContainerExternal));
+                }
+            }
+
+            memcpy(&pSfOMXComponent->portDefinition[portIndex], pPortDefinition, pPortDefinition->nSize);
+
+            /*
+              Some client may set '0' or '1' to output port, in this case use input port parameters
+            */
+            if (width <= 1)
+            {
+                width = pInputPort->format.video.nFrameWidth;
+            }
+            if (height <= 1)
+            {
+                height = pInputPort->format.video.nFrameHeight;
+            }
+            if (width > 0 && height > 0)
+            {
+                int scalew = pInputPort->format.video.nFrameWidth / width;
+                int scaleh = pInputPort->format.video.nFrameHeight / height;
+                if (scalew > 8 || scaleh > 8 || scalew < 1 || scaleh < 1)
+                {
+                    int nInputWidth = pInputPort->format.video.nFrameWidth;
+                    int nInputHeight = pInputPort->format.video.nFrameHeight;
+                    LOG(SF_LOG_WARN, "Scaling should be 1 to 1/8 (down-scaling only)! Use input parameter. "
+                        "OutPut[%d, %d]. Input[%d, %d]\r\n", width, height, nInputWidth, nInputHeight);
+                    width = nInputWidth;
+                    height = nInputHeight;
+                }
+            }
+            pOutputPort->format.video.nFrameWidth = width;
+            pOutputPort->format.video.nFrameHeight = height;
+            pOutputPort->format.video.nStride = width;
+            pOutputPort->format.video.nSliceHeight = height;
+            pTestDecConfig->scaleDownWidth = VPU_CEIL(width, 2);
+            pTestDecConfig->scaleDownHeight = VPU_CEIL(height, 2);
+            LOG(SF_LOG_INFO, "Set scale = %d, %d\r\n", pTestDecConfig->scaleDownWidth , pTestDecConfig->scaleDownHeight);
+             /*
+                if cbcrInterleave is FALSE and nv21 is FALSE, the default dec format is I420
+                if cbcrInterleave is TRUE and nv21 is FALSE, then the dec format is NV12
+                if cbcrInterleave is TRUE and nv21 is TRUE, then the dec format is NV21
+            */
+            LOG(SF_LOG_INFO, "Set format = %d\r\n", pOutputPort->format.video.eColorFormat);
+            switch (pOutputPort->format.video.eColorFormat)
+            {
+            case OMX_COLOR_FormatYUV420Planar: //I420
+                pTestDecConfig->cbcrInterleave = FALSE;
+                pTestDecConfig->nv21 = FALSE;
+                if (width && height)
+                    pOutputPort->nBufferSize = (width * height * 3) / 2;
+                break;
+            case OMX_COLOR_FormatYUV420SemiPlanar: //NV12
+                pTestDecConfig->cbcrInterleave = TRUE;
+                pTestDecConfig->nv21 = FALSE;
+                if (width && height)
+                    pOutputPort->nBufferSize = (width * height * 3) / 2;
+                break;
+            case OMX_COLOR_FormatYVU420SemiPlanar: //NV21
+                pTestDecConfig->cbcrInterleave = TRUE;
+                pTestDecConfig->nv21 = TRUE;
+                if (width && height)
+                    pOutputPort->nBufferSize = (width * height * 3) / 2;
+                break;
+            default:
+                LOG(SF_LOG_ERR, "Error to set parameter: %d, only nv12 nv21 i420 supported\r\n",
+                    pOutputPort->format.video.eColorFormat);
+                return OMX_ErrorBadParameter;
+                break;
+            }
+        }
+        else
+        {
+            LOG(SF_LOG_INFO,"Bad port index %d\r\n",portIndex);
+            ret = OMX_ErrorBadPortIndex;
+        }
+    }
+    break;
+    case OMX_IndexParamVideoIntraRefresh:
+
+        break;
+
+    case OMX_IndexParamStandardComponentRole:
+    {
+        if ((pSfOMXComponent->state != OMX_StateLoaded) &&
+                (pSfOMXComponent->state != OMX_StateWaitForResources)) {
+            ret = OMX_ErrorIncorrectStateOperation;
+        }
+    }
+        break;
+
+    case OMX_IndexParamVideoAvc:
+        testConfig->bitFormat = 0;
+        break;
+    case OMX_IndexParamVideoHevc:
+        testConfig->bitFormat = 12;
+        break;
+    case OMX_IndexParamCompBufferSupplier:
+    {
+        OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE *)ComponentParameterStructure;
+        OMX_U32 portIndex = bufferSupplier->nPortIndex;
+        if (portIndex >= 2)
+            ret = OMX_ErrorBadPortIndex;
+    }
+        break;
+
+    default:
+        ret = OMX_ErrorUnsupportedIndex;
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_GetConfig(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE nIndex,
+    OMX_PTR pComponentConfigStructure)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if (hComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    switch (nIndex)
+    {
+    case OMX_IndexConfigVideoAVCIntraPeriod:
+
+        break;
+    case OMX_IndexConfigVideoBitrate:
+
+        break;
+    case OMX_IndexConfigVideoFramerate:
+
+        break;
+
+    default:
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_SetConfig(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE nIndex,
+    OMX_PTR pComponentConfigStructure)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if (hComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    switch ((OMX_U32)nIndex)
+    {
+    case OMX_IndexConfigVideoAVCIntraPeriod:
+        break;
+    case OMX_IndexConfigVideoBitrate:
+        break;
+    case OMX_IndexConfigVideoFramerate:
+        break;
+    case OMX_IndexConfigVideoIntraVOPRefresh:
+        break;
+    default:
+
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_ComponentTunnelRequest(
+    OMX_IN OMX_HANDLETYPE hComp,
+    OMX_IN OMX_U32        nPort,
+    OMX_IN OMX_HANDLETYPE hTunneledComp,
+    OMX_IN OMX_U32        nTunneledPort,
+    OMX_INOUT OMX_TUNNELSETUPTYPE *pTunnelSetup)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    (void) hComp;
+    (void) nPort;
+    (void) hTunneledComp;
+    (void) nTunneledPort;
+    (void) pTunnelSetup;
+    ret = OMX_ErrorTunnelingUnsupported;
+    goto EXIT;
+EXIT:
+    return ret;
+}
+
+static OMX_ERRORTYPE InitDecoder(SF_OMX_COMPONENT *pSfOMXComponent)
+{
+    TestDecConfig *testConfig = NULL;
+    CNMComponentConfig *config = NULL;
+    Uint32 sizeInWord;
+    char *fwPath = NULL;
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+
+    if (pSfVideoImplement->hSFComponentExecoder != NULL)
+    {
+        return OMX_ErrorNone;
+    }
+
+    FunctionIn();
+
+    testConfig = (TestDecConfig *)pSfVideoImplement->testConfig;
+
+    testConfig->productId = (ProductId)pSfVideoImplement->functions->VPU_GetProductId(testConfig->coreIdx);
+    if (CheckDecTestConfig(testConfig) == FALSE)
+    {
+        LOG(SF_LOG_ERR, "fail to CheckTestConfig()\n");
+        return OMX_ErrorBadParameter;
+    }
+
+    switch (testConfig->productId)
+    {
+    case PRODUCT_ID_521:
+        fwPath = pSfOMXComponent->fwPath;
+        break;
+    case PRODUCT_ID_511:
+        fwPath = pSfOMXComponent->fwPath;
+        break;
+    case PRODUCT_ID_517:
+        fwPath = CORE_7_BIT_CODE_FILE_PATH;
+        break;
+    default:
+        LOG(SF_LOG_ERR, "Unknown product id: %d, whether kernel module loaded?\n", testConfig->productId);
+        return OMX_ErrorBadParameter;
+    }
+    LOG(SF_LOG_INFO, "FW PATH = %s\n", fwPath);
+    if (pSfVideoImplement->functions->LoadFirmware(testConfig->productId, (Uint8 **)&(pSfVideoImplement->pusBitCode), &sizeInWord, fwPath) < 0)
+    {
+        LOG(SF_LOG_ERR, "Failed to load firmware: %s\n", fwPath);
+        return OMX_ErrorInsufficientResources;
+    }
+
+    config = pSfVideoImplement->config;
+    memcpy(&(config->testDecConfig), testConfig, sizeof(TestDecConfig));
+    config->bitcode = (Uint8 *)pSfVideoImplement->pusBitCode;
+    config->sizeOfBitcode = sizeInWord;
+
+    if (pSfVideoImplement->functions->SetUpDecoderOpenParam(&config->decOpenParam, &config->testDecConfig) != RETCODE_SUCCESS)
+    {
+        LOG(SF_LOG_ERR, "SetupDecoderOpenParam error\n");
+        return OMX_ErrorBadParameter;
+    }
+    LOG(SF_LOG_DEBUG, "cbcrInterleave = %d, nv21 = %d\r\n", testConfig->cbcrInterleave, testConfig->nv21);
+    pSfVideoImplement->hSFComponentExecoder = pSfVideoImplement->functions->ComponentCreate("wave_decoder", config);
+    pSfVideoImplement->hSFComponentFeeder = pSfVideoImplement->functions->ComponentCreate("feeder", config);
+    pSfVideoImplement->hSFComponentRender = pSfVideoImplement->functions->ComponentCreate("renderer", config);
+
+    ComponentImpl *pFeederComponent = (ComponentImpl *)pSfVideoImplement->hSFComponentFeeder;
+    pSfVideoImplement->functions->ComponentPortCreate(&pFeederComponent->srcPort, pSfVideoImplement->hSFComponentFeeder,
+                                        pSfOMXComponent->portDefinition[0].nBufferCountActual, sizeof(PortContainerExternal));
+
+    ComponentImpl *pRenderComponent = (ComponentImpl *)pSfVideoImplement->hSFComponentRender;
+    pSfVideoImplement->functions->ComponentPortDestroy(&pRenderComponent->sinkPort);
+    pSfVideoImplement->functions->ComponentPortCreate(&pRenderComponent->sinkPort, pSfVideoImplement->hSFComponentRender,
+                                        pSfOMXComponent->portDefinition[1].nBufferCountActual, sizeof(PortContainerExternal));
+
+    if (pSfVideoImplement->functions->SetupDecListenerContext(pSfVideoImplement->lsnCtx, config, NULL) == TRUE)
+    {
+        pSfVideoImplement->functions->ComponentRegisterListener(pSfVideoImplement->hSFComponentExecoder,
+                                                              COMPONENT_EVENT_DEC_ALL, pSfVideoImplement->functions->DecoderListener, (void *)pSfVideoImplement->lsnCtx);
+        pSfVideoImplement->functions->ComponentRegisterListener(pSfVideoImplement->hSFComponentRender,
+                                                              COMPONENT_EVENT_DEC_DECODED_ALL, OnEventArrived, (void *)pSfOMXComponent);
+        pSfVideoImplement->functions->ComponentRegisterListener(pSfVideoImplement->hSFComponentFeeder,
+                                                              COMPONENT_EVENT_DEC_ALL, OnEventArrived, (void *)pSfOMXComponent);
+        pSfVideoImplement->functions->ComponentRegisterListener(pSfVideoImplement->hSFComponentRender,
+                                                              COMPONENT_EVENT_DEC_ALL, OnEventArrived, (void *)pSfOMXComponent);
+    }
+    else
+    {
+        LOG(SF_LOG_ERR, "ComponentRegisterListener fail\r\n");
+        return OMX_ErrorBadParameter;
+    }
+
+    pSfVideoImplement->functions->ComponentSetupTunnel(pSfVideoImplement->hSFComponentFeeder, pSfVideoImplement->hSFComponentExecoder);
+    pSfVideoImplement->functions->ComponentSetupTunnel(pSfVideoImplement->hSFComponentExecoder, pSfVideoImplement->hSFComponentRender);
+    FunctionOut();
+    return OMX_ErrorNone;
+}
+
+static OMX_ERRORTYPE SF_OMX_SendCommand(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_COMMANDTYPE Cmd,
+    OMX_IN OMX_U32 nParam,
+    OMX_IN OMX_PTR pCmdData)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    OMX_STATETYPE comCurrentState;
+    DEC_CMD cmd;
+
+    //BOOL done = 0;
+
+    FunctionIn();
+    if (hComponent == NULL || pSfOMXComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+
+    LOG(SF_LOG_INFO, "cmd = %X, nParam = %X\r\n", Cmd, nParam);
+
+    comCurrentState = pSfOMXComponent->state;
+
+    if (comCurrentState == OMX_StateInvalid) {
+        return OMX_ErrorInvalidState;
+    }
+
+    switch (Cmd)
+    {
+    case OMX_CommandStateSet:
+    {
+        if ((nParam == OMX_StateLoaded) &&
+            (pSfOMXComponent->state == OMX_StateIdle))
+        {
+            pSfOMXComponent->traningState = OMX_TransStateIdleToLoaded;
+        }
+        else if ((nParam == OMX_StateIdle) &&
+            (pSfOMXComponent->state == OMX_StateLoaded))
+        {
+            pSfOMXComponent->traningState = OMX_TransStateLoadedToIdle;
+        }
+    }
+    break;
+
+    case OMX_CommandFlush:
+    {
+        if (nParam >= 2 && nParam != OMX_ALL)
+            return OMX_ErrorBadPortIndex;
+    }
+    break;
+
+    case OMX_CommandMarkBuffer:
+    {
+        if (nParam >= 2)
+            return OMX_ErrorBadPortIndex;
+        if ((pSfOMXComponent->state != OMX_StateExecuting) &&
+            (pSfOMXComponent->state != OMX_StatePause))
+            return OMX_ErrorIncorrectStateOperation;
+    }
+    break;
+
+    case OMX_CommandPortDisable:
+    {
+        if (nParam >= 2 && nParam != OMX_ALL)
+            return OMX_ErrorBadPortIndex;
+
+        if (nParam == OMX_ALL)
+        {
+            for (int i = 0; i < 2; i++)
+            {
+                if(pSfOMXComponent->portDefinition[i].bEnabled == OMX_FALSE)
+                    return OMX_ErrorIncorrectStateOperation;
+            }
+            for (int i = 0; i < 2; i++)
+            {
+                pSfOMXComponent->portDefinition[i].bEnabled = OMX_FALSE;
+            }
+        }
+        else
+        {
+            if (pSfOMXComponent->portDefinition[nParam].bEnabled == OMX_FALSE)
+                return OMX_ErrorIncorrectStateOperation;
+            pSfOMXComponent->portDefinition[nParam].bEnabled = OMX_FALSE;
+        }
+    }
+    break;
+
+    case OMX_CommandPortEnable:
+    {
+        if (nParam >= 2 && nParam != OMX_ALL)
+            return OMX_ErrorBadPortIndex;
+
+        if (nParam == OMX_ALL)
+        {
+            for (int i = 0; i < 2; i++)
+            {
+                if(pSfOMXComponent->portDefinition[i].bEnabled == OMX_TRUE)
+                    return OMX_ErrorIncorrectStateOperation;
+            }
+            for (int i = 0; i < 2; i++)
+            {
+                pSfOMXComponent->portDefinition[i].bEnabled = OMX_TRUE;
+            }
+        }
+        else
+        {
+            if (pSfOMXComponent->portDefinition[nParam].bEnabled == OMX_TRUE)
+                return OMX_ErrorIncorrectStateOperation;
+            pSfOMXComponent->portDefinition[nParam].bEnabled = OMX_TRUE;
+        }
+    }
+    break;
+
+    default:
+    break;
+    }
+
+    cmd.Cmd = Cmd;
+    cmd.nParam = nParam;
+    cmd.pCmdData = pCmdData;
+
+    ret = SF_Queue_Enqueue(pSfVideoImplement->CmdQueue, &cmd);
+
+EXIT:
+    FunctionOut();
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_GetState(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_OUT OMX_STATETYPE *pState)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    FunctionIn();
+    *pState = pSfOMXComponent->state;
+
+    FunctionOut();
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_FreeBuffer(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_U32 nPortIndex,
+    OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    SF_OMX_BUF_INFO *pBufInfo;
+
+    FunctionIn();
+    if(pBufferHdr == NULL)
+        return OMX_ErrorBadParameter;
+
+    if(nPortIndex == 0)
+        pBufInfo = pBufferHdr->pInputPortPrivate;
+    else if(nPortIndex == 1)
+        pBufInfo = pBufferHdr->pOutputPortPrivate;
+
+    LOG(SF_LOG_INFO, "free header %p pBuffer address = %p on port %d\r\n",
+                                            pBufferHdr, pBufferHdr->pBuffer, nPortIndex);
+
+    if ((pSfOMXComponent->traningState != OMX_TransStateIdleToLoaded) &&
+            (pSfOMXComponent->portDefinition[nPortIndex].bEnabled))
+    {
+        LOG(SF_LOG_INFO, "port Unpopulated\r\n");
+        pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
+                                                    OMX_EventError, OMX_ErrorPortUnpopulated, nPortIndex, NULL);
+    }
+
+    if(pBufInfo->type == SF_BUFFER_NOMAL)
+    {
+        if(pBufferHdr->pBuffer)
+            free(pBufferHdr->pBuffer);
+    }
+
+    pSfOMXComponent->pBufferArray[nPortIndex][pBufInfo->index] = NULL;
+    pSfOMXComponent->assignedBufferNum[nPortIndex]--;
+    LOG(SF_LOG_INFO, "remain %d buff port %d assgin\r\n",pSfOMXComponent->assignedBufferNum[nPortIndex], nPortIndex);
+
+    free(pBufferHdr);
+    free(pBufInfo);
+
+    if (ret == OMX_ErrorNone) {
+        if (pSfOMXComponent->assignedBufferNum[nPortIndex] == 0) {
+            LOG(SF_LOG_INFO, "unloadedResource signal set\r\n");
+            SF_SemaphorePost(pSfOMXComponent->portUnloadSemaphore[nPortIndex]);
+            pSfOMXComponent->portDefinition[nPortIndex].bPopulated = OMX_FALSE;
+        }
+    }
+
+    FunctionOut();
+    return ret;
+}
+
+static void CmdThread(void *args)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    SF_OMX_COMPONENT *pSfOMXComponent = (SF_OMX_COMPONENT *)args;
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    OMX_STATETYPE comCurrentState;
+    ComponentImpl *pSFComponentDecoder = NULL;
+    ComponentImpl *pSFComponentFeeder = NULL;
+    ComponentImpl *pSFComponentRender = NULL;
+    ComponentState componentState;
+    OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL;
+    OMX_BUFFERHEADERTYPE **ppBuffer = NULL;
+    DEC_CMD *pCmd;
+    OMX_U32 i = 0, cnt = 0;
+
+    while(1){
+        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+        pCmd = (DEC_CMD*)SF_Queue_Dequeue_Block(pSfVideoImplement->CmdQueue);
+        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+        pthread_testcancel();
+        pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
+
+        if(!pCmd)
+            continue;
+
+        if(pCmd->Cmd == DEC_StopThread)
+            break;
+
+        switch (pCmd->Cmd)
+        {
+        case OMX_CommandStateSet:
+            LOG(SF_LOG_INFO, "OMX dest state = %X\r\n", pCmd->nParam);
+
+            //GetStateCommon(hComponent, &comCurrentState);
+            comCurrentState = pSfOMXComponent->state;
+
+            if (comCurrentState == pCmd->nParam)
+            {
+                LOG(SF_LOG_DEBUG, "same state %d\r\n", pCmd->nParam);
+                pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
+                                                    OMX_EventError, OMX_ErrorSameState, pCmd->nParam, NULL);
+                break;
+            }
+
+            ret = OMX_ErrorNone;
+
+            switch (pCmd->nParam)
+            {
+            case OMX_StateInvalid:
+                switch (comCurrentState)
+                {
+                case OMX_StateExecuting:
+                    pSfVideoImplement->functions->ComponentStop(pSfVideoImplement->hSFComponentFeeder);
+                    pSfVideoImplement->functions->ComponentStop(pSfVideoImplement->hSFComponentExecoder);
+                    pSfVideoImplement->functions->ComponentStop(pSfVideoImplement->hSFComponentRender);
+                case OMX_StateIdle:
+                case OMX_StatePause:
+                case OMX_StateLoaded:
+                case OMX_StateWaitForResources:
+                default:
+                    pSfOMXComponent->state = OMX_StateInvalid;
+                    break;
+                }
+                ret = OMX_ErrorInvalidState;
+                break;
+
+            case OMX_StateLoaded:
+                switch (comCurrentState)
+                {
+                case OMX_StateWaitForResources:
+                    break;
+                case OMX_StateIdle:
+                    for (i = 0; i < 2; i++)
+                    {
+                        if (pSfOMXComponent->portDefinition[i].bEnabled){
+                            LOG(SF_LOG_INFO,"unload SemaphoreWait \r\n");
+                            SF_SemaphoreWait(pSfOMXComponent->portUnloadSemaphore[i]);
+                            LOG(SF_LOG_INFO,"unload SemaphoreWait out\r\n");
+                        }
+                    }
+                    break;
+                default:
+                    ret = OMX_ErrorIncorrectStateTransition;
+                    break;
+                }
+                break;
+            case OMX_StateIdle:
+                if (comCurrentState == OMX_StatePause)
+                {
+                    comCurrentState = pSfOMXComponent->stateBeforePause;
+                }
+                switch (comCurrentState)
+                {
+                case OMX_StateLoaded:
+                    ret = InitDecoder(pSfOMXComponent);
+                    if (ret != OMX_ErrorNone)
+                    {
+                        break;
+                    }
+                    pSFComponentDecoder = (ComponentImpl *)pSfVideoImplement->hSFComponentExecoder;
+                    pSFComponentFeeder = (ComponentImpl *)pSfVideoImplement->hSFComponentFeeder;
+                    pSFComponentRender = (ComponentImpl *)pSfVideoImplement->hSFComponentRender;
+                    pSFComponentFeeder->pause = OMX_FALSE;
+                    pSFComponentDecoder->pause = OMX_FALSE;
+                    pSFComponentRender->pause = OMX_FALSE;
+                    for (i = 0; i < 2; i++)
+                    {
+                        if (pSfOMXComponent->portDefinition[i].bEnabled){
+                            LOG(SF_LOG_INFO,"SemaphoreWait \r\n");
+                            SF_SemaphoreWait(pSfOMXComponent->portSemaphore[i]);
+                            LOG(SF_LOG_INFO,"SemaphoreWait out\r\n");
+                        }
+                    }
+                    pSfVideoImplement->rev_eos =OMX_FALSE;
+                    break;
+                case OMX_StateExecuting:
+                    pSFComponentDecoder = (ComponentImpl *)pSfVideoImplement->hSFComponentExecoder;
+                    pSFComponentFeeder = (ComponentImpl *)pSfVideoImplement->hSFComponentFeeder;
+                    pSFComponentRender = (ComponentImpl *)pSfVideoImplement->hSFComponentRender;
+                    LOG(SF_LOG_INFO,"feeder src q cnt %d\r\n",
+                        pSfVideoImplement->functions->Queue_Get_Cnt(((ComponentImpl *)(pSfVideoImplement->hSFComponentFeeder))->srcPort.inputQ));
+                    pSfVideoImplement->functions->ComponentStop(pSFComponentRender);
+                    pSfVideoImplement->functions->ComponentStop(pSFComponentDecoder);
+                    pSfVideoImplement->functions->ComponentStop(pSFComponentFeeder);
+                    FlushBuffer(pSfOMXComponent, 0);
+                    FlushBuffer(pSfOMXComponent, 1);
+                    pSfVideoImplement->functions->ComponentWait(pSFComponentRender);
+                    pSfVideoImplement->functions->ComponentWait(pSFComponentDecoder);
+                    pSfVideoImplement->functions->ComponentWait(pSFComponentFeeder);
+                    pSFComponentRender->terminate = OMX_TRUE;
+                    pSFComponentDecoder->terminate = OMX_TRUE;
+                    pSFComponentFeeder->terminate = OMX_TRUE;
+                    pSfVideoImplement->functions->ComponentRelease(pSFComponentFeeder);
+                    pSfVideoImplement->functions->ComponentRelease(pSFComponentDecoder);
+                    pSfVideoImplement->functions->ComponentRelease(pSFComponentRender);
+                    pSfVideoImplement->functions->ComponentDestroy(pSFComponentFeeder, NULL);
+                    pSfVideoImplement->functions->ComponentDestroy(pSFComponentDecoder, NULL);
+                    pSfVideoImplement->functions->ComponentDestroy(pSFComponentRender, NULL);
+                    pSfVideoImplement->hSFComponentExecoder = NULL;
+                    pSfVideoImplement->hSFComponentFeeder = NULL;
+                    pSfVideoImplement->hSFComponentRender = NULL;
+                    pSfVideoImplement->rev_eos =OMX_FALSE;
+                    break;
+                case OMX_StateIdle:
+                    pSFComponentFeeder->pause = OMX_FALSE;
+                    pSFComponentDecoder->pause = OMX_FALSE;
+                    pSFComponentRender->pause = OMX_FALSE;
+                    break;
+                default:
+                    ret = OMX_ErrorIncorrectStateTransition;
+                    break;
+                }
+                break;
+
+            case OMX_StateWaitForResources:
+                switch (comCurrentState)
+                {
+                case OMX_StateLoaded:
+                    break;
+                default:
+                    ret = OMX_ErrorIncorrectStateTransition;
+                    break;
+                }
+                break;
+
+            case OMX_StateExecuting:
+                if (comCurrentState == OMX_StatePause)
+                {
+                    comCurrentState = pSfOMXComponent->stateBeforePause;
+                }
+                switch (comCurrentState)
+                {
+                case OMX_StateIdle:
+                    ret = InitDecoder(pSfOMXComponent);
+                    if (ret != OMX_ErrorNone)
+                    {
+                        break;
+                    }
+                    pSFComponentDecoder = (ComponentImpl *)pSfVideoImplement->hSFComponentExecoder;
+                    pSFComponentFeeder = (ComponentImpl *)pSfVideoImplement->hSFComponentFeeder;
+                    pSFComponentRender = (ComponentImpl *)pSfVideoImplement->hSFComponentRender;
+                    if (pSFComponentDecoder->thread == NULL)
+                    {
+                        LOG(SF_LOG_INFO, "execute component %s\r\n", pSFComponentDecoder->name);
+                        componentState = pSfVideoImplement->functions->ComponentExecute(pSFComponentDecoder);
+                        LOG(SF_LOG_INFO, "ret = %d\r\n", componentState);
+                    }
+                    if (pSFComponentFeeder->thread == NULL)
+                    {
+                        LOG(SF_LOG_INFO, "execute component %s\r\n", pSFComponentFeeder->name);
+                        componentState = pSfVideoImplement->functions->ComponentExecute(pSFComponentFeeder);
+                        LOG(SF_LOG_INFO, "ret = %d\r\n", componentState);
+                    }
+                    if (pSFComponentRender->thread == NULL)
+                    {
+                        LOG(SF_LOG_INFO, "execute component %s\r\n", pSFComponentRender->name);
+                        componentState = pSfVideoImplement->functions->ComponentExecute(pSFComponentRender);
+                        LOG(SF_LOG_INFO, "ret = %d\r\n", componentState);
+                    }
+                    pSFComponentFeeder->pause = OMX_FALSE;
+                    pSFComponentDecoder->pause = OMX_FALSE;
+                    pSFComponentRender->pause = OMX_FALSE;
+                    break;
+                case OMX_StateExecuting:
+                    pSFComponentFeeder->pause = OMX_FALSE;
+                    pSFComponentDecoder->pause = OMX_FALSE;
+                    pSFComponentRender->pause = OMX_FALSE;
+                    break;
+                default:
+                    ret = OMX_ErrorIncorrectStateTransition;
+                    break;
+                }
+                break;
+
+            case OMX_StatePause:
+                switch (comCurrentState)
+                {
+                case OMX_StateIdle:
+                case OMX_StateExecuting:
+                    pSFComponentFeeder->pause = OMX_TRUE;
+                    pSFComponentDecoder->pause = OMX_TRUE;
+                    pSFComponentRender->pause = OMX_TRUE;
+                    pSfOMXComponent->stateBeforePause = comCurrentState;
+                    break;
+                default:
+                    ret = OMX_ErrorIncorrectStateTransition;
+                    break;
+                }
+                break;
+
+            default:
+                ret = OMX_ErrorIncorrectStateTransition;
+                break;
+            }
+
+            if (ret == OMX_ErrorNone)
+            {
+                pSfOMXComponent->state = pCmd->nParam;
+                pSfOMXComponent->traningState = OMX_TransStateInvalid;
+                pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
+                                                    OMX_EventCmdComplete, OMX_CommandStateSet, pCmd->nParam, NULL);
+                LOG(SF_LOG_DEBUG, "complete cmd StateSet %d\r\n", pCmd->nParam);
+
+                if (pSfOMXComponent->state == OMX_StateExecuting)
+                {
+                    ppBuffer = SF_Queue_Dequeue(pSfVideoImplement->pauseQ);
+                    while (ppBuffer)
+                    {
+                        pOMXBuffer = *ppBuffer;
+                        pSfOMXComponent->callbacks->FillBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pOMXBuffer);
+                        ppBuffer = SF_Queue_Dequeue(pSfVideoImplement->pauseQ);
+                    }
+                }
+            }
+            else
+            {
+                pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
+                                                    OMX_EventError, ret, 0, NULL);
+                LOG(SF_LOG_DEBUG, "Can't go to state %d from %d, ret %X \r\n",pSfOMXComponent->state, pCmd->nParam, ret);
+            }
+            break;
+
+        case OMX_CommandFlush:
+        {
+            LOG(SF_LOG_INFO, "flush port %d\r\n", pCmd->nParam);
+            OMX_U32 nPort = pCmd->nParam;
+            cnt = (pCmd->nParam == OMX_ALL) ? 2 : 1;
+
+            for (i = 0; i < cnt; i++) {
+                if (pCmd->nParam == OMX_ALL)
+                    nPort = i;
+                else
+                    nPort = pCmd->nParam;
+
+                if (nPort == 0)
+                {
+                    FlushBuffer(pSfOMXComponent, nPort);
+                    pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
+                                                    OMX_EventCmdComplete, OMX_CommandFlush, nPort, NULL);
+                }
+                else
+                {
+                    FlushBuffer(pSfOMXComponent, nPort);
+                    if (pSfOMXComponent->state == OMX_StatePause)
+                    {
+                        ppBuffer = SF_Queue_Dequeue(pSfVideoImplement->pauseQ);
+                        while (ppBuffer)
+                        {
+                            pOMXBuffer = *ppBuffer;
+                            pSfOMXComponent->callbacks->FillBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pOMXBuffer);
+                            ppBuffer = SF_Queue_Dequeue(pSfVideoImplement->pauseQ);
+                        }
+                    }
+                    pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
+                                                    OMX_EventCmdComplete, OMX_CommandFlush, nPort, NULL);
+                }
+            }
+        }
+        break;
+
+        case OMX_CommandPortDisable:
+        {
+            LOG(SF_LOG_INFO, "disable port %d\r\n", pCmd->nParam);
+            OMX_U32 nPort;
+            cnt = (pCmd->nParam == OMX_ALL) ? 2 : 1;
+
+            for (i = 0; i < cnt; i++) {
+                if (pCmd->nParam == OMX_ALL)
+                    nPort = i;
+                else
+                    nPort = pCmd->nParam;
+
+                FlushBuffer(pSfOMXComponent, nPort);
+            }
+
+            for (i = 0; i < cnt; i++) {
+                if (pCmd->nParam == OMX_ALL)
+                    nPort = i;
+                else
+                    nPort = pCmd->nParam;
+
+                if (pSfOMXComponent->state != OMX_StateLoaded)
+                    SF_SemaphoreWait(pSfOMXComponent->portUnloadSemaphore[nPort]);
+                pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
+                                                    OMX_EventCmdComplete, OMX_CommandPortDisable, nPort, NULL);
+            }
+        }
+        break;
+
+        case OMX_CommandPortEnable:
+        {
+            LOG(SF_LOG_INFO, "enable port %d\r\n", pCmd->nParam);
+            OMX_U32 nPort;
+            cnt = (pCmd->nParam == OMX_ALL) ? 2 : 1;
+
+            for (i = 0; i < cnt; i++) {
+                if (pCmd->nParam == OMX_ALL)
+                    nPort = i;
+                else
+                    nPort = pCmd->nParam;
+
+                if ((pSfOMXComponent->state != OMX_StateLoaded) &&
+                        (pSfOMXComponent->state != OMX_StateWaitForResources))
+                    SF_SemaphoreWait(pSfOMXComponent->portSemaphore[nPort]);
+                pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
+                                                    OMX_EventCmdComplete, OMX_CommandPortEnable, nPort, NULL);
+            }
+        }
+        break;
+
+        case OMX_CommandMarkBuffer:
+        {
+            LOG(SF_LOG_INFO, "set mark %d\r\n", pCmd->nParam);
+            OMX_U32 nPort;
+            nPort = pCmd->nParam;
+            pSfOMXComponent->markType[nPort].hMarkTargetComponent =
+                                ((OMX_MARKTYPE *)pCmd->pCmdData)->hMarkTargetComponent;
+            pSfOMXComponent->markType[nPort].pMarkData =
+                                ((OMX_MARKTYPE *)pCmd->pCmdData)->pMarkData;
+        }
+        break;
+
+        default:
+            break;
+        }
+    }
+
+    pthread_exit(NULL);
+}
+
+static OMX_ERRORTYPE SF_OMX_GetComponentVersion(
+    OMX_IN  OMX_HANDLETYPE   hComponent,
+    OMX_OUT OMX_STRING       pComponentName,
+    OMX_OUT OMX_VERSIONTYPE *pComponentVersion,
+    OMX_OUT OMX_VERSIONTYPE *pSpecVersion,
+    OMX_OUT OMX_UUIDTYPE    *pComponentUUID)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE *pOMXComponent = NULL;
+    SF_OMX_COMPONENT *pSfOMXComponent = NULL;
+    OMX_U32 compUUID[4];
+
+    FunctionIn();
+
+    /* check parameters */
+    if (hComponent     == NULL ||
+        pComponentName == NULL || pComponentVersion == NULL ||
+        pSpecVersion   == NULL || pComponentUUID    == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pSfOMXComponent = (SF_OMX_COMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pSfOMXComponent->state == OMX_StateInvalid) {
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    strcpy(pComponentName, pSfOMXComponent->componentName);
+    memcpy(pComponentVersion, &(pSfOMXComponent->componentVersion), sizeof(OMX_VERSIONTYPE));
+    memcpy(pSpecVersion, &(pSfOMXComponent->specVersion), sizeof(OMX_VERSIONTYPE));
+
+    /* Fill UUID with handle address, PID and UID.
+     * This should guarantee uiniqness */
+    compUUID[0] = (OMX_U32)pOMXComponent;
+    compUUID[1] = (OMX_U32)pOMXComponent;
+    compUUID[2] = (OMX_U32)pOMXComponent;
+    compUUID[3] = (OMX_U32)pOMXComponent;
+    //compUUID[1] = getpid();
+    //compUUID[2] = getuid();
+    memcpy(*pComponentUUID, compUUID, 4 * sizeof(*compUUID));
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_U32 nInstance = 0;
+
+static OMX_ERRORTYPE SF_OMX_ComponentConstructor(SF_OMX_COMPONENT *pSfOMXComponent)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    FunctionIn();
+
+    if (nInstance >= MAX_NUM_INSTANCE)
+    {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    nInstance++;
+
+    ret = InitComponentStructorCommon(pSfOMXComponent);
+    if (ret != OMX_ErrorNone)
+    {
+        nInstance--;
+        goto EXIT;
+    }
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    TestDecConfig *pTestDecConfig = (TestDecConfig *)pSfVideoImplement->testConfig;
+    pTestDecConfig->feedingMode = FEEDING_METHOD_BUFFER;
+    pTestDecConfig->bitstreamMode = BS_MODE_PIC_END;
+    pTestDecConfig->bitFormat = pSfVideoImplement->bitFormat;
+    /*
+     if cbcrInterleave is FALSE and nv21 is FALSE, the default dec format is I420
+     if cbcrInterleave is TRUE and nv21 is FALSE, then the dec format is NV12
+     if cbcrInterleave is TRUE and nv21 is TRUE, then the dec format is NV21
+    */
+    pTestDecConfig->cbcrInterleave = TRUE;
+    pTestDecConfig->nv21 = FALSE;
+
+    pSfOMXComponent->pOMXComponent->UseBuffer = &SF_OMX_UseBuffer;
+    pSfOMXComponent->pOMXComponent->AllocateBuffer = &SF_OMX_AllocateBuffer;
+    pSfOMXComponent->pOMXComponent->EmptyThisBuffer = &SF_OMX_EmptyThisBuffer;
+    pSfOMXComponent->pOMXComponent->FillThisBuffer = &SF_OMX_FillThisBuffer;
+    pSfOMXComponent->pOMXComponent->FreeBuffer = &SF_OMX_FreeBuffer;
+    pSfOMXComponent->pOMXComponent->ComponentTunnelRequest = &SF_OMX_ComponentTunnelRequest;
+    pSfOMXComponent->pOMXComponent->GetParameter = &SF_OMX_GetParameter;
+    pSfOMXComponent->pOMXComponent->SetParameter = &SF_OMX_SetParameter;
+    pSfOMXComponent->pOMXComponent->GetConfig = &SF_OMX_GetConfig;
+    pSfOMXComponent->pOMXComponent->SetConfig = &SF_OMX_SetConfig;
+    pSfOMXComponent->pOMXComponent->SendCommand = &SF_OMX_SendCommand;
+    pSfOMXComponent->pOMXComponent->GetState = &SF_OMX_GetState;
+    pSfOMXComponent->pOMXComponent->GetComponentVersion = &SF_OMX_GetComponentVersion;
+    // pSfOMXComponent->pOMXComponent->GetExtensionIndex = &SF_OMX_GetExtensionIndex;
+    // pSfOMXComponent->pOMXComponent->ComponentRoleEnum = &SF_OMX_ComponentRoleEnum;
+    // pSfOMXComponent->pOMXComponent->ComponentDeInit = &SF_OMX_ComponentDeInit;
+
+    for (int i = 0; i < MAX_INDEX; i++)
+    {
+        pSfVideoImplement->frame_array[i] = -1;
+    }
+    pSfVideoImplement->frame_array_index = 0;
+
+    pSfVideoImplement->CmdQueue = SF_Queue_Create(20, sizeof(DEC_CMD));
+    if (NULL == pSfVideoImplement->CmdQueue)
+    {
+        LOG(SF_LOG_ERR, "create CmdQueue error");
+        nInstance--;
+        return OMX_ErrorInsufficientResources;
+    }
+    pSfVideoImplement->pauseQ = SF_Queue_Create(20, sizeof(OMX_BUFFERHEADERTYPE*));
+    if (NULL == pSfVideoImplement->pauseQ)
+    {
+        LOG(SF_LOG_ERR, "create pauseQ error");
+        nInstance--;
+        return OMX_ErrorInsufficientResources;
+    }
+
+    CreateThread(&pSfVideoImplement->pCmdThread, CmdThread, (void *)pSfOMXComponent);
+    pSfVideoImplement->bCmdRunning = OMX_TRUE;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_ComponentClear(SF_OMX_COMPONENT *pSfOMXComponent)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    DEC_CMD cmd;
+    void *ThreadRet = NULL;
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    ComponentImpl *pSFComponentDecoder = (ComponentImpl *)pSfVideoImplement->hSFComponentExecoder;
+    ComponentImpl *pSFComponentFeeder = (ComponentImpl *)pSfVideoImplement->hSFComponentFeeder;
+    ComponentImpl *pSFComponentRender = (ComponentImpl *)pSfVideoImplement->hSFComponentRender;
+
+    FunctionIn();
+    if (pSFComponentDecoder == NULL || pSFComponentFeeder == NULL || pSFComponentRender == NULL)
+    {
+        goto EXIT;
+    }
+    pSFComponentDecoder->terminate = OMX_TRUE;
+    pSFComponentFeeder->terminate = OMX_TRUE;
+    pSFComponentRender->terminate = OMX_TRUE;
+    pSfVideoImplement->functions->ComponentWait(pSfVideoImplement->hSFComponentFeeder);
+    pSfVideoImplement->functions->ComponentWait(pSfVideoImplement->hSFComponentExecoder);
+    pSfVideoImplement->functions->ComponentWait(pSfVideoImplement->hSFComponentRender);
+
+    pSfVideoImplement->bCmdRunning = 0;
+    /* enqueue DEC_StopThread mean cmd thread cycle end */
+    cmd.Cmd = DEC_StopThread;
+    SF_Queue_Enqueue(pSfVideoImplement->CmdQueue, &cmd);
+    pthread_cancel(pSfVideoImplement->pCmdThread->pthread);
+	pthread_join(pSfVideoImplement->pCmdThread->pthread, &ThreadRet);
+    LOG(SF_LOG_INFO, "Cmd thread end %ld\r\n", (Uint64)ThreadRet);
+    SF_Queue_Destroy(pSfVideoImplement->CmdQueue);
+    SF_Queue_Destroy(pSfVideoImplement->pauseQ);
+
+    free(pSfVideoImplement->pusBitCode);
+    pSfVideoImplement->functions->ClearDecListenerContext(pSfVideoImplement->lsnCtx);
+    ComponentClearCommon(pSfOMXComponent);
+EXIT:
+    nInstance--;
+    FunctionOut();
+
+    return ret;
+}
+
+SF_OMX_COMPONENT sf_dec_decoder_h265 = {
+    .componentName = "OMX.sf.video_decoder.hevc",
+    .libName = "libsfdec.so",
+    .pOMXComponent = NULL,
+    .SF_OMX_ComponentConstructor = SF_OMX_ComponentConstructor,
+    .SF_OMX_ComponentClear = SF_OMX_ComponentClear,
+    // .functions = NULL,
+    // .bitFormat = STD_HEVC,
+    .componentImpl = NULL,
+    .fwPath = "/lib/firmware/chagall.bin",
+    .componentRule = "video_decoder.hevc"};
+
+SF_OMX_COMPONENT sf_dec_decoder_h264 = {
+    .componentName = "OMX.sf.video_decoder.avc",
+    .libName = "libsfdec.so",
+    .pOMXComponent = NULL,
+    .SF_OMX_ComponentConstructor = SF_OMX_ComponentConstructor,
+    .SF_OMX_ComponentClear = SF_OMX_ComponentClear,
+    // .functions = NULL,
+    // .bitFormat = STD_AVC,
+    .componentImpl = NULL,
+    .fwPath = "/lib/firmware/chagall.bin",
+    .componentRule = "video_decoder.avc"};

+ 1246 - 0
omx-il/component/video/wave5/enc/SF_OMX_Venc_encoder.c

@@ -0,0 +1,1246 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 StarFive Technology Co., Ltd.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "SF_OMX_video_common.h"
+#include "SF_OMX_Core.h"
+
+#define WAVE521_CONFIG_FILE "/lib/firmware/encoder_defconfig.cfg"
+extern OMX_TICKS gInitTimeStamp;
+OMX_U32 tmpFramerate;
+OMX_S64 tmpCounter=0;
+
+static char* Event2Str(unsigned long event)
+{
+    char *event_str = NULL;
+    switch (event)
+    {
+    case COMPONENT_EVENT_ENC_OPEN:
+        event_str = "COMPONENT_EVENT_ENC_OPEN";
+        break;
+    case COMPONENT_EVENT_ENC_ISSUE_SEQ:
+        event_str = "COMPONENT_EVENT_ENC_ISSUE_SEQ";
+        break;
+    case COMPONENT_EVENT_ENC_COMPLETE_SEQ:
+        event_str = "COMPONENT_EVENT_ENC_COMPLETE_SEQ";
+        break;
+    case COMPONENT_EVENT_ENC_REGISTER_FB:
+        event_str = "COMPONENT_EVENT_ENC_REGISTER_FB";
+        break;
+    case COMPONENT_EVENT_ENC_READY_ONE_FRAME:
+        event_str = "COMPONENT_EVENT_ENC_READY_ONE_FRAME";
+        break;
+    case COMPONENT_EVENT_ENC_START_ONE_FRAME:
+        event_str = "COMPONENT_EVENT_ENC_START_ONE_FRAME";
+        break;
+    case COMPONENT_EVENT_ENC_GET_OUTPUT_INFO:
+        event_str = "COMPONENT_EVENT_ENC_GET_OUTPUT_INFO";
+        break;
+    case COMPONENT_EVENT_ENC_ENCODED_ALL:
+        event_str = "COMPONENT_EVENT_ENC_ENCODED_ALL";
+        break;
+    case COMPONENT_EVENT_ENC_CLOSE:
+        event_str = "COMPONENT_EVENT_ENC_CLOSE";
+        break;
+    case COMPONENT_EVENT_ENC_EMPTY_BUFFER_DONE:
+        event_str = "COMPONENT_EVENT_ENC_EMPTY_BUFFER_DONE";
+        break;
+    case COMPONENT_EVENT_ENC_FILL_BUFFER_DONE:
+        event_str = "COMPONENT_EVENT_ENC_FILL_BUFFER_DONE";
+        break;
+    case COMPONENT_EVENT_ENC_ALL:
+        event_str = "COMPONENT_EVENT_ENC_ALL";
+        break;
+    }
+    return event_str;
+}
+
+static void OnEventArrived(Component com, unsigned long event, void *data, void *context)
+{
+    FunctionIn();
+    SF_OMX_COMPONENT *pSfOMXComponent = GetSFOMXComponrntByComponent(com);
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    static OMX_U32 enc_cnt = 0;
+    static struct timeval tv_old = {0};
+    OMX_U32 fps = 0;
+    OMX_U64 diff_time = 0; // ms
+    PortContainerExternal *pPortContainerExternal = (PortContainerExternal *)data;
+    OMX_BUFFERHEADERTYPE *pOMXBuffer;
+    char *event_str = Event2Str(event);
+
+    LOG(SF_LOG_INFO, "event=%lX %s\r\n", event, event_str);
+    switch (event)
+    {
+    case COMPONENT_EVENT_ENC_EMPTY_BUFFER_DONE:
+        pOMXBuffer = GetOMXBufferByAddr(pSfOMXComponent, (OMX_U8 *)pPortContainerExternal->pBuffer);
+        if (pOMXBuffer == NULL)
+        {
+            LOG(SF_LOG_WARN, "Could not find omx buffer by address\r\n");
+            return;
+        }
+        pSfOMXComponent->callbacks->EmptyBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pOMXBuffer);
+        LOG(SF_LOG_PERF, "OMX empty one buffer, address = %p, size = %d, nTimeStamp = %d, nFlags = %X\r\n",
+        pOMXBuffer->pBuffer, pOMXBuffer->nFilledLen, pOMXBuffer->nTimeStamp, pOMXBuffer->nFlags);
+        ClearOMXBuffer(pSfOMXComponent, pOMXBuffer);
+        break;
+    case COMPONENT_EVENT_ENC_FILL_BUFFER_DONE:
+    {
+        struct timeval tv;
+        pOMXBuffer = GetOMXBufferByAddr(pSfOMXComponent, (OMX_U8 *)pPortContainerExternal->pBuffer);
+        if (pOMXBuffer == NULL)
+        {
+            LOG(SF_LOG_WARN, "Could not find omx buffer by address\r\n");
+            return;
+        }
+        gettimeofday(&tv, NULL);
+        if (gInitTimeStamp == 0)
+        {
+            gInitTimeStamp = tv.tv_sec * 1000000 + tv.tv_usec;
+        }
+
+        pOMXBuffer->nFilledLen = pPortContainerExternal->nFilledLen;
+        // pOMXBuffer->nTimeStamp = tv.tv_sec * 1000000 + tv.tv_usec - gInitTimeStamp;
+        pOMXBuffer->nTimeStamp = (tmpCounter*1000000)/tmpFramerate;
+        tmpCounter++;
+        LOG(SF_LOG_INFO,"test nTimeStamp:%ld\r\n",pOMXBuffer->nTimeStamp);
+        pOMXBuffer->nFlags = pPortContainerExternal->nFlags;
+#if 0
+            {
+                FILE *fb = fopen("./out.bcp", "ab+");
+                LOG(SF_LOG_ERR, "%d %d\r\n", pOMXBuffer->nFilledLen, pOMXBuffer->nOffset);
+                fwrite(pOMXBuffer->pBuffer, 1, pOMXBuffer->nFilledLen, fb);
+                fclose(fb);
+            }
+#endif
+        if (enc_cnt == 0) {
+            tv_old = tv;
+        }
+        if (enc_cnt++ >= 50) {
+            diff_time = (tv.tv_sec - tv_old.tv_sec) * 1000 + (tv.tv_usec - tv_old.tv_usec) / 1000;
+            fps = 1000  * (enc_cnt - 1) / diff_time;
+            enc_cnt = 0;
+            LOG(SF_LOG_WARN, "Encoding fps: %d \r\n", fps);
+        }
+        LOG(SF_LOG_PERF, "OMX finish one buffer, address = %p, size = %d, nTimeStamp = %d, nFlags = %X\r\n", pOMXBuffer->pBuffer, pOMXBuffer->nFilledLen, pOMXBuffer->nTimeStamp, pOMXBuffer->nFlags);
+        pSfOMXComponent->callbacks->FillBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pOMXBuffer);
+        ComponentImpl *pRendererComponent = (ComponentImpl *)pSfVideoImplement->hSFComponentRender;
+        LOG(SF_LOG_PERF, "output queue count=%d/%d\r\n", pSfVideoImplement->functions->Queue_Get_Cnt(pRendererComponent->sinkPort.inputQ),
+                                                    pSfOMXComponent->portDefinition[1].nBufferCountActual);
+        ClearOMXBuffer(pSfOMXComponent, pOMXBuffer);
+    }
+    break;
+    case COMPONENT_EVENT_ENC_REGISTER_FB:
+    {
+        pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, OMX_EventPortSettingsChanged,
+                                                 1, OMX_IndexParamPortDefinition, NULL);
+    }
+    break;
+    case COMPONENT_EVENT_ENC_ENCODED_ALL:
+        pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, OMX_EventBufferFlag,
+                                                 1, 1, NULL);
+    default:
+        break;
+    }
+
+    FunctionOut();
+}
+
+static OMX_ERRORTYPE SF_OMX_EmptyThisBuffer(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    FunctionIn();
+
+    if (hComponent == NULL || pBuffer == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    ComponentImpl *pFeederComponent = (ComponentImpl *)(pSfVideoImplement->hSFComponentFeeder);
+
+    PortContainerExternal *pPortContainerExternal = malloc(sizeof(PortContainerExternal));
+    if (pPortContainerExternal == NULL)
+    {
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        return OMX_ErrorInsufficientResources;
+    }
+    memset(pPortContainerExternal, 0, sizeof(PortContainerExternal));
+    pPortContainerExternal->pBuffer = pBuffer->pBuffer;
+    pPortContainerExternal->nFilledLen = pBuffer->nFilledLen;
+    pPortContainerExternal->nFlags = pBuffer->nFlags;
+    pPortContainerExternal->nBufferIndex = (OMX_U32)pBuffer->pInputPortPrivate;
+    LOG(SF_LOG_INFO, "Index = %lu, Address = %p, Flag = %X\r\n",(OMX_U64)(pBuffer->pInputPortPrivate), pBuffer->pBuffer, pBuffer->nFlags);
+    if (pSfVideoImplement->functions->Queue_Enqueue(pFeederComponent->srcPort.inputQ, (void *)pPortContainerExternal) != OMX_TRUE)
+    {
+        LOG(SF_LOG_ERR, "%p:%p FAIL\r\n", pFeederComponent->srcPort.inputQ, pPortContainerExternal);
+        free(pPortContainerExternal);
+        return OMX_ErrorInsufficientResources;
+    }
+    LOG(SF_LOG_PERF, "input queue count=%d/%d\r\n", pSfVideoImplement->functions->Queue_Get_Cnt(pFeederComponent->srcPort.inputQ),
+                                                    pSfOMXComponent->portDefinition[0].nBufferCountActual);
+    free(pPortContainerExternal);
+    pFeederComponent->pause = OMX_FALSE;
+
+    ret = StoreOMXBuffer(pSfOMXComponent, pBuffer);
+    LOG(SF_LOG_PERF, "buffer count = %d\r\n", GetOMXBufferCount(pSfOMXComponent));
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+static OMX_ERRORTYPE SF_OMX_FillThisBuffer(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    FunctionIn();
+
+    if (hComponent == NULL || pBuffer == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = (SF_OMX_COMPONENT *)pOMXComponent->pComponentPrivate;
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    ComponentImpl *pRendererComponent = (ComponentImpl *)(pSfVideoImplement->hSFComponentRender);
+    PortContainerExternal *pPortContainerExternal = malloc(sizeof(PortContainerExternal));
+    if (pPortContainerExternal == NULL)
+    {
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        return OMX_ErrorInsufficientResources;
+    }
+    memset(pPortContainerExternal, 0, sizeof(PortContainerExternal));
+    pPortContainerExternal->pBuffer = pBuffer->pBuffer;
+    pPortContainerExternal->nFilledLen = pBuffer->nAllocLen;
+    if (pSfVideoImplement->functions->Queue_Enqueue(pRendererComponent->sinkPort.inputQ, (void *)pPortContainerExternal) == -1)
+    {
+        LOG(SF_LOG_ERR, "%p:%p FAIL\r\n", pRendererComponent->sinkPort.inputQ, pPortContainerExternal);
+        free(pPortContainerExternal);
+        return OMX_ErrorInsufficientResources;
+    }
+    LOG(SF_LOG_PERF, "output queue count=%d/%d\r\n", pSfVideoImplement->functions->Queue_Get_Cnt(pRendererComponent->sinkPort.inputQ),
+                                                        pSfOMXComponent->portDefinition[1].nBufferCountActual);
+    free(pPortContainerExternal);
+    pRendererComponent->pause = OMX_FALSE;
+    ret = StoreOMXBuffer(pSfOMXComponent, pBuffer);
+    LOG(SF_LOG_PERF, "buffer count = %d\r\n", GetOMXBufferCount(pSfOMXComponent));
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_U64 nInputBufIndex = 0;
+
+static OMX_ERRORTYPE SF_OMX_UseBuffer(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
+    OMX_IN OMX_U32 nPortIndex,
+    OMX_IN OMX_PTR pAppPrivate,
+    OMX_IN OMX_U32 nSizeBytes,
+    OMX_IN OMX_U8 *pBuffer)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    ComponentImpl *pComponentFeeder = (ComponentImpl *)pSfVideoImplement->hSFComponentFeeder;
+    FunctionIn();
+
+    if (hComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    if (pSfVideoImplement->functions->AttachDMABuffer(pComponentFeeder, (Uint64)pBuffer, nSizeBytes) == FALSE)
+    {
+        LOG(SF_LOG_ERR, "Failed to attach dma buffer\r\n");
+        return OMX_ErrorInsufficientResources;
+    }
+    OMX_BUFFERHEADERTYPE *temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)malloc(sizeof(OMX_BUFFERHEADERTYPE));
+    if (temp_bufferHeader == NULL)
+    {
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        return OMX_ErrorInsufficientResources;
+    }
+    memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE));
+    temp_bufferHeader->nAllocLen = nSizeBytes;
+    temp_bufferHeader->pAppPrivate = pAppPrivate;
+    temp_bufferHeader->pBuffer = pBuffer;
+    *ppBufferHdr = temp_bufferHeader;
+    if (nPortIndex == 0)
+    {
+        temp_bufferHeader->pInputPortPrivate = (OMX_PTR)nInputBufIndex;
+        nInputBufIndex ++;
+    }
+    LOG(SF_LOG_INFO, "pBuffer address = %p, nInputBufIndex = %d\r\n", temp_bufferHeader->pBuffer, (OMX_U64)temp_bufferHeader->pInputPortPrivate);
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_AllocateBuffer(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
+    OMX_IN OMX_U32 nPortIndex,
+    OMX_IN OMX_PTR pAppPrivate,
+    OMX_IN OMX_U32 nSizeBytes)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    ComponentImpl *pComponentFeeder = (ComponentImpl *)pSfVideoImplement->hSFComponentFeeder;
+    // OMX_U32 i = 0;
+
+    FunctionIn();
+    if (nSizeBytes == 0)
+    {
+        LOG(SF_LOG_ERR, "nSizeBytes = %d\r\n", nSizeBytes);
+        return OMX_ErrorBadParameter;
+    }
+    OMX_BUFFERHEADERTYPE *temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)malloc(sizeof(OMX_BUFFERHEADERTYPE));
+    if (temp_bufferHeader == NULL)
+    {
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        return OMX_ErrorInsufficientResources;
+    }
+    memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE));
+
+    temp_bufferHeader->nAllocLen = nSizeBytes;
+    temp_bufferHeader->pAppPrivate = pAppPrivate;
+
+    if (nPortIndex == 0)
+    {
+        // Alloc DMA memory first
+        if (pSfOMXComponent->memory_optimization)
+        {
+            temp_bufferHeader->pBuffer = pSfVideoImplement->functions->AllocateFrameBuffer2(pComponentFeeder, nSizeBytes);
+        }
+        // DMA Memory alloc fail, goto normal alloc
+        if (temp_bufferHeader->pBuffer == NULL)
+        {
+            pSfOMXComponent->memory_optimization = OMX_FALSE;
+            temp_bufferHeader->pBuffer = malloc(nSizeBytes);
+            memset(temp_bufferHeader->pBuffer, 0, nSizeBytes);
+            LOG(SF_LOG_PERF, "Use normal buffer\r\n");
+        }
+        else
+        {
+            LOG(SF_LOG_PERF, "Use DMA buffer\r\n");
+            temp_bufferHeader->pInputPortPrivate = (OMX_PTR)nInputBufIndex;
+            nInputBufIndex ++;
+        }
+    }
+    else if (nPortIndex == 1)
+    {
+        temp_bufferHeader->pBuffer = malloc(nSizeBytes);
+
+        memset(temp_bufferHeader->pBuffer, 0, nSizeBytes);
+    }
+
+    if (temp_bufferHeader->pBuffer == NULL)
+    {
+        free(temp_bufferHeader);
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        return OMX_ErrorInsufficientResources;
+    }
+    *ppBuffer = temp_bufferHeader;
+    LOG(SF_LOG_INFO, "pBuffer address = %p\r\n", temp_bufferHeader->pBuffer);
+
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_GetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE nParamIndex,
+    OMX_INOUT OMX_PTR ComponentParameterStructure)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    OMX_PARAM_PORTDEFINITIONTYPE *pOutputPort = &pSfOMXComponent->portDefinition[1];
+
+    FunctionIn();
+
+    if (hComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    LOG(SF_LOG_INFO, "Get parameter on index %X\r\n", nParamIndex);
+    switch ((OMX_U32)nParamIndex)
+    {
+    case OMX_IndexParamVideoInit:
+    {
+        OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure;
+        portParam->nPorts           = 2;
+        portParam->nStartPortNumber = 0;
+    }
+    break;
+    case OMX_IndexParamVideoPortFormat:
+    {
+        OMX_VIDEO_PARAM_PORTFORMATTYPE *portFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure;
+        OMX_U32 index = portFormat->nIndex;
+        LOG(SF_LOG_INFO, "Get video port format at index %d\r\n", index);
+        switch (index)
+        {
+        case 0:
+            portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
+            portFormat->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+            portFormat->xFramerate = 30;
+            break;
+        case 1:
+            portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
+            portFormat->eColorFormat = OMX_COLOR_FormatYUV420Planar;
+            portFormat->xFramerate = 30;
+            break;
+        case 2:
+            portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
+            portFormat->eColorFormat = OMX_COLOR_FormatYVU420SemiPlanar;
+            portFormat->xFramerate = 30;
+            break;
+        default:
+            if (index > 0)
+            {
+                ret = OMX_ErrorNoMore;
+            }
+            break;
+        }
+    }
+
+    break;
+    case OMX_IndexParamVideoBitrate:
+    {
+        OMX_VIDEO_PARAM_BITRATETYPE     *videoRateControl = (OMX_VIDEO_PARAM_BITRATETYPE *)ComponentParameterStructure;
+        OMX_U32                          portIndex = videoRateControl->nPortIndex;
+        if ((portIndex != 1)) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+        else
+        {
+            videoRateControl->nTargetBitrate = pOutputPort->format.video.nBitrate;
+        }
+        LOG(SF_LOG_INFO, "Get nTargetBitrate = %u on port %d\r\n",videoRateControl->nTargetBitrate, videoRateControl->nPortIndex);
+    }
+        break;
+    case OMX_IndexParamVideoQuantization:
+
+        break;
+    case OMX_IndexParamPortDefinition:
+    {
+        OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
+        OMX_U32 portIndex = pPortDefinition->nPortIndex;
+        memcpy(pPortDefinition, &pSfOMXComponent->portDefinition[portIndex], pPortDefinition->nSize);
+        LOG(SF_LOG_INFO, "Get portDefinition on port %d\r\n", portIndex);
+        LOG(SF_LOG_INFO, "Got width = %d, height = %d\r\n", pPortDefinition->format.video.nFrameWidth, pPortDefinition->format.video.nFrameHeight);
+    }
+
+    break;
+    case OMX_IndexParamVideoIntraRefresh:
+
+        break;
+
+    case OMX_IndexParamStandardComponentRole:
+
+        break;
+    case OMX_IndexParamVideoAvc:
+    {
+        OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)ComponentParameterStructure;
+        OMX_U32 nPortIndex = pDstAVCComponent->nPortIndex;
+        OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = &pSfVideoImplement->AVCComponent[nPortIndex];
+
+        LOG(SF_LOG_INFO, "Get nPFrames = %d on port %d\r\n", pSrcAVCComponent->nPFrames, nPortIndex);
+        memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
+    }
+    break;
+    case OMX_IndexParamVideoHevc:
+    {
+        OMX_VIDEO_PARAM_HEVCTYPE *pDstHEVCComponent = (OMX_VIDEO_PARAM_HEVCTYPE *)ComponentParameterStructure;
+        OMX_U32 nPortIndex = pDstHEVCComponent->nPortIndex;
+        OMX_VIDEO_PARAM_HEVCTYPE *pSrcHEVCComponent = &pSfVideoImplement->HEVCComponent[nPortIndex];
+
+        LOG(SF_LOG_INFO, "Get nKeyFrameInterval = %d on port %d\r\n", pSrcHEVCComponent->nKeyFrameInterval, nPortIndex);
+        memcpy(pDstHEVCComponent, pSrcHEVCComponent, sizeof(OMX_VIDEO_PARAM_HEVCTYPE));
+    }
+    break;
+    case OMX_IndexParamVideoProfileLevelQuerySupported:
+
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)ComponentParameterStructure;
+        LOG(SF_LOG_INFO, "Get ProfileLevel on port %d\r\n", pParam->nPortIndex);
+        if (pParam->nPortIndex == 1)
+        {
+            //TODO
+            pParam->eProfile = OMX_VIDEO_HEVCProfileMain;
+            pParam->eLevel = OMX_VIDEO_HEVCMainTierLevel5;
+            LOG(SF_LOG_INFO, "eProfile = OMX_VIDEO_HEVCProfileMain\r\n");
+        }
+    }
+        // ret = OMX_ErrorNotImplemented;
+        break;
+    default:
+        ret = OMX_ErrorUnsupportedIndex;
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_SetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE nIndex,
+    OMX_IN OMX_PTR ComponentParameterStructure)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+    if (hComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    OMX_PARAM_PORTDEFINITIONTYPE *pInputPort = &pSfOMXComponent->portDefinition[0];
+    OMX_PARAM_PORTDEFINITIONTYPE *pOutputPort = &pSfOMXComponent->portDefinition[1];
+
+    if (pSfOMXComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    LOG(SF_LOG_INFO, "Set parameter on index %X\r\n", nIndex);
+    switch ((OMX_U32)nIndex)
+    {
+    case OMX_IndexParamPortDefinition:
+    {
+        OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
+        OMX_U32 portIndex = pPortDefinition->nPortIndex;
+        OMX_U32 width = pPortDefinition->format.video.nFrameWidth;
+        OMX_U32 height = pPortDefinition->format.video.nFrameHeight;
+        OMX_U32 nBitrate = pPortDefinition->format.video.nBitrate;
+        OMX_U32 xFramerate = pPortDefinition->format.video.xFramerate;
+        tmpFramerate = xFramerate;
+        OMX_U32 nBufferCountActual = pPortDefinition->nBufferCountActual;
+        LOG(SF_LOG_INFO, "Set width = %d, height = %d, xFramerate = %d, nBitrate = %d, nBufferCountActual = %d on port %d\r\n",
+            width, height, xFramerate, nBitrate, nBufferCountActual, portIndex);
+        OMX_COLOR_FORMATTYPE eColorFormat = pPortDefinition->format.video.eColorFormat;
+        TestEncConfig *pTestEncConfig = (TestEncConfig *)pSfVideoImplement->testConfig;
+
+        if (xFramerate == 0)
+        {
+            LOG(SF_LOG_ERR, "Fail to set xFramerate = %d\r\n", xFramerate);
+            return OMX_ErrorBadParameter;
+        }
+        if (portIndex == 0)
+        {
+            if (nBufferCountActual != pInputPort->nBufferCountActual)
+            {
+                LOG(SF_LOG_INFO, "Set input buffer count = %d\r\n", nBufferCountActual);
+                ComponentImpl *pFeederComponent = (ComponentImpl *)pSfVideoImplement->hSFComponentFeeder;
+                pSfVideoImplement->functions->SetFeederTotalBufferNumber(pFeederComponent, nBufferCountActual);
+                pSfVideoImplement->functions->ComponentPortDestroy(&pFeederComponent->srcPort);
+                pSfVideoImplement->functions->ComponentPortCreate(&pFeederComponent->srcPort, pSfVideoImplement->hSFComponentFeeder,
+                                                                nBufferCountActual, sizeof(PortContainerExternal));
+            }
+
+            memcpy(&pSfOMXComponent->portDefinition[portIndex], pPortDefinition, pPortDefinition->nSize);
+            pInputPort->format.video.nStride = width;
+            pInputPort->format.video.nSliceHeight = height;
+            pInputPort->nBufferSize = width * height * 3 / 2;
+            LOG(SF_LOG_INFO, "Set eColorFormat to %d\r\n", eColorFormat);
+            switch (eColorFormat)
+            {
+            case OMX_COLOR_FormatYUV420Planar: //I420
+                pTestEncConfig->cbcrInterleave = FALSE;
+                pTestEncConfig->nv21 = FALSE;
+                break;
+            case OMX_COLOR_FormatYUV420SemiPlanar: //NV12
+                pTestEncConfig->cbcrInterleave = TRUE;
+                pTestEncConfig->nv21 = FALSE;
+                break;
+            case OMX_COLOR_FormatYVU420SemiPlanar: //NV21
+                pTestEncConfig->cbcrInterleave = TRUE;
+                pTestEncConfig->nv21 = TRUE;
+                break;
+            default:
+                break;
+            }
+        }
+        else if (portIndex == 1)
+        {
+            LOG(SF_LOG_INFO, "Current output buffer count = %d\r\n", pOutputPort->nBufferCountActual);
+            if (nBufferCountActual != pOutputPort->nBufferCountActual)
+            {
+                ComponentImpl *pRenderComponent = (ComponentImpl *)pSfVideoImplement->hSFComponentRender;
+                LOG(SF_LOG_INFO, "Set output buffer count = %d\r\n", nBufferCountActual);
+                pSfVideoImplement->functions->ComponentPortDestroy(&pRenderComponent->sinkPort);
+                pSfVideoImplement->functions->ComponentPortCreate(&pRenderComponent->sinkPort, pSfVideoImplement->hSFComponentRender,
+                                                                nBufferCountActual, sizeof(PortContainerExternal));
+            }
+
+            memcpy(&pSfOMXComponent->portDefinition[portIndex], pPortDefinition, pPortDefinition->nSize);
+            width = pInputPort->format.video.nFrameWidth;
+            height = pInputPort->format.video.nFrameHeight;
+            pOutputPort->format.video.nFrameWidth = width;
+            pOutputPort->format.video.nFrameHeight = height;
+            pOutputPort->format.video.nStride = width;
+            pOutputPort->format.video.nSliceHeight = height;
+            switch (eColorFormat)
+            {
+            case OMX_COLOR_FormatYUV420Planar:
+            case OMX_COLOR_FormatYUV420SemiPlanar:
+            case OMX_COLOR_FormatYVU420SemiPlanar:
+                if (width && height)
+                    pOutputPort->nBufferSize = (width * height * 3) / 2;
+                break;
+            default:
+                if (width && height)
+                    pOutputPort->nBufferSize = width * height * 2;
+                break;
+            }
+        }
+    }
+    break;
+    case OMX_IndexParamVideoPortFormat:
+        {
+            OMX_VIDEO_PARAM_PORTFORMATTYPE *portFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure;
+            TestEncConfig *pTestEncConfig = (TestEncConfig *)pSfVideoImplement->testConfig;
+            OMX_COLOR_FORMATTYPE eColorFormat = portFormat->eColorFormat;
+            LOG(SF_LOG_INFO, "Set eColorFormat to %d\r\n", eColorFormat);
+            switch (eColorFormat)
+            {
+            case OMX_COLOR_FormatYUV420Planar:
+                pTestEncConfig->cbcrInterleave = OMX_FALSE;
+                pTestEncConfig->nv21 = OMX_FALSE;
+                break;
+            case OMX_COLOR_FormatYUV420SemiPlanar:
+                pTestEncConfig->cbcrInterleave = OMX_TRUE;
+                pTestEncConfig->nv21 = OMX_FALSE;
+                break;
+            default:
+                ret = OMX_ErrorBadParameter;
+                break;
+            }
+        }
+    break;
+    case OMX_IndexParamVideoBitrate:
+    {
+        OMX_VIDEO_PARAM_BITRATETYPE     *videoRateControl = (OMX_VIDEO_PARAM_BITRATETYPE *)ComponentParameterStructure;
+        OMX_U32                          portIndex = videoRateControl->nPortIndex;
+
+        LOG(SF_LOG_INFO, "Set nTargetBitrate = %u on port %d\r\n",videoRateControl->nTargetBitrate, portIndex);
+
+        if ((portIndex != 1)) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+        else
+        {
+            pOutputPort->format.video.nBitrate = videoRateControl->nTargetBitrate;
+        }
+        ret = OMX_ErrorNone;
+    }
+    break;
+    case OMX_IndexConfigVideoAVCIntraPeriod:
+    {
+        OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pAVCIntraPeriod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD *)ComponentParameterStructure;
+        OMX_U32           portIndex = pAVCIntraPeriod->nPortIndex;
+
+        LOG(SF_LOG_INFO, "Set nIDRPeriod = %d nPFrames = %d on port %d\r\n",pAVCIntraPeriod->nIDRPeriod, pAVCIntraPeriod->nPFrames, portIndex);
+        if ((portIndex != 1)) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+        else
+        {
+            pSfVideoImplement->AVCComponent[1].nPFrames = pAVCIntraPeriod->nPFrames;
+        }
+    }
+    break;
+    case OMX_IndexParamVideoAvc:
+    {
+        OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent= (OMX_VIDEO_PARAM_AVCTYPE *)ComponentParameterStructure;
+        OMX_U32 nPortIndex = pSrcAVCComponent->nPortIndex;
+        OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = &pSfVideoImplement->AVCComponent[nPortIndex];
+        OMX_U32 nPFrames = pSrcAVCComponent->nPFrames;
+
+        LOG(SF_LOG_INFO, "Set nPFrames = %d on port %d\r\n", nPFrames, nPortIndex);
+        if (nPFrames == 1)
+        {
+            LOG(SF_LOG_ERR, "Set nPFrames = %d not supported!\r\n", nPFrames);
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+        memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
+    }
+    break;
+    case OMX_IndexParamVideoHevc:
+    {
+        OMX_VIDEO_PARAM_HEVCTYPE *pSrcHEVCComponent= (OMX_VIDEO_PARAM_HEVCTYPE *)ComponentParameterStructure;
+        OMX_U32 nPortIndex = pSrcHEVCComponent->nPortIndex;
+        OMX_VIDEO_PARAM_HEVCTYPE *pDstHEVCComponent = &pSfVideoImplement->HEVCComponent[nPortIndex];
+        OMX_U32 nKeyFrameInterval = pSrcHEVCComponent->nKeyFrameInterval;
+
+        LOG(SF_LOG_INFO, "Set nKeyFrameInterval = %d on port %d\r\n", nKeyFrameInterval, nPortIndex);
+        if (nKeyFrameInterval == 1)
+        {
+            LOG(SF_LOG_ERR, "Set nKeyFrameInterval = %d not supported!\r\n", nKeyFrameInterval);
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+        memcpy(pDstHEVCComponent, pSrcHEVCComponent, sizeof(OMX_VIDEO_PARAM_HEVCTYPE));
+    }
+    break;
+    case OMX_IndexParamVideoQuantization:
+    case OMX_IndexParamVideoIntraRefresh:
+    default:
+        ret = OMX_ErrorUnsupportedIndex;
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+static OMX_ERRORTYPE SF_OMX_GetConfig(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE nIndex,
+    OMX_PTR pComponentConfigStructure)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if (hComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    switch (nIndex)
+    {
+    case OMX_IndexConfigVideoAVCIntraPeriod:
+
+        break;
+    case OMX_IndexConfigVideoBitrate:
+
+        break;
+    case OMX_IndexConfigVideoFramerate:
+
+        break;
+
+    default:
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_SetConfig(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE nIndex,
+    OMX_PTR pComponentConfigStructure)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if (hComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    switch ((OMX_U32)nIndex)
+    {
+    case OMX_IndexConfigVideoAVCIntraPeriod:
+        break;
+    case OMX_IndexConfigVideoBitrate:
+        break;
+    case OMX_IndexConfigVideoFramerate:
+        break;
+    case OMX_IndexConfigVideoIntraVOPRefresh:
+        break;
+    default:
+
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE InitEncoder(SF_OMX_COMPONENT *pSfOMXComponent)
+{
+    TestEncConfig *testConfig = NULL;
+    CNMComponentConfig *config = NULL;
+    Uint32 sizeInWord;
+    Int32 alignedWidth = 0, alignedHeight = 0;
+    char *fwPath = NULL;
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+
+    if (pSfVideoImplement->hSFComponentExecoder != NULL)
+    {
+        return OMX_ErrorNone;
+    }
+
+    FunctionIn();
+
+    testConfig = (TestEncConfig *)pSfVideoImplement->testConfig;
+
+    testConfig->productId = (ProductId)pSfVideoImplement->functions->VPU_GetProductId(testConfig->coreIdx);
+    if (CheckEncTestConfig(testConfig) == FALSE)
+    {
+        LOG(SF_LOG_ERR, "fail to CheckTestConfig()\n");
+        return OMX_ErrorBadParameter;
+    }
+
+    switch (testConfig->productId)
+    {
+    case PRODUCT_ID_521:
+        fwPath = pSfOMXComponent->fwPath;
+        break;
+    case PRODUCT_ID_511:
+        fwPath = pSfOMXComponent->fwPath;
+        break;
+    case PRODUCT_ID_517:
+        fwPath = CORE_7_BIT_CODE_FILE_PATH;
+        break;
+    default:
+        LOG(SF_LOG_ERR, "Unknown product id: %d, whether kernel module loaded?\n", testConfig->productId);
+        return OMX_ErrorBadParameter;
+    }
+    LOG(SF_LOG_INFO, "FW PATH = %s\n", fwPath);
+    if (pSfVideoImplement->functions->LoadFirmware(testConfig->productId, (Uint8 **)&(pSfVideoImplement->pusBitCode), &sizeInWord, fwPath) < 0)
+    {
+        LOG(SF_LOG_ERR, "Failed to load firmware: %s\n", fwPath);
+        return OMX_ErrorInsufficientResources;
+    }
+
+    config = pSfVideoImplement->config;
+    memcpy(&(config->testEncConfig), testConfig, sizeof(TestEncConfig));
+    config->bitcode = (Uint8 *)pSfVideoImplement->pusBitCode;
+    config->sizeOfBitcode = sizeInWord;
+    LOG(SF_LOG_INFO, "cbcrInterleave= %d, nv21 = %d\r\n", config->testEncConfig.cbcrInterleave, config->testEncConfig.nv21);
+    memcpy(config->testEncConfig.cfgFileName, WAVE521_CONFIG_FILE, sizeof(WAVE521_CONFIG_FILE));
+    LOG(SF_LOG_INFO, "Get width = %d, height = %d \r\n", config->encOpenParam.picWidth, config->encOpenParam.picHeight);
+    if (pSfVideoImplement->functions->SetupEncoderOpenParam(&config->encOpenParam, &config->testEncConfig, NULL) == OMX_FALSE)
+    {
+        LOG(SF_LOG_ERR, "SetupEncoderOpenParam error\n");
+        return OMX_ErrorBadParameter;
+    }
+    config->encOpenParam.picWidth = pSfOMXComponent->portDefinition[0].format.video.nFrameWidth;
+    config->encOpenParam.picHeight = pSfOMXComponent->portDefinition[0].format.video.nFrameHeight;
+
+    /* If xFramerate value from user is stored in Q16 format, should convert into integer */
+    if(pSfOMXComponent->portDefinition[0].format.video.xFramerate > (1 << 16))
+    {
+        config->encOpenParam.frameRateInfo = pSfOMXComponent->portDefinition[0].format.video.xFramerate >> 16;
+    }
+    else
+    {
+        config->encOpenParam.frameRateInfo = pSfOMXComponent->portDefinition[0].format.video.xFramerate;
+    }
+
+    if(pSfOMXComponent->portDefinition[1].format.video.nBitrate)
+    {
+        config->encOpenParam.rcEnable = 1;
+        config->encOpenParam.bitRate = pSfOMXComponent->portDefinition[1].format.video.nBitrate;
+    }
+    else if(config->encOpenParam.rcEnable == 1)
+    {
+        pSfOMXComponent->portDefinition[1].format.video.nBitrate = config->encOpenParam.bitRate;
+    }
+
+    if (pSfVideoImplement->bitFormat == STD_AVC)
+    {
+        config->encOpenParam.EncStdParam.waveParam.intraPeriod = pSfVideoImplement->AVCComponent[1].nPFrames;
+        alignedWidth = (config->encOpenParam.picWidth + 15) & ~15;
+        alignedHeight= (config->encOpenParam.picHeight+ 15) & ~15;
+        config->encOpenParam.EncStdParam.waveParam.confWinRight = alignedWidth - config->encOpenParam.picWidth;
+        config->encOpenParam.EncStdParam.waveParam.confWinBot = alignedHeight - config->encOpenParam.picHeight;
+    }
+    else if (pSfVideoImplement->bitFormat == STD_HEVC)
+    {
+        config->encOpenParam.EncStdParam.waveParam.intraPeriod = pSfVideoImplement->HEVCComponent[1].nKeyFrameInterval;
+    }
+    LOG(SF_LOG_INFO, "Get width = %d, height = %d frameRateInfo = %d intraPeriod = %d bitrate = %d confWinRight = %d confWinBot = %d\r\n",
+        config->encOpenParam.picWidth, config->encOpenParam.picHeight, config->encOpenParam.frameRateInfo,
+        config->encOpenParam.EncStdParam.waveParam.intraPeriod, config->encOpenParam.bitRate,
+        config->encOpenParam.EncStdParam.waveParam.confWinRight, config->encOpenParam.EncStdParam.waveParam.confWinBot);
+
+    pSfVideoImplement->hSFComponentExecoder = pSfVideoImplement->functions->ComponentCreate("wave_encoder", config);
+    pSfVideoImplement->hSFComponentFeeder = pSfVideoImplement->functions->ComponentCreate("yuvfeeder", config);
+    pSfVideoImplement->hSFComponentRender = pSfVideoImplement->functions->ComponentCreate("reader", config);
+
+    ComponentImpl *pFeederComponent = (ComponentImpl *)pSfVideoImplement->hSFComponentFeeder;
+    pSfVideoImplement->functions->ComponentPortCreate(&pFeederComponent->srcPort, pSfVideoImplement->hSFComponentFeeder,
+                    pSfOMXComponent->portDefinition[0].nBufferCountActual, sizeof(PortContainerExternal));
+
+    ComponentImpl *pRenderComponent = (ComponentImpl *)pSfVideoImplement->hSFComponentRender;
+    pSfVideoImplement->functions->ComponentPortDestroy(&pRenderComponent->sinkPort);
+    pSfVideoImplement->functions->ComponentPortCreate(&pRenderComponent->sinkPort, pSfVideoImplement->hSFComponentRender,
+                    pSfOMXComponent->portDefinition[1].nBufferCountActual, sizeof(PortContainerExternal));
+
+    if (pSfVideoImplement->functions->SetupEncListenerContext(pSfVideoImplement->lsnCtx, config) == TRUE)
+    {
+        pSfVideoImplement->functions->ComponentRegisterListener(pSfVideoImplement->hSFComponentExecoder,
+                                                              COMPONENT_EVENT_ENC_ALL, pSfVideoImplement->functions->EncoderListener, (void *)pSfVideoImplement->lsnCtx);
+        pSfVideoImplement->functions->ComponentRegisterListener(pSfVideoImplement->hSFComponentExecoder,
+                                                              COMPONENT_EVENT_ENC_REGISTER_FB, OnEventArrived, (void *)pSfVideoImplement->lsnCtx);
+        pSfVideoImplement->functions->ComponentRegisterListener(pSfVideoImplement->hSFComponentExecoder,
+                                                              COMPONENT_EVENT_ENC_ENCODED_ALL, OnEventArrived, (void *)pSfVideoImplement->lsnCtx);
+        pSfVideoImplement->functions->ComponentRegisterListener(pSfVideoImplement->hSFComponentFeeder,
+                                                              COMPONENT_EVENT_ENC_ALL, OnEventArrived, (void *)pSfVideoImplement->lsnCtx);
+        pSfVideoImplement->functions->ComponentRegisterListener(pSfVideoImplement->hSFComponentRender,
+                                                              COMPONENT_EVENT_ENC_ALL, OnEventArrived, (void *)pSfVideoImplement->lsnCtx);
+    }
+    else
+    {
+        LOG(SF_LOG_ERR, "ComponentRegisterListener fail\r\n");
+        return OMX_ErrorBadParameter;
+    }
+    pSfVideoImplement->functions->ComponentSetupTunnel(pSfVideoImplement->hSFComponentFeeder, pSfVideoImplement->hSFComponentExecoder);
+    pSfVideoImplement->functions->ComponentSetupTunnel(pSfVideoImplement->hSFComponentExecoder, pSfVideoImplement->hSFComponentRender);
+    FunctionOut();
+    return OMX_ErrorNone;
+}
+
+static OMX_ERRORTYPE SF_OMX_SendCommand(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_COMMANDTYPE Cmd,
+    OMX_IN OMX_U32 nParam,
+    OMX_IN OMX_PTR pCmdData)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    ComponentImpl *pSFComponentEncoder = NULL;
+    ComponentImpl *pSFComponentFeeder = NULL;
+    ComponentImpl *pSFComponentRender = NULL;
+    ComponentState currentState;
+
+    FunctionIn();
+    if (hComponent == NULL || pSfOMXComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+
+    LOG(SF_LOG_INFO, "cmd = %X, nParam = %X\r\n", Cmd, nParam);
+    switch (Cmd)
+    {
+    case OMX_CommandStateSet:
+        pSfOMXComponent->state = nParam;
+        LOG(SF_LOG_INFO, "OMX dest state = %X\r\n", nParam);
+        switch (nParam)
+        {
+        case OMX_StateLoaded:
+            if (pSfVideoImplement->hSFComponentExecoder == NULL)
+            {
+                break;
+            }
+            pSFComponentEncoder = (ComponentImpl *)pSfVideoImplement->hSFComponentExecoder;
+            pSFComponentFeeder = (ComponentImpl *)pSfVideoImplement->hSFComponentFeeder;
+            pSFComponentRender = (ComponentImpl *)pSfVideoImplement->hSFComponentRender;
+            currentState = pSfVideoImplement->functions->ComponentGetState(pSfVideoImplement->hSFComponentExecoder);
+            LOG(SF_LOG_INFO, "VPU Current state = %X\r\n", currentState);
+            switch(currentState)
+            {
+                case COMPONENT_STATE_CREATED:
+                case COMPONENT_STATE_PREPARED:
+                case COMPONENT_STATE_EXECUTED:
+                case COMPONENT_STATE_TERMINATED:
+                if (pSfVideoImplement->functions->Queue_Get_Cnt(pSFComponentRender->sinkPort.inputQ) > 0 ||
+                    pSfVideoImplement->functions->Queue_Get_Cnt(pSFComponentFeeder->srcPort.inputQ) > 0)
+                {
+                    LOG(SF_LOG_ERR, "Buffer not flush!\r\n")
+                    // ret = OMX_ErrorIncorrectStateTransition;
+                }
+                break;
+                pSFComponentEncoder->terminate = OMX_TRUE;
+                pSFComponentFeeder->terminate = OMX_TRUE;
+                pSFComponentRender->terminate = OMX_TRUE;
+                case COMPONENT_STATE_NONE:
+                default:
+                    ret = OMX_ErrorIncorrectStateTransition;
+                    break;
+            }
+            break;
+        case OMX_StateIdle:
+            if (pSfVideoImplement->hSFComponentExecoder == NULL)
+            {
+                ret = InitEncoder(pSfOMXComponent);
+                if (ret != OMX_ErrorNone)
+                {
+                    goto EXIT;
+                }
+            }
+
+            pSFComponentEncoder = (ComponentImpl *)pSfVideoImplement->hSFComponentExecoder;
+            pSFComponentFeeder = (ComponentImpl *)pSfVideoImplement->hSFComponentFeeder;
+            pSFComponentRender = (ComponentImpl *)pSfVideoImplement->hSFComponentRender;
+            currentState = pSfVideoImplement->functions->ComponentGetState(pSfVideoImplement->hSFComponentExecoder);
+            LOG(SF_LOG_INFO, "VPU Current state = %X\r\n", currentState);
+            switch(currentState)
+            {
+            case COMPONENT_STATE_NONE:
+                ret = OMX_ErrorIncorrectStateTransition;
+                break;
+            case COMPONENT_STATE_CREATED:
+                if (pSFComponentEncoder->thread == NULL)
+                {
+                    LOG(SF_LOG_INFO, "execute component %s\r\n", pSFComponentEncoder->name);
+                    currentState = pSfVideoImplement->functions->ComponentExecute(pSFComponentEncoder);
+                    LOG(SF_LOG_INFO, "ret = %d\r\n", currentState);
+                }
+                if (pSFComponentFeeder->thread == NULL)
+                {
+                    LOG(SF_LOG_INFO, "execute component %s\r\n", pSFComponentFeeder->name);
+                    currentState = pSfVideoImplement->functions->ComponentExecute(pSFComponentFeeder);
+                    LOG(SF_LOG_INFO, "ret = %d\r\n", currentState);
+                }
+                if (pSFComponentRender->thread == NULL)
+                {
+                    LOG(SF_LOG_INFO, "execute component %s\r\n", pSFComponentRender->name);
+                    currentState = pSfVideoImplement->functions->ComponentExecute(pSFComponentRender);
+                    LOG(SF_LOG_INFO, "ret = %d\r\n", currentState);
+                }
+                pSfVideoImplement->functions->WaitForExecoderReady(pSFComponentEncoder);
+                break;
+            case COMPONENT_STATE_PREPARED:
+            case COMPONENT_STATE_EXECUTED:
+            case COMPONENT_STATE_TERMINATED:
+                {
+                    pSFComponentEncoder->pause = OMX_TRUE;
+                    pSFComponentFeeder->pause = OMX_TRUE;
+                    pSFComponentRender->pause = OMX_TRUE;
+                    FlushBuffer(pSfOMXComponent, 0);
+                    FlushBuffer(pSfOMXComponent, 1);
+                }
+                break;
+            case COMPONENT_STATE_MAX:
+                break;
+            }
+            break;
+
+        case OMX_StateExecuting:
+            pSFComponentEncoder = (ComponentImpl *)pSfVideoImplement->hSFComponentExecoder;
+            pSFComponentFeeder = (ComponentImpl *)pSfVideoImplement->hSFComponentFeeder;
+            pSFComponentRender = (ComponentImpl *)pSfVideoImplement->hSFComponentRender;
+
+
+            currentState = pSfVideoImplement->functions->ComponentGetState(pSfVideoImplement->hSFComponentExecoder);
+            LOG(SF_LOG_INFO, "VPU Current state = %X\r\n", currentState);
+            switch(currentState)
+            {
+            case COMPONENT_STATE_NONE:
+            case COMPONENT_STATE_TERMINATED:
+                ret = OMX_ErrorIncorrectStateTransition;
+                break;
+            case COMPONENT_STATE_CREATED:
+                break;
+            case COMPONENT_STATE_PREPARED:
+            case COMPONENT_STATE_EXECUTED:
+                pSFComponentEncoder->pause = OMX_FALSE;
+                pSFComponentFeeder->pause = OMX_FALSE;
+                pSFComponentRender->pause = OMX_FALSE;
+                break;
+            case COMPONENT_STATE_MAX:
+                break;
+            }
+            break;
+        default:
+            ret = OMX_ErrorIncorrectStateTransition;
+            break;
+        }
+        pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
+                                                 OMX_EventCmdComplete, OMX_CommandStateSet, nParam, NULL);
+        break;
+    case OMX_CommandFlush:
+    {
+        OMX_U32 nPort = nParam;
+        FlushBuffer(pSfOMXComponent, nPort);
+        pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
+                                                 OMX_EventCmdComplete, OMX_CommandFlush, nParam, NULL);
+    }
+    break;
+    case OMX_CommandPortDisable:
+        pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
+                                                 OMX_EventCmdComplete, OMX_CommandPortDisable, nParam, NULL);
+        break;
+    case OMX_CommandPortEnable:
+        pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
+                                                 OMX_EventCmdComplete, OMX_CommandPortEnable, nParam, NULL);
+        break;
+    case OMX_CommandMarkBuffer:
+
+        break;
+    default:
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_GetState(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_OUT OMX_STATETYPE *pState)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    FunctionIn();
+    GetStateCommon(hComponent, pState);
+
+    FunctionOut();
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_FreeBuffer(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_U32 nPortIndex,
+    OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    FunctionIn();
+    LOG(SF_LOG_PERF, "buffer count = %d\r\n", GetOMXBufferCount(pSfOMXComponent));
+    free(pBufferHdr);
+
+    FunctionOut();
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_ComponentConstructor(SF_OMX_COMPONENT *pSfOMXComponent)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    FunctionIn();
+    ret = InitComponentStructorCommon(pSfOMXComponent);
+    if (ret != OMX_ErrorNone)
+    {
+        goto EXIT;
+    }
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    TestEncConfig *pTestEncConfig = (TestEncConfig *)pSfVideoImplement->testConfig;
+    pTestEncConfig->stdMode = pSfVideoImplement->bitFormat;
+    pTestEncConfig->frame_endian = VPU_FRAME_ENDIAN;
+    pTestEncConfig->stream_endian = VPU_STREAM_ENDIAN;
+    pTestEncConfig->source_endian = VPU_SOURCE_ENDIAN;
+    pTestEncConfig->mapType = COMPRESSED_FRAME_MAP;
+    pTestEncConfig->lineBufIntEn = TRUE;
+    pTestEncConfig->ringBufferEnable = FALSE;
+    pTestEncConfig->ringBufferWrapEnable = FALSE;
+    pTestEncConfig->yuv_mode = SOURCE_YUV_WITH_BUFFER;
+    /*
+     if cbcrInterleave is FALSE and nv21 is FALSE, the default enc format is I420
+     if cbcrInterleave is TRUE and nv21 is FALSE, then the enc format is NV12
+     if cbcrInterleave is TRUE and nv21 is TRUE, then the enc format is NV21
+    */
+    pTestEncConfig->cbcrInterleave = TRUE;
+    pTestEncConfig->nv21 = FALSE;
+
+    pSfOMXComponent->pOMXComponent->UseBuffer = &SF_OMX_UseBuffer;
+    pSfOMXComponent->pOMXComponent->AllocateBuffer = &SF_OMX_AllocateBuffer;
+    pSfOMXComponent->pOMXComponent->EmptyThisBuffer = &SF_OMX_EmptyThisBuffer;
+    pSfOMXComponent->pOMXComponent->FillThisBuffer = &SF_OMX_FillThisBuffer;
+    pSfOMXComponent->pOMXComponent->FreeBuffer = &SF_OMX_FreeBuffer;
+    // pSfOMXComponent->pOMXComponent->ComponentTunnelRequest = &SF_OMX_ComponentTunnelRequest;
+    pSfOMXComponent->pOMXComponent->GetParameter = &SF_OMX_GetParameter;
+    pSfOMXComponent->pOMXComponent->SetParameter = &SF_OMX_SetParameter;
+    pSfOMXComponent->pOMXComponent->GetConfig = &SF_OMX_GetConfig;
+    pSfOMXComponent->pOMXComponent->SetConfig = &SF_OMX_SetConfig;
+    pSfOMXComponent->pOMXComponent->SendCommand = &SF_OMX_SendCommand;
+    pSfOMXComponent->pOMXComponent->GetState = &SF_OMX_GetState;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE SF_OMX_ComponentClear(SF_OMX_COMPONENT *pSfOMXComponent)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    ComponentImpl *pSFComponentEncoder = (ComponentImpl *)pSfVideoImplement->hSFComponentExecoder;
+    ComponentImpl *pSFComponentFeeder = (ComponentImpl *)pSfVideoImplement->hSFComponentFeeder;
+    ComponentImpl *pSFComponentRender = (ComponentImpl *)pSfVideoImplement->hSFComponentRender;
+
+    FunctionIn();
+    if (pSFComponentEncoder == NULL || pSFComponentFeeder == NULL || pSFComponentRender == NULL)
+    {
+        goto EXIT;
+    }
+    pSFComponentEncoder->terminate = OMX_TRUE;
+    pSFComponentFeeder->terminate = OMX_TRUE;
+    pSFComponentRender->terminate = OMX_TRUE;
+    pSfVideoImplement->functions->ComponentWait(pSfVideoImplement->hSFComponentFeeder);
+    pSfVideoImplement->functions->ComponentWait(pSfVideoImplement->hSFComponentExecoder);
+    pSfVideoImplement->functions->ComponentWait(pSfVideoImplement->hSFComponentRender);
+
+    free(pSfVideoImplement->pusBitCode);
+    pSfVideoImplement->functions->ClearEncListenerContext(pSfVideoImplement->lsnCtx);
+    ComponentClearCommon(pSfOMXComponent);
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+SF_OMX_COMPONENT sf_enc_encoder_h265 = {
+    .componentName = "sf.enc.encoder.h265",
+    .libName = "libsfenc.so",
+    .pOMXComponent = NULL,
+    .SF_OMX_ComponentConstructor = SF_OMX_ComponentConstructor,
+    .SF_OMX_ComponentClear = SF_OMX_ComponentClear,
+    // .bitFormat = STD_HEVC,
+    .componentImpl = NULL,
+    .fwPath = "/lib/firmware/chagall.bin",
+    .componentRule = "video_encoder.hevc"};
+
+SF_OMX_COMPONENT sf_enc_encoder_h264 = {
+    .componentName = "sf.enc.encoder.h264",
+    .libName = "libsfenc.so",
+    .pOMXComponent = NULL,
+    .SF_OMX_ComponentConstructor = SF_OMX_ComponentConstructor,
+    .SF_OMX_ComponentClear = SF_OMX_ComponentClear,
+    // .bitFormat = STD_AVC,
+    .componentImpl = NULL,
+    .fwPath = "/lib/firmware/chagall.bin",
+    .componentRule = "video_encoder.avc"};

+ 309 - 0
omx-il/core/SF_OMX_Core.c

@@ -0,0 +1,309 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 StarFive Technology Co., Ltd.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdlib.h>
+#include "SF_OMX_Core.h"
+
+static int gInitialized = 0;
+OMX_TICKS gInitTimeStamp = 0;
+int gDebugLevel = SF_LOG_ERR;
+extern SF_OMX_COMPONENT sf_dec_decoder_h265;
+extern SF_OMX_COMPONENT sf_dec_decoder_h264;
+extern SF_OMX_COMPONENT sf_enc_encoder_h265;
+//extern SF_OMX_COMPONENT sf_enc_encoder_h264;
+extern SF_OMX_COMPONENT sf_dec_decoder_mjpeg;
+
+SF_OMX_COMPONENT *sf_omx_component_list[] = {
+    &sf_dec_decoder_h265,
+    &sf_dec_decoder_h264,
+    &sf_enc_encoder_h265,
+ //   &sf_enc_encoder_h264,
+    &sf_dec_decoder_mjpeg,
+    NULL,
+};
+
+#define SF_OMX_COMPONENT_NUM ((sizeof(sf_omx_component_list) / sizeof(SF_OMX_COMPONENT *)) - 1)
+
+int GetNumberOfComponent()
+{
+    return sizeof(sf_omx_component_list) / sizeof(SF_OMX_COMPONENT *);
+}
+
+OMX_ERRORTYPE SF_OMX_ComponentLoad(SF_OMX_COMPONENT *sf_component)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    sf_component->SF_OMX_ComponentConstructor(sf_component);
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Init(void)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    char *debugLevel = NULL;
+    FunctionIn();
+    if (gInitialized == 0)
+    {
+        gInitialized = 1;
+    }
+
+    debugLevel = getenv("OMX_DEBUG");
+    if (debugLevel != NULL)
+    {
+        gDebugLevel = atoi(debugLevel);
+    }
+
+    FunctionOut();
+    return ret;
+}
+
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Deinit(void)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    FunctionOut();
+    return ret;
+}
+
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_ComponentNameEnum(
+    OMX_OUT OMX_STRING cComponentName,
+    OMX_IN OMX_U32 nNameLength,
+    OMX_IN OMX_U32 nIndex)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if (nIndex >= SF_OMX_COMPONENT_NUM)
+    {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+    snprintf(cComponentName, nNameLength, "%s", sf_omx_component_list[nIndex]->componentName);
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle(
+    OMX_OUT OMX_HANDLETYPE *pHandle,
+    OMX_IN OMX_STRING cComponentName,
+    OMX_IN OMX_PTR pAppData,
+    OMX_IN OMX_CALLBACKTYPE *pCallBacks)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    unsigned int i = 0;
+    SF_OMX_COMPONENT *pSf_omx_component = NULL;
+
+    FunctionIn();
+    if (gInitialized != 1)
+    {
+        ret = OMX_ErrorNotReady;
+        goto EXIT;
+    }
+
+    if ((pHandle == NULL) || (cComponentName == NULL))
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    for (i = 0; i < SF_OMX_COMPONENT_NUM; i++)
+    {
+        if (sf_omx_component_list[i] == NULL)
+        {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+        if (strcmp(cComponentName, sf_omx_component_list[i]->componentName) == 0)
+        {
+            pSf_omx_component = malloc(sizeof(SF_OMX_COMPONENT));
+            if (!pSf_omx_component)
+            {
+                goto EXIT;
+            }
+            memcpy(pSf_omx_component, sf_omx_component_list[i], sizeof(SF_OMX_COMPONENT));
+            ret = pSf_omx_component->SF_OMX_ComponentConstructor(pSf_omx_component);
+            if (ret != OMX_ErrorNone)
+            {
+                free(pSf_omx_component);
+                goto EXIT;
+            }
+            *pHandle = pSf_omx_component->pOMXComponent;
+            pSf_omx_component->callbacks = pCallBacks;
+            pSf_omx_component->pAppData = pAppData;
+            pSf_omx_component->state = OMX_StateLoaded;
+            break;
+        }
+    }
+EXIT:
+    FunctionOut();
+    return ret;
+}
+
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle(OMX_IN OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = (SF_OMX_COMPONENT *)pOMXComponent->pComponentPrivate;
+    FunctionIn();
+    ret = pSfOMXComponent->SF_OMX_ComponentClear(pSfOMXComponent);
+    if (!ret)
+    {
+        free(pSfOMXComponent);
+    }
+
+    FunctionOut();
+    return ret;
+}
+
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_SetupTunnel(
+    OMX_IN OMX_HANDLETYPE hOutput,
+    OMX_IN OMX_U32 nPortOutput,
+    OMX_IN OMX_HANDLETYPE hInput,
+    OMX_IN OMX_U32 nPortInput)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    // OMX_COMPONENTTYPE *pOMXComponent_hOutput = (OMX_COMPONENTTYPE *)hOutput;
+    // OMX_COMPONENTTYPE *pOMXComponent_hInput = (OMX_COMPONENTTYPE *)hInput;
+
+    FunctionIn();
+    ret = OMX_ErrorNotImplemented;
+
+    FunctionOut();
+    return ret;
+}
+
+OMX_API OMX_ERRORTYPE OMX_GetContentPipe(
+    OMX_OUT OMX_HANDLETYPE *hPipe,
+    OMX_IN OMX_STRING szURI)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    FunctionIn();
+
+    FunctionOut();
+    return ret;
+}
+
+OMX_API OMX_ERRORTYPE OMX_GetComponentsOfRole(
+    OMX_IN OMX_STRING role,
+    OMX_INOUT OMX_U32 *pNumComps,
+    OMX_INOUT OMX_U8 **compNames)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    FunctionIn();
+
+    LOG(SF_LOG_INFO, "Role = %s\r\n", role);
+    *pNumComps = 0;
+    for (int i = 0; i < SF_OMX_COMPONENT_NUM; i ++)
+    {
+        if (sf_omx_component_list[i] == NULL)
+        {
+            break;
+        }
+        if (strcmp(sf_omx_component_list[i]->componentRule, role) == 0)
+        {
+            if (compNames != NULL) {
+                strcpy((OMX_STRING)compNames[*pNumComps], sf_omx_component_list[i]->componentName);
+            }
+            *pNumComps = (*pNumComps + 1);
+            LOG(SF_LOG_INFO,"Get component %s, Role = %s\r\n", sf_omx_component_list[i]->componentName, sf_omx_component_list[i]->componentRule)
+        }
+    }
+    FunctionOut();
+    return ret;
+}
+
+OMX_API OMX_ERRORTYPE OMX_GetRolesOfComponent(
+    OMX_IN OMX_STRING compName,
+    OMX_INOUT OMX_U32 *pNumRoles,
+    OMX_OUT OMX_U8 **roles)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    FunctionIn();
+
+#if 0 //todo
+    for (int i = 0; i < SF_OMX_COMPONENT_NUM; i ++)
+    {
+        if (sf_omx_component_list[i] == NULL)
+        {
+            break;
+        }
+        if (strcmp(sf_omx_component_list[i]->componentName, compName) == 0)
+        {
+            *pNumRoles = 1;
+            if (roles != NULL) {
+                strcpy((OMX_STRING)roles[0], sf_omx_component_list[i]->componentRule);
+            }
+            LOG(SF_LOG_INFO,"Get component %s, Role = %s\r\n", sf_omx_component_list[i]->componentName, sf_omx_component_list[i]->componentRule)
+        }
+    }
+#endif
+
+    FunctionOut();
+    return ret;
+}
+
+void SF_LogMsgAppend(int level, const char *format, ...)
+{
+    va_list ptr;
+
+    if (level > gDebugLevel)
+    {
+        return;
+    }
+    
+    printf("%66s\t", " ");
+    va_start(ptr, format);
+    vprintf(format, ptr);
+    va_end(ptr);
+}
+void SF_LogMsg(int level, const char *function, int line, const char *format, ...)
+{
+    char *prefix = "";
+    va_list ptr;
+    struct timeval tv;
+
+    if (level > gDebugLevel)
+    {
+        return;
+    }
+
+    switch (level)
+    {
+    case SF_LOG_ERR:
+        prefix = "[ERROR]";
+        break;
+    case SF_LOG_WARN:
+        prefix = "[WARN ]";
+        break;
+    case SF_LOG_PERF:
+        prefix = "[PERF ]";
+        break;
+    case SF_LOG_INFO:
+        prefix = "[INFO ]";
+        break;
+    case SF_LOG_DEBUG:
+        prefix = "[DEBUG]";
+        break;
+    default:
+        break;
+    }
+    gettimeofday(&tv, NULL);
+    printf("[%06ld:%06ld]%10s%32s%10d\t", tv.tv_sec, tv.tv_usec, prefix, function, line);
+    va_start(ptr, format);
+    vprintf(format, ptr);
+    va_end(ptr);
+}

+ 156 - 0
omx-il/core/SF_OMX_Core.h

@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 StarFive Technology Co., Ltd.
+ */
+#ifndef OMX__CORE
+#define OMX__CORE
+
+#include "OMX_Types.h"
+#include "OMX_Core.h"
+#include "OMX_Component.h"
+#include "OMX_VideoExt.h"
+
+#include <sys/time.h>
+#include <stdarg.h>
+#include <dlfcn.h>
+#include <string.h>
+
+#define ENABLE_DEBUG
+#ifdef ENABLE_DEBUG
+enum
+{
+    SF_LOG_ERR = 0,
+    SF_LOG_WARN,
+    SF_LOG_PERF,
+    SF_LOG_INFO,
+    SF_LOG_DEBUG,
+    SF_LOG_ALL,
+};
+void SF_LogMsg(int level, const char *function, int line, const char *format, ...);
+void SF_LogMsgAppend(int level, const char *format, ...);
+#define LOG(level, ...) SF_LogMsg(level, __FUNCTION__, __LINE__, __VA_ARGS__);
+#define LOG_APPEND(level, ...) SF_LogMsgAppend(level, __VA_ARGS__);
+#define FunctionIn() SF_LogMsg(SF_LOG_DEBUG, __FUNCTION__, __LINE__, "FUN IN\r\n");
+#define FunctionOut() SF_LogMsg(SF_LOG_DEBUG, __FUNCTION__, __LINE__, "FUN OUT\r\n");
+#else
+#define FunctionIn()
+#define FunctionOut()
+#endif
+#define VPU_OUTPUT_BUF_NUMBER              10
+#define VPU_INPUT_BUF_NUMBER               5
+#define MAX_BUFF_NUM                       32
+
+#define VERSIONMAJOR_NUMBER                1
+#define VERSIONMINOR_NUMBER                0
+#define REVISION_NUMBER                    0
+#define STEP_NUMBER                        0
+
+typedef enum SF_BUFFER_TYPE
+{
+    SF_BUFFER_NOMAL = 0,
+    SF_BUFFER_DMA,
+    SF_BUFFER_DMA_EXTERNAL,
+    SF_BUFFER_DMA_FD,
+    SF_BUFFER_DMA_FD_EXTERNAL,
+    SF_BUFFER_ALL,
+}SF_BUFFER_TYPE;
+
+/** This enum defines the transition states of the Component*/
+typedef enum OMX_TRANS_STATETYPE {
+    OMX_TransStateInvalid,
+    OMX_TransStateLoadedToIdle,
+    OMX_TransStateIdleToPause,
+    OMX_TransStatePauseToExecuting,
+    OMX_TransStateIdleToExecuting,
+    OMX_TransStateExecutingToIdle,
+    OMX_TransStateExecutingToPause,
+    OMX_TransStatePauseToIdle,
+    OMX_TransStateIdleToLoaded,
+    OMX_TransStateMax = 0X7FFFFFFF
+} OMX_TRANS_STATETYPE;
+
+typedef struct _SF_OMX_BUF_INFO
+{
+    SF_BUFFER_TYPE type;
+    OMX_U64 PhysicalAddress;
+    OMX_S32 fd;
+    OMX_U32 index;
+}SF_OMX_BUF_INFO;
+
+typedef struct _SF_OMX_COMPONENT
+{
+    OMX_STRING componentName;
+    OMX_STRING libName;
+    OMX_VERSIONTYPE componentVersion;
+    OMX_VERSIONTYPE specVersion;
+    OMX_COMPONENTTYPE *pOMXComponent;
+    OMX_ERRORTYPE (*SF_OMX_ComponentConstructor)(struct _SF_OMX_COMPONENT *hComponent);
+    OMX_ERRORTYPE (*SF_OMX_ComponentClear)(struct _SF_OMX_COMPONENT *hComponent);
+    OMX_PTR soHandle;
+    // SF_COMPONENT_FUNCTIONS *functions;
+    OMX_PTR componentImpl;
+
+    // OMX_PTR functions;
+    // Component *hSFComponentExecoder;
+    // Component *hSFComponentFeeder;
+    // Component *hSFComponentRender;
+    // void *testConfig;
+    // CNMComponentConfig *config;
+    // void *lsnCtx;
+    // Uint16 *pusBitCode;
+    // CodStd bitFormat;
+    // OMX_VIDEO_PARAM_AVCTYPE AVCComponent[2];
+    // OMX_VIDEO_PARAM_HEVCTYPE HEVCComponent[2];
+
+    OMX_CALLBACKTYPE *callbacks;
+    OMX_PTR pAppData;
+    OMX_PARAM_PORTDEFINITIONTYPE portDefinition[2];
+    OMX_HANDLETYPE portSemaphore[2];
+    OMX_HANDLETYPE portUnloadSemaphore[2];
+    OMX_BUFFERHEADERTYPE *pBufferArray[2][MAX_BUFF_NUM];
+    OMX_U32 assignedBufferNum[2];
+    OMX_STRING fwPath;
+    OMX_STRING componentRule;
+    OMX_STATETYPE state;
+    OMX_STATETYPE stateBeforePause;
+    OMX_TRANS_STATETYPE traningState;
+    OMX_MARKTYPE markType[2];
+    OMX_MARKTYPE propagateMarkType;
+    OMX_BOOL memory_optimization;
+} SF_OMX_COMPONENT;
+
+typedef struct _SF_PORT_PRIVATE
+{
+    OMX_U32 nPortnumber;
+} SF_PORT_PRIVATE;
+
+#define PRINT_STUCT(a, b)                                   \
+    do                                                      \
+    {                                                       \
+        printf("size = %d\r\n", sizeof(b));                 \
+        for (int i = 0; i < sizeof(b); i += sizeof(void *)) \
+        {                                                   \
+            for (int j = 0; j < sizeof(void *); j++)        \
+            {                                               \
+                printf("%02X ", *((char *)a + i + j));      \
+            }                                               \
+            for (int j = 0; j < sizeof(void *); j++)        \
+            {                                               \
+                printf("%c", *((char *)a + i + j));         \
+            }                                               \
+            printf("\r\n");                                 \
+        }                                                   \
+    } while (0)
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+int GetNumberOfComponent();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 1310 - 0
omx-il/include/khronos/OMX_Audio.h

@@ -0,0 +1,1310 @@
+/*
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** @file OMX_Audio.h - OpenMax IL version 1.1.2
+ *  The structures needed by Audio components to exchange
+ *  parameters and configuration data with the componenmilts.
+ */
+
+#ifndef OMX_Audio_h
+#define OMX_Audio_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* Each OMX header must include all required header files to allow the
+ *  header to compile without errors.  The includes below are required
+ *  for this header file to compile successfully
+ */
+
+#include <OMX_Core.h>
+
+/** @defgroup midi MIDI
+ * @ingroup audio
+ */
+
+/** @defgroup effects Audio effects
+ * @ingroup audio
+ */
+
+/** @defgroup audio OpenMAX IL Audio Domain
+ * Structures for OpenMAX IL Audio domain
+ * @{
+ */
+
+/** Enumeration used to define the possible audio codings.
+ *  If "OMX_AUDIO_CodingUnused" is selected, the coding selection must
+ *  be done in a vendor specific way.  Since this is for an audio
+ *  processing element this enum is relevant.  However, for another
+ *  type of component other enums would be in this area.
+ */
+typedef enum OMX_AUDIO_CODINGTYPE {
+    OMX_AUDIO_CodingUnused = 0,  /**< Placeholder value when coding is N/A  */
+    OMX_AUDIO_CodingAutoDetect,  /**< auto detection of audio format */
+    OMX_AUDIO_CodingPCM,         /**< Any variant of PCM coding */
+    OMX_AUDIO_CodingADPCM,       /**< Any variant of ADPCM encoded data */
+    OMX_AUDIO_CodingAMR,         /**< Any variant of AMR encoded data */
+    OMX_AUDIO_CodingGSMFR,       /**< Any variant of GSM fullrate (i.e. GSM610) */
+    OMX_AUDIO_CodingGSMEFR,      /**< Any variant of GSM Enhanced Fullrate encoded data*/
+    OMX_AUDIO_CodingGSMHR,       /**< Any variant of GSM Halfrate encoded data */
+    OMX_AUDIO_CodingPDCFR,       /**< Any variant of PDC Fullrate encoded data */
+    OMX_AUDIO_CodingPDCEFR,      /**< Any variant of PDC Enhanced Fullrate encoded data */
+    OMX_AUDIO_CodingPDCHR,       /**< Any variant of PDC Halfrate encoded data */
+    OMX_AUDIO_CodingTDMAFR,      /**< Any variant of TDMA Fullrate encoded data (TIA/EIA-136-420) */
+    OMX_AUDIO_CodingTDMAEFR,     /**< Any variant of TDMA Enhanced Fullrate encoded data (TIA/EIA-136-410) */
+    OMX_AUDIO_CodingQCELP8,      /**< Any variant of QCELP 8kbps encoded data */
+    OMX_AUDIO_CodingQCELP13,     /**< Any variant of QCELP 13kbps encoded data */
+    OMX_AUDIO_CodingEVRC,        /**< Any variant of EVRC encoded data */
+    OMX_AUDIO_CodingSMV,         /**< Any variant of SMV encoded data */
+    OMX_AUDIO_CodingG711,        /**< Any variant of G.711 encoded data */
+    OMX_AUDIO_CodingG723,        /**< Any variant of G.723 dot 1 encoded data */
+    OMX_AUDIO_CodingG726,        /**< Any variant of G.726 encoded data */
+    OMX_AUDIO_CodingG729,        /**< Any variant of G.729 encoded data */
+    OMX_AUDIO_CodingAAC,         /**< Any variant of AAC encoded data */
+    OMX_AUDIO_CodingMP3,         /**< Any variant of MP3 encoded data */
+    OMX_AUDIO_CodingSBC,         /**< Any variant of SBC encoded data */
+    OMX_AUDIO_CodingVORBIS,      /**< Any variant of VORBIS encoded data */
+    OMX_AUDIO_CodingWMA,         /**< Any variant of WMA encoded data */
+    OMX_AUDIO_CodingRA,          /**< Any variant of RA encoded data */
+    OMX_AUDIO_CodingMIDI,        /**< Any variant of MIDI encoded data */
+    OMX_AUDIO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_AUDIO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_CodingMax = 0x7FFFFFFF
+} OMX_AUDIO_CODINGTYPE;
+
+
+/** The PortDefinition structure is used to define all of the parameters
+ *  necessary for the compliant component to setup an input or an output audio
+ *  path.  If additional information is needed to define the parameters of the
+ *  port (such as frequency), additional structures must be sent such as the
+ *  OMX_AUDIO_PARAM_PCMMODETYPE structure to supply the extra parameters for the port.
+ */
+typedef struct OMX_AUDIO_PORTDEFINITIONTYPE {
+    OMX_STRING cMIMEType;            /**< MIME type of data for the port */
+    OMX_NATIVE_DEVICETYPE pNativeRender; /** < platform specific reference
+                                               for an output device,
+                                               otherwise this field is 0 */
+    OMX_BOOL bFlagErrorConcealment;  /**< Turns on error concealment if it is
+                                          supported by the OMX component */
+    OMX_AUDIO_CODINGTYPE eEncoding;  /**< Type of data expected for this
+                                          port (e.g. PCM, AMR, MP3, etc) */
+} OMX_AUDIO_PORTDEFINITIONTYPE;
+
+
+/**  Port format parameter.  This structure is used to enumerate
+  *  the various data input/output format supported by the port.
+  */
+typedef struct OMX_AUDIO_PARAM_PORTFORMATTYPE {
+    OMX_U32 nSize;                  /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;       /**< OMX specification version information */
+    OMX_U32 nPortIndex;             /**< Indicates which port to set */
+    OMX_U32 nIndex;                 /**< Indicates the enumeration index for the format from 0x0 to N-1 */
+    OMX_AUDIO_CODINGTYPE eEncoding; /**< Type of data expected for this port (e.g. PCM, AMR, MP3, etc) */
+} OMX_AUDIO_PARAM_PORTFORMATTYPE;
+
+
+/** PCM mode type  */
+typedef enum OMX_AUDIO_PCMMODETYPE {
+    OMX_AUDIO_PCMModeLinear = 0,  /**< Linear PCM encoded data */
+    OMX_AUDIO_PCMModeALaw,        /**< A law PCM encoded data (G.711) */
+    OMX_AUDIO_PCMModeMULaw,       /**< Mu law PCM encoded data (G.711)  */
+    OMX_AUDIO_PCMModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_AUDIO_PCMModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_PCMModeMax = 0x7FFFFFFF
+} OMX_AUDIO_PCMMODETYPE;
+
+
+typedef enum OMX_AUDIO_CHANNELTYPE {
+    OMX_AUDIO_ChannelNone = 0x0,    /**< Unused or empty */
+    OMX_AUDIO_ChannelLF   = 0x1,    /**< Left front */
+    OMX_AUDIO_ChannelRF   = 0x2,    /**< Right front */
+    OMX_AUDIO_ChannelCF   = 0x3,    /**< Center front */
+    OMX_AUDIO_ChannelLS   = 0x4,    /**< Left surround */
+    OMX_AUDIO_ChannelRS   = 0x5,    /**< Right surround */
+    OMX_AUDIO_ChannelLFE  = 0x6,    /**< Low frequency effects */
+    OMX_AUDIO_ChannelCS   = 0x7,    /**< Back surround */
+    OMX_AUDIO_ChannelLR   = 0x8,    /**< Left rear. */
+    OMX_AUDIO_ChannelRR   = 0x9,    /**< Right rear. */
+    OMX_AUDIO_ChannelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_AUDIO_ChannelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_ChannelMax  = 0x7FFFFFFF
+} OMX_AUDIO_CHANNELTYPE;
+
+#define OMX_AUDIO_MAXCHANNELS 16  /**< maximum number distinct audio channels that a buffer may contain */
+#define OMX_MIN_PCMPAYLOAD_MSEC 5 /**< Minimum audio buffer payload size for uncompressed (PCM) audio */
+
+/** PCM format description */
+typedef struct OMX_AUDIO_PARAM_PCMMODETYPE {
+    OMX_U32 nSize;                    /**< Size of this structure, in Bytes */
+    OMX_VERSIONTYPE nVersion;         /**< OMX specification version information */
+    OMX_U32 nPortIndex;               /**< port that this structure applies to */
+    OMX_U32 nChannels;                /**< Number of channels (e.g. 2 for stereo) */
+    OMX_NUMERICALDATATYPE eNumData;   /**< indicates PCM data as signed or unsigned */
+    OMX_ENDIANTYPE eEndian;           /**< indicates PCM data as little or big endian */
+    OMX_BOOL bInterleaved;            /**< True for normal interleaved data; false for
+                                           non-interleaved data (e.g. block data) */
+    OMX_U32 nBitPerSample;            /**< Bit per sample */
+    OMX_U32 nSamplingRate;            /**< Sampling rate of the source data.  Use 0 for
+                                           variable or unknown sampling rate. */
+    OMX_AUDIO_PCMMODETYPE ePCMMode;   /**< PCM mode enumeration */
+    OMX_AUDIO_CHANNELTYPE eChannelMapping[OMX_AUDIO_MAXCHANNELS]; /**< Slot i contains channel defined by eChannelMap[i] */
+
+} OMX_AUDIO_PARAM_PCMMODETYPE;
+
+
+/** Audio channel mode.  This is used by both AAC and MP3, although the names are more appropriate
+ * for the MP3.  For example, JointStereo for MP3 is CouplingChannels for AAC.
+ */
+typedef enum OMX_AUDIO_CHANNELMODETYPE {
+    OMX_AUDIO_ChannelModeStereo = 0,  /**< 2 channels, the bitrate allocation between those
+                                          two channels changes accordingly to each channel information */
+    OMX_AUDIO_ChannelModeJointStereo, /**< mode that takes advantage of what is common between
+                                           2 channels for higher compression gain */
+    OMX_AUDIO_ChannelModeDual,        /**< 2 mono-channels, each channel is encoded with half
+                                           the bitrate of the overall bitrate */
+    OMX_AUDIO_ChannelModeMono,        /**< Mono channel mode */
+    OMX_AUDIO_ChannelModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_AUDIO_ChannelModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_ChannelModeMax = 0x7FFFFFFF
+} OMX_AUDIO_CHANNELMODETYPE;
+
+
+typedef enum OMX_AUDIO_MP3STREAMFORMATTYPE {
+    OMX_AUDIO_MP3StreamFormatMP1Layer3 = 0, /**< MP3 Audio MPEG 1 Layer 3 Stream format */
+    OMX_AUDIO_MP3StreamFormatMP2Layer3,     /**< MP3 Audio MPEG 2 Layer 3 Stream format */
+    OMX_AUDIO_MP3StreamFormatMP2_5Layer3,   /**< MP3 Audio MPEG2.5 Layer 3 Stream format */
+    OMX_AUDIO_MP3StreamFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_AUDIO_MP3StreamFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_MP3StreamFormatMax = 0x7FFFFFFF
+} OMX_AUDIO_MP3STREAMFORMATTYPE;
+
+/** MP3 params */
+typedef struct OMX_AUDIO_PARAM_MP3TYPE {
+    OMX_U32 nSize;                 /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;      /**< OMX specification version information */
+    OMX_U32 nPortIndex;            /**< port that this structure applies to */
+    OMX_U32 nChannels;             /**< Number of channels */
+    OMX_U32 nBitRate;              /**< Bit rate of the input data.  Use 0 for variable
+                                        rate or unknown bit rates */
+    OMX_U32 nSampleRate;           /**< Sampling rate of the source data.  Use 0 for
+                                        variable or unknown sampling rate. */
+    OMX_U32 nAudioBandWidth;       /**< Audio band width (in Hz) to which an encoder should
+                                        limit the audio signal. Use 0 to let encoder decide */
+    OMX_AUDIO_CHANNELMODETYPE eChannelMode;   /**< Channel mode enumeration */
+    OMX_AUDIO_MP3STREAMFORMATTYPE eFormat;  /**< MP3 stream format */
+} OMX_AUDIO_PARAM_MP3TYPE;
+
+
+typedef enum OMX_AUDIO_AACSTREAMFORMATTYPE {
+    OMX_AUDIO_AACStreamFormatMP2ADTS = 0, /**< AAC Audio Data Transport Stream 2 format */
+    OMX_AUDIO_AACStreamFormatMP4ADTS,     /**< AAC Audio Data Transport Stream 4 format */
+    OMX_AUDIO_AACStreamFormatMP4LOAS,     /**< AAC Low Overhead Audio Stream format */
+    OMX_AUDIO_AACStreamFormatMP4LATM,     /**< AAC Low overhead Audio Transport Multiplex */
+    OMX_AUDIO_AACStreamFormatADIF,        /**< AAC Audio Data Interchange Format */
+    OMX_AUDIO_AACStreamFormatMP4FF,       /**< AAC inside MPEG-4/ISO File Format */
+    OMX_AUDIO_AACStreamFormatRAW,         /**< AAC Raw Format */
+    OMX_AUDIO_AACStreamFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_AUDIO_AACStreamFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_AACStreamFormatMax = 0x7FFFFFFF
+} OMX_AUDIO_AACSTREAMFORMATTYPE;
+
+
+/** AAC mode type.  Note that the term profile is used with the MPEG-2
+ * standard and the term object type and profile is used with MPEG-4 */
+typedef enum OMX_AUDIO_AACPROFILETYPE {
+    OMX_AUDIO_AACObjectNull = 0,      /**< Null, not used */
+    OMX_AUDIO_AACObjectMain = 1,      /**< AAC Main object */
+    OMX_AUDIO_AACObjectLC,            /**< AAC Low Complexity object (AAC profile) */
+    OMX_AUDIO_AACObjectSSR,           /**< AAC Scalable Sample Rate object */
+    OMX_AUDIO_AACObjectLTP,           /**< AAC Long Term Prediction object */
+    OMX_AUDIO_AACObjectHE,            /**< AAC High Efficiency (object type SBR, HE-AAC profile) */
+    OMX_AUDIO_AACObjectScalable,      /**< AAC Scalable object */
+    OMX_AUDIO_AACObjectERLC = 17,     /**< ER AAC Low Complexity object (Error Resilient AAC-LC) */
+    OMX_AUDIO_AACObjectLD = 23,       /**< AAC Low Delay object (Error Resilient) */
+    OMX_AUDIO_AACObjectHE_PS = 29,    /**< AAC High Efficiency with Parametric Stereo coding (HE-AAC v2, object type PS) */
+    OMX_AUDIO_AACObjectKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_AUDIO_AACObjectVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_AACObjectMax = 0x7FFFFFFF
+} OMX_AUDIO_AACPROFILETYPE;
+
+
+/** AAC tool usage (for nAACtools in OMX_AUDIO_PARAM_AACPROFILETYPE).
+ * Required for encoder configuration and optional as decoder info output.
+ * For MP3, OMX_AUDIO_CHANNELMODETYPE is sufficient. */
+#define OMX_AUDIO_AACToolNone 0x00000000 /**< no AAC tools allowed (encoder config) or active (decoder info output) */
+#define OMX_AUDIO_AACToolMS   0x00000001 /**< MS: Mid/side joint coding tool allowed or active */
+#define OMX_AUDIO_AACToolIS   0x00000002 /**< IS: Intensity stereo tool allowed or active */
+#define OMX_AUDIO_AACToolTNS  0x00000004 /**< TNS: Temporal Noise Shaping tool allowed or active */
+#define OMX_AUDIO_AACToolPNS  0x00000008 /**< PNS: MPEG-4 Perceptual Noise substitution tool allowed or active */
+#define OMX_AUDIO_AACToolLTP  0x00000010 /**< LTP: MPEG-4 Long Term Prediction tool allowed or active */
+#define OMX_AUDIO_AACToolAll  0x7FFFFFFF /**< all AAC tools allowed or active (*/
+
+/** MPEG-4 AAC error resilience (ER) tool usage (for nAACERtools in OMX_AUDIO_PARAM_AACPROFILETYPE).
+ * Required for ER encoder configuration and optional as decoder info output */
+#define OMX_AUDIO_AACERNone  0x00000000  /**< no AAC ER tools allowed/used */
+#define OMX_AUDIO_AACERVCB11 0x00000001  /**< VCB11: Virtual Code Books for AAC section data */
+#define OMX_AUDIO_AACERRVLC  0x00000002  /**< RVLC: Reversible Variable Length Coding */
+#define OMX_AUDIO_AACERHCR   0x00000004  /**< HCR: Huffman Codeword Reordering */
+#define OMX_AUDIO_AACERAll   0x7FFFFFFF  /**< all AAC ER tools allowed/used */
+
+
+/** AAC params */
+typedef struct OMX_AUDIO_PARAM_AACPROFILETYPE {
+    OMX_U32 nSize;                 /**< Size of this structure, in Bytes */
+    OMX_VERSIONTYPE nVersion;      /**< OMX specification version information */
+    OMX_U32 nPortIndex;            /**< Port that this structure applies to */
+    OMX_U32 nChannels;             /**< Number of channels */
+    OMX_U32 nSampleRate;           /**< Sampling rate of the source data.  Use 0 for
+                                        variable or unknown sampling rate. */
+    OMX_U32 nBitRate;              /**< Bit rate of the input data.  Use 0 for variable
+                                        rate or unknown bit rates */
+    OMX_U32 nAudioBandWidth;       /**< Audio band width (in Hz) to which an encoder should
+                                        limit the audio signal. Use 0 to let encoder decide */
+    OMX_U32 nFrameLength;          /**< Frame length (in audio samples per channel) of the codec.
+                                        Can be 1024 or 960 (AAC-LC), 2048 (HE-AAC), 480 or 512 (AAC-LD).
+                                        Use 0 to let encoder decide */
+    OMX_U32 nAACtools;             /**< AAC tool usage */
+    OMX_U32 nAACERtools;           /**< MPEG-4 AAC error resilience tool usage */
+    OMX_AUDIO_AACPROFILETYPE eAACProfile;   /**< AAC profile enumeration */
+    OMX_AUDIO_AACSTREAMFORMATTYPE eAACStreamFormat; /**< AAC stream format enumeration */
+    OMX_AUDIO_CHANNELMODETYPE eChannelMode;   /**< Channel mode enumeration */
+} OMX_AUDIO_PARAM_AACPROFILETYPE;
+
+
+/** VORBIS params */
+typedef struct OMX_AUDIO_PARAM_VORBISTYPE {
+    OMX_U32 nSize;            /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_U32 nPortIndex;       /**< port that this structure applies to */
+    OMX_U32 nChannels;        /**< Number of channels */
+    OMX_U32 nBitRate;         /**< Bit rate of the encoded data data.  Use 0 for variable
+                                   rate or unknown bit rates. Encoding is set to the
+                                   bitrate closest to specified  value (in bps) */
+    OMX_U32 nMinBitRate;      /**< Sets minimum bitrate (in bps). */
+    OMX_U32 nMaxBitRate;      /**< Sets maximum bitrate (in bps). */
+
+    OMX_U32 nSampleRate;      /**< Sampling rate of the source data.  Use 0 for
+                                   variable or unknown sampling rate. */
+    OMX_U32 nAudioBandWidth;  /**< Audio band width (in Hz) to which an encoder should
+                                   limit the audio signal. Use 0 to let encoder decide */
+    OMX_S32 nQuality;         /**< Sets encoding quality to n, between -1 (low) and 10 (high).
+                                   In the default mode of operation, teh quality level is 3.
+                                   Normal quality range is 0 - 10. */
+    OMX_BOOL bManaged;        /**< Set  bitrate  management  mode. This turns off the
+                                   normal VBR encoding, but allows hard or soft bitrate
+                                   constraints to be enforced by the encoder. This mode can
+                                   be slower, and may also be lower quality. It is
+                                   primarily useful for streaming. */
+    OMX_BOOL bDownmix;        /**< Downmix input from stereo to mono (has no effect on
+                                   non-stereo streams). Useful for lower-bitrate encoding. */
+} OMX_AUDIO_PARAM_VORBISTYPE;
+
+
+/** WMA Version */
+typedef enum OMX_AUDIO_WMAFORMATTYPE {
+    OMX_AUDIO_WMAFormatUnused = 0, /**< format unused or unknown */
+    OMX_AUDIO_WMAFormat7,          /**< Windows Media Audio format 7 */
+    OMX_AUDIO_WMAFormat8,          /**< Windows Media Audio format 8 */
+    OMX_AUDIO_WMAFormat9,          /**< Windows Media Audio format 9 */
+    OMX_AUDIO_WMAFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_AUDIO_WMAFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_WMAFormatMax = 0x7FFFFFFF
+} OMX_AUDIO_WMAFORMATTYPE;
+
+
+/** WMA Profile */
+typedef enum OMX_AUDIO_WMAPROFILETYPE {
+    OMX_AUDIO_WMAProfileUnused = 0,  /**< profile unused or unknown */
+    OMX_AUDIO_WMAProfileL1,          /**< Windows Media audio version 9 profile L1 */
+    OMX_AUDIO_WMAProfileL2,          /**< Windows Media audio version 9 profile L2 */
+    OMX_AUDIO_WMAProfileL3,          /**< Windows Media audio version 9 profile L3 */
+    OMX_AUDIO_WMAProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_AUDIO_WMAProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_WMAProfileMax = 0x7FFFFFFF
+} OMX_AUDIO_WMAPROFILETYPE;
+
+
+/** WMA params */
+typedef struct OMX_AUDIO_PARAM_WMATYPE {
+    OMX_U32 nSize;            /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_U32 nPortIndex;       /**< port that this structure applies to */
+    OMX_U16 nChannels;        /**< Number of channels */
+    OMX_U32 nBitRate;         /**< Bit rate of the input data.  Use 0 for variable
+                                   rate or unknown bit rates */
+    OMX_AUDIO_WMAFORMATTYPE eFormat; /**< Version of WMA stream / data */
+    OMX_AUDIO_WMAPROFILETYPE eProfile;  /**< Profile of WMA stream / data */
+    OMX_U32 nSamplingRate;    /**< Sampling rate of the source data */
+    OMX_U16 nBlockAlign;      /**< is the block alignment, or block size, in bytes of the audio codec */
+    OMX_U16 nEncodeOptions;   /**< WMA Type-specific data */
+    OMX_U32 nSuperBlockAlign; /**< WMA Type-specific data */
+} OMX_AUDIO_PARAM_WMATYPE;
+
+/**
+ * RealAudio format
+ */
+typedef enum OMX_AUDIO_RAFORMATTYPE {
+    OMX_AUDIO_RAFormatUnused = 0, /**< Format unused or unknown */
+    OMX_AUDIO_RA8,                /**< RealAudio 8 codec */
+    OMX_AUDIO_RA9,                /**< RealAudio 9 codec */
+    OMX_AUDIO_RA10_AAC,           /**< MPEG-4 AAC codec for bitrates of more than 128kbps */
+    OMX_AUDIO_RA10_CODEC,         /**< RealAudio codec for bitrates less than 128 kbps */
+    OMX_AUDIO_RA10_LOSSLESS,      /**< RealAudio Lossless */
+    OMX_AUDIO_RA10_MULTICHANNEL,  /**< RealAudio Multichannel */
+    OMX_AUDIO_RA10_VOICE,         /**< RealAudio Voice for bitrates below 15 kbps */
+    OMX_AUDIO_RAFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_AUDIO_RAFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_RAFormatMax = 0x7FFFFFFF
+} OMX_AUDIO_RAFORMATTYPE;
+
+/** RA (Real Audio) params */
+typedef struct OMX_AUDIO_PARAM_RATYPE {
+    OMX_U32 nSize;              /**< Size of this structure, in Bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPortIndex;         /**< Port that this structure applies to */
+    OMX_U32 nChannels;          /**< Number of channels */
+    OMX_U32 nSamplingRate;      /**< is the sampling rate of the source data */
+    OMX_U32 nBitsPerFrame;      /**< is the value for bits per frame  */
+    OMX_U32 nSamplePerFrame;    /**< is the value for samples per frame */
+    OMX_U32 nCouplingQuantBits; /**< is the number of coupling quantization bits in the stream */
+    OMX_U32 nCouplingStartRegion;   /**< is the coupling start region in the stream  */
+    OMX_U32 nNumRegions;        /**< is the number of regions value */
+    OMX_AUDIO_RAFORMATTYPE eFormat; /**< is the RealAudio audio format */
+} OMX_AUDIO_PARAM_RATYPE;
+
+
+/** SBC Allocation Method Type */
+typedef enum OMX_AUDIO_SBCALLOCMETHODTYPE {
+    OMX_AUDIO_SBCAllocMethodLoudness, /**< Loudness allocation method */
+    OMX_AUDIO_SBCAllocMethodSNR,      /**< SNR allocation method */
+    OMX_AUDIO_SBCAllocMethodKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_AUDIO_SBCAllocMethodVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_SBCAllocMethodMax = 0x7FFFFFFF
+} OMX_AUDIO_SBCALLOCMETHODTYPE;
+
+
+/** SBC params */
+typedef struct OMX_AUDIO_PARAM_SBCTYPE {
+    OMX_U32 nSize;             /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
+    OMX_U32 nPortIndex;        /**< port that this structure applies to */
+    OMX_U32 nChannels;         /**< Number of channels */
+    OMX_U32 nBitRate;          /**< Bit rate of the input data.  Use 0 for variable
+                                    rate or unknown bit rates */
+    OMX_U32 nSampleRate;       /**< Sampling rate of the source data.  Use 0 for
+                                    variable or unknown sampling rate. */
+    OMX_U32 nBlocks;           /**< Number of blocks */
+    OMX_U32 nSubbands;         /**< Number of subbands */
+    OMX_U32 nBitPool;          /**< Bitpool value */
+    OMX_BOOL bEnableBitrate;   /**< Use bitrate value instead of bitpool */
+    OMX_AUDIO_CHANNELMODETYPE eChannelMode; /**< Channel mode enumeration */
+    OMX_AUDIO_SBCALLOCMETHODTYPE eSBCAllocType;   /**< SBC Allocation method type */
+} OMX_AUDIO_PARAM_SBCTYPE;
+
+
+/** ADPCM stream format parameters */
+typedef struct OMX_AUDIO_PARAM_ADPCMTYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPortIndex;         /**< port that this structure applies to */
+    OMX_U32 nChannels;          /**< Number of channels in the data stream (not
+                                     necessarily the same as the number of channels
+                                     to be rendered. */
+    OMX_U32 nBitsPerSample;     /**< Number of bits in each sample */
+    OMX_U32 nSampleRate;        /**< Sampling rate of the source data.  Use 0 for
+                                    variable or unknown sampling rate. */
+} OMX_AUDIO_PARAM_ADPCMTYPE;
+
+
+/** G723 rate */
+typedef enum OMX_AUDIO_G723RATE {
+    OMX_AUDIO_G723ModeUnused = 0,  /**< AMRNB Mode unused / unknown */
+    OMX_AUDIO_G723ModeLow,         /**< 5300 bps */
+    OMX_AUDIO_G723ModeHigh,        /**< 6300 bps */
+    OMX_AUDIO_G723ModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_AUDIO_G723ModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_G723ModeMax = 0x7FFFFFFF
+} OMX_AUDIO_G723RATE;
+
+
+/** G723 - Sample rate must be 8 KHz */
+typedef struct OMX_AUDIO_PARAM_G723TYPE {
+    OMX_U32 nSize;                /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */
+    OMX_U32 nPortIndex;           /**< port that this structure applies to */
+    OMX_U32 nChannels;            /**< Number of channels in the data stream (not
+                                       necessarily the same as the number of channels
+                                       to be rendered. */
+    OMX_BOOL bDTX;                /**< Enable Discontinuous Transmisssion */
+    OMX_AUDIO_G723RATE eBitRate;  /**< todo: Should this be moved to a config? */
+    OMX_BOOL bHiPassFilter;       /**< Enable High Pass Filter */
+    OMX_BOOL bPostFilter;         /**< Enable Post Filter */
+} OMX_AUDIO_PARAM_G723TYPE;
+
+
+/** ITU G726 (ADPCM) rate */
+typedef enum OMX_AUDIO_G726MODE {
+    OMX_AUDIO_G726ModeUnused = 0,  /**< G726 Mode unused / unknown */
+    OMX_AUDIO_G726Mode16,          /**< 16 kbps */
+    OMX_AUDIO_G726Mode24,          /**< 24 kbps */
+    OMX_AUDIO_G726Mode32,          /**< 32 kbps, most common rate, also G721 */
+    OMX_AUDIO_G726Mode40,          /**< 40 kbps */
+    OMX_AUDIO_G726ModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_AUDIO_G726ModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_G726ModeMax = 0x7FFFFFFF
+} OMX_AUDIO_G726MODE;
+
+
+/** G.726 stream format parameters - must be at 8KHz */
+typedef struct OMX_AUDIO_PARAM_G726TYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPortIndex;         /**< port that this structure applies to */
+    OMX_U32 nChannels;          /**< Number of channels in the data stream (not
+                                     necessarily the same as the number of channels
+                                     to be rendered. */
+    OMX_AUDIO_G726MODE eG726Mode;
+} OMX_AUDIO_PARAM_G726TYPE;
+
+
+/** G729 coder type */
+typedef enum OMX_AUDIO_G729TYPE {
+    OMX_AUDIO_G729 = 0,           /**< ITU G.729  encoded data */
+    OMX_AUDIO_G729A,              /**< ITU G.729 annex A  encoded data */
+    OMX_AUDIO_G729B,              /**< ITU G.729 with annex B encoded data */
+    OMX_AUDIO_G729AB,             /**< ITU G.729 annexes A and B encoded data */
+    OMX_AUDIO_G729KhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_AUDIO_G729VendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_G729Max = 0x7FFFFFFF
+} OMX_AUDIO_G729TYPE;
+
+
+/** G729 stream format parameters - fixed 6KHz sample rate */
+typedef struct OMX_AUDIO_PARAM_G729TYPE {
+    OMX_U32 nSize;            /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_U32 nPortIndex;       /**< port that this structure applies to */
+    OMX_U32 nChannels;        /**< Number of channels in the data stream (not
+                                   necessarily the same as the number of channels
+                                   to be rendered. */
+    OMX_BOOL bDTX;            /**< Enable Discontinuous Transmisssion */
+    OMX_AUDIO_G729TYPE eBitType;
+} OMX_AUDIO_PARAM_G729TYPE;
+
+
+/** AMR Frame format */
+typedef enum OMX_AUDIO_AMRFRAMEFORMATTYPE {
+    OMX_AUDIO_AMRFrameFormatConformance = 0,  /**< Frame Format is AMR Conformance
+                                                   (Standard) Format */
+    OMX_AUDIO_AMRFrameFormatIF1,              /**< Frame Format is AMR Interface
+                                                   Format 1 */
+    OMX_AUDIO_AMRFrameFormatIF2,              /**< Frame Format is AMR Interface
+                                                   Format 2*/
+    OMX_AUDIO_AMRFrameFormatFSF,              /**< Frame Format is AMR File Storage
+                                                   Format */
+    OMX_AUDIO_AMRFrameFormatRTPPayload,       /**< Frame Format is AMR Real-Time
+                                                   Transport Protocol Payload Format */
+    OMX_AUDIO_AMRFrameFormatITU,              /**< Frame Format is ITU Format (added at Motorola request) */
+    OMX_AUDIO_AMRFrameFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_AUDIO_AMRFrameFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_AMRFrameFormatMax = 0x7FFFFFFF
+} OMX_AUDIO_AMRFRAMEFORMATTYPE;
+
+
+/** AMR band mode */
+typedef enum OMX_AUDIO_AMRBANDMODETYPE {
+    OMX_AUDIO_AMRBandModeUnused = 0,          /**< AMRNB Mode unused / unknown */
+    OMX_AUDIO_AMRBandModeNB0,                 /**< AMRNB Mode 0 =  4750 bps */
+    OMX_AUDIO_AMRBandModeNB1,                 /**< AMRNB Mode 1 =  5150 bps */
+    OMX_AUDIO_AMRBandModeNB2,                 /**< AMRNB Mode 2 =  5900 bps */
+    OMX_AUDIO_AMRBandModeNB3,                 /**< AMRNB Mode 3 =  6700 bps */
+    OMX_AUDIO_AMRBandModeNB4,                 /**< AMRNB Mode 4 =  7400 bps */
+    OMX_AUDIO_AMRBandModeNB5,                 /**< AMRNB Mode 5 =  7950 bps */
+    OMX_AUDIO_AMRBandModeNB6,                 /**< AMRNB Mode 6 = 10200 bps */
+    OMX_AUDIO_AMRBandModeNB7,                 /**< AMRNB Mode 7 = 12200 bps */
+    OMX_AUDIO_AMRBandModeWB0,                 /**< AMRWB Mode 0 =  6600 bps */
+    OMX_AUDIO_AMRBandModeWB1,                 /**< AMRWB Mode 1 =  8850 bps */
+    OMX_AUDIO_AMRBandModeWB2,                 /**< AMRWB Mode 2 = 12650 bps */
+    OMX_AUDIO_AMRBandModeWB3,                 /**< AMRWB Mode 3 = 14250 bps */
+    OMX_AUDIO_AMRBandModeWB4,                 /**< AMRWB Mode 4 = 15850 bps */
+    OMX_AUDIO_AMRBandModeWB5,                 /**< AMRWB Mode 5 = 18250 bps */
+    OMX_AUDIO_AMRBandModeWB6,                 /**< AMRWB Mode 6 = 19850 bps */
+    OMX_AUDIO_AMRBandModeWB7,                 /**< AMRWB Mode 7 = 23050 bps */
+    OMX_AUDIO_AMRBandModeWB8,                 /**< AMRWB Mode 8 = 23850 bps */
+    OMX_AUDIO_AMRBandModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_AUDIO_AMRBandModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_AMRBandModeMax = 0x7FFFFFFF
+} OMX_AUDIO_AMRBANDMODETYPE;
+
+
+/** AMR Discontinuous Transmission mode */
+typedef enum OMX_AUDIO_AMRDTXMODETYPE {
+    OMX_AUDIO_AMRDTXModeOff = 0,        /**< AMR Discontinuous Transmission Mode is disabled */
+    OMX_AUDIO_AMRDTXModeOnVAD1,         /**< AMR Discontinuous Transmission Mode using
+                                             Voice Activity Detector 1 (VAD1) is enabled */
+    OMX_AUDIO_AMRDTXModeOnVAD2,         /**< AMR Discontinuous Transmission Mode using
+                                             Voice Activity Detector 2 (VAD2) is enabled */
+    OMX_AUDIO_AMRDTXModeOnAuto,         /**< The codec will automatically select between
+                                             Off, VAD1 or VAD2 modes */
+
+    OMX_AUDIO_AMRDTXasEFR,             /**< DTX as EFR instead of AMR standard (3GPP 26.101, frame type =8,9,10) */
+
+    OMX_AUDIO_AMRDTXModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_AUDIO_AMRDTXModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_AMRDTXModeMax = 0x7FFFFFFF
+} OMX_AUDIO_AMRDTXMODETYPE;
+
+
+/** AMR params */
+typedef struct OMX_AUDIO_PARAM_AMRTYPE {
+    OMX_U32 nSize;                          /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;               /**< OMX specification version information */
+    OMX_U32 nPortIndex;                     /**< port that this structure applies to */
+    OMX_U32 nChannels;                      /**< Number of channels */
+    OMX_U32 nBitRate;                       /**< Bit rate read only field */
+    OMX_AUDIO_AMRBANDMODETYPE eAMRBandMode; /**< AMR Band Mode enumeration */
+    OMX_AUDIO_AMRDTXMODETYPE  eAMRDTXMode;  /**< AMR DTX Mode enumeration */
+    OMX_AUDIO_AMRFRAMEFORMATTYPE eAMRFrameFormat; /**< AMR frame format enumeration */
+} OMX_AUDIO_PARAM_AMRTYPE;
+
+
+/** GSM_FR (ETSI 06.10, 3GPP 46.010) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_GSMFRTYPE {
+    OMX_U32 nSize;            /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_U32 nPortIndex;       /**< port that this structure applies to */
+    OMX_BOOL bDTX;            /**< Enable Discontinuous Transmisssion */
+    OMX_BOOL bHiPassFilter;   /**< Enable High Pass Filter */
+} OMX_AUDIO_PARAM_GSMFRTYPE;
+
+
+/** GSM-HR (ETSI 06.20, 3GPP 46.020) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_GSMHRTYPE {
+    OMX_U32 nSize;            /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_U32 nPortIndex;       /**< port that this structure applies to */
+    OMX_BOOL bDTX;            /**< Enable Discontinuous Transmisssion */
+    OMX_BOOL bHiPassFilter;   /**< Enable High Pass Filter */
+} OMX_AUDIO_PARAM_GSMHRTYPE;
+
+
+/** GSM-EFR (ETSI 06.60, 3GPP 46.060) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_GSMEFRTYPE {
+    OMX_U32 nSize;            /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_U32 nPortIndex;       /**< port that this structure applies to */
+    OMX_BOOL bDTX;            /**< Enable Discontinuous Transmisssion */
+    OMX_BOOL bHiPassFilter;   /**< Enable High Pass Filter */
+} OMX_AUDIO_PARAM_GSMEFRTYPE;
+
+
+/** TDMA FR (TIA/EIA-136-420, VSELP 7.95kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_TDMAFRTYPE {
+    OMX_U32 nSize;                /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */
+    OMX_U32 nPortIndex;           /**< port that this structure applies to */
+    OMX_U32 nChannels;            /**< Number of channels in the data stream (not
+                                       necessarily the same as the number of channels
+                                       to be rendered. */
+    OMX_BOOL bDTX;                /**< Enable Discontinuous Transmisssion */
+    OMX_BOOL bHiPassFilter;       /**< Enable High Pass Filter */
+} OMX_AUDIO_PARAM_TDMAFRTYPE;
+
+
+/** TDMA EFR (TIA/EIA-136-410, ACELP 7.4kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_TDMAEFRTYPE {
+    OMX_U32 nSize;                /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */
+    OMX_U32 nPortIndex;           /**< port that this structure applies to */
+    OMX_U32 nChannels;            /**< Number of channels in the data stream (not
+                                       necessarily the same as the number of channels
+                                       to be rendered. */
+    OMX_BOOL bDTX;                /**< Enable Discontinuous Transmisssion */
+    OMX_BOOL bHiPassFilter;       /**< Enable High Pass Filter */
+} OMX_AUDIO_PARAM_TDMAEFRTYPE;
+
+
+/** PDC FR ( RCR-27, VSELP 6.7kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_PDCFRTYPE {
+    OMX_U32 nSize;                /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */
+    OMX_U32 nPortIndex;           /**< port that this structure applies to */
+    OMX_U32 nChannels;            /**< Number of channels in the data stream (not
+                                       necessarily the same as the number of channels
+                                       to be rendered. */
+    OMX_BOOL bDTX;                /**< Enable Discontinuous Transmisssion */
+    OMX_BOOL bHiPassFilter;       /**< Enable High Pass Filter */
+} OMX_AUDIO_PARAM_PDCFRTYPE;
+
+
+/** PDC EFR ( RCR-27, ACELP 6.7kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_PDCEFRTYPE {
+    OMX_U32 nSize;                /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */
+    OMX_U32 nPortIndex;           /**< port that this structure applies to */
+    OMX_U32 nChannels;            /**< Number of channels in the data stream (not
+                                       necessarily the same as the number of channels
+                                       to be rendered. */
+    OMX_BOOL bDTX;                /**< Enable Discontinuous Transmisssion */
+    OMX_BOOL bHiPassFilter;       /**< Enable High Pass Filter */
+} OMX_AUDIO_PARAM_PDCEFRTYPE;
+
+/** PDC HR ( RCR-27, PSI-CELP 3.45kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_PDCHRTYPE {
+    OMX_U32 nSize;                /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */
+    OMX_U32 nPortIndex;           /**< port that this structure applies to */
+    OMX_U32 nChannels;            /**< Number of channels in the data stream (not
+                                       necessarily the same as the number of channels
+                                       to be rendered. */
+    OMX_BOOL bDTX;                /**< Enable Discontinuous Transmisssion */
+    OMX_BOOL bHiPassFilter;       /**< Enable High Pass Filter */
+} OMX_AUDIO_PARAM_PDCHRTYPE;
+
+
+/** CDMA Rate types */
+typedef enum OMX_AUDIO_CDMARATETYPE {
+    OMX_AUDIO_CDMARateBlank = 0,          /**< CDMA encoded frame is blank */
+    OMX_AUDIO_CDMARateFull,               /**< CDMA encoded frame in full rate */
+    OMX_AUDIO_CDMARateHalf,               /**< CDMA encoded frame in half rate */
+    OMX_AUDIO_CDMARateQuarter,            /**< CDMA encoded frame in quarter rate */
+    OMX_AUDIO_CDMARateEighth,             /**< CDMA encoded frame in eighth rate (DTX)*/
+    OMX_AUDIO_CDMARateErasure,            /**< CDMA erasure frame */
+    OMX_AUDIO_CDMARateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_AUDIO_CDMARateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_CDMARateMax = 0x7FFFFFFF
+} OMX_AUDIO_CDMARATETYPE;
+
+
+/** QCELP8 (TIA/EIA-96, up to 8kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_QCELP8TYPE {
+    OMX_U32 nSize;                /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */
+    OMX_U32 nPortIndex;           /**< port that this structure applies to */
+    OMX_U32 nChannels;            /**< Number of channels in the data stream (not
+                                       necessarily the same as the number of channels
+                                       to be rendered. */
+    OMX_U32 nBitRate;             /**< Bit rate of the input data.  Use 0 for variable
+                                       rate or unknown bit rates */
+    OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */
+    OMX_U32 nMinBitRate;          /**< minmal rate for the encoder = 1,2,3,4, default = 1 */
+    OMX_U32 nMaxBitRate;          /**< maximal rate for the encoder = 1,2,3,4, default = 4 */
+} OMX_AUDIO_PARAM_QCELP8TYPE;
+
+
+/** QCELP13 ( CDMA, EIA/TIA-733, 13.3kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_QCELP13TYPE {
+    OMX_U32 nSize;                /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */
+    OMX_U32 nPortIndex;           /**< port that this structure applies to */
+    OMX_U32 nChannels;            /**< Number of channels in the data stream (not
+                                       necessarily the same as the number of channels
+                                       to be rendered. */
+    OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */
+    OMX_U32 nMinBitRate;          /**< minmal rate for the encoder = 1,2,3,4, default = 1 */
+    OMX_U32 nMaxBitRate;          /**< maximal rate for the encoder = 1,2,3,4, default = 4 */
+} OMX_AUDIO_PARAM_QCELP13TYPE;
+
+
+/** EVRC ( CDMA, EIA/TIA-127, RCELP up to 8.55kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_EVRCTYPE {
+    OMX_U32 nSize;                /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */
+    OMX_U32 nPortIndex;           /**< port that this structure applies to */
+    OMX_U32 nChannels;            /**< Number of channels in the data stream (not
+                                       necessarily the same as the number of channels
+                                       to be rendered. */
+    OMX_AUDIO_CDMARATETYPE eCDMARate; /**< actual Frame rate */
+    OMX_BOOL bRATE_REDUCon;       /**< RATE_REDUCtion is requested for this frame */
+    OMX_U32 nMinBitRate;          /**< minmal rate for the encoder = 1,2,3,4, default = 1 */
+    OMX_U32 nMaxBitRate;          /**< maximal rate for the encoder = 1,2,3,4, default = 4 */
+    OMX_BOOL bHiPassFilter;       /**< Enable encoder's High Pass Filter */
+    OMX_BOOL bNoiseSuppressor;    /**< Enable encoder's noise suppressor pre-processing */
+    OMX_BOOL bPostFilter;         /**< Enable decoder's post Filter */
+} OMX_AUDIO_PARAM_EVRCTYPE;
+
+
+/** SMV ( up to 8.55kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_SMVTYPE {
+    OMX_U32 nSize;                /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */
+    OMX_U32 nPortIndex;           /**< port that this structure applies to */
+    OMX_U32 nChannels;            /**< Number of channels in the data stream (not
+                                       necessarily the same as the number of channels
+                                       to be rendered. */
+    OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */
+    OMX_BOOL bRATE_REDUCon;           /**< RATE_REDUCtion is requested for this frame */
+    OMX_U32 nMinBitRate;          /**< minmal rate for the encoder = 1,2,3,4, default = 1 ??*/
+    OMX_U32 nMaxBitRate;          /**< maximal rate for the encoder = 1,2,3,4, default = 4 ??*/
+    OMX_BOOL bHiPassFilter;       /**< Enable encoder's High Pass Filter ??*/
+    OMX_BOOL bNoiseSuppressor;    /**< Enable encoder's noise suppressor pre-processing */
+    OMX_BOOL bPostFilter;         /**< Enable decoder's post Filter ??*/
+} OMX_AUDIO_PARAM_SMVTYPE;
+
+
+/** MIDI Format
+ * @ingroup midi
+ */
+typedef enum OMX_AUDIO_MIDIFORMATTYPE {
+    OMX_AUDIO_MIDIFormatUnknown = 0, /**< MIDI Format unknown or don't care */
+    OMX_AUDIO_MIDIFormatSMF0,        /**< Standard MIDI File Type 0 */
+    OMX_AUDIO_MIDIFormatSMF1,        /**< Standard MIDI File Type 1 */
+    OMX_AUDIO_MIDIFormatSMF2,        /**< Standard MIDI File Type 2 */
+    OMX_AUDIO_MIDIFormatSPMIDI,      /**< SP-MIDI */
+    OMX_AUDIO_MIDIFormatXMF0,        /**< eXtensible Music Format type 0 */
+    OMX_AUDIO_MIDIFormatXMF1,        /**< eXtensible Music Format type 1 */
+    OMX_AUDIO_MIDIFormatMobileXMF,   /**< Mobile XMF (eXtensible Music Format type 2) */
+    OMX_AUDIO_MIDIFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_AUDIO_MIDIFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_MIDIFormatMax = 0x7FFFFFFF
+} OMX_AUDIO_MIDIFORMATTYPE;
+
+
+/** MIDI params
+ * @ingroup midi
+ */
+typedef struct OMX_AUDIO_PARAM_MIDITYPE {
+    OMX_U32 nSize;                 /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;      /**< OMX specification version information */
+    OMX_U32 nPortIndex;            /**< port that this structure applies to */
+    OMX_U32 nFileSize;             /**< size of the MIDI file in bytes, where the entire
+                                        MIDI file passed in, otherwise if 0x0, the MIDI data
+                                        is merged and streamed (instead of passed as an
+                                        entire MIDI file) */
+    OMX_BU32 sMaxPolyphony;        /**< Specifies the maximum simultaneous polyphonic
+                                        voices. A value of zero indicates that the default
+                                        polyphony of the device is used  */
+    OMX_BOOL bLoadDefaultSound;    /**< Whether to load default sound
+                                        bank at initialization */
+    OMX_AUDIO_MIDIFORMATTYPE eMidiFormat; /**< Version of the MIDI file */
+} OMX_AUDIO_PARAM_MIDITYPE;
+
+
+/** Type of the MIDI sound bank
+ * @ingroup midi
+ */
+typedef enum OMX_AUDIO_MIDISOUNDBANKTYPE {
+    OMX_AUDIO_MIDISoundBankUnused = 0,           /**< unused/unknown soundbank type */
+    OMX_AUDIO_MIDISoundBankDLS1,                 /**< DLS version 1 */
+    OMX_AUDIO_MIDISoundBankDLS2,                 /**< DLS version 2 */
+    OMX_AUDIO_MIDISoundBankMobileDLSBase,        /**< Mobile DLS, using the base functionality */
+    OMX_AUDIO_MIDISoundBankMobileDLSPlusOptions, /**< Mobile DLS, using the specification-defined optional feature set */
+    OMX_AUDIO_MIDISoundBankKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_AUDIO_MIDISoundBankVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_MIDISoundBankMax = 0x7FFFFFFF
+} OMX_AUDIO_MIDISOUNDBANKTYPE;
+
+
+/** Bank Layout describes how bank MSB & LSB are used in the DLS instrument definitions sound bank
+ * @ingroup midi
+ */
+typedef enum OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE {
+    OMX_AUDIO_MIDISoundBankLayoutUnused = 0,   /**< unused/unknown soundbank type */
+    OMX_AUDIO_MIDISoundBankLayoutGM,           /**< GS layout (based on bank MSB 0x00) */
+    OMX_AUDIO_MIDISoundBankLayoutGM2,          /**< General MIDI 2 layout (using MSB 0x78/0x79, LSB 0x00) */
+    OMX_AUDIO_MIDISoundBankLayoutUser,         /**< Does not conform to any bank numbering standards */
+    OMX_AUDIO_MIDISoundBankLayoutKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_AUDIO_MIDISoundBankLayoutVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_MIDISoundBankLayoutMax = 0x7FFFFFFF
+} OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE;
+
+
+/** MIDI params to load/unload user soundbank
+ * @ingroup midi
+ */
+typedef struct OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE {
+    OMX_U32 nSize;            /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_U32 nPortIndex;       /**< port that this structure applies to */
+    OMX_U32 nDLSIndex;        /**< DLS file index to be loaded */
+    OMX_U32 nDLSSize;         /**< Size in bytes */
+    OMX_PTR pDLSData;         /**< Pointer to DLS file data */
+    OMX_AUDIO_MIDISOUNDBANKTYPE eMidiSoundBank;   /**< Midi sound bank type enumeration */
+    OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE eMidiSoundBankLayout; /**< Midi sound bank layout enumeration */
+} OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE;
+
+
+/** Structure for Live MIDI events and MIP messages.
+ * (MIP = Maximum Instantaneous Polyphony; part of the SP-MIDI standard.)
+ * @ingroup midi
+ */
+typedef struct OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE {
+    OMX_U32 nSize;            /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_U32 nPortIndex;       /**< Port that this structure applies to */
+    OMX_U32 nMidiEventSize;   /**< Size of immediate MIDI events or MIP message in bytes  */
+    OMX_U8 nMidiEvents[1];    /**< MIDI event array to be rendered immediately, or an
+                                   array for the MIP message buffer, where the size is
+                                   indicated by nMidiEventSize */
+} OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE;
+
+
+/** MIDI sound bank/ program pair in a given channel
+ * @ingroup midi
+ */
+typedef struct OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPortIndex;         /**< Port that this structure applies to */
+    OMX_U32 nChannel;           /**< Valid channel values range from 1 to 16 */
+    OMX_U16 nIDProgram;         /**< Valid program ID range is 1 to 128 */
+    OMX_U16 nIDSoundBank;       /**< Sound bank ID */
+    OMX_U32 nUserSoundBankIndex;/**< User soundbank index, easier to access soundbanks
+                                     by index if multiple banks are present */
+} OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE;
+
+
+/** MIDI control
+ * @ingroup midi
+ */
+typedef struct OMX_AUDIO_CONFIG_MIDICONTROLTYPE {
+    OMX_U32 nSize;                /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */
+    OMX_U32 nPortIndex;           /**< port that this structure applies to */
+    OMX_BS32 sPitchTransposition; /**< Pitch transposition in semitones, stored as Q22.10
+                                       format based on JAVA MMAPI (JSR-135) requirement */
+    OMX_BU32 sPlayBackRate;       /**< Relative playback rate, stored as Q14.17 fixed-point
+                                       number based on JSR-135 requirement */
+    OMX_BU32 sTempo ;             /**< Tempo in beats per minute (BPM), stored as Q22.10
+                                       fixed-point number based on JSR-135 requirement */
+    OMX_U32 nMaxPolyphony;        /**< Specifies the maximum simultaneous polyphonic
+                                       voices. A value of zero indicates that the default
+                                       polyphony of the device is used  */
+    OMX_U32 nNumRepeat;           /**< Number of times to repeat playback */
+    OMX_U32 nStopTime;            /**< Time in milliseconds to indicate when playback
+                                       will stop automatically.  Set to zero if not used */
+    OMX_U16 nChannelMuteMask;     /**< 16 bit mask for channel mute status */
+    OMX_U16 nChannelSoloMask;     /**< 16 bit mask for channel solo status */
+    OMX_U32 nTrack0031MuteMask;   /**< 32 bit mask for track mute status. Note: This is for tracks 0-31 */
+    OMX_U32 nTrack3263MuteMask;   /**< 32 bit mask for track mute status. Note: This is for tracks 32-63 */
+    OMX_U32 nTrack0031SoloMask;   /**< 32 bit mask for track solo status. Note: This is for tracks 0-31 */
+    OMX_U32 nTrack3263SoloMask;   /**< 32 bit mask for track solo status. Note: This is for tracks 32-63 */
+
+} OMX_AUDIO_CONFIG_MIDICONTROLTYPE;
+
+
+/** MIDI Playback States
+ * @ingroup midi
+ */
+typedef enum OMX_AUDIO_MIDIPLAYBACKSTATETYPE {
+    OMX_AUDIO_MIDIPlayBackStateUnknown = 0,      /**< Unknown state or state does not map to
+                                                    other defined states */
+    OMX_AUDIO_MIDIPlayBackStateClosedEngaged,    /**< No MIDI resource is currently open.
+                                                    The MIDI engine is currently processing
+                                                    MIDI events. */
+    OMX_AUDIO_MIDIPlayBackStateParsing,          /**< A MIDI resource is open and is being
+                                                    primed. The MIDI engine is currently
+                                                    processing MIDI events. */
+    OMX_AUDIO_MIDIPlayBackStateOpenEngaged,      /**< A MIDI resource is open and primed but
+                                                    not playing. The MIDI engine is currently
+                                                    processing MIDI events. The transition to
+                                                    this state is only possible from the
+                                                    OMX_AUDIO_MIDIPlayBackStatePlaying state,
+                                                    when the 'playback head' reaches the end
+                                                    of media data or the playback stops due
+                                                    to stop time set.*/
+    OMX_AUDIO_MIDIPlayBackStatePlaying,          /**< A MIDI resource is open and currently
+                                                    playing. The MIDI engine is currently
+                                                    processing MIDI events.*/
+    OMX_AUDIO_MIDIPlayBackStatePlayingPartially, /**< Best-effort playback due to SP-MIDI/DLS
+                                                    resource constraints */
+    OMX_AUDIO_MIDIPlayBackStatePlayingSilently,  /**< Due to system resource constraints and
+                                                    SP-MIDI content constraints, there is
+                                                    no audible MIDI content during playback
+                                                    currently. The situation may change if
+                                                    resources are freed later.*/
+    OMX_AUDIO_MIDIPlayBackStateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_AUDIO_MIDIPlayBackStateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_MIDIPlayBackStateMax = 0x7FFFFFFF
+} OMX_AUDIO_MIDIPLAYBACKSTATETYPE;
+
+
+/** MIDI status
+ * @ingroup midi
+ */
+typedef struct OMX_AUDIO_CONFIG_MIDISTATUSTYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPortIndex;         /**< port that this structure applies to */
+    OMX_U16 nNumTracks;         /**< Number of MIDI tracks in the file, read only field.
+                                     NOTE: May not return a meaningful value until the entire
+                                     file is parsed and buffered.  */
+    OMX_U32 nDuration;          /**< The length of the currently open MIDI resource
+                                     in milliseconds. NOTE: May not return a meaningful value
+                                     until the entire file is parsed and buffered.  */
+    OMX_U32 nPosition;          /**< Current Position of the MIDI resource being played
+                                     in milliseconds */
+    OMX_BOOL bVibra;            /**< Does Vibra track exist? NOTE: May not return a meaningful
+                                     value until the entire file is parsed and buffered. */
+    OMX_U32 nNumMetaEvents;     /**< Total number of MIDI Meta Events in the currently
+                                     open MIDI resource. NOTE: May not return a meaningful value
+                                     until the entire file is parsed and buffered.  */
+    OMX_U32 nNumActiveVoices;   /**< Number of active voices in the currently playing
+                                     MIDI resource. NOTE: May not return a meaningful value until
+                                     the entire file is parsed and buffered. */
+    OMX_AUDIO_MIDIPLAYBACKSTATETYPE eMIDIPlayBackState;  /**< MIDI playback state enumeration, read only field */
+} OMX_AUDIO_CONFIG_MIDISTATUSTYPE;
+
+
+/** MIDI Meta Event structure one per Meta Event.
+ *  MIDI Meta Events are like audio metadata, except that they are interspersed
+ *  with the MIDI content throughout the file and are not localized in the header.
+ *  As such, it is necessary to retrieve information about these Meta Events from
+ *  the engine, as it encounters these Meta Events within the MIDI content.
+ *  For example, SMF files can have up to 14 types of MIDI Meta Events (copyright,
+ *  author, default tempo, etc.) scattered throughout the file.
+ *  @ingroup midi
+ */
+typedef struct OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE {
+    OMX_U32 nSize;            /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_U32 nPortIndex;       /**< port that this structure applies to */
+    OMX_U32 nIndex;           /**< Index of Meta Event */
+    OMX_U8 nMetaEventType;    /**< Meta Event Type, 7bits (i.e. 0 - 127) */
+    OMX_U32 nMetaEventSize;   /**< size of the Meta Event in bytes */
+    OMX_U32 nTrack;           /**< track number for the meta event */
+    OMX_U32 nPosition;        /**< Position of the meta-event in milliseconds */
+} OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE;
+
+
+/** MIDI Meta Event Data structure - one per Meta Event.
+ * @ingroup midi
+ */
+typedef struct OMX_AUDIO_CONFIG_MIDIMETAEVENTDATATYPE {
+    OMX_U32 nSize;            /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_U32 nPortIndex;       /**< port that this structure applies to */
+    OMX_U32 nIndex;           /**< Index of Meta Event */
+    OMX_U32 nMetaEventSize;   /**< size of the Meta Event in bytes */
+    OMX_U8 nData[1];          /**< array of one or more bytes of meta data
+                                   as indicated by the nMetaEventSize field */
+} OMX_AUDIO_CONFIG__MIDIMETAEVENTDATATYPE;
+
+
+/** Audio Volume adjustment for a port */
+typedef struct OMX_AUDIO_CONFIG_VOLUMETYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPortIndex;         /**< Port index indicating which port to
+                                     set.  Select the input port to set
+                                     just that port's volume.  Select the
+                                     output port to adjust the master
+                                     volume. */
+    OMX_BOOL bLinear;           /**< Is the volume to be set in linear (0.100)
+                                     or logarithmic scale (mB) */
+    OMX_BS32 sVolume;           /**< Volume linear setting in the 0..100 range, OR
+                                     Volume logarithmic setting for this port.  The values
+                                     for volume are in mB (millibels = 1/100 dB) relative
+                                     to a gain of 1 (e.g. the output is the same as the
+                                     input level).  Values are in mB from nMax
+                                     (maximum volume) to nMin mB (typically negative).
+                                     Since the volume is "voltage"
+                                     and not a "power", it takes a setting of
+                                     -600 mB to decrease the volume by 1/2.  If
+                                     a component cannot accurately set the
+                                     volume to the requested value, it must
+                                     set the volume to the closest value BELOW
+                                     the requested value.  When getting the
+                                     volume setting, the current actual volume
+                                     must be returned. */
+} OMX_AUDIO_CONFIG_VOLUMETYPE;
+
+
+/** Audio Volume adjustment for a channel */
+typedef struct OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPortIndex;         /**< Port index indicating which port to
+                                     set.  Select the input port to set
+                                     just that port's volume.  Select the
+                                     output port to adjust the master
+                                     volume. */
+    OMX_U32 nChannel;           /**< channel to select from 0 to N-1,
+                                     using OMX_ALL to apply volume settings
+                                     to all channels */
+    OMX_BOOL bLinear;           /**< Is the volume to be set in linear (0.100) or
+                                     logarithmic scale (mB) */
+    OMX_BS32 sVolume;           /**< Volume linear setting in the 0..100 range, OR
+                                     Volume logarithmic setting for this port.
+                                     The values for volume are in mB
+                                     (millibels = 1/100 dB) relative to a gain
+                                     of 1 (e.g. the output is the same as the
+                                     input level).  Values are in mB from nMax
+                                     (maximum volume) to nMin mB (typically negative).
+                                     Since the volume is "voltage"
+                                     and not a "power", it takes a setting of
+                                     -600 mB to decrease the volume by 1/2.  If
+                                     a component cannot accurately set the
+                                     volume to the requested value, it must
+                                     set the volume to the closest value BELOW
+                                     the requested value.  When getting the
+                                     volume setting, the current actual volume
+                                     must be returned. */
+    OMX_BOOL bIsMIDI;           /**< TRUE if nChannel refers to a MIDI channel,
+                                     FALSE otherwise */
+} OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE;
+
+
+/** Audio balance setting */
+typedef struct OMX_AUDIO_CONFIG_BALANCETYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPortIndex;         /**< Port index indicating which port to
+                                     set.  Select the input port to set
+                                     just that port's balance.  Select the
+                                     output port to adjust the master
+                                     balance. */
+    OMX_S32 nBalance;           /**< balance setting for this port
+                                     (-100 to 100, where -100 indicates
+                                     all left, and no right */
+} OMX_AUDIO_CONFIG_BALANCETYPE;
+
+
+/** Audio Port mute */
+typedef struct OMX_AUDIO_CONFIG_MUTETYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPortIndex;         /**< Port index indicating which port to
+                                     set.  Select the input port to set
+                                     just that port's mute.  Select the
+                                     output port to adjust the master
+                                     mute. */
+    OMX_BOOL bMute;             /**< Mute setting for this port */
+} OMX_AUDIO_CONFIG_MUTETYPE;
+
+
+/** Audio Channel mute */
+typedef struct OMX_AUDIO_CONFIG_CHANNELMUTETYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPortIndex;         /**< port that this structure applies to */
+    OMX_U32 nChannel;           /**< channel to select from 0 to N-1,
+                                     using OMX_ALL to apply mute settings
+                                     to all channels */
+    OMX_BOOL bMute;             /**< Mute setting for this channel */
+    OMX_BOOL bIsMIDI;           /**< TRUE if nChannel refers to a MIDI channel,
+                                     FALSE otherwise */
+} OMX_AUDIO_CONFIG_CHANNELMUTETYPE;
+
+
+
+/** Enable / Disable for loudness control, which boosts bass and to a
+ *  smaller extent high end frequencies to compensate for hearing
+ *  ability at the extreme ends of the audio spectrum
+ */
+typedef struct OMX_AUDIO_CONFIG_LOUDNESSTYPE {
+    OMX_U32 nSize;             /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
+    OMX_U32 nPortIndex;        /**< port that this structure applies to */
+    OMX_BOOL bLoudness;        /**< Enable/disable for loudness */
+} OMX_AUDIO_CONFIG_LOUDNESSTYPE;
+
+
+/** Enable / Disable for bass, which controls low frequencies
+ */
+typedef struct OMX_AUDIO_CONFIG_BASSTYPE {
+    OMX_U32 nSize;             /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
+    OMX_U32 nPortIndex;        /**< port that this structure applies to */
+    OMX_BOOL bEnable;          /**< Enable/disable for bass control */
+    OMX_S32 nBass;             /**< bass setting for the port, as a
+                                    continuous value from -100 to 100
+                                    (0 means no change in bass level)*/
+} OMX_AUDIO_CONFIG_BASSTYPE;
+
+
+/** Enable / Disable for treble, which controls high frequencies tones
+ */
+typedef struct OMX_AUDIO_CONFIG_TREBLETYPE {
+    OMX_U32 nSize;             /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
+    OMX_U32 nPortIndex;        /**< port that this structure applies to */
+    OMX_BOOL bEnable;          /**< Enable/disable for treble control */
+    OMX_S32  nTreble;          /**< treble setting for the port, as a
+                                    continuous value from -100 to 100
+                                    (0 means no change in treble level) */
+} OMX_AUDIO_CONFIG_TREBLETYPE;
+
+
+/** An equalizer is typically used for two reasons: to compensate for an
+ *  sub-optimal frequency response of a system to make it sound more natural
+ *  or to create intentionally some unnatural coloring to the sound to create
+ *  an effect.
+ *  @ingroup effects
+ */
+typedef struct OMX_AUDIO_CONFIG_EQUALIZERTYPE {
+    OMX_U32 nSize;             /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
+    OMX_U32 nPortIndex;        /**< port that this structure applies to */
+    OMX_BOOL bEnable;          /**< Enable/disable for equalizer */
+    OMX_BU32 sBandIndex;       /**< Band number to be set.  Upper Limit is
+                                    N-1, where N is the number of bands, lower limit is 0 */
+    OMX_BU32 sCenterFreq;      /**< Center frequecies in Hz.  This is a
+                                    read only element and is used to determine
+                                    the lower, center and upper frequency of
+                                    this band.  */
+    OMX_BS32 sBandLevel;       /**< band level in millibels */
+} OMX_AUDIO_CONFIG_EQUALIZERTYPE;
+
+
+/** Stereo widening mode type
+ * @ingroup effects
+ */
+typedef enum OMX_AUDIO_STEREOWIDENINGTYPE {
+    OMX_AUDIO_StereoWideningHeadphones,    /**< Stereo widening for loudspeakers */
+    OMX_AUDIO_StereoWideningLoudspeakers,  /**< Stereo widening for closely spaced loudspeakers */
+    OMX_AUDIO_StereoWideningKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_AUDIO_StereoWideningVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_StereoWideningMax = 0x7FFFFFFF
+} OMX_AUDIO_STEREOWIDENINGTYPE;
+
+
+/** Control for stereo widening, which is a special 2-channel
+ *  case of the audio virtualizer effect. For example, for 5.1-channel
+ *  output, it translates to virtual surround sound.
+ * @ingroup effects
+ */
+typedef struct OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE {
+    OMX_U32 nSize;             /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
+    OMX_U32 nPortIndex;        /**< port that this structure applies to */
+    OMX_BOOL bEnable;          /**< Enable/disable for stereo widening control */
+    OMX_AUDIO_STEREOWIDENINGTYPE eWideningType; /**< Stereo widening algorithm type */
+    OMX_U32  nStereoWidening;  /**< stereo widening setting for the port,
+                                    as a continuous value from 0 to 100  */
+} OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE;
+
+
+/** The chorus effect (or ``choralizer'') is any signal processor which makes
+ *  one sound source (such as a voice) sound like many such sources singing
+ *  (or playing) in unison. Since performance in unison is never exact, chorus
+ *  effects simulate this by making independently modified copies of the input
+ *  signal. Modifications may include (1) delay, (2) frequency shift, and
+ *  (3) amplitude modulation.
+ * @ingroup effects
+ */
+typedef struct OMX_AUDIO_CONFIG_CHORUSTYPE {
+    OMX_U32 nSize;             /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
+    OMX_U32 nPortIndex;        /**< port that this structure applies to */
+    OMX_BOOL bEnable;          /**< Enable/disable for chorus */
+    OMX_BU32 sDelay;           /**< average delay in milliseconds */
+    OMX_BU32 sModulationRate;  /**< rate of modulation in millihertz */
+    OMX_U32 nModulationDepth;  /**< depth of modulation as a percentage of
+                                    delay (i.e. 0 to 100) */
+    OMX_BU32 nFeedback;        /**< Feedback from chorus output to input in percentage */
+} OMX_AUDIO_CONFIG_CHORUSTYPE;
+
+
+/** Reverberation is part of the reflected sound that follows the early
+ *  reflections. In a typical room, this consists of a dense succession of
+ *  echoes whose energy decays exponentially. The reverberation effect structure
+ *  as defined here includes both (early) reflections as well as (late) reverberations.
+ * @ingroup effects
+ */
+typedef struct OMX_AUDIO_CONFIG_REVERBERATIONTYPE {
+    OMX_U32 nSize;                /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */
+    OMX_U32 nPortIndex;           /**< port that this structure applies to */
+    OMX_BOOL bEnable;             /**< Enable/disable for reverberation control */
+    OMX_BS32 sRoomLevel;          /**< Intensity level for the whole room effect
+                                       (i.e. both early reflections and late
+                                       reverberation) in millibels */
+    OMX_BS32 sRoomHighFreqLevel;  /**< Attenuation at high frequencies
+                                       relative to the intensity at low
+                                       frequencies in millibels */
+    OMX_BS32 sReflectionsLevel;   /**< Intensity level of early reflections
+                                       (relative to room value), in millibels */
+    OMX_BU32 sReflectionsDelay;   /**< Delay time of the first reflection relative
+                                       to the direct path, in milliseconds */
+    OMX_BS32 sReverbLevel;        /**< Intensity level of late reverberation
+                                       relative to room level, in millibels */
+    OMX_BU32 sReverbDelay;        /**< Time delay from the first early reflection
+                                       to the beginning of the late reverberation
+                                       section, in milliseconds */
+    OMX_BU32 sDecayTime;          /**< Late reverberation decay time at low
+                                       frequencies, in milliseconds */
+    OMX_BU32 nDecayHighFreqRatio; /**< Ratio of high frequency decay time relative
+                                       to low frequency decay time in percent  */
+    OMX_U32 nDensity;             /**< Modal density in the late reverberation decay,
+                                       in percent (i.e. 0 - 100) */
+    OMX_U32 nDiffusion;           /**< Echo density in the late reverberation decay,
+                                       in percent (i.e. 0 - 100) */
+    OMX_BU32 sReferenceHighFreq;  /**< Reference high frequency in Hertz. This is
+                                       the frequency used as the reference for all
+                                       the high-frequency settings above */
+
+} OMX_AUDIO_CONFIG_REVERBERATIONTYPE;
+
+
+/** Possible settings for the Echo Cancelation structure to use
+ * @ingroup effects
+ */
+typedef enum OMX_AUDIO_ECHOCANTYPE {
+    OMX_AUDIO_EchoCanOff = 0,    /**< Echo Cancellation is disabled */
+    OMX_AUDIO_EchoCanNormal,     /**< Echo Cancellation normal operation -
+                                     echo from plastics and face */
+    OMX_AUDIO_EchoCanHFree,      /**< Echo Cancellation optimized for
+                                     Hands Free operation */
+    OMX_AUDIO_EchoCanCarKit,    /**< Echo Cancellation optimized for
+                                     Car Kit (longer echo) */
+    OMX_AUDIO_EchoCanKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_AUDIO_EchoCanVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_EchoCanMax = 0x7FFFFFFF
+} OMX_AUDIO_ECHOCANTYPE;
+
+
+/** Enable / Disable for echo cancelation, which removes undesired echo's
+ *  from the audio
+ * @ingroup effects
+ */
+typedef struct OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE {
+    OMX_U32 nSize;             /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
+    OMX_U32 nPortIndex;        /**< port that this structure applies to */
+    OMX_AUDIO_ECHOCANTYPE eEchoCancelation; /**< Echo cancelation settings */
+} OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE;
+
+
+/** Enable / Disable for noise reduction, which undesired noise from
+ * the audio
+ * @ingroup effects
+ */
+typedef struct OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE {
+    OMX_U32 nSize;             /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
+    OMX_U32 nPortIndex;        /**< port that this structure applies to */
+    OMX_BOOL bNoiseReduction;  /**< Enable/disable for noise reduction */
+} OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */
+

+ 569 - 0
omx-il/include/khronos/OMX_Component.h

@@ -0,0 +1,569 @@
+/*
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** OMX_Component.h - OpenMax IL version 1.1.2
+ *  The OMX_Component header file contains the definitions used to define
+ *  the public interface of a component.  This header file is intended to
+ *  be used by both the application and the component.
+ */
+
+#ifndef OMX_Component_h
+#define OMX_Component_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+
+/* Each OMX header must include all required header files to allow the
+ *  header to compile without errors.  The includes below are required
+ *  for this header file to compile successfully
+ */
+
+#include <OMX_Audio.h>
+#include <OMX_Video.h>
+#include <OMX_Image.h>
+#include <OMX_Other.h>
+
+/** @ingroup comp */
+typedef enum OMX_PORTDOMAINTYPE {
+    OMX_PortDomainAudio,
+    OMX_PortDomainVideo,
+    OMX_PortDomainImage,
+    OMX_PortDomainOther,
+    OMX_PortDomainKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_PortDomainVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_PortDomainMax = 0x7ffffff
+} OMX_PORTDOMAINTYPE;
+
+/** @ingroup comp */
+typedef struct OMX_PARAM_PORTDEFINITIONTYPE {
+    OMX_U32 nSize;                 /**< Size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;      /**< OMX specification version information */
+    OMX_U32 nPortIndex;            /**< Port number the structure applies to */
+    OMX_DIRTYPE eDir;              /**< Direction (input or output) of this port */
+    OMX_U32 nBufferCountActual;    /**< The actual number of buffers allocated on this port */
+    OMX_U32 nBufferCountMin;       /**< The minimum number of buffers this port requires */
+    OMX_U32 nBufferSize;           /**< Size, in bytes, for buffers to be used for this channel */
+    OMX_BOOL bEnabled;             /**< Ports default to enabled and are enabled/disabled by
+                                        OMX_CommandPortEnable/OMX_CommandPortDisable.
+                                        When disabled a port is unpopulated. A disabled port
+                                        is not populated with buffers on a transition to IDLE. */
+    OMX_BOOL bPopulated;           /**< Port is populated with all of its buffers as indicated by
+                                        nBufferCountActual. A disabled port is always unpopulated.
+                                        An enabled port is populated on a transition to OMX_StateIdle
+                                        and unpopulated on a transition to loaded. */
+    OMX_PORTDOMAINTYPE eDomain;    /**< Domain of the port. Determines the contents of metadata below. */
+    union {
+        OMX_AUDIO_PORTDEFINITIONTYPE audio;
+        OMX_VIDEO_PORTDEFINITIONTYPE video;
+        OMX_IMAGE_PORTDEFINITIONTYPE image;
+        OMX_OTHER_PORTDEFINITIONTYPE other;
+    } format;
+    OMX_BOOL bBuffersContiguous;
+    OMX_U32 nBufferAlignment;
+} OMX_PARAM_PORTDEFINITIONTYPE;
+
+/** @ingroup comp */
+typedef struct OMX_PARAM_U32TYPE {
+    OMX_U32 nSize;                    /**< Size of this structure, in Bytes */
+    OMX_VERSIONTYPE nVersion;         /**< OMX specification version information */
+    OMX_U32 nPortIndex;               /**< port that this structure applies to */
+    OMX_U32 nU32;                     /**< U32 value */
+} OMX_PARAM_U32TYPE;
+
+/** @ingroup rpm */
+typedef enum OMX_SUSPENSIONPOLICYTYPE {
+    OMX_SuspensionDisabled, /**< No suspension; v1.0 behavior */
+    OMX_SuspensionEnabled,  /**< Suspension allowed */
+    OMX_SuspensionPolicyKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_SuspensionPolicyStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_SuspensionPolicyMax = 0x7fffffff
+} OMX_SUSPENSIONPOLICYTYPE;
+
+/** @ingroup rpm */
+typedef struct OMX_PARAM_SUSPENSIONPOLICYTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_SUSPENSIONPOLICYTYPE ePolicy;
+} OMX_PARAM_SUSPENSIONPOLICYTYPE;
+
+/** @ingroup rpm */
+typedef enum OMX_SUSPENSIONTYPE {
+    OMX_NotSuspended, /**< component is not suspended */
+    OMX_Suspended,    /**< component is suspended */
+    OMX_SuspensionKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_SuspensionVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_SuspendMax = 0x7FFFFFFF
+} OMX_SUSPENSIONTYPE;
+
+/** @ingroup rpm */
+typedef struct OMX_PARAM_SUSPENSIONTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_SUSPENSIONTYPE eType;
+} OMX_PARAM_SUSPENSIONTYPE ;
+
+typedef struct OMX_CONFIG_BOOLEANTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_BOOL bEnabled;
+} OMX_CONFIG_BOOLEANTYPE;
+
+/* Parameter specifying the content uri to use. */
+/** @ingroup cp */
+typedef struct OMX_PARAM_CONTENTURITYPE {
+    OMX_U32 nSize;                      /**< size of the structure in bytes, including
+                                             actual URI name */
+    OMX_VERSIONTYPE nVersion;           /**< OMX specification version information */
+    OMX_U8 contentURI[1];               /**< The URI name */
+} OMX_PARAM_CONTENTURITYPE;
+
+/* Parameter specifying the pipe to use. */
+/** @ingroup cp */
+typedef struct OMX_PARAM_CONTENTPIPETYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_HANDLETYPE hPipe;       /**< The pipe handle*/
+} OMX_PARAM_CONTENTPIPETYPE;
+
+/** @ingroup rpm */
+typedef struct OMX_RESOURCECONCEALMENTTYPE {
+    OMX_U32 nSize;             /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
+    OMX_BOOL bResourceConcealmentForbidden; /**< disallow the use of resource concealment
+                                            methods (like degrading algorithm quality to
+                                            lower resource consumption or functional bypass)
+                                            on a component as a resolution to resource conflicts. */
+} OMX_RESOURCECONCEALMENTTYPE;
+
+
+/** @ingroup metadata */
+typedef enum OMX_METADATACHARSETTYPE {
+    OMX_MetadataCharsetUnknown = 0,
+    OMX_MetadataCharsetASCII,
+    OMX_MetadataCharsetBinary,
+    OMX_MetadataCharsetCodePage1252,
+    OMX_MetadataCharsetUTF8,
+    OMX_MetadataCharsetJavaConformantUTF8,
+    OMX_MetadataCharsetUTF7,
+    OMX_MetadataCharsetImapUTF7,
+    OMX_MetadataCharsetUTF16LE,
+    OMX_MetadataCharsetUTF16BE,
+    OMX_MetadataCharsetGB12345,
+    OMX_MetadataCharsetHZGB2312,
+    OMX_MetadataCharsetGB2312,
+    OMX_MetadataCharsetGB18030,
+    OMX_MetadataCharsetGBK,
+    OMX_MetadataCharsetBig5,
+    OMX_MetadataCharsetISO88591,
+    OMX_MetadataCharsetISO88592,
+    OMX_MetadataCharsetISO88593,
+    OMX_MetadataCharsetISO88594,
+    OMX_MetadataCharsetISO88595,
+    OMX_MetadataCharsetISO88596,
+    OMX_MetadataCharsetISO88597,
+    OMX_MetadataCharsetISO88598,
+    OMX_MetadataCharsetISO88599,
+    OMX_MetadataCharsetISO885910,
+    OMX_MetadataCharsetISO885913,
+    OMX_MetadataCharsetISO885914,
+    OMX_MetadataCharsetISO885915,
+    OMX_MetadataCharsetShiftJIS,
+    OMX_MetadataCharsetISO2022JP,
+    OMX_MetadataCharsetISO2022JP1,
+    OMX_MetadataCharsetISOEUCJP,
+    OMX_MetadataCharsetSMS7Bit,
+    OMX_MetadataCharsetKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_MetadataCharsetVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_MetadataCharsetTypeMax = 0x7FFFFFFF
+} OMX_METADATACHARSETTYPE;
+
+/** @ingroup metadata */
+typedef enum OMX_METADATASCOPETYPE {
+    OMX_MetadataScopeAllLevels,
+    OMX_MetadataScopeTopLevel,
+    OMX_MetadataScopePortLevel,
+    OMX_MetadataScopeNodeLevel,
+    OMX_MetadataScopeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_MetadataScopeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_MetadataScopeTypeMax = 0x7fffffff
+} OMX_METADATASCOPETYPE;
+
+/** @ingroup metadata */
+typedef enum OMX_METADATASEARCHMODETYPE {
+    OMX_MetadataSearchValueSizeByIndex,
+    OMX_MetadataSearchItemByIndex,
+    OMX_MetadataSearchNextItemByKey,
+    OMX_MetadataSearchKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_MetadataSearchVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_MetadataSearchTypeMax = 0x7fffffff
+} OMX_METADATASEARCHMODETYPE;
+/** @ingroup metadata */
+typedef struct OMX_CONFIG_METADATAITEMCOUNTTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_METADATASCOPETYPE eScopeMode;
+    OMX_U32 nScopeSpecifier;
+    OMX_U32 nMetadataItemCount;
+} OMX_CONFIG_METADATAITEMCOUNTTYPE;
+
+/** @ingroup metadata */
+typedef struct OMX_CONFIG_METADATAITEMTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_METADATASCOPETYPE eScopeMode;
+    OMX_U32 nScopeSpecifier;
+    OMX_U32 nMetadataItemIndex;
+    OMX_METADATASEARCHMODETYPE eSearchMode;
+    OMX_METADATACHARSETTYPE eKeyCharset;
+    OMX_U8 nKeySizeUsed;
+    OMX_U8 nKey[128];
+    OMX_METADATACHARSETTYPE eValueCharset;
+    OMX_STRING sLanguageCountry;
+    OMX_U32 nValueMaxSize;
+    OMX_U32 nValueSizeUsed;
+    OMX_U8 nValue[1];
+} OMX_CONFIG_METADATAITEMTYPE;
+
+/* @ingroup metadata */
+typedef struct OMX_CONFIG_CONTAINERNODECOUNTTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_BOOL bAllKeys;
+    OMX_U32 nParentNodeID;
+    OMX_U32 nNumNodes;
+} OMX_CONFIG_CONTAINERNODECOUNTTYPE;
+
+/** @ingroup metadata */
+typedef struct OMX_CONFIG_CONTAINERNODEIDTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_BOOL bAllKeys;
+    OMX_U32 nParentNodeID;
+    OMX_U32 nNodeIndex;
+    OMX_U32 nNodeID;
+    OMX_STRING cNodeName;
+    OMX_BOOL bIsLeafType;
+} OMX_CONFIG_CONTAINERNODEIDTYPE;
+
+/** @ingroup metadata */
+typedef struct OMX_PARAM_METADATAFILTERTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_BOOL bAllKeys;  /* if true then this structure refers to all keys and
+                         * the three key fields below are ignored */
+    OMX_METADATACHARSETTYPE eKeyCharset;
+    OMX_U32 nKeySizeUsed;
+    OMX_U8   nKey [128];
+    OMX_U32 nLanguageCountrySizeUsed;
+    OMX_U8 nLanguageCountry[128];
+    OMX_BOOL bEnabled;  /* if true then key is part of filter (e.g.
+                         * retained for query later). If false then
+                         * key is not part of filter */
+} OMX_PARAM_METADATAFILTERTYPE;
+
+/** The OMX_HANDLETYPE structure defines the component handle.  The component
+ *  handle is used to access all of the component's public methods and also
+ *  contains pointers to the component's private data area.  The component
+ *  handle is initialized by the OMX core (with help from the component)
+ *  during the process of loading the component.  After the component is
+ *  successfully loaded, the application can safely access any of the
+ *  component's public functions (although some may return an error because
+ *  the state is inappropriate for the access).
+ *
+ *  @ingroup comp
+ */
+typedef struct OMX_COMPONENTTYPE {
+    /** The size of this structure, in bytes.  It is the responsibility
+        of the allocator of this structure to fill in this value.  Since
+        this structure is allocated by the GetHandle function, this
+        function will fill in this value. */
+    OMX_U32 nSize;
+
+    /** nVersion is the version of the OMX specification that the structure
+        is built against.  It is the responsibility of the creator of this
+        structure to initialize this value and every user of this structure
+        should verify that it knows how to use the exact version of
+        this structure found herein. */
+    OMX_VERSIONTYPE nVersion;
+
+    /** pComponentPrivate is a pointer to the component private data area.
+        This member is allocated and initialized by the component when the
+        component is first loaded.  The application should not access this
+        data area. */
+    OMX_PTR pComponentPrivate;
+
+    /** pApplicationPrivate is a pointer that is a parameter to the
+        OMX_GetHandle method, and contains an application private value
+        provided by the IL client.  This application private data is
+        returned to the IL Client by OMX in all callbacks */
+    OMX_PTR pApplicationPrivate;
+
+    /** refer to OMX_GetComponentVersion in OMX_core.h or the OMX IL
+        specification for details on the GetComponentVersion method.
+     */
+    OMX_ERRORTYPE (*GetComponentVersion)(
+        OMX_IN  OMX_HANDLETYPE hComponent,
+        OMX_OUT OMX_STRING pComponentName,
+        OMX_OUT OMX_VERSIONTYPE* pComponentVersion,
+        OMX_OUT OMX_VERSIONTYPE* pSpecVersion,
+        OMX_OUT OMX_UUIDTYPE* pComponentUUID);
+
+    /** refer to OMX_SendCommand in OMX_core.h or the OMX IL
+        specification for details on the SendCommand method.
+     */
+    OMX_ERRORTYPE (*SendCommand)(
+        OMX_IN  OMX_HANDLETYPE hComponent,
+        OMX_IN  OMX_COMMANDTYPE Cmd,
+        OMX_IN  OMX_U32 nParam1,
+        OMX_IN  OMX_PTR pCmdData);
+
+    /** refer to OMX_GetParameter in OMX_core.h or the OMX IL
+        specification for details on the GetParameter method.
+     */
+    OMX_ERRORTYPE (*GetParameter)(
+        OMX_IN  OMX_HANDLETYPE hComponent,
+        OMX_IN  OMX_INDEXTYPE nParamIndex,
+        OMX_INOUT OMX_PTR pComponentParameterStructure);
+
+
+    /** refer to OMX_SetParameter in OMX_core.h or the OMX IL
+        specification for details on the SetParameter method.
+     */
+    OMX_ERRORTYPE (*SetParameter)(
+        OMX_IN  OMX_HANDLETYPE hComponent,
+        OMX_IN  OMX_INDEXTYPE nIndex,
+        OMX_IN  OMX_PTR pComponentParameterStructure);
+
+
+    /** refer to OMX_GetConfig in OMX_core.h or the OMX IL
+        specification for details on the GetConfig method.
+     */
+    OMX_ERRORTYPE (*GetConfig)(
+        OMX_IN  OMX_HANDLETYPE hComponent,
+        OMX_IN  OMX_INDEXTYPE nIndex,
+        OMX_INOUT OMX_PTR pComponentConfigStructure);
+
+
+    /** refer to OMX_SetConfig in OMX_core.h or the OMX IL
+        specification for details on the SetConfig method.
+     */
+    OMX_ERRORTYPE (*SetConfig)(
+        OMX_IN  OMX_HANDLETYPE hComponent,
+        OMX_IN  OMX_INDEXTYPE nIndex,
+        OMX_IN  OMX_PTR pComponentConfigStructure);
+
+
+    /** refer to OMX_GetExtensionIndex in OMX_core.h or the OMX IL
+        specification for details on the GetExtensionIndex method.
+     */
+    OMX_ERRORTYPE (*GetExtensionIndex)(
+        OMX_IN  OMX_HANDLETYPE hComponent,
+        OMX_IN  OMX_STRING cParameterName,
+        OMX_OUT OMX_INDEXTYPE* pIndexType);
+
+
+    /** refer to OMX_GetState in OMX_core.h or the OMX IL
+        specification for details on the GetState method.
+     */
+    OMX_ERRORTYPE (*GetState)(
+        OMX_IN  OMX_HANDLETYPE hComponent,
+        OMX_OUT OMX_STATETYPE* pState);
+
+
+    /** The ComponentTunnelRequest method will interact with another OMX
+        component to determine if tunneling is possible and to setup the
+        tunneling.  The return codes for this method can be used to
+        determine if tunneling is not possible, or if tunneling is not
+        supported.
+
+        Base profile components (i.e. non-interop) do not support this
+        method and should return OMX_ErrorNotImplemented
+
+        The interop profile component MUST support tunneling to another
+        interop profile component with a compatible port parameters.
+        A component may also support proprietary communication.
+
+        If proprietary communication is supported the negotiation of
+        proprietary communication is done outside of OMX in a vendor
+        specific way. It is only required that the proper result be
+        returned and the details of how the setup is done is left
+        to the component implementation.
+
+        When this method is invoked when nPort in an output port, the
+        component will:
+        1.  Populate the pTunnelSetup structure with the output port's
+            requirements and constraints for the tunnel.
+
+        When this method is invoked when nPort in an input port, the
+        component will:
+        1.  Query the necessary parameters from the output port to
+            determine if the ports are compatible for tunneling
+        2.  If the ports are compatible, the component should store
+            the tunnel step provided by the output port
+        3.  Determine which port (either input or output) is the buffer
+            supplier, and call OMX_SetParameter on the output port to
+            indicate this selection.
+
+        The component will return from this call within 5 msec.
+
+        @param [in] hComp
+            Handle of the component to be accessed.  This is the component
+            handle returned by the call to the OMX_GetHandle method.
+        @param [in] nPort
+            nPort is used to select the port on the component to be used
+            for tunneling.
+        @param [in] hTunneledComp
+            Handle of the component to tunnel with.  This is the component
+            handle returned by the call to the OMX_GetHandle method.  When
+            this parameter is 0x0 the component should setup the port for
+            communication with the application / IL Client.
+        @param [in] nPortOutput
+            nPortOutput is used indicate the port the component should
+            tunnel with.
+        @param [in] pTunnelSetup
+            Pointer to the tunnel setup structure.  When nPort is an output port
+            the component should populate the fields of this structure.  When
+            When nPort is an input port the component should review the setup
+            provided by the component with the output port.
+        @return OMX_ERRORTYPE
+            If the command successfully executes, the return code will be
+            OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+        @ingroup tun
+    */
+
+    OMX_ERRORTYPE (*ComponentTunnelRequest)(
+        OMX_IN  OMX_HANDLETYPE hComp,
+        OMX_IN  OMX_U32 nPort,
+        OMX_IN  OMX_HANDLETYPE hTunneledComp,
+        OMX_IN  OMX_U32 nTunneledPort,
+        OMX_INOUT  OMX_TUNNELSETUPTYPE* pTunnelSetup);
+
+    /** refer to OMX_UseBuffer in OMX_core.h or the OMX IL
+        specification for details on the UseBuffer method.
+        @ingroup buf
+     */
+    OMX_ERRORTYPE (*UseBuffer)(
+        OMX_IN OMX_HANDLETYPE hComponent,
+        OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
+        OMX_IN OMX_U32 nPortIndex,
+        OMX_IN OMX_PTR pAppPrivate,
+        OMX_IN OMX_U32 nSizeBytes,
+        OMX_IN OMX_U8* pBuffer);
+
+    /** refer to OMX_AllocateBuffer in OMX_core.h or the OMX IL
+        specification for details on the AllocateBuffer method.
+        @ingroup buf
+     */
+    OMX_ERRORTYPE (*AllocateBuffer)(
+        OMX_IN OMX_HANDLETYPE hComponent,
+        OMX_INOUT OMX_BUFFERHEADERTYPE** ppBuffer,
+        OMX_IN OMX_U32 nPortIndex,
+        OMX_IN OMX_PTR pAppPrivate,
+        OMX_IN OMX_U32 nSizeBytes);
+
+    /** refer to OMX_FreeBuffer in OMX_core.h or the OMX IL
+        specification for details on the FreeBuffer method.
+        @ingroup buf
+     */
+    OMX_ERRORTYPE (*FreeBuffer)(
+        OMX_IN  OMX_HANDLETYPE hComponent,
+        OMX_IN  OMX_U32 nPortIndex,
+        OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer);
+
+    /** refer to OMX_EmptyThisBuffer in OMX_core.h or the OMX IL
+        specification for details on the EmptyThisBuffer method.
+        @ingroup buf
+     */
+    OMX_ERRORTYPE (*EmptyThisBuffer)(
+        OMX_IN  OMX_HANDLETYPE hComponent,
+        OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer);
+
+    /** refer to OMX_FillThisBuffer in OMX_core.h or the OMX IL
+        specification for details on the FillThisBuffer method.
+        @ingroup buf
+     */
+    OMX_ERRORTYPE (*FillThisBuffer)(
+        OMX_IN  OMX_HANDLETYPE hComponent,
+        OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer);
+
+    /** The SetCallbacks method is used by the core to specify the callback
+        structure from the application to the component.  This is a blocking
+        call.  The component will return from this call within 5 msec.
+        @param [in] hComponent
+            Handle of the component to be accessed.  This is the component
+            handle returned by the call to the GetHandle function.
+        @param [in] pCallbacks
+            pointer to an OMX_CALLBACKTYPE structure used to provide the
+            callback information to the component
+        @param [in] pAppData
+            pointer to an application defined value.  It is anticipated that
+            the application will pass a pointer to a data structure or a "this
+            pointer" in this area to allow the callback (in the application)
+            to determine the context of the call
+        @return OMX_ERRORTYPE
+            If the command successfully executes, the return code will be
+            OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+     */
+    OMX_ERRORTYPE (*SetCallbacks)(
+        OMX_IN  OMX_HANDLETYPE hComponent,
+        OMX_IN  OMX_CALLBACKTYPE* pCallbacks,
+        OMX_IN  OMX_PTR pAppData);
+
+    /** ComponentDeInit method is used to deinitialize the component
+        providing a means to free any resources allocated at component
+        initialization.  NOTE:  After this call the component handle is
+        not valid for further use.
+        @param [in] hComponent
+            Handle of the component to be accessed.  This is the component
+            handle returned by the call to the GetHandle function.
+        @return OMX_ERRORTYPE
+            If the command successfully executes, the return code will be
+            OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+     */
+    OMX_ERRORTYPE (*ComponentDeInit)(
+        OMX_IN  OMX_HANDLETYPE hComponent);
+
+    /** @ingroup buf */
+    OMX_ERRORTYPE (*UseEGLImage)(
+        OMX_IN OMX_HANDLETYPE hComponent,
+        OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
+        OMX_IN OMX_U32 nPortIndex,
+        OMX_IN OMX_PTR pAppPrivate,
+        OMX_IN void* eglImage);
+
+    OMX_ERRORTYPE (*ComponentRoleEnum)(
+        OMX_IN OMX_HANDLETYPE hComponent,
+        OMX_OUT OMX_U8 *cRole,
+        OMX_IN OMX_U32 nIndex);
+
+} OMX_COMPONENTTYPE;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */

+ 61 - 0
omx-il/include/khronos/OMX_ComponentExt.h

@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** OMX_ComponentExt.h - OpenMax IL version 1.1.2
+ * The OMX_ComponentExt header file contains extensions to the definitions used
+ * by both the application and the component to access common items.
+ */
+
+#ifndef OMX_ComponentExt_h
+#define OMX_ComponentExt_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Each OMX header must include all required header files to allow the
+ * header to compile without errors.  The includes below are required
+ * for this header file to compile successfully 
+ */
+#include <OMX_Types.h>
+
+
+/** Set/query the commit mode */
+typedef struct OMX_CONFIG_COMMITMODETYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_BOOL bDeferred;
+} OMX_CONFIG_COMMITMODETYPE;
+
+/** Explicit commit */
+typedef struct OMX_CONFIG_COMMITTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+} OMX_CONFIG_COMMITTYPE;
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* OMX_ComponentExt_h */

+ 193 - 0
omx-il/include/khronos/OMX_ContentPipe.h

@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** OMX_ContentPipe.h - OpenMax IL version 1.1.2
+ *  The OMX_ContentPipe header file contains the definitions used to define
+ *  the public interface for content piples.  This header file is intended to
+ *  be used by the component.
+ */
+
+#ifndef OMX_CONTENTPIPE_H
+#define OMX_CONTENTPIPE_H
+
+#ifndef KD_EACCES
+/* OpenKODE error codes. CPResult values may be zero (indicating success
+   or one of the following values) */
+#define KD_EACCES (1)
+#define KD_EADDRINUSE (2)
+#define KD_EAGAIN (5)
+#define KD_EBADF (7)
+#define KD_EBUSY (8)
+#define KD_ECONNREFUSED (9)
+#define KD_ECONNRESET (10)
+#define KD_EDEADLK (11)
+#define KD_EDESTADDRREQ (12)
+#define KD_ERANGE (35)
+#define KD_EEXIST (13)
+#define KD_EFBIG (14)
+#define KD_EHOSTUNREACH (15)
+#define KD_EINVAL (17)
+#define KD_EIO (18)
+#define KD_EISCONN (20)
+#define KD_EISDIR (21)
+#define KD_EMFILE (22)
+#define KD_ENAMETOOLONG (23)
+#define KD_ENOENT (24)
+#define KD_ENOMEM (25)
+#define KD_ENOSPC (26)
+#define KD_ENOSYS (27)
+#define KD_ENOTCONN (28)
+#define KD_EPERM (33)
+#define KD_ETIMEDOUT (36)
+#define KD_EILSEQ (19)
+#endif
+
+/** Map types from OMX standard types only here so interface is as generic as possible. */
+typedef OMX_U32    CPresult;
+typedef char *     CPstring;
+typedef void *     CPhandle;
+typedef OMX_U32    CPuint;
+typedef OMX_S32    CPint;
+typedef char       CPbyte;
+typedef OMX_BOOL   CPbool;
+
+/** enumeration of origin types used in the CP_PIPETYPE's Seek function
+ * @ingroup cp
+ */
+typedef enum CP_ORIGINTYPE {
+    CP_OriginBegin,
+    CP_OriginCur,
+    CP_OriginEnd,
+    CP_OriginKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    CP_OriginVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    CP_OriginMax = 0X7FFFFFFF
+} CP_ORIGINTYPE;
+
+/** enumeration of contact access types used in the CP_PIPETYPE's Open function
+ * @ingroup cp
+ */
+typedef enum CP_ACCESSTYPE {
+    CP_AccessRead,
+    CP_AccessWrite,
+    CP_AccessReadWrite ,
+    CP_AccessKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    CP_AccessVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    CP_AccessMax = 0X7FFFFFFF
+} CP_ACCESSTYPE;
+
+/** enumeration of results returned by the CP_PIPETYPE's CheckAvailableBytes function
+ * @ingroup cp
+ */
+typedef enum CP_CHECKBYTESRESULTTYPE {
+    CP_CheckBytesOk,                    /**< There are at least the request number
+                                              of bytes available */
+    CP_CheckBytesNotReady,              /**< The pipe is still retrieving bytes
+                                              and presently lacks sufficient bytes.
+                                              Client will be called when they are
+                                              sufficient bytes are available. */
+    CP_CheckBytesInsufficientBytes  ,     /**< The pipe has retrieved all bytes
+                                              but those available are less than those
+                                              requested */
+    CP_CheckBytesAtEndOfStream,         /**< The pipe has reached the end of stream
+                                              and no more bytes are available. */
+    CP_CheckBytesOutOfBuffers,          /**< All read/write buffers are currently in use. */
+    CP_CheckBytesKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    CP_CheckBytesVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    CP_CheckBytesMax = 0X7FFFFFFF
+} CP_CHECKBYTESRESULTTYPE;
+
+/** enumeration of content pipe events sent to the client callback.
+ * @ingroup cp
+ */
+typedef enum CP_EVENTTYPE {
+    CP_BytesAvailable,              /** bytes requested in a CheckAvailableBytes call are now available*/
+    CP_Overflow,                   /** enumeration of content pipe events sent to the client callback*/
+    CP_PipeDisconnected  ,              /** enumeration of content pipe events sent to the client callback*/
+    CP_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    CP_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    CP_EventMax = 0X7FFFFFFF
+} CP_EVENTTYPE;
+
+/** content pipe definition
+ * @ingroup cp
+ */
+typedef struct CP_PIPETYPE {
+    /** Open a content stream for reading or writing. */
+    CPresult (*Open)( CPhandle* hContent, CPstring szURI, CP_ACCESSTYPE eAccess );
+
+    /** Close a content stream. */
+    CPresult (*Close)( CPhandle hContent );
+
+    /** Create a content source and open it for writing. */
+    CPresult (*Create)( CPhandle *hContent, CPstring szURI );
+
+    /** Check the that specified number of bytes are available for reading or writing (depending on access type).*/
+    CPresult (*CheckAvailableBytes)( CPhandle hContent, CPuint nBytesRequested, CP_CHECKBYTESRESULTTYPE *eResult );
+
+    /** Seek to certain position in the content relative to the specified origin. */
+    CPresult (*SetPosition)( CPhandle  hContent, CPint nOffset, CP_ORIGINTYPE eOrigin);
+
+    /** Retrieve the current position relative to the start of the content. */
+    CPresult (*GetPosition)( CPhandle hContent, CPuint *pPosition);
+
+    /** Retrieve data of the specified size from the content stream (advance content pointer by size of data).
+       Note: pipe client provides pointer. This function is appropriate for small high frequency reads. */
+    CPresult (*Read)( CPhandle hContent, CPbyte *pData, CPuint nSize);
+
+    /** Retrieve a buffer allocated by the pipe that contains the requested number of bytes.
+       Buffer contains the next block of bytes, as specified by nSize, of the content. nSize also
+       returns the size of the block actually read. Content pointer advances the by the returned size.
+       Note: pipe provides pointer. This function is appropriate for large reads. The client must call
+       ReleaseReadBuffer when done with buffer.
+
+       In some cases the requested block may not reside in contiguous memory within the
+       pipe implementation. For instance if the pipe leverages a circular buffer then the requested
+       block may straddle the boundary of the circular buffer. By default a pipe implementation
+       performs a copy in this case to provide the block to the pipe client in one contiguous buffer.
+       If, however, the client sets bForbidCopy, then the pipe returns only those bytes preceding the memory
+       boundary. Here the client may retrieve the data in segments over successive calls. */
+    CPresult (*ReadBuffer)( CPhandle hContent, CPbyte **ppBuffer, CPuint *nSize, CPbool bForbidCopy);
+
+    /** Release a buffer obtained by ReadBuffer back to the pipe. */
+    CPresult (*ReleaseReadBuffer)(CPhandle hContent, CPbyte *pBuffer);
+
+    /** Write data of the specified size to the content (advance content pointer by size of data).
+       Note: pipe client provides pointer. This function is appropriate for small high frequency writes. */
+    CPresult (*Write)( CPhandle hContent, CPbyte *data, CPuint nSize);
+
+    /** Retrieve a buffer allocated by the pipe used to write data to the content.
+       Client will fill buffer with output data. Note: pipe provides pointer. This function is appropriate
+       for large writes. The client must call WriteBuffer when done it has filled the buffer with data.*/
+    CPresult (*GetWriteBuffer)( CPhandle hContent, CPbyte **ppBuffer, CPuint nSize);
+
+    /** Deliver a buffer obtained via GetWriteBuffer to the pipe. Pipe will write the
+       the contents of the buffer to content and advance content pointer by the size of the buffer */
+    CPresult (*WriteBuffer)( CPhandle hContent, CPbyte *pBuffer, CPuint nFilledSize);
+
+    /** Register a per-handle client callback with the content pipe. */
+    CPresult (*RegisterCallback)( CPhandle hContent, CPresult (*ClientCallback)(CP_EVENTTYPE eEvent, CPuint iParam));
+
+} CP_PIPETYPE;
+
+#endif
+

+ 1422 - 0
omx-il/include/khronos/OMX_Core.h

@@ -0,0 +1,1422 @@
+/*
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** OMX_Core.h - OpenMax IL version 1.1.2
+ *  The OMX_Core header file contains the definitions used by both the
+ *  application and the component to access common items.
+ */
+
+#ifndef OMX_Core_h
+#define OMX_Core_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* Each OMX header shall include all required header files to allow the
+ *  header to compile without errors.  The includes below are required
+ *  for this header file to compile successfully
+ */
+
+#include <OMX_Index.h>
+
+
+/** The OMX_COMMANDTYPE enumeration is used to specify the action in the
+ *  OMX_SendCommand macro.
+ *  @ingroup core
+ */
+typedef enum OMX_COMMANDTYPE
+{
+    OMX_CommandStateSet,    /**< Change the component state */
+    OMX_CommandFlush,       /**< Flush the data queue(s) of a component */
+    OMX_CommandPortDisable, /**< Disable a port on a component. */
+    OMX_CommandPortEnable,  /**< Enable a port on a component. */
+    OMX_CommandMarkBuffer,  /**< Mark a component/buffer for observation */
+    OMX_CommandKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_CommandVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_CommandMax = 0X7FFFFFFF
+} OMX_COMMANDTYPE;
+
+
+
+/** The OMX_STATETYPE enumeration is used to indicate or change the component
+ *  state.  This enumeration reflects the current state of the component when
+ *  used with the OMX_GetState macro or becomes the parameter in a state change
+ *  command when used with the OMX_SendCommand macro.
+ *
+ *  The component will be in the Loaded state after the component is initially
+ *  loaded into memory.  In the Loaded state, the component is not allowed to
+ *  allocate or hold resources other than to build it's internal parameter
+ *  and configuration tables.  The application will send one or more
+ *  SetParameters/GetParameters and SetConfig/GetConfig commands to the
+ *  component and the component will record each of these parameter and
+ *  configuration changes for use later.  When the application sends the
+ *  Idle command, the component will acquire the resources needed for the
+ *  specified configuration and will transition to the idle state if the
+ *  allocation is successful.  If the component cannot successfully
+ *  transition to the idle state for any reason, the state of the component
+ *  shall be fully rolled back to the Loaded state (e.g. all allocated
+ *  resources shall be released).  When the component receives the command
+ *  to go to the Executing state, it shall begin processing buffers by
+ *  sending all input buffers it holds to the application.  While
+ *  the component is in the Idle state, the application may also send the
+ *  Pause command.  If the component receives the pause command while in the
+ *  Idle state, the component shall send all input buffers it holds to the
+ *  application, but shall not begin processing buffers.  This will allow the
+ *  application to prefill buffers.
+ *
+ *  @ingroup comp
+ */
+
+typedef enum OMX_STATETYPE {
+    OMX_StateInvalid,      /**< component has detected that it's internal data
+                                structures are corrupted to the point that
+                                it cannot determine it's state properly */
+    OMX_StateLoaded,      /**< component has been loaded but has not completed
+                                initialization.  The OMX_SetParameter macro
+                                and the OMX_GetParameter macro are the only
+                                valid macros allowed to be sent to the
+                                component in this state. */
+    OMX_StateIdle,        /**< component initialization has been completed
+                                successfully and the component is ready to
+                                to start. */
+    OMX_StateExecuting,   /**< component has accepted the start command and
+                                is processing data (if data is available) */
+    OMX_StatePause,       /**< component has received pause command */
+    OMX_StateWaitForResources, /**< component is waiting for resources, either after
+                                preemption or before it gets the resources requested.
+                                See specification for complete details. */
+    OMX_StateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_StateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_StateMax = 0X7FFFFFFF
+} OMX_STATETYPE;
+
+/** The OMX_ERRORTYPE enumeration defines the standard OMX Errors.  These
+ *  errors should cover most of the common failure cases.  However,
+ *  vendors are free to add additional error messages of their own as
+ *  long as they follow these rules:
+ *  1.  Vendor error messages shall be in the range of 0x90000000 to
+ *      0x9000FFFF.
+ *  2.  Vendor error messages shall be defined in a header file provided
+ *      with the component.  No error messages are allowed that are
+ *      not defined.
+ */
+typedef enum OMX_ERRORTYPE {
+    OMX_ErrorNone = 0,
+
+    /** There were insufficient resources to perform the requested operation */
+    OMX_ErrorInsufficientResources = (OMX_S32) 0x80001000,
+
+    /** There was an error, but the cause of the error could not be determined */
+    OMX_ErrorUndefined = (OMX_S32) 0x80001001,
+
+    /** The component name string was not valid */
+    OMX_ErrorInvalidComponentName = (OMX_S32) 0x80001002,
+
+    /** No component with the specified name string was found */
+    OMX_ErrorComponentNotFound = (OMX_S32) 0x80001003,
+
+    /** The component specified did not have a "OMX_ComponentInit" or
+        "OMX_ComponentDeInit entry point */
+    OMX_ErrorInvalidComponent = (OMX_S32) 0x80001004,
+
+    /** One or more parameters were not valid */
+    OMX_ErrorBadParameter = (OMX_S32) 0x80001005,
+
+    /** The requested function is not implemented */
+    OMX_ErrorNotImplemented = (OMX_S32) 0x80001006,
+
+    /** The buffer was emptied before the next buffer was ready */
+    OMX_ErrorUnderflow = (OMX_S32) 0x80001007,
+
+    /** The buffer was not available when it was needed */
+    OMX_ErrorOverflow = (OMX_S32) 0x80001008,
+
+    /** The hardware failed to respond as expected */
+    OMX_ErrorHardware = (OMX_S32) 0x80001009,
+
+    /** The component is in the state OMX_StateInvalid */
+    OMX_ErrorInvalidState = (OMX_S32) 0x8000100A,
+
+    /** Stream is found to be corrupt */
+    OMX_ErrorStreamCorrupt = (OMX_S32) 0x8000100B,
+
+    /** Ports being connected are not compatible */
+    OMX_ErrorPortsNotCompatible = (OMX_S32) 0x8000100C,
+
+    /** Resources allocated to an idle component have been
+        lost resulting in the component returning to the loaded state */
+    OMX_ErrorResourcesLost = (OMX_S32) 0x8000100D,
+
+    /** No more indicies can be enumerated */
+    OMX_ErrorNoMore = (OMX_S32) 0x8000100E,
+
+    /** The component detected a version mismatch */
+    OMX_ErrorVersionMismatch = (OMX_S32) 0x8000100F,
+
+    /** The component is not ready to return data at this time */
+    OMX_ErrorNotReady = (OMX_S32) 0x80001010,
+
+    /** There was a timeout that occurred */
+    OMX_ErrorTimeout = (OMX_S32) 0x80001011,
+
+    /** This error occurs when trying to transition into the state you are already in */
+    OMX_ErrorSameState = (OMX_S32) 0x80001012,
+
+    /** Resources allocated to an executing or paused component have been
+        preempted, causing the component to return to the idle state */
+    OMX_ErrorResourcesPreempted = (OMX_S32) 0x80001013,
+
+    /** A non-supplier port sends this error to the IL client (via the EventHandler callback)
+        during the allocation of buffers (on a transition from the LOADED to the IDLE state or
+        on a port restart) when it deems that it has waited an unusually long time for the supplier
+        to send it an allocated buffer via a UseBuffer call. */
+    OMX_ErrorPortUnresponsiveDuringAllocation = (OMX_S32) 0x80001014,
+
+    /** A non-supplier port sends this error to the IL client (via the EventHandler callback)
+        during the deallocation of buffers (on a transition from the IDLE to LOADED state or
+        on a port stop) when it deems that it has waited an unusually long time for the supplier
+        to request the deallocation of a buffer header via a FreeBuffer call. */
+    OMX_ErrorPortUnresponsiveDuringDeallocation = (OMX_S32) 0x80001015,
+
+    /** A supplier port sends this error to the IL client (via the EventHandler callback)
+        during the stopping of a port (either on a transition from the IDLE to LOADED
+        state or a port stop) when it deems that it has waited an unusually long time for
+        the non-supplier to return a buffer via an EmptyThisBuffer or FillThisBuffer call. */
+    OMX_ErrorPortUnresponsiveDuringStop = (OMX_S32) 0x80001016,
+
+    /** Attempting a state transtion that is not allowed */
+    OMX_ErrorIncorrectStateTransition = (OMX_S32) 0x80001017,
+
+    /* Attempting a command that is not allowed during the present state. */
+    OMX_ErrorIncorrectStateOperation = (OMX_S32) 0x80001018,
+
+    /** The values encapsulated in the parameter or config structure are not supported. */
+    OMX_ErrorUnsupportedSetting = (OMX_S32) 0x80001019,
+
+    /** The parameter or config indicated by the given index is not supported. */
+    OMX_ErrorUnsupportedIndex = (OMX_S32) 0x8000101A,
+
+    /** The port index supplied is incorrect. */
+    OMX_ErrorBadPortIndex = (OMX_S32) 0x8000101B,
+
+    /** The port has lost one or more of its buffers and it thus unpopulated. */
+    OMX_ErrorPortUnpopulated = (OMX_S32) 0x8000101C,
+
+    /** Component suspended due to temporary loss of resources */
+    OMX_ErrorComponentSuspended = (OMX_S32) 0x8000101D,
+
+    /** Component suspended due to an inability to acquire dynamic resources */
+    OMX_ErrorDynamicResourcesUnavailable = (OMX_S32) 0x8000101E,
+
+    /** When the macroblock error reporting is enabled the component returns new error
+    for every frame that has errors */
+    OMX_ErrorMbErrorsInFrame = (OMX_S32) 0x8000101F,
+
+    /** A component reports this error when it cannot parse or determine the format of an input stream. */
+    OMX_ErrorFormatNotDetected = (OMX_S32) 0x80001020,
+
+    /** The content open operation failed. */
+    OMX_ErrorContentPipeOpenFailed = (OMX_S32) 0x80001021,
+
+    /** The content creation operation failed. */
+    OMX_ErrorContentPipeCreationFailed = (OMX_S32) 0x80001022,
+
+    /** Separate table information is being used */
+    OMX_ErrorSeperateTablesUsed = (OMX_S32) 0x80001023,
+
+    /** Tunneling is unsupported by the component*/
+    OMX_ErrorTunnelingUnsupported = (OMX_S32) 0x80001024,
+
+    OMX_ErrorKhronosExtensions = (OMX_S32)0x8F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_ErrorVendorStartUnused = (OMX_S32)0x90000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_ErrorMax = 0x7FFFFFFF
+} OMX_ERRORTYPE;
+
+/** @ingroup core */
+typedef OMX_ERRORTYPE (* OMX_COMPONENTINITTYPE)(OMX_IN  OMX_HANDLETYPE hComponent);
+
+/** @ingroup core */
+typedef struct OMX_COMPONENTREGISTERTYPE {
+    const char          * pName;       /* Component name, 128 byte limit (including '\0') applies */
+    OMX_COMPONENTINITTYPE pInitialize; /* Component instance initialization function */
+} OMX_COMPONENTREGISTERTYPE;
+
+/** @ingroup core */
+extern OMX_COMPONENTREGISTERTYPE OMX_ComponentRegistered[];
+
+/** @ingroup rpm */
+typedef struct OMX_PRIORITYMGMTTYPE {
+    OMX_U32 nSize;             /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
+    OMX_U32 nGroupPriority;            /**< Priority of the component group */
+    OMX_U32 nGroupID;                  /**< ID of the component group */
+} OMX_PRIORITYMGMTTYPE;
+
+/* Component name and Role names are limited to 128 characters including the terminating '\0'. */
+#define OMX_MAX_STRINGNAME_SIZE 128
+
+/** @ingroup comp */
+typedef struct OMX_PARAM_COMPONENTROLETYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U8 cRole[OMX_MAX_STRINGNAME_SIZE];  /**< name of standard component which defines component role */
+} OMX_PARAM_COMPONENTROLETYPE;
+
+/** End of Stream Buffer Flag:
+  *
+  * A component sets EOS when it has no more data to emit on a particular
+  * output port. Thus an output port shall set EOS on the last buffer it
+  * emits. A component's determination of when an output port should
+  * cease sending data is implemenation specific.
+  * @ingroup buf
+  */
+
+#define OMX_BUFFERFLAG_EOS 0x00000001
+
+/** Start Time Buffer Flag:
+ *
+ * The source of a stream (e.g. a demux component) sets the STARTTIME
+ * flag on the buffer that contains the starting timestamp for the
+ * stream. The starting timestamp corresponds to the first data that
+ * should be displayed at startup or after a seek.
+ * The first timestamp of the stream is not necessarily the start time.
+ * For instance, in the case of a seek to a particular video frame,
+ * the target frame may be an interframe. Thus the first buffer of
+ * the stream will be the intra-frame preceding the target frame and
+ * the starttime will occur with the target frame (with any other
+ * required frames required to reconstruct the target intervening).
+ *
+ * The STARTTIME flag is directly associated with the buffer's
+ * timestamp ' thus its association to buffer data and its
+ * propagation is identical to the timestamp's.
+ *
+ * When a Sync Component client receives a buffer with the
+ * STARTTIME flag it shall perform a SetConfig on its sync port
+ * using OMX_ConfigTimeClientStartTime and passing the buffer's
+ * timestamp.
+ *
+ * @ingroup buf
+ */
+
+#define OMX_BUFFERFLAG_STARTTIME 0x00000002
+
+
+
+/** Decode Only Buffer Flag:
+ *
+ * The source of a stream (e.g. a demux component) sets the DECODEONLY
+ * flag on any buffer that should shall be decoded but should not be
+ * displayed. This flag is used, for instance, when a source seeks to
+ * a target interframe that requires the decode of frames preceding the
+ * target to facilitate the target's reconstruction. In this case the
+ * source would emit the frames preceding the target downstream
+ * but mark them as decode only.
+ *
+ * The DECODEONLY is associated with buffer data and propagated in a
+ * manner identical to the buffer timestamp.
+ *
+ * A component that renders data should ignore all buffers with
+ * the DECODEONLY flag set.
+ *
+ * @ingroup buf
+ */
+
+#define OMX_BUFFERFLAG_DECODEONLY 0x00000004
+
+
+/* Data Corrupt Flag: This flag is set when the IL client believes the data in the associated buffer is corrupt
+ * @ingroup buf
+ */
+
+#define OMX_BUFFERFLAG_DATACORRUPT 0x00000008
+
+/* End of Frame: The buffer contains exactly one end of frame and no data
+ *  occurs after the end of frame. This flag is an optional hint. The absence
+ *  of this flag does not imply the absence of an end of frame within the buffer.
+ * @ingroup buf
+*/
+#define OMX_BUFFERFLAG_ENDOFFRAME 0x00000010
+
+/* Sync Frame Flag: This flag is set when the buffer content contains a coded sync frame '
+ *  a frame that has no dependency on any other frame information
+ *  @ingroup buf
+ */
+#define OMX_BUFFERFLAG_SYNCFRAME 0x00000020
+
+/* Extra data present flag: there is extra data appended to the data stream
+ * residing in the buffer
+ * @ingroup buf
+ */
+#define OMX_BUFFERFLAG_EXTRADATA 0x00000040
+
+/** Codec Config Buffer Flag:
+* OMX_BUFFERFLAG_CODECCONFIG is an optional flag that is set by an
+* output port when all bytes in the buffer form part or all of a set of
+* codec specific configuration data.  Examples include SPS/PPS nal units
+* for OMX_VIDEO_CodingAVC or AudioSpecificConfig data for
+* OMX_AUDIO_CodingAAC.  Any component that for a given stream sets
+* OMX_BUFFERFLAG_CODECCONFIG shall not mix codec configuration bytes
+* with frame data in the same buffer, and shall send all buffers
+* containing codec configuration bytes before any buffers containing
+* frame data that those configurations bytes describe.
+* If the stream format for a particular codec has a frame specific
+* header at the start of each frame, for example OMX_AUDIO_CodingMP3 or
+* OMX_AUDIO_CodingAAC in ADTS mode, then these shall be presented as
+* normal without setting OMX_BUFFERFLAG_CODECCONFIG.
+ * @ingroup buf
+ */
+#define OMX_BUFFERFLAG_CODECCONFIG 0x00000080
+
+
+
+/** @ingroup buf */
+typedef struct OMX_BUFFERHEADERTYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U8* pBuffer;            /**< Pointer to actual block of memory
+                                     that is acting as the buffer */
+    OMX_U32 nAllocLen;          /**< size of the buffer allocated, in bytes */
+    OMX_U32 nFilledLen;         /**< number of bytes currently in the
+                                     buffer */
+    OMX_U32 nOffset;            /**< start offset of valid data in bytes from
+                                     the start of the buffer */
+    OMX_PTR pAppPrivate;        /**< pointer to any data the application
+                                     wants to associate with this buffer */
+    OMX_PTR pPlatformPrivate;   /**< pointer to any data the platform
+                                     wants to associate with this buffer */
+    OMX_PTR pInputPortPrivate;  /**< pointer to any data the input port
+                                     wants to associate with this buffer */
+    OMX_PTR pOutputPortPrivate; /**< pointer to any data the output port
+                                     wants to associate with this buffer */
+    OMX_HANDLETYPE hMarkTargetComponent; /**< The component that will generate a
+                                              mark event upon processing this buffer. */
+    OMX_PTR pMarkData;          /**< Application specific data associated with
+                                     the mark sent on a mark event to disambiguate
+                                     this mark from others. */
+    OMX_U32 nTickCount;         /**< Optional entry that the component and
+                                     application can update with a tick count
+                                     when they access the component.  This
+                                     value should be in microseconds.  Since
+                                     this is a value relative to an arbitrary
+                                     starting point, this value cannot be used
+                                     to determine absolute time.  This is an
+                                     optional entry and not all components
+                                     will update it.*/
+    OMX_TICKS nTimeStamp;          /**< Timestamp corresponding to the sample
+                                     starting at the first logical sample
+                                     boundary in the buffer. Timestamps of
+                                     successive samples within the buffer may
+                                     be inferred by adding the duration of the
+                                     of the preceding buffer to the timestamp
+                                     of the preceding buffer.*/
+    OMX_U32     nFlags;           /**< buffer specific flags */
+    OMX_U32 nOutputPortIndex;     /**< The index of the output port (if any) using
+                                     this buffer */
+    OMX_U32 nInputPortIndex;      /**< The index of the input port (if any) using
+                                     this buffer */
+} OMX_BUFFERHEADERTYPE;
+
+/** The OMX_EXTRADATATYPE enumeration is used to define the
+ * possible extra data payload types.
+ * NB: this enum is binary backwards compatible with the previous
+ * OMX_EXTRADATA_QUANT define.  This should be replaced with
+ * OMX_ExtraDataQuantization.
+ */
+typedef enum OMX_EXTRADATATYPE {
+    OMX_ExtraDataNone = 0,                       /**< Indicates that no more extra data sections follow */
+    OMX_ExtraDataQuantization,                   /**< The data payload contains quantization data */
+    OMX_ExtraDataKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_ExtraDataVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_ExtraDataMax = 0x7FFFFFFF
+} OMX_EXTRADATATYPE;
+
+
+typedef struct OMX_OTHER_EXTRADATATYPE  {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_EXTRADATATYPE eType;       /* Extra Data type */
+    OMX_U32 nDataSize;   /* Size of the supporting data to follow */
+    OMX_U8  data[1];     /* Supporting data hint  */
+} OMX_OTHER_EXTRADATATYPE;
+
+/** @ingroup comp */
+typedef struct OMX_PORT_PARAM_TYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPorts;             /**< The number of ports for this component */
+    OMX_U32 nStartPortNumber;   /** first port number for this type of port */
+} OMX_PORT_PARAM_TYPE;
+
+/** @ingroup comp */
+typedef enum OMX_EVENTTYPE {
+    OMX_EventCmdComplete,         /**< component has sucessfully completed a command */
+    OMX_EventError,               /**< component has detected an error condition */
+    OMX_EventMark,                /**< component has detected a buffer mark */
+    OMX_EventPortSettingsChanged, /**< component is reported a port settings change */
+    OMX_EventBufferFlag,          /**< component has detected an EOS */
+    OMX_EventResourcesAcquired,   /**< component has been granted resources and is
+                                       automatically starting the state change from
+                                       OMX_StateWaitForResources to OMX_StateIdle. */
+    OMX_EventComponentResumed,     /**< Component resumed due to reacquisition of resources */
+    OMX_EventDynamicResourcesAvailable, /**< Component has acquired previously unavailable dynamic resources */
+    OMX_EventPortFormatDetected,      /**< Component has detected a supported format. */
+    OMX_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_EventMax = 0x7FFFFFFF
+} OMX_EVENTTYPE;
+
+typedef struct OMX_CALLBACKTYPE {
+    /** The EventHandler method is used to notify the application when an
+        event of interest occurs.  Events are defined in the OMX_EVENTTYPE
+        enumeration.  Please see that enumeration for details of what will
+        be returned for each type of event. Callbacks should not return
+        an error to the component, so if an error occurs, the application
+        shall handle it internally.  This is a blocking call.
+
+        The application should return from this call within 5 msec to avoid
+        blocking the component for an excessively long period of time.
+
+        @param hComponent
+            handle of the component to access.  This is the component
+            handle returned by the call to the GetHandle function.
+        @param pAppData
+            pointer to an application defined value that was provided in the
+            pAppData parameter to the OMX_GetHandle method for the component.
+            This application defined value is provided so that the application
+            can have a component specific context when receiving the callback.
+        @param eEvent
+            Event that the component wants to notify the application about.
+        @param nData1
+            nData will be the OMX_ERRORTYPE for an error event and will be
+            an OMX_COMMANDTYPE for a command complete event and OMX_INDEXTYPE for a OMX_PortSettingsChanged event.
+         @param nData2
+            nData2 will hold further information related to the event. Can be OMX_STATETYPE for
+            a OMX_CommandStateSet command or port index for a OMX_PortSettingsChanged event.
+            Default value is 0 if not used. )
+        @param pEventData
+            Pointer to additional event-specific data (see spec for meaning).
+      */
+
+    OMX_ERRORTYPE (*EventHandler)(
+        OMX_IN OMX_HANDLETYPE hComponent,
+        OMX_IN OMX_PTR pAppData,
+        OMX_IN OMX_EVENTTYPE eEvent,
+        OMX_IN OMX_U32 nData1,
+        OMX_IN OMX_U32 nData2,
+        OMX_IN OMX_PTR pEventData);
+
+    /** The EmptyBufferDone method is used to return emptied buffers from an
+        input port back to the application for reuse.  This is a blocking call
+        so the application should not attempt to refill the buffers during this
+        call, but should queue them and refill them in another thread.  There
+        is no error return, so the application shall handle any errors generated
+        internally.
+
+        The application should return from this call within 5 msec.
+
+        @param hComponent
+            handle of the component to access.  This is the component
+            handle returned by the call to the GetHandle function.
+        @param pAppData
+            pointer to an application defined value that was provided in the
+            pAppData parameter to the OMX_GetHandle method for the component.
+            This application defined value is provided so that the application
+            can have a component specific context when receiving the callback.
+        @param pBuffer
+            pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer
+            or AllocateBuffer indicating the buffer that was emptied.
+        @ingroup buf
+     */
+    OMX_ERRORTYPE (*EmptyBufferDone)(
+        OMX_IN OMX_HANDLETYPE hComponent,
+        OMX_IN OMX_PTR pAppData,
+        OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
+
+    /** The FillBufferDone method is used to return filled buffers from an
+        output port back to the application for emptying and then reuse.
+        This is a blocking call so the application should not attempt to
+        empty the buffers during this call, but should queue the buffers
+        and empty them in another thread.  There is no error return, so
+        the application shall handle any errors generated internally.  The
+        application shall also update the buffer header to indicate the
+        number of bytes placed into the buffer.
+
+        The application should return from this call within 5 msec.
+
+        @param hComponent
+            handle of the component to access.  This is the component
+            handle returned by the call to the GetHandle function.
+        @param pAppData
+            pointer to an application defined value that was provided in the
+            pAppData parameter to the OMX_GetHandle method for the component.
+            This application defined value is provided so that the application
+            can have a component specific context when receiving the callback.
+        @param pBuffer
+            pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer
+            or AllocateBuffer indicating the buffer that was filled.
+        @ingroup buf
+     */
+    OMX_ERRORTYPE (*FillBufferDone)(
+        OMX_OUT OMX_HANDLETYPE hComponent,
+        OMX_OUT OMX_PTR pAppData,
+        OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer);
+
+} OMX_CALLBACKTYPE;
+
+/** The OMX_BUFFERSUPPLIERTYPE enumeration is used to dictate port supplier
+    preference when tunneling between two ports.
+    @ingroup tun buf
+*/
+typedef enum OMX_BUFFERSUPPLIERTYPE {
+    OMX_BufferSupplyUnspecified = 0x0, /**< port supplying the buffers is unspecified,
+                                              or don't care */
+    OMX_BufferSupplyInput,             /**< input port supplies the buffers */
+    OMX_BufferSupplyOutput,            /**< output port supplies the buffers */
+    OMX_BufferSupplyKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_BufferSupplyVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_BufferSupplyMax = 0x7FFFFFFF
+} OMX_BUFFERSUPPLIERTYPE;
+
+
+/** buffer supplier parameter
+ * @ingroup tun
+ */
+typedef struct OMX_PARAM_BUFFERSUPPLIERTYPE {
+    OMX_U32 nSize; /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_U32 nPortIndex; /**< port that this structure applies to */
+    OMX_BUFFERSUPPLIERTYPE eBufferSupplier; /**< buffer supplier */
+} OMX_PARAM_BUFFERSUPPLIERTYPE;
+
+
+/**< indicates that buffers received by an input port of a tunnel
+     may not modify the data in the buffers
+     @ingroup tun
+ */
+#define OMX_PORTTUNNELFLAG_READONLY 0x00000001
+
+
+/** The OMX_TUNNELSETUPTYPE structure is used to pass data from an output
+    port to an input port as part the two ComponentTunnelRequest calls
+    resulting from a OMX_SetupTunnel call from the IL Client.
+    @ingroup tun
+ */
+typedef struct OMX_TUNNELSETUPTYPE {
+    OMX_U32 nTunnelFlags;             /**< bit flags for tunneling */
+    OMX_BUFFERSUPPLIERTYPE eSupplier; /**< supplier preference */
+} OMX_TUNNELSETUPTYPE;
+
+/* OMX Component headers is included to enable the core to use
+   macros for functions into the component for OMX release 1.0.
+   Developers should not access any structures or data from within
+   the component header directly */
+/* TO BE REMOVED - #include <OMX_Component.h> */
+
+/** GetComponentVersion will return information about the component.
+    This is a blocking call.  This macro will go directly from the
+    application to the component (via a core macro).  The
+    component will return from this call within 5 msec.
+    @param [in] hComponent
+        handle of component to execute the command
+    @param [out] pComponentName
+        pointer to an empty string of length 128 bytes.  The component
+        will write its name into this string.  The name will be
+        terminated by a single zero byte.  The name of a component will
+        be 127 bytes or less to leave room for the trailing zero byte.
+        An example of a valid component name is "OMX.ABC.ChannelMixer\0".
+    @param [out] pComponentVersion
+        pointer to an OMX Version structure that the component will fill
+        in.  The component will fill in a value that indicates the
+        component version.  NOTE: the component version is NOT the same
+        as the OMX Specification version (found in all structures).  The
+        component version is defined by the vendor of the component and
+        its value is entirely up to the component vendor.
+    @param [out] pSpecVersion
+        pointer to an OMX Version structure that the component will fill
+        in.  The SpecVersion is the version of the specification that the
+        component was built against.  Please note that this value may or
+        may not match the structure's version.  For example, if the
+        component was built against the 2.0 specification, but the
+        application (which creates the structure is built against the
+        1.0 specification the versions would be different.
+    @param [out] pComponentUUID
+        pointer to the UUID of the component which will be filled in by
+        the component.  The UUID is a unique identifier that is set at
+        RUN time for the component and is unique to each instantion of
+        the component.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp
+ */
+#define OMX_GetComponentVersion(                            \
+        hComponent,                                         \
+        pComponentName,                                     \
+        pComponentVersion,                                  \
+        pSpecVersion,                                       \
+        pComponentUUID)                                     \
+    ((OMX_COMPONENTTYPE*)hComponent)->GetComponentVersion(  \
+        hComponent,                                         \
+        pComponentName,                                     \
+        pComponentVersion,                                  \
+        pSpecVersion,                                       \
+        pComponentUUID)                 /* Macro End */
+
+
+/** Send a command to the component.  This call is a non-blocking call.
+    The component should check the parameters and then queue the command
+    to the component thread to be executed.  The component thread shall
+    send the EventHandler() callback at the conclusion of the command.
+    This macro will go directly from the application to the component (via
+    a core macro).  The component will return from this call within 5 msec.
+
+    When the command is "OMX_CommandStateSet" the component will queue a
+    state transition to the new state idenfied in nParam.
+
+    When the command is "OMX_CommandFlush", to flush a port's buffer queues,
+    the command will force the component to return all buffers NOT CURRENTLY
+    BEING PROCESSED to the application, in the order in which the buffers
+    were received.
+
+    When the command is "OMX_CommandPortDisable" or
+    "OMX_CommandPortEnable", the component's port (given by the value of
+    nParam) will be stopped or restarted.
+
+    When the command "OMX_CommandMarkBuffer" is used to mark a buffer, the
+    pCmdData will point to a OMX_MARKTYPE structure containing the component
+    handle of the component to examine the buffer chain for the mark.  nParam1
+    contains the index of the port on which the buffer mark is applied.
+
+    Specification text for more details.
+
+    @param [in] hComponent
+        handle of component to execute the command
+    @param [in] Cmd
+        Command for the component to execute
+    @param [in] nParam
+        Parameter for the command to be executed.  When Cmd has the value
+        OMX_CommandStateSet, value is a member of OMX_STATETYPE.  When Cmd has
+        the value OMX_CommandFlush, value of nParam indicates which port(s)
+        to flush. -1 is used to flush all ports a single port index will
+        only flush that port.  When Cmd has the value "OMX_CommandPortDisable"
+        or "OMX_CommandPortEnable", the component's port is given by
+        the value of nParam.  When Cmd has the value "OMX_CommandMarkBuffer"
+        the components pot is given by the value of nParam.
+    @param [in] pCmdData
+        Parameter pointing to the OMX_MARKTYPE structure when Cmd has the value
+        "OMX_CommandMarkBuffer".
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp
+ */
+#define OMX_SendCommand(                                    \
+         hComponent,                                        \
+         Cmd,                                               \
+         nParam,                                            \
+         pCmdData)                                          \
+     ((OMX_COMPONENTTYPE*)hComponent)->SendCommand(         \
+         hComponent,                                        \
+         Cmd,                                               \
+         nParam,                                            \
+         pCmdData)                          /* Macro End */
+
+
+/** The OMX_GetParameter macro will get one of the current parameter
+    settings from the component.  This macro cannot only be invoked when
+    the component is in the OMX_StateInvalid state.  The nParamIndex
+    parameter is used to indicate which structure is being requested from
+    the component.  The application shall allocate the correct structure
+    and shall fill in the structure size and version information before
+    invoking this macro.  When the parameter applies to a port, the
+    caller shall fill in the appropriate nPortIndex value indicating the
+    port on which the parameter applies. If the component has not had
+    any settings changed, then the component should return a set of
+    valid DEFAULT  parameters for the component.  This is a blocking
+    call.
+
+    The component should return from this call within 20 msec.
+
+    @param [in] hComponent
+        Handle of the component to be accessed.  This is the component
+        handle returned by the call to the OMX_GetHandle function.
+    @param [in] nParamIndex
+        Index of the structure to be filled.  This value is from the
+        OMX_INDEXTYPE enumeration.
+    @param [in,out] pComponentParameterStructure
+        Pointer to application allocated structure to be filled by the
+        component.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp
+ */
+#define OMX_GetParameter(                                   \
+        hComponent,                                         \
+        nParamIndex,                                        \
+        pComponentParameterStructure)                        \
+    ((OMX_COMPONENTTYPE*)hComponent)->GetParameter(         \
+        hComponent,                                         \
+        nParamIndex,                                        \
+        pComponentParameterStructure)    /* Macro End */
+
+
+/** The OMX_SetParameter macro will send an initialization parameter
+    structure to a component.  Each structure shall be sent one at a time,
+    in a separate invocation of the macro.  This macro can only be
+    invoked when the component is in the OMX_StateLoaded state, or the
+    port is disabled (when the parameter applies to a port). The
+    nParamIndex parameter is used to indicate which structure is being
+    passed to the component.  The application shall allocate the
+    correct structure and shall fill in the structure size and version
+    information (as well as the actual data) before invoking this macro.
+    The application is free to dispose of this structure after the call
+    as the component is required to copy any data it shall retain.  This
+    is a blocking call.
+
+    The component should return from this call within 20 msec.
+
+    @param [in] hComponent
+        Handle of the component to be accessed.  This is the component
+        handle returned by the call to the OMX_GetHandle function.
+    @param [in] nIndex
+        Index of the structure to be sent.  This value is from the
+        OMX_INDEXTYPE enumeration.
+    @param [in] pComponentParameterStructure
+        pointer to application allocated structure to be used for
+        initialization by the component.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp
+ */
+#define OMX_SetParameter(                                   \
+        hComponent,                                         \
+        nParamIndex,                                        \
+        pComponentParameterStructure)                        \
+    ((OMX_COMPONENTTYPE*)hComponent)->SetParameter(         \
+        hComponent,                                         \
+        nParamIndex,                                        \
+        pComponentParameterStructure)    /* Macro End */
+
+
+/** The OMX_GetConfig macro will get one of the configuration structures
+    from a component.  This macro can be invoked anytime after the
+    component has been loaded.  The nParamIndex call parameter is used to
+    indicate which structure is being requested from the component.  The
+    application shall allocate the correct structure and shall fill in the
+    structure size and version information before invoking this macro.
+    If the component has not had this configuration parameter sent before,
+    then the component should return a set of valid DEFAULT values for the
+    component.  This is a blocking call.
+
+    The component should return from this call within 5 msec.
+
+    @param [in] hComponent
+        Handle of the component to be accessed.  This is the component
+        handle returned by the call to the OMX_GetHandle function.
+    @param [in] nIndex
+        Index of the structure to be filled.  This value is from the
+        OMX_INDEXTYPE enumeration.
+    @param [in,out] pComponentConfigStructure
+        pointer to application allocated structure to be filled by the
+        component.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp
+*/
+#define OMX_GetConfig(                                      \
+        hComponent,                                         \
+        nConfigIndex,                                       \
+        pComponentConfigStructure)                           \
+    ((OMX_COMPONENTTYPE*)hComponent)->GetConfig(            \
+        hComponent,                                         \
+        nConfigIndex,                                       \
+        pComponentConfigStructure)       /* Macro End */
+
+
+/** The OMX_SetConfig macro will send one of the configuration
+    structures to a component.  Each structure shall be sent one at a time,
+    each in a separate invocation of the macro.  This macro can be invoked
+    anytime after the component has been loaded.  The application shall
+    allocate the correct structure and shall fill in the structure size
+    and version information (as well as the actual data) before invoking
+    this macro.  The application is free to dispose of this structure after
+    the call as the component is required to copy any data it shall retain.
+    This is a blocking call.
+
+    The component should return from this call within 5 msec.
+
+    @param [in] hComponent
+        Handle of the component to be accessed.  This is the component
+        handle returned by the call to the OMX_GetHandle function.
+    @param [in] nConfigIndex
+        Index of the structure to be sent.  This value is from the
+        OMX_INDEXTYPE enumeration above.
+    @param [in] pComponentConfigStructure
+        pointer to application allocated structure to be used for
+        initialization by the component.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp
+ */
+#define OMX_SetConfig(                                      \
+        hComponent,                                         \
+        nConfigIndex,                                       \
+        pComponentConfigStructure)                           \
+    ((OMX_COMPONENTTYPE*)hComponent)->SetConfig(            \
+        hComponent,                                         \
+        nConfigIndex,                                       \
+        pComponentConfigStructure)       /* Macro End */
+
+
+/** The OMX_GetExtensionIndex macro will invoke a component to translate
+    a vendor specific configuration or parameter string into an OMX
+    structure index.  There is no requirement for the vendor to support
+    this command for the indexes already found in the OMX_INDEXTYPE
+    enumeration (this is done to save space in small components).  The
+    component shall support all vendor supplied extension indexes not found
+    in the master OMX_INDEXTYPE enumeration.  This is a blocking call.
+
+    The component should return from this call within 5 msec.
+
+    @param [in] hComponent
+        Handle of the component to be accessed.  This is the component
+        handle returned by the call to the GetHandle function.
+    @param [in] cParameterName
+        OMX_STRING that shall be less than 128 characters long including
+        the trailing null byte.  This is the string that will get
+        translated by the component into a configuration index.
+    @param [out] pIndexType
+        a pointer to a OMX_INDEXTYPE to receive the index value.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp
+ */
+#define OMX_GetExtensionIndex(                              \
+        hComponent,                                         \
+        cParameterName,                                     \
+        pIndexType)                                         \
+    ((OMX_COMPONENTTYPE*)hComponent)->GetExtensionIndex(    \
+        hComponent,                                         \
+        cParameterName,                                     \
+        pIndexType)                     /* Macro End */
+
+
+/** The OMX_GetState macro will invoke the component to get the current
+    state of the component and place the state value into the location
+    pointed to by pState.
+
+    The component should return from this call within 5 msec.
+
+    @param [in] hComponent
+        Handle of the component to be accessed.  This is the component
+        handle returned by the call to the OMX_GetHandle function.
+    @param [out] pState
+        pointer to the location to receive the state.  The value returned
+        is one of the OMX_STATETYPE members
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp
+ */
+#define OMX_GetState(                                       \
+        hComponent,                                         \
+        pState)                                             \
+    ((OMX_COMPONENTTYPE*)hComponent)->GetState(             \
+        hComponent,                                         \
+        pState)                         /* Macro End */
+
+
+/** The OMX_UseBuffer macro will request that the component use
+    a buffer (and allocate its own buffer header) already allocated
+    by another component, or by the IL Client. This is a blocking
+    call.
+
+    The component should return from this call within 20 msec.
+
+    @param [in] hComponent
+        Handle of the component to be accessed.  This is the component
+        handle returned by the call to the OMX_GetHandle function.
+    @param [out] ppBuffer
+        pointer to an OMX_BUFFERHEADERTYPE structure used to receive the
+        pointer to the buffer header
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp buf
+ */
+
+#define OMX_UseBuffer(                                      \
+           hComponent,                                      \
+           ppBufferHdr,                                     \
+           nPortIndex,                                      \
+           pAppPrivate,                                     \
+           nSizeBytes,                                      \
+           pBuffer)                                         \
+    ((OMX_COMPONENTTYPE*)hComponent)->UseBuffer(            \
+           hComponent,                                      \
+           ppBufferHdr,                                     \
+           nPortIndex,                                      \
+           pAppPrivate,                                     \
+           nSizeBytes,                                      \
+           pBuffer)
+
+
+/** The OMX_AllocateBuffer macro will request that the component allocate
+    a new buffer and buffer header.  The component will allocate the
+    buffer and the buffer header and return a pointer to the buffer
+    header.  This is a blocking call.
+
+    The component should return from this call within 5 msec.
+
+    @param [in] hComponent
+        Handle of the component to be accessed.  This is the component
+        handle returned by the call to the OMX_GetHandle function.
+    @param [out] ppBuffer
+        pointer to an OMX_BUFFERHEADERTYPE structure used to receive
+        the pointer to the buffer header
+    @param [in] nPortIndex
+        nPortIndex is used to select the port on the component the buffer will
+        be used with.  The port can be found by using the nPortIndex
+        value as an index into the Port Definition array of the component.
+    @param [in] pAppPrivate
+        pAppPrivate is used to initialize the pAppPrivate member of the
+        buffer header structure.
+    @param [in] nSizeBytes
+        size of the buffer to allocate.  Used when bAllocateNew is true.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp buf
+ */
+#define OMX_AllocateBuffer(                                 \
+        hComponent,                                         \
+        ppBuffer,                                           \
+        nPortIndex,                                         \
+        pAppPrivate,                                        \
+        nSizeBytes)                                         \
+    ((OMX_COMPONENTTYPE*)hComponent)->AllocateBuffer(       \
+        hComponent,                                         \
+        ppBuffer,                                           \
+        nPortIndex,                                         \
+        pAppPrivate,                                        \
+        nSizeBytes)                     /* Macro End */
+
+
+/** The OMX_FreeBuffer macro will release a buffer header from the component
+    which was allocated using either OMX_AllocateBuffer or OMX_UseBuffer. If
+    the component allocated the buffer (see the OMX_UseBuffer macro) then
+    the component shall free the buffer and buffer header. This is a
+    blocking call.
+
+    The component should return from this call within 20 msec.
+
+    @param [in] hComponent
+        Handle of the component to be accessed.  This is the component
+        handle returned by the call to the OMX_GetHandle function.
+    @param [in] nPortIndex
+        nPortIndex is used to select the port on the component the buffer will
+        be used with.
+    @param [in] pBuffer
+        pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer
+        or AllocateBuffer.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp buf
+ */
+#define OMX_FreeBuffer(                                     \
+        hComponent,                                         \
+        nPortIndex,                                         \
+        pBuffer)                                            \
+    ((OMX_COMPONENTTYPE*)hComponent)->FreeBuffer(           \
+        hComponent,                                         \
+        nPortIndex,                                         \
+        pBuffer)                        /* Macro End */
+
+
+/** The OMX_EmptyThisBuffer macro will send a buffer full of data to an
+    input port of a component.  The buffer will be emptied by the component
+    and returned to the application via the EmptyBufferDone call back.
+    This is a non-blocking call in that the component will record the buffer
+    and return immediately and then empty the buffer, later, at the proper
+    time.  As expected, this macro may be invoked only while the component
+    is in the OMX_StateExecuting.  If nPortIndex does not specify an input
+    port, the component shall return an error.
+
+    The component should return from this call within 5 msec.
+
+    @param [in] hComponent
+        Handle of the component to be accessed.  This is the component
+        handle returned by the call to the OMX_GetHandle function.
+    @param [in] pBuffer
+        pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer
+        or AllocateBuffer.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp buf
+ */
+#define OMX_EmptyThisBuffer(                                \
+        hComponent,                                         \
+        pBuffer)                                            \
+    ((OMX_COMPONENTTYPE*)hComponent)->EmptyThisBuffer(      \
+        hComponent,                                         \
+        pBuffer)                        /* Macro End */
+
+
+/** The OMX_FillThisBuffer macro will send an empty buffer to an
+    output port of a component.  The buffer will be filled by the component
+    and returned to the application via the FillBufferDone call back.
+    This is a non-blocking call in that the component will record the buffer
+    and return immediately and then fill the buffer, later, at the proper
+    time.  As expected, this macro may be invoked only while the component
+    is in the OMX_ExecutingState.  If nPortIndex does not specify an output
+    port, the component shall return an error.
+
+    The component should return from this call within 5 msec.
+
+    @param [in] hComponent
+        Handle of the component to be accessed.  This is the component
+        handle returned by the call to the OMX_GetHandle function.
+    @param [in] pBuffer
+        pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer
+        or AllocateBuffer.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp buf
+ */
+#define OMX_FillThisBuffer(                                 \
+        hComponent,                                         \
+        pBuffer)                                            \
+    ((OMX_COMPONENTTYPE*)hComponent)->FillThisBuffer(       \
+        hComponent,                                         \
+        pBuffer)                        /* Macro End */
+
+
+
+/** The OMX_UseEGLImage macro will request that the component use
+    a EGLImage provided by EGL (and allocate its own buffer header)
+    This is a blocking call.
+
+    The component should return from this call within 20 msec.
+
+    @param [in] hComponent
+        Handle of the component to be accessed.  This is the component
+        handle returned by the call to the OMX_GetHandle function.
+    @param [out] ppBuffer
+        pointer to an OMX_BUFFERHEADERTYPE structure used to receive the
+        pointer to the buffer header.  Note that the memory location used
+        for this buffer is NOT visible to the IL Client.
+    @param [in] nPortIndex
+        nPortIndex is used to select the port on the component the buffer will
+        be used with.  The port can be found by using the nPortIndex
+        value as an index into the Port Definition array of the component.
+    @param [in] pAppPrivate
+        pAppPrivate is used to initialize the pAppPrivate member of the
+        buffer header structure.
+    @param [in] eglImage
+        eglImage contains the handle of the EGLImage to use as a buffer on the
+        specified port.  The component is expected to validate properties of
+        the EGLImage against the configuration of the port to ensure the component
+        can use the EGLImage as a buffer.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp buf
+ */
+#define OMX_UseEGLImage(                                    \
+           hComponent,                                      \
+           ppBufferHdr,                                     \
+           nPortIndex,                                      \
+           pAppPrivate,                                     \
+           eglImage)                                        \
+    ((OMX_COMPONENTTYPE*)hComponent)->UseEGLImage(          \
+           hComponent,                                      \
+           ppBufferHdr,                                     \
+           nPortIndex,                                      \
+           pAppPrivate,                                     \
+           eglImage)
+
+/** The OMX_Init method is used to initialize the OMX core.  It shall be the
+    first call made into OMX and it should only be executed one time without
+    an interviening OMX_Deinit call.
+
+    The core should return from this call within 20 msec.
+
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup core
+ */
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Init(void);
+
+
+/** The OMX_Deinit method is used to deinitialize the OMX core.  It shall be
+    the last call made into OMX. In the event that the core determines that
+    thare are components loaded when this call is made, the core may return
+    with an error rather than try to unload the components.
+
+    The core should return from this call within 20 msec.
+
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup core
+ */
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Deinit(void);
+
+
+/** The OMX_ComponentNameEnum method will enumerate through all the names of
+    recognised valid components in the system. This function is provided
+    as a means to detect all the components in the system run-time. There is
+    no strict ordering to the enumeration order of component names, although
+    each name will only be enumerated once.  If the OMX core supports run-time
+    installation of new components, it is only requried to detect newly
+    installed components when the first call to enumerate component names
+    is made (i.e. when nIndex is 0x0).
+
+    The core should return from this call in 20 msec.
+
+    @param [out] cComponentName
+        pointer to a null terminated string with the component name.  The
+        names of the components are strings less than 127 bytes in length
+        plus the trailing null for a maximum size of 128 bytes.  An example
+        of a valid component name is "OMX.TI.AUDIO.DSP.MIXER\0".  Names are
+        assigned by the vendor, but shall start with "OMX." and then have
+        the Vendor designation next.
+    @param [in] nNameLength
+        number of characters in the cComponentName string.  With all
+        component name strings restricted to less than 128 characters
+        (including the trailing null) it is recomended that the caller
+        provide a input string for the cComponentName of 128 characters.
+    @param [in] nIndex
+        number containing the enumeration index for the component.
+        Multiple calls to OMX_ComponentNameEnum with increasing values
+        of nIndex will enumerate through the component names in the
+        system until OMX_ErrorNoMore is returned.  The value of nIndex
+        is 0 to (N-1), where N is the number of valid installed components
+        in the system.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  When the value of nIndex exceeds the number of
+        components in the system minus 1, OMX_ErrorNoMore will be
+        returned. Otherwise the appropriate OMX error will be returned.
+    @ingroup core
+ */
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_ComponentNameEnum(
+    OMX_OUT OMX_STRING cComponentName,
+    OMX_IN  OMX_U32 nNameLength,
+    OMX_IN  OMX_U32 nIndex);
+
+
+/** The OMX_GetHandle method will locate the component specified by the
+    component name given, load that component into memory and then invoke
+    the component's methods to create an instance of the component.
+
+    The core should return from this call within 20 msec.
+
+    @param [out] pHandle
+        pointer to an OMX_HANDLETYPE pointer to be filled in by this method.
+    @param [in] cComponentName
+        pointer to a null terminated string with the component name.  The
+        names of the components are strings less than 127 bytes in length
+        plus the trailing null for a maximum size of 128 bytes.  An example
+        of a valid component name is "OMX.TI.AUDIO.DSP.MIXER\0".  Names are
+        assigned by the vendor, but shall start with "OMX." and then have
+        the Vendor designation next.
+    @param [in] pAppData
+        pointer to an application defined value that will be returned
+        during callbacks so that the application can identify the source
+        of the callback.
+    @param [in] pCallBacks
+        pointer to a OMX_CALLBACKTYPE structure that will be passed to the
+        component to initialize it with.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup core
+ */
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle(
+    OMX_OUT OMX_HANDLETYPE* pHandle,
+    OMX_IN  OMX_STRING cComponentName,
+    OMX_IN  OMX_PTR pAppData,
+    OMX_IN  OMX_CALLBACKTYPE* pCallBacks);
+
+
+/** The OMX_FreeHandle method will free a handle allocated by the OMX_GetHandle
+    method.  If the component reference count goes to zero, the component will
+    be unloaded from memory.
+
+    The core should return from this call within 20 msec when the component is
+    in the OMX_StateLoaded state.
+
+    @param [in] hComponent
+        Handle of the component to be accessed.  This is the component
+        handle returned by the call to the GetHandle function.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup core
+ */
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle(
+    OMX_IN  OMX_HANDLETYPE hComponent);
+
+
+
+/** The OMX_SetupTunnel method will handle the necessary calls to the components
+    to setup the specified tunnel the two components.  NOTE: This is
+    an actual method (not a #define macro).  This method will make calls into
+    the component ComponentTunnelRequest method to do the actual tunnel
+    connection.
+
+    The ComponentTunnelRequest method on both components will be called.
+    This method shall not be called unless the component is in the
+    OMX_StateLoaded state except when the ports used for the tunnel are
+    disabled. In this case, the component may be in the OMX_StateExecuting,
+    OMX_StatePause, or OMX_StateIdle states.
+
+    The core should return from this call within 20 msec.
+
+    @param [in] hOutput
+        Handle of the component to be accessed.  Also this is the handle
+        of the component whose port, specified in the nPortOutput parameter
+        will be used the source for the tunnel. This is the component handle
+        returned by the call to the OMX_GetHandle function.  There is a
+        requirement that hOutput be the source for the data when
+        tunelling (i.e. nPortOutput is an output port).  If 0x0, the component
+        specified in hInput will have it's port specified in nPortInput
+        setup for communication with the application / IL client.
+    @param [in] nPortOutput
+        nPortOutput is used to select the source port on component to be
+        used in the tunnel.
+    @param [in] hInput
+        This is the component to setup the tunnel with. This is the handle
+        of the component whose port, specified in the nPortInput parameter
+        will be used the destination for the tunnel. This is the component handle
+        returned by the call to the OMX_GetHandle function.  There is a
+        requirement that hInput be the destination for the data when
+        tunelling (i.e. nPortInut is an input port).   If 0x0, the component
+        specified in hOutput will have it's port specified in nPortPOutput
+        setup for communication with the application / IL client.
+    @param [in] nPortInput
+        nPortInput is used to select the destination port on component to be
+        used in the tunnel.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+        When OMX_ErrorNotImplemented is returned, one or both components is
+        a non-interop component and does not support tunneling.
+
+        On failure, the ports of both components are setup for communication
+        with the application / IL Client.
+    @ingroup core tun
+ */
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_SetupTunnel(
+    OMX_IN  OMX_HANDLETYPE hOutput,
+    OMX_IN  OMX_U32 nPortOutput,
+    OMX_IN  OMX_HANDLETYPE hInput,
+    OMX_IN  OMX_U32 nPortInput);
+
+/** @ingroup cp */
+OMX_API OMX_ERRORTYPE   OMX_GetContentPipe(
+    OMX_OUT OMX_HANDLETYPE *hPipe,
+    OMX_IN OMX_STRING szURI);
+
+/** The OMX_GetComponentsOfRole method will return the number of components that support the given
+    role and (if the compNames field is non-NULL) the names of those components. The call will fail if
+    an insufficiently sized array of names is supplied. To ensure the array is sufficiently sized the
+    client should:
+        * first call this function with the compNames field NULL to determine the number of component names
+        * second call this function with the compNames field pointing to an array of names allocated
+          according to the number returned by the first call.
+
+    The core should return from this call within 5 msec.
+
+    @param [in] role
+        This is generic standard component name consisting only of component class
+        name and the type within that class (e.g. 'audio_decoder.aac').
+    @param [inout] pNumComps
+        This is used both as input and output.
+
+        If compNames is NULL, the input is ignored and the output specifies how many components support
+        the given role.
+
+        If compNames is not NULL, on input it bounds the size of the input structure and
+        on output, it specifies the number of components string names listed within the compNames parameter.
+    @param [inout] compNames
+        If NULL this field is ignored. If non-NULL this points to an array of 128-byte strings which accepts
+        a list of the names of all physical components that implement the specified standard component name.
+        Each name is NULL terminated. numComps indicates the number of names.
+    @ingroup core
+ */
+OMX_API OMX_ERRORTYPE OMX_GetComponentsOfRole (
+    OMX_IN      OMX_STRING role,
+    OMX_INOUT   OMX_U32 *pNumComps,
+    OMX_INOUT   OMX_U8  **compNames);
+
+/** The OMX_GetRolesOfComponent method will return the number of roles supported by the given
+    component and (if the roles field is non-NULL) the names of those roles. The call will fail if
+    an insufficiently sized array of names is supplied. To ensure the array is sufficiently sized the
+    client should:
+        * first call this function with the roles field NULL to determine the number of role names
+        * second call this function with the roles field pointing to an array of names allocated
+          according to the number returned by the first call.
+
+    The core should return from this call within 5 msec.
+
+    @param [in] compName
+        This is the name of the component being queried about.
+    @param [inout] pNumRoles
+        This is used both as input and output.
+
+        If roles is NULL, the input is ignored and the output specifies how many roles the component supports.
+
+        If compNames is not NULL, on input it bounds the size of the input structure and
+        on output, it specifies the number of roles string names listed within the roles parameter.
+    @param [out] roles
+        If NULL this field is ignored. If non-NULL this points to an array of 128-byte strings
+        which accepts a list of the names of all standard components roles implemented on the
+        specified component name. numComps indicates the number of names.
+    @ingroup core
+ */
+OMX_API OMX_ERRORTYPE OMX_GetRolesOfComponent (
+    OMX_IN      OMX_STRING compName,
+    OMX_INOUT   OMX_U32 *pNumRoles,
+    OMX_OUT     OMX_U8 **roles);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */
+

+ 73 - 0
omx-il/include/khronos/OMX_CoreExt.h

@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** OMX_CoreExt.h - OpenMax IL version 1.1.2
+ * The OMX_CoreExt header file contains extensions to the definitions used
+ * by both the application and the component to access common items.
+ */
+
+#ifndef OMX_CoreExt_h
+#define OMX_CoreExt_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Each OMX header shall include all required header files to allow the
+ * header to compile without errors.  The includes below are required
+ * for this header file to compile successfully
+ */
+#include <OMX_Core.h>
+
+/** Extensions to the standard IL errors. */ 
+typedef enum OMX_ERROREXTTYPE 
+{
+    OMX_ErrorInvalidMode = (OMX_S32) (OMX_ErrorKhronosExtensions + 0x00000001),
+    OMX_ErrorExtMax = 0x7FFFFFFF
+} OMX_ERROREXTTYPE;
+
+
+/** Event type extensions. */
+typedef enum OMX_EVENTEXTTYPE
+{
+    OMX_EventIndexSettingChanged = OMX_EventKhronosExtensions, /**< component signals the IL client of a change
+                                                                    in a param, config, or extension */
+    OMX_EventExtMax = 0x7FFFFFFF
+} OMX_EVENTEXTTYPE;
+
+
+/** Enable or disable a callback event. */
+typedef struct OMX_CONFIG_CALLBACKREQUESTTYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPortIndex;         /**< port that this structure applies to */
+    OMX_INDEXTYPE nIndex;       /**< the index the callback is requested for */
+    OMX_BOOL bEnable;           /**< enable (OMX_TRUE) or disable (OMX_FALSE) the callback */
+} OMX_CONFIG_CALLBACKREQUESTTYPE;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* OMX_CoreExt_h */
+/* File EOF */

+ 993 - 0
omx-il/include/khronos/OMX_IVCommon.h

@@ -0,0 +1,993 @@
+/**
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/**
+ * @file OMX_IVCommon.h - OpenMax IL version 1.1.2
+ *  The structures needed by Video and Image components to exchange
+ *  parameters and configuration data with the components.
+ */
+#ifndef OMX_IVCommon_h
+#define OMX_IVCommon_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * Each OMX header must include all required header files to allow the header
+ * to compile without errors.  The includes below are required for this header
+ * file to compile successfully
+ */
+
+#include <OMX_Core.h>
+
+/** @defgroup iv OpenMAX IL Imaging and Video Domain
+ * Common structures for OpenMAX IL Imaging and Video domains
+ * @{
+ */
+
+
+/**
+ * Enumeration defining possible uncompressed image/video formats.
+ *
+ * ENUMS:
+ *  Unused                 : Placeholder value when format is N/A
+ *  Monochrome             : black and white
+ *  8bitRGB332             : Red 7:5, Green 4:2, Blue 1:0
+ *  12bitRGB444            : Red 11:8, Green 7:4, Blue 3:0
+ *  16bitARGB4444          : Alpha 15:12, Red 11:8, Green 7:4, Blue 3:0
+ *  16bitARGB1555          : Alpha 15, Red 14:10, Green 9:5, Blue 4:0
+ *  16bitRGB565            : Red 15:11, Green 10:5, Blue 4:0
+ *  16bitBGR565            : Blue 15:11, Green 10:5, Red 4:0
+ *  18bitRGB666            : Red 17:12, Green 11:6, Blue 5:0
+ *  18bitARGB1665          : Alpha 17, Red 16:11, Green 10:5, Blue 4:0
+ *  19bitARGB1666          : Alpha 18, Red 17:12, Green 11:6, Blue 5:0
+ *  24bitRGB888            : Red 24:16, Green 15:8, Blue 7:0
+ *  24bitBGR888            : Blue 24:16, Green 15:8, Red 7:0
+ *  24bitARGB1887          : Alpha 23, Red 22:15, Green 14:7, Blue 6:0
+ *  25bitARGB1888          : Alpha 24, Red 23:16, Green 15:8, Blue 7:0
+ *  32bitBGRA8888          : Blue 31:24, Green 23:16, Red 15:8, Alpha 7:0
+ *  32bitARGB8888          : Alpha 31:24, Red 23:16, Green 15:8, Blue 7:0
+ *  YUV411Planar           : U,Y are subsampled by a factor of 4 horizontally
+ *  YUV411PackedPlanar     : packed per payload in planar slices
+ *  YUV420Planar           : Three arrays Y,U,V.
+ *  YUV420PackedPlanar     : packed per payload in planar slices
+ *  YUV420SemiPlanar       : Two arrays, one is all Y, the other is U and V
+ *  YUV422Planar           : Three arrays Y,U,V.
+ *  YUV422PackedPlanar     : packed per payload in planar slices
+ *  YUV422SemiPlanar       : Two arrays, one is all Y, the other is U and V
+ *  YCbYCr                 : Organized as 16bit YUYV (i.e. YCbYCr)
+ *  YCrYCb                 : Organized as 16bit YVYU (i.e. YCrYCb)
+ *  CbYCrY                 : Organized as 16bit UYVY (i.e. CbYCrY)
+ *  CrYCbY                 : Organized as 16bit VYUY (i.e. CrYCbY)
+ *  YUV444Interleaved      : Each pixel contains equal parts YUV
+ *  RawBayer8bit           : SMIA camera output format
+ *  RawBayer10bit          : SMIA camera output format
+ *  RawBayer8bitcompressed : SMIA camera output format
+ */
+typedef enum OMX_COLOR_FORMATTYPE {
+    OMX_COLOR_FormatUnused,
+    OMX_COLOR_FormatMonochrome,
+    OMX_COLOR_Format8bitRGB332,
+    OMX_COLOR_Format12bitRGB444,
+    OMX_COLOR_Format16bitARGB4444,
+    OMX_COLOR_Format16bitARGB1555,
+    OMX_COLOR_Format16bitRGB565,
+    OMX_COLOR_Format16bitBGR565,
+    OMX_COLOR_Format18bitRGB666,
+    OMX_COLOR_Format18bitARGB1665,
+    OMX_COLOR_Format19bitARGB1666,
+    OMX_COLOR_Format24bitRGB888,
+    OMX_COLOR_Format24bitBGR888,
+    OMX_COLOR_Format24bitARGB1887,
+    OMX_COLOR_Format25bitARGB1888,
+    OMX_COLOR_Format32bitBGRA8888,
+    OMX_COLOR_Format32bitARGB8888,
+    OMX_COLOR_FormatYUV411Planar,
+    OMX_COLOR_FormatYUV411PackedPlanar,
+    OMX_COLOR_FormatYUV420Planar,
+    OMX_COLOR_FormatYUV420PackedPlanar,
+    OMX_COLOR_FormatYUV420SemiPlanar,
+    OMX_COLOR_FormatYUV422Planar,
+    OMX_COLOR_FormatYUV422PackedPlanar,
+    OMX_COLOR_FormatYUV422SemiPlanar,
+    OMX_COLOR_FormatYCbYCr,
+    OMX_COLOR_FormatYCrYCb,
+    OMX_COLOR_FormatCbYCrY,
+    OMX_COLOR_FormatCrYCbY,
+    OMX_COLOR_FormatYUV444Interleaved,
+    OMX_COLOR_FormatRawBayer8bit,
+    OMX_COLOR_FormatRawBayer10bit,
+    OMX_COLOR_FormatRawBayer8bitcompressed,
+    OMX_COLOR_FormatL2,
+    OMX_COLOR_FormatL4,
+    OMX_COLOR_FormatL8,
+    OMX_COLOR_FormatL16,
+    OMX_COLOR_FormatL24,
+    OMX_COLOR_FormatL32,
+    OMX_COLOR_FormatYUV420PackedSemiPlanar,
+    OMX_COLOR_FormatYUV422PackedSemiPlanar,
+    OMX_COLOR_Format18BitBGR666,
+    OMX_COLOR_Format24BitARGB6666,
+    OMX_COLOR_Format24BitABGR6666,
+    OMX_COLOR_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_COLOR_FormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+
+    /* Starfive extensions */
+    /* I420 */
+    OMX_COLOR_FormatYUV420Planar_P10_16BIT_MSB,
+    OMX_COLOR_FormatYUV420Planar_P10_16BIT_LSB,
+    OMX_COLOR_FormatYUV420Planar_P12_16BIT_MSB,
+    OMX_COLOR_FormatYUV420Planar_P12_16BIT_LSB,
+    /* NV12 */
+    OMX_COLOR_FormatYUV420SemiPlanar_P10_16BIT_MSB,
+    OMX_COLOR_FormatYUV420SemiPlanar_P10_16BIT_LSB,
+    OMX_COLOR_FormatYUV420SemiPlanar_P12_16BIT_MSB,
+    OMX_COLOR_FormatYUV420SemiPlanar_P12_16BIT_LSB,
+    /* NV21 */
+    OMX_COLOR_FormatYVU420SemiPlanar,
+    OMX_COLOR_FormatYVU420SemiPlanar_P10_16BIT_MSB,
+    OMX_COLOR_FormatYVU420SemiPlanar_P10_16BIT_LSB,
+    OMX_COLOR_FormatYVU420SemiPlanar_P12_16BIT_MSB,
+    OMX_COLOR_FormatYVU420SemiPlanar_P12_16BIT_LSB,
+    /* I422 */
+    OMX_COLOR_FormatYUV422Planar_P10_16BIT_MSB,
+    OMX_COLOR_FormatYUV422Planar_P10_16BIT_LSB,
+    OMX_COLOR_FormatYUV422Planar_P12_16BIT_MSB,
+    OMX_COLOR_FormatYUV422Planar_P12_16BIT_LSB,
+    /* NV16 */
+    OMX_COLOR_FormatYUV422SemiPlanar_P10_16BIT_MSB,
+    OMX_COLOR_FormatYUV422SemiPlanar_P10_16BIT_LSB,
+    OMX_COLOR_FormatYUV422SemiPlanar_P12_16BIT_MSB,
+    OMX_COLOR_FormatYUV422SemiPlanar_P12_16BIT_LSB,
+    /* NV61 */
+    OMX_COLOR_FormatYVU422SemiPlanar,
+    OMX_COLOR_FormatYVU422SemiPlanar_P10_16BIT_MSB,
+    OMX_COLOR_FormatYVU422SemiPlanar_P10_16BIT_LSB,
+    OMX_COLOR_FormatYVU422SemiPlanar_P12_16BIT_MSB,
+    OMX_COLOR_FormatYVU422SemiPlanar_P12_16BIT_LSB,
+    /* YUYV */
+    OMX_COLOR_FormatYCbYCr_P10_16BIT_MSB,
+    OMX_COLOR_FormatYCbYCr_P10_16BIT_LSB,
+    OMX_COLOR_FormatYCbYCr_P12_16BIT_MSB,
+    OMX_COLOR_FormatYCbYCr_P12_16BIT_LSB,
+    /* YVYU */
+    OMX_COLOR_FormatYCrYCb_P10_16BIT_MSB,
+    OMX_COLOR_FormatYCrYCb_P10_16BIT_LSB,
+    OMX_COLOR_FormatYCrYCb_P12_16BIT_MSB,
+    OMX_COLOR_FormatYCrYCb_P12_16BIT_LSB,
+    /* UYVY */
+    OMX_COLOR_FormatCbYCrY_P10_16BIT_MSB,
+    OMX_COLOR_FormatCbYCrY_P10_16BIT_LSB,
+    OMX_COLOR_FormatCbYCrY_P12_16BIT_MSB,
+    OMX_COLOR_FormatCbYCrY_P12_16BIT_LSB,
+    /* VYUY */
+    OMX_COLOR_FormatCrYCbY_P10_16BIT_MSB,
+    OMX_COLOR_FormatCrYCbY_P10_16BIT_LSB,
+    OMX_COLOR_FormatCrYCbY_P12_16BIT_MSB,
+    OMX_COLOR_FormatCrYCbY_P12_16BIT_LSB,
+    /* I444 */
+    OMX_COLOR_FormatYUV444Planar,
+    OMX_COLOR_FormatYUV444Planar_P10_16BIT_MSB,
+    OMX_COLOR_FormatYUV444Planar_P10_16BIT_LSB,
+    OMX_COLOR_FormatYUV444Planar_P12_16BIT_MSB,
+    OMX_COLOR_FormatYUV444Planar_P12_16BIT_LSB,
+    /* YUV444PACKED */
+    OMX_COLOR_FormatYUV444Interleaved_P10_16BIT_MSB,
+    OMX_COLOR_FormatYUV444Interleaved_P10_16BIT_LSB,
+    OMX_COLOR_FormatYUV444Interleaved_P12_16BIT_MSB,
+    OMX_COLOR_FormatYUV444Interleaved_P12_16BIT_LSB,
+    /* YUV400 */
+    OMX_COLOR_FormatYUV400,
+    OMX_COLOR_FormatYUV400_P10_16BIT_MSB,
+    OMX_COLOR_FormatYUV400_P10_16BIT_LSB,
+    OMX_COLOR_FormatYUV400_P12_16BIT_MSB,
+    OMX_COLOR_FormatYUV400_P12_16BIT_LSB,
+    /* Starfive extensions end */
+
+    OMX_COLOR_FormatMax = 0x7FFFFFFF
+} OMX_COLOR_FORMATTYPE;
+
+
+/**
+ * Defines the matrix for conversion from RGB to YUV or vice versa.
+ * iColorMatrix should be initialized with the fixed point values
+ * used in converting between formats.
+ */
+typedef struct OMX_CONFIG_COLORCONVERSIONTYPE {
+    OMX_U32 nSize;              /**< Size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version info */
+    OMX_U32 nPortIndex;         /**< Port that this struct applies to */
+    OMX_S32 xColorMatrix[3][3]; /**< Stored in signed Q16 format */
+    OMX_S32 xColorOffset[4];    /**< Stored in signed Q16 format */
+} OMX_CONFIG_COLORCONVERSIONTYPE;
+
+
+/**
+ * Structure defining percent to scale each frame dimension.  For example:
+ * To make the width 50% larger, use fWidth = 1.5 and to make the width
+ * 1/2 the original size, use fWidth = 0.5
+ */
+typedef struct OMX_CONFIG_SCALEFACTORTYPE {
+    OMX_U32 nSize;            /**< Size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version info */
+    OMX_U32 nPortIndex;       /**< Port that this struct applies to */
+    OMX_S32 xWidth;           /**< Fixed point value stored as Q16 */
+    OMX_S32 xHeight;          /**< Fixed point value stored as Q16 */
+} OMX_CONFIG_SCALEFACTORTYPE;
+
+
+/**
+ * Enumeration of possible image filter types
+ */
+typedef enum OMX_IMAGEFILTERTYPE {
+    OMX_ImageFilterNone,
+    OMX_ImageFilterNoise,
+    OMX_ImageFilterEmboss,
+    OMX_ImageFilterNegative,
+    OMX_ImageFilterSketch,
+    OMX_ImageFilterOilPaint,
+    OMX_ImageFilterHatch,
+    OMX_ImageFilterGpen,
+    OMX_ImageFilterAntialias,
+    OMX_ImageFilterDeRing,
+    OMX_ImageFilterSolarize,
+    OMX_ImageFilterKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_ImageFilterVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_ImageFilterMax = 0x7FFFFFFF
+} OMX_IMAGEFILTERTYPE;
+
+
+/**
+ * Image filter configuration
+ *
+ * STRUCT MEMBERS:
+ *  nSize        : Size of the structure in bytes
+ *  nVersion     : OMX specification version information
+ *  nPortIndex   : Port that this structure applies to
+ *  eImageFilter : Image filter type enumeration
+ */
+typedef struct OMX_CONFIG_IMAGEFILTERTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_IMAGEFILTERTYPE eImageFilter;
+} OMX_CONFIG_IMAGEFILTERTYPE;
+
+
+/**
+ * Customized U and V for color enhancement
+ *
+ * STRUCT MEMBERS:
+ *  nSize             : Size of the structure in bytes
+ *  nVersion          : OMX specification version information
+ *  nPortIndex        : Port that this structure applies to
+ *  bColorEnhancement : Enable/disable color enhancement
+ *  nCustomizedU      : Practical values: 16-240, range: 0-255, value set for
+ *                      U component
+ *  nCustomizedV      : Practical values: 16-240, range: 0-255, value set for
+ *                      V component
+ */
+typedef struct OMX_CONFIG_COLORENHANCEMENTTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL bColorEnhancement;
+    OMX_U8 nCustomizedU;
+    OMX_U8 nCustomizedV;
+} OMX_CONFIG_COLORENHANCEMENTTYPE;
+
+
+/**
+ * Define color key and color key mask
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  nARGBColor : 32bit Alpha, Red, Green, Blue Color
+ *  nARGBMask  : 32bit Mask for Alpha, Red, Green, Blue channels
+ */
+typedef struct OMX_CONFIG_COLORKEYTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nARGBColor;
+    OMX_U32 nARGBMask;
+} OMX_CONFIG_COLORKEYTYPE;
+
+
+/**
+ * List of color blend types for pre/post processing
+ *
+ * ENUMS:
+ *  None          : No color blending present
+ *  AlphaConstant : Function is (alpha_constant * src) +
+ *                  (1 - alpha_constant) * dst)
+ *  AlphaPerPixel : Function is (alpha * src) + (1 - alpha) * dst)
+ *  Alternate     : Function is alternating pixels from src and dst
+ *  And           : Function is (src & dst)
+ *  Or            : Function is (src | dst)
+ *  Invert        : Function is ~src
+ */
+typedef enum OMX_COLORBLENDTYPE {
+    OMX_ColorBlendNone,
+    OMX_ColorBlendAlphaConstant,
+    OMX_ColorBlendAlphaPerPixel,
+    OMX_ColorBlendAlternate,
+    OMX_ColorBlendAnd,
+    OMX_ColorBlendOr,
+    OMX_ColorBlendInvert,
+    OMX_ColorBlendKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_ColorBlendVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_ColorBlendMax = 0x7FFFFFFF
+} OMX_COLORBLENDTYPE;
+
+
+/**
+ * Color blend configuration
+ *
+ * STRUCT MEMBERS:
+ *  nSize             : Size of the structure in bytes
+ *  nVersion          : OMX specification version information
+ *  nPortIndex        : Port that this structure applies to
+ *  nRGBAlphaConstant : Constant global alpha values when global alpha is used
+ *  eColorBlend       : Color blend type enumeration
+ */
+typedef struct OMX_CONFIG_COLORBLENDTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nRGBAlphaConstant;
+    OMX_COLORBLENDTYPE  eColorBlend;
+} OMX_CONFIG_COLORBLENDTYPE;
+
+
+/**
+ * Hold frame dimension
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  nWidth     : Frame width in pixels
+ *  nHeight    : Frame height in pixels
+ */
+typedef struct OMX_FRAMESIZETYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nWidth;
+    OMX_U32 nHeight;
+} OMX_FRAMESIZETYPE;
+
+
+/**
+ * Rotation configuration
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  nRotation  : +/- integer rotation value
+ */
+typedef struct OMX_CONFIG_ROTATIONTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_S32 nRotation;
+} OMX_CONFIG_ROTATIONTYPE;
+
+
+/**
+ * Possible mirroring directions for pre/post processing
+ *
+ * ENUMS:
+ *  None       : No mirroring
+ *  Vertical   : Vertical mirroring, flip on X axis
+ *  Horizontal : Horizontal mirroring, flip on Y axis
+ *  Both       : Both vertical and horizontal mirroring
+ */
+typedef enum OMX_MIRRORTYPE {
+    OMX_MirrorNone = 0,
+    OMX_MirrorVertical,
+    OMX_MirrorHorizontal,
+    OMX_MirrorBoth,
+    OMX_MirrorKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_MirrorVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_MirrorMax = 0x7FFFFFFF
+} OMX_MIRRORTYPE;
+
+
+/**
+ * Mirroring configuration
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  eMirror    : Mirror type enumeration
+ */
+typedef struct OMX_CONFIG_MIRRORTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_MIRRORTYPE  eMirror;
+} OMX_CONFIG_MIRRORTYPE;
+
+
+/**
+ * Position information only
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  nX         : X coordinate for the point
+ *  nY         : Y coordinate for the point
+ */
+typedef struct OMX_CONFIG_POINTTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_S32 nX;
+    OMX_S32 nY;
+} OMX_CONFIG_POINTTYPE;
+
+
+/**
+ * Frame size plus position
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  nLeft      : X Coordinate of the top left corner of the rectangle
+ *  nTop       : Y Coordinate of the top left corner of the rectangle
+ *  nWidth     : Width of the rectangle
+ *  nHeight    : Height of the rectangle
+ */
+typedef struct OMX_CONFIG_RECTTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_S32 nLeft;
+    OMX_S32 nTop;
+    OMX_U32 nWidth;
+    OMX_U32 nHeight;
+} OMX_CONFIG_RECTTYPE;
+
+
+/**
+ * Deblocking state; it is required to be set up before starting the codec
+ *
+ * STRUCT MEMBERS:
+ *  nSize       : Size of the structure in bytes
+ *  nVersion    : OMX specification version information
+ *  nPortIndex  : Port that this structure applies to
+ *  bDeblocking : Enable/disable deblocking mode
+ */
+typedef struct OMX_PARAM_DEBLOCKINGTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL bDeblocking;
+} OMX_PARAM_DEBLOCKINGTYPE;
+
+
+/**
+ * Stabilization state
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  bStab      : Enable/disable frame stabilization state
+ */
+typedef struct OMX_CONFIG_FRAMESTABTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL bStab;
+} OMX_CONFIG_FRAMESTABTYPE;
+
+
+/**
+ * White Balance control type
+ *
+ * STRUCT MEMBERS:
+ *  SunLight : Referenced in JSR-234
+ *  Flash    : Optimal for device's integrated flash
+ */
+typedef enum OMX_WHITEBALCONTROLTYPE {
+    OMX_WhiteBalControlOff = 0,
+    OMX_WhiteBalControlAuto,
+    OMX_WhiteBalControlSunLight,
+    OMX_WhiteBalControlCloudy,
+    OMX_WhiteBalControlShade,
+    OMX_WhiteBalControlTungsten,
+    OMX_WhiteBalControlFluorescent,
+    OMX_WhiteBalControlIncandescent,
+    OMX_WhiteBalControlFlash,
+    OMX_WhiteBalControlHorizon,
+    OMX_WhiteBalControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_WhiteBalControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_WhiteBalControlMax = 0x7FFFFFFF
+} OMX_WHITEBALCONTROLTYPE;
+
+
+/**
+ * White Balance control configuration
+ *
+ * STRUCT MEMBERS:
+ *  nSize            : Size of the structure in bytes
+ *  nVersion         : OMX specification version information
+ *  nPortIndex       : Port that this structure applies to
+ *  eWhiteBalControl : White balance enumeration
+ */
+typedef struct OMX_CONFIG_WHITEBALCONTROLTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_WHITEBALCONTROLTYPE eWhiteBalControl;
+} OMX_CONFIG_WHITEBALCONTROLTYPE;
+
+
+/**
+ * Exposure control type
+ */
+typedef enum OMX_EXPOSURECONTROLTYPE {
+    OMX_ExposureControlOff = 0,
+    OMX_ExposureControlAuto,
+    OMX_ExposureControlNight,
+    OMX_ExposureControlBackLight,
+    OMX_ExposureControlSpotLight,
+    OMX_ExposureControlSports,
+    OMX_ExposureControlSnow,
+    OMX_ExposureControlBeach,
+    OMX_ExposureControlLargeAperture,
+    OMX_ExposureControlSmallApperture,
+    OMX_ExposureControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_ExposureControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_ExposureControlMax = 0x7FFFFFFF
+} OMX_EXPOSURECONTROLTYPE;
+
+
+/**
+ * White Balance control configuration
+ *
+ * STRUCT MEMBERS:
+ *  nSize            : Size of the structure in bytes
+ *  nVersion         : OMX specification version information
+ *  nPortIndex       : Port that this structure applies to
+ *  eExposureControl : Exposure control enumeration
+ */
+typedef struct OMX_CONFIG_EXPOSURECONTROLTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_EXPOSURECONTROLTYPE eExposureControl;
+} OMX_CONFIG_EXPOSURECONTROLTYPE;
+
+
+/**
+ * Defines sensor supported mode.
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  nFrameRate : Single shot mode is indicated by a 0
+ *  bOneShot   : Enable for single shot, disable for streaming
+ *  sFrameSize : Framesize
+ */
+typedef struct OMX_PARAM_SENSORMODETYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nFrameRate;
+    OMX_BOOL bOneShot;
+    OMX_FRAMESIZETYPE sFrameSize;
+} OMX_PARAM_SENSORMODETYPE;
+
+
+/**
+ * Defines contrast level
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  nContrast  : Values allowed for contrast -100 to 100, zero means no change
+ */
+typedef struct OMX_CONFIG_CONTRASTTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_S32 nContrast;
+} OMX_CONFIG_CONTRASTTYPE;
+
+
+/**
+ * Defines brightness level
+ *
+ * STRUCT MEMBERS:
+ *  nSize       : Size of the structure in bytes
+ *  nVersion    : OMX specification version information
+ *  nPortIndex  : Port that this structure applies to
+ *  nBrightness : 0-100%
+ */
+typedef struct OMX_CONFIG_BRIGHTNESSTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nBrightness;
+} OMX_CONFIG_BRIGHTNESSTYPE;
+
+
+/**
+ * Defines backlight level configuration for a video sink, e.g. LCD panel
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  nBacklight : Values allowed for backlight 0-100%
+ *  nTimeout   : Number of milliseconds before backlight automatically turns
+ *               off.  A value of 0x0 disables backight timeout
+ */
+typedef struct OMX_CONFIG_BACKLIGHTTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nBacklight;
+    OMX_U32 nTimeout;
+} OMX_CONFIG_BACKLIGHTTYPE;
+
+
+/**
+ * Defines setting for Gamma
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  nGamma     : Values allowed for gamma -100 to 100, zero means no change
+ */
+typedef struct OMX_CONFIG_GAMMATYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_S32 nGamma;
+} OMX_CONFIG_GAMMATYPE;
+
+
+/**
+ * Define for setting saturation
+ *
+ * STRUCT MEMBERS:
+ *  nSize       : Size of the structure in bytes
+ *  nVersion    : OMX specification version information
+ *  nPortIndex  : Port that this structure applies to
+ *  nSaturation : Values allowed for saturation -100 to 100, zero means
+ *                no change
+ */
+typedef struct OMX_CONFIG_SATURATIONTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_S32 nSaturation;
+} OMX_CONFIG_SATURATIONTYPE;
+
+
+/**
+ * Define for setting Lightness
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  nLightness : Values allowed for lightness -100 to 100, zero means no
+ *               change
+ */
+typedef struct OMX_CONFIG_LIGHTNESSTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_S32 nLightness;
+} OMX_CONFIG_LIGHTNESSTYPE;
+
+
+/**
+ * Plane blend configuration
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Index of input port associated with the plane.
+ *  nDepth     : Depth of the plane in relation to the screen. Higher
+ *               numbered depths are "behind" lower number depths.
+ *               This number defaults to the Port Index number.
+ *  nAlpha     : Transparency blending component for the entire plane.
+ *               See blending modes for more detail.
+ */
+typedef struct OMX_CONFIG_PLANEBLENDTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nDepth;
+    OMX_U32 nAlpha;
+} OMX_CONFIG_PLANEBLENDTYPE;
+
+
+/**
+ * Define interlace type
+ *
+ * STRUCT MEMBERS:
+ *  nSize                 : Size of the structure in bytes
+ *  nVersion              : OMX specification version information
+ *  nPortIndex            : Port that this structure applies to
+ *  bEnable               : Enable control variable for this functionality
+ *                          (see below)
+ *  nInterleavePortIndex  : Index of input or output port associated with
+ *                          the interleaved plane.
+ *  pPlanarPortIndexes[4] : Index of input or output planar ports.
+ */
+typedef struct OMX_PARAM_INTERLEAVETYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL bEnable;
+    OMX_U32 nInterleavePortIndex;
+} OMX_PARAM_INTERLEAVETYPE;
+
+
+/**
+ * Defines the picture effect used for an input picture
+ */
+typedef enum OMX_TRANSITIONEFFECTTYPE {
+    OMX_EffectNone,
+    OMX_EffectFadeFromBlack,
+    OMX_EffectFadeToBlack,
+    OMX_EffectUnspecifiedThroughConstantColor,
+    OMX_EffectDissolve,
+    OMX_EffectWipe,
+    OMX_EffectUnspecifiedMixOfTwoScenes,
+    OMX_EffectKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_EffectVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_EffectMax = 0x7FFFFFFF
+} OMX_TRANSITIONEFFECTTYPE;
+
+
+/**
+ * Structure used to configure current transition effect
+ *
+ * STRUCT MEMBERS:
+ * nSize      : Size of the structure in bytes
+ * nVersion   : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * eEffect    : Effect to enable
+ */
+typedef struct OMX_CONFIG_TRANSITIONEFFECTTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_TRANSITIONEFFECTTYPE eEffect;
+} OMX_CONFIG_TRANSITIONEFFECTTYPE;
+
+
+/**
+ * Defines possible data unit types for encoded video data. The data unit
+ * types are used both for encoded video input for playback as well as
+ * encoded video output from recording.
+ */
+typedef enum OMX_DATAUNITTYPE {
+    OMX_DataUnitCodedPicture,
+    OMX_DataUnitVideoSegment,
+    OMX_DataUnitSeveralSegments,
+    OMX_DataUnitArbitraryStreamSection,
+    OMX_DataUnitKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_DataUnitVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_DataUnitMax = 0x7FFFFFFF
+} OMX_DATAUNITTYPE;
+
+
+/**
+ * Defines possible encapsulation types for coded video data unit. The
+ * encapsulation information is used both for encoded video input for
+ * playback as well as encoded video output from recording.
+ */
+typedef enum OMX_DATAUNITENCAPSULATIONTYPE {
+    OMX_DataEncapsulationElementaryStream,
+    OMX_DataEncapsulationGenericPayload,
+    OMX_DataEncapsulationRtpPayload,
+    OMX_DataEncapsulationKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_DataEncapsulationVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_DataEncapsulationMax = 0x7FFFFFFF
+} OMX_DATAUNITENCAPSULATIONTYPE;
+
+
+/**
+ * Structure used to configure the type of being decoded/encoded
+ */
+typedef struct OMX_PARAM_DATAUNITTYPE {
+    OMX_U32 nSize;            /**< Size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_U32 nPortIndex;       /**< Port that this structure applies to */
+    OMX_DATAUNITTYPE eUnitType;
+    OMX_DATAUNITENCAPSULATIONTYPE eEncapsulationType;
+} OMX_PARAM_DATAUNITTYPE;
+
+
+/**
+ * Defines dither types
+ */
+typedef enum OMX_DITHERTYPE {
+    OMX_DitherNone,
+    OMX_DitherOrdered,
+    OMX_DitherErrorDiffusion,
+    OMX_DitherOther,
+    OMX_DitherKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_DitherVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_DitherMax = 0x7FFFFFFF
+} OMX_DITHERTYPE;
+
+
+/**
+ * Structure used to configure current type of dithering
+ */
+typedef struct OMX_CONFIG_DITHERTYPE {
+    OMX_U32 nSize;            /**< Size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_U32 nPortIndex;       /**< Port that this structure applies to */
+    OMX_DITHERTYPE eDither;   /**< Type of dithering to use */
+} OMX_CONFIG_DITHERTYPE;
+
+typedef struct OMX_CONFIG_CAPTUREMODETYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;     /**< Port that this structure applies to */
+    OMX_BOOL bContinuous;   /**< If true then ignore frame rate and emit capture
+                             *   data as fast as possible (otherwise obey port's frame rate). */
+    OMX_BOOL bFrameLimited; /**< If true then terminate capture after the port emits the
+                             *   specified number of frames (otherwise the port does not
+                             *   terminate the capture until instructed to do so by the client).
+                             *   Even if set, the client may manually terminate the capture prior
+                             *   to reaching the limit. */
+    OMX_U32 nFrameLimit;      /**< Limit on number of frames emitted during a capture (only
+                               *   valid if bFrameLimited is set). */
+} OMX_CONFIG_CAPTUREMODETYPE;
+
+typedef enum OMX_METERINGTYPE {
+
+    OMX_MeteringModeAverage,     /**< Center-weighted average metering. */
+    OMX_MeteringModeSpot,         /**< Spot (partial) metering. */
+    OMX_MeteringModeMatrix,      /**< Matrix or evaluative metering. */
+
+    OMX_MeteringKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_MeteringVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_EVModeMax = 0x7fffffff
+} OMX_METERINGTYPE;
+
+typedef struct OMX_CONFIG_EXPOSUREVALUETYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_METERINGTYPE eMetering;
+    OMX_S32 xEVCompensation;      /**< Fixed point value stored as Q16 */
+    OMX_U32 nApertureFNumber;     /**< e.g. nApertureFNumber = 2 implies "f/2" - Q16 format */
+    OMX_BOOL bAutoAperture;     /**< Whether aperture number is defined automatically */
+    OMX_U32 nShutterSpeedMsec;    /**< Shutterspeed in milliseconds */
+    OMX_BOOL bAutoShutterSpeed; /**< Whether shutter speed is defined automatically */
+    OMX_U32 nSensitivity;         /**< e.g. nSensitivity = 100 implies "ISO 100" */
+    OMX_BOOL bAutoSensitivity;  /**< Whether sensitivity is defined automatically */
+} OMX_CONFIG_EXPOSUREVALUETYPE;
+
+/**
+ * Focus region configuration
+ *
+ * STRUCT MEMBERS:
+ *  nSize           : Size of the structure in bytes
+ *  nVersion        : OMX specification version information
+ *  nPortIndex      : Port that this structure applies to
+ *  bCenter         : Use center region as focus region of interest
+ *  bLeft           : Use left region as focus region of interest
+ *  bRight          : Use right region as focus region of interest
+ *  bTop            : Use top region as focus region of interest
+ *  bBottom         : Use bottom region as focus region of interest
+ *  bTopLeft        : Use top left region as focus region of interest
+ *  bTopRight       : Use top right region as focus region of interest
+ *  bBottomLeft     : Use bottom left region as focus region of interest
+ *  bBottomRight    : Use bottom right region as focus region of interest
+ */
+typedef struct OMX_CONFIG_FOCUSREGIONTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL bCenter;
+    OMX_BOOL bLeft;
+    OMX_BOOL bRight;
+    OMX_BOOL bTop;
+    OMX_BOOL bBottom;
+    OMX_BOOL bTopLeft;
+    OMX_BOOL bTopRight;
+    OMX_BOOL bBottomLeft;
+    OMX_BOOL bBottomRight;
+} OMX_CONFIG_FOCUSREGIONTYPE;
+
+/**
+ * Focus Status type
+ */
+typedef enum OMX_FOCUSSTATUSTYPE {
+    OMX_FocusStatusOff = 0,
+    OMX_FocusStatusRequest,
+    OMX_FocusStatusReached,
+    OMX_FocusStatusUnableToReach,
+    OMX_FocusStatusLost,
+    OMX_FocusStatusKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_FocusStatusVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_FocusStatusMax = 0x7FFFFFFF
+} OMX_FOCUSSTATUSTYPE;
+
+/**
+ * Focus status configuration
+ *
+ * STRUCT MEMBERS:
+ *  nSize               : Size of the structure in bytes
+ *  nVersion            : OMX specification version information
+ *  nPortIndex          : Port that this structure applies to
+ *  eFocusStatus        : Specifies the focus status
+ *  bCenterStatus       : Use center region as focus region of interest
+ *  bLeftStatus         : Use left region as focus region of interest
+ *  bRightStatus        : Use right region as focus region of interest
+ *  bTopStatus          : Use top region as focus region of interest
+ *  bBottomStatus       : Use bottom region as focus region of interest
+ *  bTopLeftStatus      : Use top left region as focus region of interest
+ *  bTopRightStatus     : Use top right region as focus region of interest
+ *  bBottomLeftStatus   : Use bottom left region as focus region of interest
+ *  bBottomRightStatus  : Use bottom right region as focus region of interest
+ */
+typedef struct OMX_PARAM_FOCUSSTATUSTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_FOCUSSTATUSTYPE eFocusStatus;
+    OMX_BOOL bCenterStatus;
+    OMX_BOOL bLeftStatus;
+    OMX_BOOL bRightStatus;
+    OMX_BOOL bTopStatus;
+    OMX_BOOL bBottomStatus;
+    OMX_BOOL bTopLeftStatus;
+    OMX_BOOL bTopRightStatus;
+    OMX_BOOL bBottomLeftStatus;
+    OMX_BOOL bBottomRightStatus;
+} OMX_PARAM_FOCUSSTATUSTYPE;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */

+ 328 - 0
omx-il/include/khronos/OMX_Image.h

@@ -0,0 +1,328 @@
+/**
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file OMX_Image.h - OpenMax IL version 1.1.2
+ * The structures needed by Image components to exchange parameters and
+ * configuration data with the components.
+ */
+#ifndef OMX_Image_h
+#define OMX_Image_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/**
+ * Each OMX header must include all required header files to allow the
+ * header to compile without errors.  The includes below are required
+ * for this header file to compile successfully
+ */
+
+#include <OMX_IVCommon.h>
+
+/** @defgroup imaging OpenMAX IL Imaging Domain
+ * @ingroup iv
+ * Structures for OpenMAX IL Imaging domain
+ * @{
+ */
+
+/**
+ * Enumeration used to define the possible image compression coding.
+ */
+typedef enum OMX_IMAGE_CODINGTYPE {
+    OMX_IMAGE_CodingUnused,      /**< Value when format is N/A */
+    OMX_IMAGE_CodingAutoDetect,  /**< Auto detection of image format */
+    OMX_IMAGE_CodingJPEG,        /**< JPEG/JFIF image format */
+    OMX_IMAGE_CodingJPEG2K,      /**< JPEG 2000 image format */
+    OMX_IMAGE_CodingEXIF,        /**< EXIF image format */
+    OMX_IMAGE_CodingTIFF,        /**< TIFF image format */
+    OMX_IMAGE_CodingGIF,         /**< Graphics image format */
+    OMX_IMAGE_CodingPNG,         /**< PNG image format */
+    OMX_IMAGE_CodingLZW,         /**< LZW image format */
+    OMX_IMAGE_CodingBMP,         /**< Windows Bitmap format */
+    OMX_IMAGE_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_IMAGE_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_IMAGE_CodingMax = 0x7FFFFFFF
+} OMX_IMAGE_CODINGTYPE;
+
+
+/**
+ * Data structure used to define an image path. The number of image paths
+ * for input and output will vary by type of the image component.
+ *
+ *  Input (aka Source) : Zero Inputs, one Output,
+ *  Splitter           : One Input, 2 or more Outputs,
+ *  Processing Element : One Input, one output,
+ *  Mixer              : 2 or more inputs, one output,
+ *  Output (aka Sink)  : One Input, zero outputs.
+ *
+ * The PortDefinition structure is used to define all of the parameters
+ * necessary for the compliant component to setup an input or an output
+ * image path.  If additional vendor specific data is required, it should
+ * be transmitted to the component using the CustomCommand function.
+ * Compliant components will prepopulate this structure with optimal
+ * values during the OMX_GetParameter() command.
+ *
+ * STRUCT MEMBERS:
+ *  cMIMEType             : MIME type of data for the port
+ *  pNativeRender         : Platform specific reference for a display if a
+ *                          sync, otherwise this field is 0
+ *  nFrameWidth           : Width of frame to be used on port if
+ *                          uncompressed format is used.  Use 0 for
+ *                          unknown, don't care or variable
+ *  nFrameHeight          : Height of frame to be used on port if
+ *                          uncompressed format is used. Use 0 for
+ *                          unknown, don't care or variable
+ *  nStride               : Number of bytes per span of an image (i.e.
+ *                          indicates the number of bytes to get from
+ *                          span N to span N+1, where negative stride
+ *                          indicates the image is bottom up
+ *  nSliceHeight          : Height used when encoding in slices
+ *  bFlagErrorConcealment : Turns on error concealment if it is supported by
+ *                          the OMX component
+ *  eCompressionFormat    : Compression format used in this instance of
+ *                          the component. When OMX_IMAGE_CodingUnused is
+ *                          specified, eColorFormat is valid
+ *  eColorFormat          : Decompressed format used by this component
+ *  pNativeWindow         : Platform specific reference for a window object if a
+ *                          display sink , otherwise this field is 0x0.
+ */
+typedef struct OMX_IMAGE_PORTDEFINITIONTYPE {
+    OMX_STRING cMIMEType;
+    OMX_NATIVE_DEVICETYPE pNativeRender;
+    OMX_U32 nFrameWidth;
+    OMX_U32 nFrameHeight;
+    OMX_S32 nStride;
+    OMX_U32 nSliceHeight;
+    OMX_BOOL bFlagErrorConcealment;
+    OMX_IMAGE_CODINGTYPE eCompressionFormat;
+    OMX_COLOR_FORMATTYPE eColorFormat;
+    OMX_NATIVE_WINDOWTYPE pNativeWindow;
+} OMX_IMAGE_PORTDEFINITIONTYPE;
+
+
+/**
+ * Port format parameter.  This structure is used to enumerate the various
+ * data input/output format supported by the port.
+ *
+ * STRUCT MEMBERS:
+ *  nSize              : Size of the structure in bytes
+ *  nVersion           : OMX specification version information
+ *  nPortIndex         : Indicates which port to set
+ *  nIndex             : Indicates the enumeration index for the format from
+ *                       0x0 to N-1
+ *  eCompressionFormat : Compression format used in this instance of the
+ *                       component. When OMX_IMAGE_CodingUnused is specified,
+ *                       eColorFormat is valid
+ *  eColorFormat       : Decompressed format used by this component
+ */
+typedef struct OMX_IMAGE_PARAM_PORTFORMATTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nIndex;
+    OMX_IMAGE_CODINGTYPE eCompressionFormat;
+    OMX_COLOR_FORMATTYPE eColorFormat;
+} OMX_IMAGE_PARAM_PORTFORMATTYPE;
+
+
+/**
+ * Flash control type
+ *
+ * ENUMS
+ *  Torch : Flash forced constantly on
+ */
+typedef enum OMX_IMAGE_FLASHCONTROLTYPE {
+    OMX_IMAGE_FlashControlOn = 0,
+    OMX_IMAGE_FlashControlOff,
+    OMX_IMAGE_FlashControlAuto,
+    OMX_IMAGE_FlashControlRedEyeReduction,
+    OMX_IMAGE_FlashControlFillin,
+    OMX_IMAGE_FlashControlTorch,
+    OMX_IMAGE_FlashControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_IMAGE_FlashControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_IMAGE_FlashControlMax = 0x7FFFFFFF
+} OMX_IMAGE_FLASHCONTROLTYPE;
+
+
+/**
+ * Flash control configuration
+ *
+ * STRUCT MEMBERS:
+ *  nSize         : Size of the structure in bytes
+ *  nVersion      : OMX specification version information
+ *  nPortIndex    : Port that this structure applies to
+ *  eFlashControl : Flash control type
+ */
+typedef struct OMX_IMAGE_PARAM_FLASHCONTROLTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_IMAGE_FLASHCONTROLTYPE eFlashControl;
+} OMX_IMAGE_PARAM_FLASHCONTROLTYPE;
+
+
+/**
+ * Focus control type
+ */
+typedef enum OMX_IMAGE_FOCUSCONTROLTYPE {
+    OMX_IMAGE_FocusControlOn = 0,
+    OMX_IMAGE_FocusControlOff,
+    OMX_IMAGE_FocusControlAuto,
+    OMX_IMAGE_FocusControlAutoLock,
+    OMX_IMAGE_FocusControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_IMAGE_FocusControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_IMAGE_FocusControlMax = 0x7FFFFFFF
+} OMX_IMAGE_FOCUSCONTROLTYPE;
+
+
+/**
+ * Focus control configuration
+ *
+ * STRUCT MEMBERS:
+ *  nSize           : Size of the structure in bytes
+ *  nVersion        : OMX specification version information
+ *  nPortIndex      : Port that this structure applies to
+ *  eFocusControl   : Focus control
+ *  nFocusSteps     : Focus can take on values from 0 mm to infinity.
+ *                    Interest is only in number of steps over this range.
+ *  nFocusStepIndex : Current focus step index
+ */
+typedef struct OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_IMAGE_FOCUSCONTROLTYPE eFocusControl;
+    OMX_U32 nFocusSteps;
+    OMX_U32 nFocusStepIndex;
+} OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE;
+
+
+/**
+ * Q Factor for JPEG compression, which controls the tradeoff between image
+ * quality and size.  Q Factor provides a more simple means of controlling
+ * JPEG compression quality, without directly programming Quantization
+ * tables for chroma and luma
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  nQFactor   : JPEG Q factor value in the range of 1-100. A factor of 1
+ *               produces the smallest, worst quality images, and a factor
+ *               of 100 produces the largest, best quality images.  A
+ *               typical default is 75 for small good quality images
+ */
+typedef struct OMX_IMAGE_PARAM_QFACTORTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nQFactor;
+} OMX_IMAGE_PARAM_QFACTORTYPE;
+
+/**
+ * Quantization table type
+ */
+
+typedef enum OMX_IMAGE_QUANTIZATIONTABLETYPE {
+    OMX_IMAGE_QuantizationTableLuma = 0,
+    OMX_IMAGE_QuantizationTableChroma,
+    OMX_IMAGE_QuantizationTableChromaCb,
+    OMX_IMAGE_QuantizationTableChromaCr,
+    OMX_IMAGE_QuantizationTableKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_IMAGE_QuantizationTableVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_IMAGE_QuantizationTableMax = 0x7FFFFFFF
+} OMX_IMAGE_QUANTIZATIONTABLETYPE;
+
+/**
+ * JPEG quantization tables are used to determine DCT compression for
+ * YUV data, as an alternative to specifying Q factor, providing exact
+ * control of compression
+ *
+ * STRUCT MEMBERS:
+ *  nSize                   : Size of the structure in bytes
+ *  nVersion                : OMX specification version information
+ *  nPortIndex              : Port that this structure applies to
+ *  eQuantizationTable      : Quantization table type
+ *  nQuantizationMatrix[64] : JPEG quantization table of coefficients stored
+ *                            in increasing columns then by rows of data (i.e.
+ *                            row 1, ... row 8). Quantization values are in
+ *                            the range 0-255 and stored in linear order
+ *                            (i.e. the component will zig-zag the
+ *                            quantization table data if required internally)
+ */
+typedef struct OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_IMAGE_QUANTIZATIONTABLETYPE eQuantizationTable;
+    OMX_U8 nQuantizationMatrix[64];
+} OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE;
+
+
+/**
+ * Huffman table type, the same Huffman table is applied for chroma and
+ * luma component
+ */
+typedef enum OMX_IMAGE_HUFFMANTABLETYPE {
+    OMX_IMAGE_HuffmanTableAC = 0,
+    OMX_IMAGE_HuffmanTableDC,
+    OMX_IMAGE_HuffmanTableACLuma,
+    OMX_IMAGE_HuffmanTableACChroma,
+    OMX_IMAGE_HuffmanTableDCLuma,
+    OMX_IMAGE_HuffmanTableDCChroma,
+    OMX_IMAGE_HuffmanTableKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_IMAGE_HuffmanTableVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_IMAGE_HuffmanTableMax = 0x7FFFFFFF
+} OMX_IMAGE_HUFFMANTABLETYPE;
+
+/**
+ * JPEG Huffman table
+ *
+ * STRUCT MEMBERS:
+ *  nSize                            : Size of the structure in bytes
+ *  nVersion                         : OMX specification version information
+ *  nPortIndex                       : Port that this structure applies to
+ *  eHuffmanTable                    : Huffman table type
+ *  nNumberOfHuffmanCodeOfLength[16] : 0-16, number of Huffman codes of each
+ *                                     possible length
+ *  nHuffmanTable[256]               : 0-255, the size used for AC and DC
+ *                                     HuffmanTable are 16 and 162
+ */
+typedef struct OMX_IMAGE_PARAM_HUFFMANTTABLETYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_IMAGE_HUFFMANTABLETYPE eHuffmanTable;
+    OMX_U8 nNumberOfHuffmanCodeOfLength[16];
+    OMX_U8 nHuffmanTable[256];
+} OMX_IMAGE_PARAM_HUFFMANTTABLETYPE;
+
+/** @} */
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */

+ 55 - 0
omx-il/include/khronos/OMX_ImageExt.h

@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** OMX_ImageExt.h - OpenMax IL version 1.1.2
+ * The OMX_ImageExt header file contains extensions to the
+ * definitions used by both the application and the component to
+ * access image items.
+ */
+
+#ifndef OMX_ImageExt_h
+#define OMX_ImageExt_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Each OMX header shall include all required header files to allow the
+ * header to compile without errors.  The includes below are required
+ * for this header file to compile successfully
+ */
+#include <OMX_Core.h>
+
+/** Enum for standard image codingtype extensions */
+typedef enum OMX_IMAGE_CODINGEXTTYPE {
+    OMX_IMAGE_CodingExtUnused = OMX_IMAGE_CodingKhronosExtensions,
+    OMX_IMAGE_CodingWEBP,         /**< WebP image format */
+} OMX_IMAGE_CODINGEXTTYPE;
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* OMX_ImageExt_h */
+/* File EOF */

+ 260 - 0
omx-il/include/khronos/OMX_Index.h

@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** @file OMX_Index.h - OpenMax IL version 1.1.2
+ *  The OMX_Index header file contains the definitions for both applications
+ *  and components .
+ */
+
+
+#ifndef OMX_Index_h
+#define OMX_Index_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* Each OMX header must include all required header files to allow the
+ *  header to compile without errors.  The includes below are required
+ *  for this header file to compile successfully
+ */
+#include <OMX_Types.h>
+
+
+/** The OMX_INDEXTYPE enumeration is used to select a structure when either
+ *  getting or setting parameters and/or configuration data.  Each entry in
+ *  this enumeration maps to an OMX specified structure.  When the
+ *  OMX_GetParameter, OMX_SetParameter, OMX_GetConfig or OMX_SetConfig methods
+ *  are used, the second parameter will always be an entry from this enumeration
+ *  and the third entry will be the structure shown in the comments for the entry.
+ *  For example, if the application is initializing a cropping function, the
+ *  OMX_SetConfig command would have OMX_IndexConfigCommonInputCrop as the second parameter
+ *  and would send a pointer to an initialized OMX_RECTTYPE structure as the
+ *  third parameter.
+ *
+ *  The enumeration entries named with the OMX_Config prefix are sent using
+ *  the OMX_SetConfig command and the enumeration entries named with the
+ *  OMX_PARAM_ prefix are sent using the OMX_SetParameter command.
+ */
+typedef enum OMX_INDEXTYPE {
+
+    OMX_IndexComponentStartUnused = 0x01000000,
+    OMX_IndexParamPriorityMgmt,             /**< reference: OMX_PRIORITYMGMTTYPE */
+    OMX_IndexParamAudioInit,                /**< reference: OMX_PORT_PARAM_TYPE */
+    OMX_IndexParamImageInit,                /**< reference: OMX_PORT_PARAM_TYPE */
+    OMX_IndexParamVideoInit,                /**< reference: OMX_PORT_PARAM_TYPE */
+    OMX_IndexParamOtherInit,                /**< reference: OMX_PORT_PARAM_TYPE */
+    OMX_IndexParamNumAvailableStreams,      /**< reference: OMX_PARAM_U32TYPE */
+    OMX_IndexParamActiveStream,             /**< reference: OMX_PARAM_U32TYPE */
+    OMX_IndexParamSuspensionPolicy,         /**< reference: OMX_PARAM_SUSPENSIONPOLICYTYPE */
+    OMX_IndexParamComponentSuspended,       /**< reference: OMX_PARAM_SUSPENSIONTYPE */
+    OMX_IndexConfigCapturing,               /**< reference: OMX_CONFIG_BOOLEANTYPE */
+    OMX_IndexConfigCaptureMode,             /**< reference: OMX_CONFIG_CAPTUREMODETYPE */
+    OMX_IndexAutoPauseAfterCapture,         /**< reference: OMX_CONFIG_BOOLEANTYPE */
+    OMX_IndexParamContentURI,               /**< reference: OMX_PARAM_CONTENTURITYPE */
+    OMX_IndexParamCustomContentPipe,        /**< reference: OMX_PARAM_CONTENTPIPETYPE */
+    OMX_IndexParamDisableResourceConcealment, /**< reference: OMX_RESOURCECONCEALMENTTYPE */
+    OMX_IndexConfigMetadataItemCount,       /**< reference: OMX_CONFIG_METADATAITEMCOUNTTYPE */
+    OMX_IndexConfigContainerNodeCount,      /**< reference: OMX_CONFIG_CONTAINERNODECOUNTTYPE */
+    OMX_IndexConfigMetadataItem,            /**< reference: OMX_CONFIG_METADATAITEMTYPE */
+    OMX_IndexConfigCounterNodeID,           /**< reference: OMX_CONFIG_CONTAINERNODEIDTYPE */
+    OMX_IndexParamMetadataFilterType,       /**< reference: OMX_PARAM_METADATAFILTERTYPE */
+    OMX_IndexParamMetadataKeyFilter,        /**< reference: OMX_PARAM_METADATAFILTERTYPE */
+    OMX_IndexConfigPriorityMgmt,            /**< reference: OMX_PRIORITYMGMTTYPE */
+    OMX_IndexParamStandardComponentRole,    /**< reference: OMX_PARAM_COMPONENTROLETYPE */
+
+    OMX_IndexPortStartUnused = 0x02000000,
+    OMX_IndexParamPortDefinition,           /**< reference: OMX_PARAM_PORTDEFINITIONTYPE */
+    OMX_IndexParamCompBufferSupplier,       /**< reference: OMX_PARAM_BUFFERSUPPLIERTYPE */
+    OMX_IndexReservedStartUnused = 0x03000000,
+
+    /* Audio parameters and configurations */
+    OMX_IndexAudioStartUnused = 0x04000000,
+    OMX_IndexParamAudioPortFormat,          /**< reference: OMX_AUDIO_PARAM_PORTFORMATTYPE */
+    OMX_IndexParamAudioPcm,                 /**< reference: OMX_AUDIO_PARAM_PCMMODETYPE */
+    OMX_IndexParamAudioAac,                 /**< reference: OMX_AUDIO_PARAM_AACPROFILETYPE */
+    OMX_IndexParamAudioRa,                  /**< reference: OMX_AUDIO_PARAM_RATYPE */
+    OMX_IndexParamAudioMp3,                 /**< reference: OMX_AUDIO_PARAM_MP3TYPE */
+    OMX_IndexParamAudioAdpcm,               /**< reference: OMX_AUDIO_PARAM_ADPCMTYPE */
+    OMX_IndexParamAudioG723,                /**< reference: OMX_AUDIO_PARAM_G723TYPE */
+    OMX_IndexParamAudioG729,                /**< reference: OMX_AUDIO_PARAM_G729TYPE */
+    OMX_IndexParamAudioAmr,                 /**< reference: OMX_AUDIO_PARAM_AMRTYPE */
+    OMX_IndexParamAudioWma,                 /**< reference: OMX_AUDIO_PARAM_WMATYPE */
+    OMX_IndexParamAudioSbc,                 /**< reference: OMX_AUDIO_PARAM_SBCTYPE */
+    OMX_IndexParamAudioMidi,                /**< reference: OMX_AUDIO_PARAM_MIDITYPE */
+    OMX_IndexParamAudioGsm_FR,              /**< reference: OMX_AUDIO_PARAM_GSMFRTYPE */
+    OMX_IndexParamAudioMidiLoadUserSound,   /**< reference: OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE */
+    OMX_IndexParamAudioG726,                /**< reference: OMX_AUDIO_PARAM_G726TYPE */
+    OMX_IndexParamAudioGsm_EFR,             /**< reference: OMX_AUDIO_PARAM_GSMEFRTYPE */
+    OMX_IndexParamAudioGsm_HR,              /**< reference: OMX_AUDIO_PARAM_GSMHRTYPE */
+    OMX_IndexParamAudioPdc_FR,              /**< reference: OMX_AUDIO_PARAM_PDCFRTYPE */
+    OMX_IndexParamAudioPdc_EFR,             /**< reference: OMX_AUDIO_PARAM_PDCEFRTYPE */
+    OMX_IndexParamAudioPdc_HR,              /**< reference: OMX_AUDIO_PARAM_PDCHRTYPE */
+    OMX_IndexParamAudioTdma_FR,             /**< reference: OMX_AUDIO_PARAM_TDMAFRTYPE */
+    OMX_IndexParamAudioTdma_EFR,            /**< reference: OMX_AUDIO_PARAM_TDMAEFRTYPE */
+    OMX_IndexParamAudioQcelp8,              /**< reference: OMX_AUDIO_PARAM_QCELP8TYPE */
+    OMX_IndexParamAudioQcelp13,             /**< reference: OMX_AUDIO_PARAM_QCELP13TYPE */
+    OMX_IndexParamAudioEvrc,                /**< reference: OMX_AUDIO_PARAM_EVRCTYPE */
+    OMX_IndexParamAudioSmv,                 /**< reference: OMX_AUDIO_PARAM_SMVTYPE */
+    OMX_IndexParamAudioVorbis,              /**< reference: OMX_AUDIO_PARAM_VORBISTYPE */
+
+    OMX_IndexConfigAudioMidiImmediateEvent, /**< reference: OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE */
+    OMX_IndexConfigAudioMidiControl,        /**< reference: OMX_AUDIO_CONFIG_MIDICONTROLTYPE */
+    OMX_IndexConfigAudioMidiSoundBankProgram, /**< reference: OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE */
+    OMX_IndexConfigAudioMidiStatus,         /**< reference: OMX_AUDIO_CONFIG_MIDISTATUSTYPE */
+    OMX_IndexConfigAudioMidiMetaEvent,      /**< reference: OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE */
+    OMX_IndexConfigAudioMidiMetaEventData,  /**< reference: OMX_AUDIO_CONFIG_MIDIMETAEVENTDATATYPE */
+    OMX_IndexConfigAudioVolume,             /**< reference: OMX_AUDIO_CONFIG_VOLUMETYPE */
+    OMX_IndexConfigAudioBalance,            /**< reference: OMX_AUDIO_CONFIG_BALANCETYPE */
+    OMX_IndexConfigAudioChannelMute,        /**< reference: OMX_AUDIO_CONFIG_CHANNELMUTETYPE */
+    OMX_IndexConfigAudioMute,               /**< reference: OMX_AUDIO_CONFIG_MUTETYPE */
+    OMX_IndexConfigAudioLoudness,           /**< reference: OMX_AUDIO_CONFIG_LOUDNESSTYPE */
+    OMX_IndexConfigAudioEchoCancelation,    /**< reference: OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE */
+    OMX_IndexConfigAudioNoiseReduction,     /**< reference: OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE */
+    OMX_IndexConfigAudioBass,               /**< reference: OMX_AUDIO_CONFIG_BASSTYPE */
+    OMX_IndexConfigAudioTreble,             /**< reference: OMX_AUDIO_CONFIG_TREBLETYPE */
+    OMX_IndexConfigAudioStereoWidening,     /**< reference: OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE */
+    OMX_IndexConfigAudioChorus,             /**< reference: OMX_AUDIO_CONFIG_CHORUSTYPE */
+    OMX_IndexConfigAudioEqualizer,          /**< reference: OMX_AUDIO_CONFIG_EQUALIZERTYPE */
+    OMX_IndexConfigAudioReverberation,      /**< reference: OMX_AUDIO_CONFIG_REVERBERATIONTYPE */
+    OMX_IndexConfigAudioChannelVolume,      /**< reference: OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE */
+
+    /* Image specific parameters and configurations */
+    OMX_IndexImageStartUnused = 0x05000000,
+    OMX_IndexParamImagePortFormat,          /**< reference: OMX_IMAGE_PARAM_PORTFORMATTYPE */
+    OMX_IndexParamFlashControl,             /**< reference: OMX_IMAGE_PARAM_FLASHCONTROLTYPE */
+    OMX_IndexConfigFocusControl,            /**< reference: OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE */
+    OMX_IndexParamQFactor,                  /**< reference: OMX_IMAGE_PARAM_QFACTORTYPE */
+    OMX_IndexParamQuantizationTable,        /**< reference: OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE */
+    OMX_IndexParamHuffmanTable,             /**< reference: OMX_IMAGE_PARAM_HUFFMANTTABLETYPE */
+    OMX_IndexConfigFlashControl,            /**< reference: OMX_IMAGE_PARAM_FLASHCONTROLTYPE */
+
+    /* Video specific parameters and configurations */
+    OMX_IndexVideoStartUnused = 0x06000000,
+    OMX_IndexParamVideoPortFormat,          /**< reference: OMX_VIDEO_PARAM_PORTFORMATTYPE */
+    OMX_IndexParamVideoQuantization,        /**< reference: OMX_VIDEO_PARAM_QUANTIZATIONTYPE */
+    OMX_IndexParamVideoFastUpdate,          /**< reference: OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE */
+    OMX_IndexParamVideoBitrate,             /**< reference: OMX_VIDEO_PARAM_BITRATETYPE */
+    OMX_IndexParamVideoMotionVector,        /**< reference: OMX_VIDEO_PARAM_MOTIONVECTORTYPE */
+    OMX_IndexParamVideoIntraRefresh,        /**< reference: OMX_VIDEO_PARAM_INTRAREFRESHTYPE */
+    OMX_IndexParamVideoErrorCorrection,     /**< reference: OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE */
+    OMX_IndexParamVideoVBSMC,               /**< reference: OMX_VIDEO_PARAM_VBSMCTYPE */
+    OMX_IndexParamVideoMpeg2,               /**< reference: OMX_VIDEO_PARAM_MPEG2TYPE */
+    OMX_IndexParamVideoMpeg4,               /**< reference: OMX_VIDEO_PARAM_MPEG4TYPE */
+    OMX_IndexParamVideoWmv,                 /**< reference: OMX_VIDEO_PARAM_WMVTYPE */
+    OMX_IndexParamVideoRv,                  /**< reference: OMX_VIDEO_PARAM_RVTYPE */
+    OMX_IndexParamVideoAvc,                 /**< reference: OMX_VIDEO_PARAM_AVCTYPE */
+    OMX_IndexParamVideoH263,                /**< reference: OMX_VIDEO_PARAM_H263TYPE */
+    OMX_IndexParamVideoProfileLevelQuerySupported, /**< reference: OMX_VIDEO_PARAM_PROFILELEVELTYPE */
+    OMX_IndexParamVideoProfileLevelCurrent, /**< reference: OMX_VIDEO_PARAM_PROFILELEVELTYPE */
+    OMX_IndexConfigVideoBitrate,            /**< reference: OMX_VIDEO_CONFIG_BITRATETYPE */
+    OMX_IndexConfigVideoFramerate,          /**< reference: OMX_CONFIG_FRAMERATETYPE */
+    OMX_IndexConfigVideoIntraVOPRefresh,    /**< reference: OMX_CONFIG_INTRAREFRESHVOPTYPE */
+    OMX_IndexConfigVideoIntraMBRefresh,     /**< reference: OMX_CONFIG_MACROBLOCKERRORMAPTYPE */
+    OMX_IndexConfigVideoMBErrorReporting,   /**< reference: OMX_CONFIG_MBERRORREPORTINGTYPE */
+    OMX_IndexParamVideoMacroblocksPerFrame, /**< reference: OMX_PARAM_MACROBLOCKSTYPE */
+    OMX_IndexConfigVideoMacroBlockErrorMap, /**< reference: OMX_CONFIG_MACROBLOCKERRORMAPTYPE */
+    OMX_IndexParamVideoSliceFMO,            /**< reference: OMX_VIDEO_PARAM_AVCSLICEFMO */
+    OMX_IndexConfigVideoAVCIntraPeriod,     /**< reference: OMX_VIDEO_CONFIG_AVCINTRAPERIOD */
+    OMX_IndexConfigVideoNalSize,            /**< reference: OMX_VIDEO_CONFIG_NALSIZE */
+
+    /* Image & Video common Configurations */
+    OMX_IndexCommonStartUnused = 0x07000000,
+    OMX_IndexParamCommonDeblocking,         /**< reference: OMX_PARAM_DEBLOCKINGTYPE */
+    OMX_IndexParamCommonSensorMode,         /**< reference: OMX_PARAM_SENSORMODETYPE */
+    OMX_IndexParamCommonInterleave,         /**< reference: OMX_PARAM_INTERLEAVETYPE */
+    OMX_IndexConfigCommonColorFormatConversion, /**< reference: OMX_CONFIG_COLORCONVERSIONTYPE */
+    OMX_IndexConfigCommonScale,             /**< reference: OMX_CONFIG_SCALEFACTORTYPE */
+    OMX_IndexConfigCommonImageFilter,       /**< reference: OMX_CONFIG_IMAGEFILTERTYPE */
+    OMX_IndexConfigCommonColorEnhancement,  /**< reference: OMX_CONFIG_COLORENHANCEMENTTYPE */
+    OMX_IndexConfigCommonColorKey,          /**< reference: OMX_CONFIG_COLORKEYTYPE */
+    OMX_IndexConfigCommonColorBlend,        /**< reference: OMX_CONFIG_COLORBLENDTYPE */
+    OMX_IndexConfigCommonFrameStabilisation,/**< reference: OMX_CONFIG_FRAMESTABTYPE */
+    OMX_IndexConfigCommonRotate,            /**< reference: OMX_CONFIG_ROTATIONTYPE */
+    OMX_IndexConfigCommonMirror,            /**< reference: OMX_CONFIG_MIRRORTYPE */
+    OMX_IndexConfigCommonOutputPosition,    /**< reference: OMX_CONFIG_POINTTYPE */
+    OMX_IndexConfigCommonInputCrop,         /**< reference: OMX_CONFIG_RECTTYPE */
+    OMX_IndexConfigCommonOutputCrop,        /**< reference: OMX_CONFIG_RECTTYPE */
+    OMX_IndexConfigCommonDigitalZoom,       /**< reference: OMX_CONFIG_SCALEFACTORTYPE */
+    OMX_IndexConfigCommonOpticalZoom,       /**< reference: OMX_CONFIG_SCALEFACTORTYPE*/
+    OMX_IndexConfigCommonWhiteBalance,      /**< reference: OMX_CONFIG_WHITEBALCONTROLTYPE */
+    OMX_IndexConfigCommonExposure,          /**< reference: OMX_CONFIG_EXPOSURECONTROLTYPE */
+    OMX_IndexConfigCommonContrast,          /**< reference: OMX_CONFIG_CONTRASTTYPE */
+    OMX_IndexConfigCommonBrightness,        /**< reference: OMX_CONFIG_BRIGHTNESSTYPE */
+    OMX_IndexConfigCommonBacklight,         /**< reference: OMX_CONFIG_BACKLIGHTTYPE */
+    OMX_IndexConfigCommonGamma,             /**< reference: OMX_CONFIG_GAMMATYPE */
+    OMX_IndexConfigCommonSaturation,        /**< reference: OMX_CONFIG_SATURATIONTYPE */
+    OMX_IndexConfigCommonLightness,         /**< reference: OMX_CONFIG_LIGHTNESSTYPE */
+    OMX_IndexConfigCommonExclusionRect,     /**< reference: OMX_CONFIG_RECTTYPE */
+    OMX_IndexConfigCommonDithering,         /**< reference: OMX_CONFIG_DITHERTYPE */
+    OMX_IndexConfigCommonPlaneBlend,        /**< reference: OMX_CONFIG_PLANEBLENDTYPE */
+    OMX_IndexConfigCommonExposureValue,     /**< reference: OMX_CONFIG_EXPOSUREVALUETYPE */
+    OMX_IndexConfigCommonOutputSize,        /**< reference: OMX_FRAMESIZETYPE */
+    OMX_IndexParamCommonExtraQuantData,     /**< reference: OMX_OTHER_EXTRADATATYPE */
+    OMX_IndexConfigCommonFocusRegion,       /**< reference: OMX_CONFIG_FOCUSREGIONTYPE */
+    OMX_IndexConfigCommonFocusStatus,       /**< reference: OMX_PARAM_FOCUSSTATUSTYPE */
+    OMX_IndexConfigCommonTransitionEffect,  /**< reference: OMX_CONFIG_TRANSITIONEFFECTTYPE */
+
+    /* Reserved Configuration range */
+    OMX_IndexOtherStartUnused = 0x08000000,
+    OMX_IndexParamOtherPortFormat,          /**< reference: OMX_OTHER_PARAM_PORTFORMATTYPE */
+    OMX_IndexConfigOtherPower,              /**< reference: OMX_OTHER_CONFIG_POWERTYPE */
+    OMX_IndexConfigOtherStats,              /**< reference: OMX_OTHER_CONFIG_STATSTYPE */
+
+
+    /* Reserved Time range */
+    OMX_IndexTimeStartUnused = 0x09000000,
+    OMX_IndexConfigTimeScale,               /**< reference: OMX_TIME_CONFIG_SCALETYPE */
+    OMX_IndexConfigTimeClockState,          /**< reference: OMX_TIME_CONFIG_CLOCKSTATETYPE */
+    OMX_IndexConfigTimeActiveRefClock,      /**< reference: OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE */
+    OMX_IndexConfigTimeCurrentMediaTime,    /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (read only) */
+    OMX_IndexConfigTimeCurrentWallTime,     /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (read only) */
+    OMX_IndexConfigTimeCurrentAudioReference, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */
+    OMX_IndexConfigTimeCurrentVideoReference, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */
+    OMX_IndexConfigTimeMediaTimeRequest,    /**< reference: OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE (write only) */
+    OMX_IndexConfigTimeClientStartTime,     /**<reference:  OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */
+    OMX_IndexConfigTimePosition,            /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE */
+    OMX_IndexConfigTimeSeekMode,            /**< reference: OMX_TIME_CONFIG_SEEKMODETYPE */
+
+
+    OMX_IndexKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    /* Vendor specific area */
+    OMX_IndexRockchipExtensions = 0x70000000, /**< Reserved region for introducing Rockchip Standard Extensions */
+    OMX_IndexParamVideoHDRRockchipExtensions,  /**< reference: OMX_EXTENSION_VIDEO_PARAM_HDR */
+    OMX_IndexVendorStartUnused = 0x7F000000,
+    /* Vendor specific structures should be in the range of 0x7F000000
+       to 0x7FFFFFFE.  This range is not broken out by vendor, so
+       private indexes are not guaranteed unique and therefore should
+       only be sent to the appropriate component. */
+
+    OMX_IndexMax = 0x7FFFFFFF
+
+} OMX_INDEXTYPE;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */

+ 105 - 0
omx-il/include/khronos/OMX_IndexExt.h

@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2010 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** @file OMX_IndexExt.h - OpenMax IL version 1.1.2
+ * The OMX_IndexExt header file contains extensions to the definitions
+ * for both applications and components .
+ */
+
+#ifndef OMX_IndexExt_h
+#define OMX_IndexExt_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Each OMX header shall include all required header files to allow the
+ * header to compile without errors.  The includes below are required
+ * for this header file to compile successfully
+ */
+#include <OMX_Index.h>
+
+
+/** Khronos standard extension indices.
+
+This enum lists the current Khronos extension indices to OpenMAX IL.
+*/
+typedef enum OMX_INDEXEXTTYPE {
+
+    /* Component parameters and configurations */
+    OMX_IndexExtComponentStartUnused = OMX_IndexKhronosExtensions + 0x00100000,
+    OMX_IndexConfigCallbackRequest,                 /**< reference: OMX_CONFIG_CALLBACKREQUESTTYPE */
+    OMX_IndexConfigCommitMode,                      /**< reference: OMX_CONFIG_COMMITMODETYPE */
+    OMX_IndexConfigCommit,                          /**< reference: OMX_CONFIG_COMMITTYPE */
+
+    /* Port parameters and configurations */
+    OMX_IndexExtPortStartUnused = OMX_IndexKhronosExtensions + 0x00200000,
+
+    /* Audio parameters and configurations */
+    OMX_IndexExtAudioStartUnused = OMX_IndexKhronosExtensions + 0x00400000,
+    OMX_IndexParamAudioAndroidAc3,                  /**< reference: OMX_AUDIO_PARAM_ANDROID_AC3TYPE */
+    OMX_IndexParamAudioAndroidOpus,                 /**< reference: OMX_AUDIO_PARAM_ANDROID_OPUSTYPE */
+    OMX_IndexParamAudioAndroidAacPresentation,      /**< reference: OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE */
+    OMX_IndexParamAudioAndroidEac3,                 /**< reference: OMX_AUDIO_PARAM_ANDROID_EAC3TYPE */
+    OMX_IndexParamAudioProfileQuerySupported,       /**< reference: OMX_AUDIO_PARAM_ANDROID_PROFILETYPE */
+
+    /* Image parameters and configurations */
+    OMX_IndexExtImageStartUnused = OMX_IndexKhronosExtensions + 0x00500000,
+
+    /* Video parameters and configurations */
+    OMX_IndexExtVideoStartUnused = OMX_IndexKhronosExtensions + 0x00600000,
+    OMX_IndexParamNalStreamFormatSupported,         /**< reference: OMX_NALSTREAMFORMATTYPE */
+    OMX_IndexParamNalStreamFormat,                  /**< reference: OMX_NALSTREAMFORMATTYPE */
+    OMX_IndexParamNalStreamFormatSelect,            /**< reference: OMX_NALSTREAMFORMATTYPE */
+    OMX_IndexParamVideoVp8,                         /**< reference: OMX_VIDEO_PARAM_VP8TYPE */
+    OMX_IndexConfigVideoVp8ReferenceFrame,          /**< reference: OMX_VIDEO_VP8REFERENCEFRAMETYPE */
+    OMX_IndexConfigVideoVp8ReferenceFrameType,      /**< reference: OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE */
+    OMX_IndexParamVideoAndroidVp8Encoder,           /**< reference: OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE */
+    OMX_IndexParamVideoHevc,                        /**< reference: OMX_VIDEO_PARAM_HEVCTYPE */
+    OMX_IndexParamSliceSegments,                    /**< reference: OMX_VIDEO_SLICESEGMENTSTYPE */
+    OMX_IndexConfigAndroidIntraRefresh,             /**< reference: OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE */
+    OMX_IndexParamAndroidVideoTemporalLayering,     /**< reference: OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE */
+    OMX_IndexConfigAndroidVideoTemporalLayering,    /**< reference: OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE */
+
+    /* Image & Video common configurations */
+    OMX_IndexExtCommonStartUnused = OMX_IndexKhronosExtensions + 0x00700000,
+
+    /* Other configurations */
+    OMX_IndexExtOtherStartUnused = OMX_IndexKhronosExtensions + 0x00800000,
+    OMX_IndexConfigAutoFramerateConversion,         /**< reference: OMX_CONFIG_BOOLEANTYPE */
+    OMX_IndexConfigPriority,                        /**< reference: OMX_PARAM_U32TYPE */
+    OMX_IndexConfigOperatingRate,                   /**< reference: OMX_PARAM_U32TYPE in Q16 format for video and in Hz for audio */
+    OMX_IndexParamConsumerUsageBits,                /**< reference: OMX_PARAM_U32TYPE */
+
+    /* Time configurations */
+    OMX_IndexExtTimeStartUnused = OMX_IndexKhronosExtensions + 0x00900000,
+
+    OMX_IndexExtMax = 0x7FFFFFFF
+} OMX_INDEXEXTTYPE;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* OMX_IndexExt_h */
+/* File EOF */

+ 366 - 0
omx-il/include/khronos/OMX_Other.h

@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** @file OMX_Other.h - OpenMax IL version 1.1.2
+ *  The structures needed by Other components to exchange
+ *  parameters and configuration data with the components.
+ */
+
+#ifndef OMX_Other_h
+#define OMX_Other_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* Each OMX header must include all required header files to allow the
+ *  header to compile without errors.  The includes below are required
+ *  for this header file to compile successfully
+ */
+
+#include <OMX_Core.h>
+
+
+/**
+ * Enumeration of possible data types which match to multiple domains or no
+ * domain at all.  For types which are vendor specific, a value above
+ * OMX_OTHER_VENDORTSTART should be used.
+ */
+typedef enum OMX_OTHER_FORMATTYPE {
+    OMX_OTHER_FormatTime = 0, /**< Transmission of various timestamps, elapsed time,
+                                   time deltas, etc */
+                           OMX_OTHER_FormatPower,    /**< Perhaps used for enabling/disabling power
+                                   management, setting clocks? */
+                           OMX_OTHER_FormatStats,    /**< Could be things such as frame rate, frames
+                                   dropped, etc */
+                           OMX_OTHER_FormatBinary,   /**< Arbitrary binary data */
+                           OMX_OTHER_FormatVendorReserved = 1000, /**< Starting value for vendor specific
+                                                formats */
+
+                                                            OMX_OTHER_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+                                                            OMX_OTHER_FormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+                                                            OMX_OTHER_FormatMax = 0x7FFFFFFF
+} OMX_OTHER_FORMATTYPE;
+
+/**
+ * Enumeration of seek modes.
+ */
+typedef enum OMX_TIME_SEEKMODETYPE {
+    OMX_TIME_SeekModeFast = 0, /**< Prefer seeking to an approximation
+                                * of the requested seek position over
+                                * the actual seek position if it
+                                * results in a faster seek. */
+    OMX_TIME_SeekModeAccurate, /**< Prefer seeking to the actual seek
+                                * position over an approximation
+                                * of the requested seek position even
+                                * if it results in a slower seek. */
+    OMX_TIME_SeekModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_TIME_SeekModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_TIME_SeekModeMax = 0x7FFFFFFF
+} OMX_TIME_SEEKMODETYPE;
+
+/* Structure representing the seekmode of the component */
+typedef struct OMX_TIME_CONFIG_SEEKMODETYPE {
+    OMX_U32 nSize;                  /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;       /**< OMX specification version information */
+    OMX_TIME_SEEKMODETYPE eType;    /**< The seek mode */
+} OMX_TIME_CONFIG_SEEKMODETYPE;
+
+/**
+ * colorspace 
+ */
+typedef enum OMX_ROCKCHIP_EXT_COLORSPACE {
+    OMX_RK_EXT_ColorspaceBT709 = 1,
+    OMX_RK_EXT_ColorspaceBT2020,
+    OMX_RK_EXT_ColorspaceMax = 0x7FFFFFFF
+} OMX_RK_EXT_COLORSPACE;
+
+/**
+ * dynamic range
+ */
+typedef enum OMX_ROCKCHIP_EXT_DYNCRANGE {
+    OMX_RK_EXT_DyncrangeSDR = 0,
+    OMX_RK_EXT_DyncrangeHDR10,
+    OMX_RK_EXT_DyncrangeHDRHLG,
+    OMX_RK_EXT_DyncrangeHDRDOLBY,
+    OMX_RK_EXT_DyncrangeMax = 0x7FFFFFFF
+} OMX_RK_EXT_DYNCRANGE;
+
+
+/* Structure Rockchip extension HDR param of the component */
+ typedef struct OMX_EXTENSION_VIDEO_PARAM_HDR {
+    OMX_U32 nSize;                  /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;       /**< OMX specification version information */
+    OMX_RK_EXT_COLORSPACE eColorSpace;    /**< Color space */
+    OMX_RK_EXT_DYNCRANGE eDyncRange;    /**< dynamic range */
+} OMX_EXTENSION_VIDEO_PARAM_HDR;
+
+/** Structure representing a time stamp used with the following configs
+ * on the Clock Component (CC):
+ *
+ * OMX_IndexConfigTimeCurrentWallTime: query of the CC’s current wall
+ *     time
+ * OMX_IndexConfigTimeCurrentMediaTime: query of the CC’s current media
+ *     time
+ * OMX_IndexConfigTimeCurrentAudioReference and
+ * OMX_IndexConfigTimeCurrentVideoReference: audio/video reference
+ *     clock sending SC its reference time
+ * OMX_IndexConfigTimeClientStartTime: a Clock Component client sends
+ *     this structure to the Clock Component via a SetConfig on its
+ *     client port when it receives a buffer with
+ *     OMX_BUFFERFLAG_STARTTIME set. It must use the timestamp
+ *     specified by that buffer for nStartTimestamp.
+ *
+ * It’s also used with the following config on components in general:
+ *
+ * OMX_IndexConfigTimePosition: IL client querying component position
+ * (GetConfig) or commanding a component to seek to the given location
+ * (SetConfig)
+ */
+typedef struct OMX_TIME_CONFIG_TIMESTAMPTYPE {
+    OMX_U32 nSize;               /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;    /**< OMX specification version
+                                  *   information */
+    OMX_U32 nPortIndex;     /**< port that this structure applies to */
+    OMX_TICKS nTimestamp;        /**< timestamp .*/
+} OMX_TIME_CONFIG_TIMESTAMPTYPE;
+
+/** Enumeration of possible reference clocks to the media time. */
+typedef enum OMX_TIME_UPDATETYPE {
+    OMX_TIME_UpdateRequestFulfillment,    /**< Update is the fulfillment of a media time request. */
+    OMX_TIME_UpdateScaleChanged,          /**< Update was generated because the scale chagned. */
+    OMX_TIME_UpdateClockStateChanged,     /**< Update was generated because the clock state changed. */
+    OMX_TIME_UpdateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_TIME_UpdateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_TIME_UpdateMax = 0x7FFFFFFF
+} OMX_TIME_UPDATETYPE;
+
+/** Enumeration of possible reference clocks to the media time. */
+typedef enum OMX_TIME_REFCLOCKTYPE {
+    OMX_TIME_RefClockNone,    /**< Use no references. */
+    OMX_TIME_RefClockAudio,   /**< Use references sent through OMX_IndexConfigTimeCurrentAudioReference */
+    OMX_TIME_RefClockVideo,   /**< Use references sent through OMX_IndexConfigTimeCurrentVideoReference */
+    OMX_TIME_RefClockKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_TIME_RefClockVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_TIME_RefClockMax = 0x7FFFFFFF
+} OMX_TIME_REFCLOCKTYPE;
+
+/** Enumeration of clock states. */
+typedef enum OMX_TIME_CLOCKSTATE {
+    OMX_TIME_ClockStateRunning,             /**< Clock running. */
+    OMX_TIME_ClockStateWaitingForStartTime, /**< Clock waiting until the
+                                               *   prescribed clients emit their
+                                               *   start time. */
+    OMX_TIME_ClockStateStopped,             /**< Clock stopped. */
+    OMX_TIME_ClockStateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_TIME_ClockStateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_TIME_ClockStateMax = 0x7FFFFFFF
+} OMX_TIME_CLOCKSTATE;
+
+/** Structure representing a media time request to the clock component.
+ *
+ *  A client component sends this structure to the Clock Component via a SetConfig
+ *  on its client port to specify a media timestamp the Clock Component
+ *  should emit.  The Clock Component should fulfill the request by sending a
+ *  OMX_TIME_MEDIATIMETYPE when its media clock matches the requested
+ *  timestamp.
+ *
+ *  The client may require a media time request be fulfilled slightly
+ *  earlier than the media time specified. In this case the client specifies
+ *  an offset which is equal to the difference between wall time corresponding
+ *  to the requested media time and the wall time when it will be
+ *  fulfilled.
+ *
+ *  A client component may uses these requests and the OMX_TIME_MEDIATIMETYPE to
+ *  time events according to timestamps. If a client must perform an operation O at
+ *  a time T (e.g. deliver a video frame at its corresponding timestamp), it makes a
+ *  media time request at T (perhaps specifying an offset to ensure the request fulfillment
+ *  is a little early). When the clock component passes the resulting OMX_TIME_MEDIATIMETYPE
+ *  structure back to the client component, the client may perform operation O (perhaps having
+ *  to wait a slight amount more time itself as specified by the return values).
+ */
+
+typedef struct OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPortIndex;         /**< port that this structure applies to */
+    OMX_PTR pClientPrivate;     /**< Client private data to disabiguate this media time
+                                 *   from others (e.g. the number of the frame to deliver).
+                                 *   Duplicated in the media time structure that fulfills
+                                 *   this request. A value of zero is reserved for time scale
+                                 *   updates. */
+    OMX_TICKS nMediaTimestamp;  /**< Media timestamp requested.*/
+    OMX_TICKS nOffset;          /**< Amount of wall clock time by which this
+                                 *   request should be fulfilled early */
+} OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE;
+
+/**< Structure sent from the clock component client either when fulfilling
+ *   a media time request or when the time scale has changed.
+ *
+ *   In the former case the Clock Component fills this structure and times its emission
+ *   to a client component (via the client port) according to the corresponding media
+ *   time request sent by the client. The Clock Component should time the emission to occur
+ *   when the requested timestamp matches the Clock Component's media time but also the
+ *   prescribed offset early.
+ *
+ *   Upon scale changes the clock component clears the nClientPrivate data, sends the current
+ *   media time and sets the nScale to the new scale via the client port. It emits a
+ *   OMX_TIME_MEDIATIMETYPE to all clients independent of any requests. This allows clients to
+ *   alter processing to accomodate scaling. For instance a video component might skip inter-frames
+ *   in the case of extreme fastforward. Likewise an audio component might add or remove samples
+ *   from an audio frame to scale audio data.
+ *
+ *   It is expected that some clock components may not be able to fulfill requests
+ *   at exactly the prescribed time. This is acceptable so long as the request is
+ *   fulfilled at least as early as described and not later. This structure provides
+ *   fields the client may use to wait for the remaining time.
+ *
+ *   The client may use either the nOffset or nWallTimeAtMedia fields to determine the
+ *   wall time until the nMediaTimestamp actually occurs. In the latter case the
+ *   client can get a more accurate value for offset by getting the current wall
+ *   from the cloc component and subtracting it from nWallTimeAtMedia.
+ */
+
+typedef struct OMX_TIME_MEDIATIMETYPE {
+    OMX_U32 nSize;                  /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;       /**< OMX specification version information */
+    OMX_U32 nClientPrivate;         /**< Client private data to disabiguate this media time
+                                     *   from others. Copied from the media time request.
+                                     *   A value of zero is reserved for time scale updates. */
+    OMX_TIME_UPDATETYPE eUpdateType; /**< Reason for the update */
+    OMX_TICKS nMediaTimestamp;      /**< Media time requested. If no media time was
+                                     *   requested then this is the current media time. */
+    OMX_TICKS nOffset;              /**< Amount of wall clock time by which this
+                                     *   request was actually fulfilled early */
+
+    OMX_TICKS nWallTimeAtMediaTime; /**< Wall time corresponding to nMediaTimeStamp.
+                                     *   A client may compare this value to current
+                                     *   media time obtained from the Clock Component to determine
+                                     *   the wall time until the media timestamp is really
+                                     *   current. */
+    OMX_S32 xScale;                 /**< Current media time scale in Q16 format. */
+    OMX_TIME_CLOCKSTATE eState;     /* Seeking Change. Added 7/12.*/
+    /**< State of the media time. */
+} OMX_TIME_MEDIATIMETYPE;
+
+/** Structure representing the current media time scale factor. Applicable only to clock
+ *  component, other components see scale changes via OMX_TIME_MEDIATIMETYPE buffers sent via
+ *  the clock component client ports. Upon recieving this config the clock component changes
+ *  the rate by which the media time increases or decreases effectively implementing trick modes.
+ */
+typedef struct OMX_TIME_CONFIG_SCALETYPE {
+    OMX_U32 nSize;                  /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;       /**< OMX specification version information */
+    OMX_S32 xScale;                 /**< This is a value in Q16 format which is used for
+                                     * scaling the media time */
+} OMX_TIME_CONFIG_SCALETYPE;
+
+/** Bits used to identify a clock port. Used in OMX_TIME_CONFIG_CLOCKSTATETYPE’s nWaitMask field */
+#define OMX_CLOCKPORT0 0x00000001
+#define OMX_CLOCKPORT1 0x00000002
+#define OMX_CLOCKPORT2 0x00000004
+#define OMX_CLOCKPORT3 0x00000008
+#define OMX_CLOCKPORT4 0x00000010
+#define OMX_CLOCKPORT5 0x00000020
+#define OMX_CLOCKPORT6 0x00000040
+#define OMX_CLOCKPORT7 0x00000080
+
+/** Structure representing the current mode of the media clock.
+ *  IL Client uses this config to change or query the mode of the
+ *  media clock of the clock component. Applicable only to clock
+ *  component.
+ *
+ *  On a SetConfig if eState is OMX_TIME_ClockStateRunning media time
+ *  starts immediately at the prescribed start time. If
+ *  OMX_TIME_ClockStateWaitingForStartTime the Clock Component ignores
+ *  the given nStartTime and waits for all clients specified in the
+ *  nWaitMask to send starttimes (via
+ *  OMX_IndexConfigTimeClientStartTime). The Clock Component then starts
+ *  the media clock using the earliest start time supplied. */
+typedef struct OMX_TIME_CONFIG_CLOCKSTATETYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version
+                                 *   information */
+    OMX_TIME_CLOCKSTATE eState; /**< State of the media time. */
+    OMX_TICKS nStartTime;       /**< Start time of the media time. */
+    OMX_TICKS nOffset;          /**< Time to offset the media time by
+                                 * (e.g. preroll). Media time will be
+                                 * reported to be nOffset ticks earlier.
+                                 */
+    OMX_U32 nWaitMask;          /**< Mask of OMX_CLOCKPORT values. */
+} OMX_TIME_CONFIG_CLOCKSTATETYPE;
+
+/** Structure representing the reference clock currently being used to
+ *  compute media time. IL client uses this config to change or query the
+ *  clock component's active reference clock */
+typedef struct OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE {
+    OMX_U32 nSize;                  /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;       /**< OMX specification version information */
+    OMX_TIME_REFCLOCKTYPE eClock;   /**< Reference clock used to compute media time */
+} OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE;
+
+/** Descriptor for setting specifics of power type.
+ *  Note: this structure is listed for backwards compatibility. */
+typedef struct OMX_OTHER_CONFIG_POWERTYPE {
+    OMX_U32 nSize;            /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_BOOL bEnablePM;       /**< Flag to enable Power Management */
+} OMX_OTHER_CONFIG_POWERTYPE;
+
+
+/** Descriptor for setting specifics of stats type.
+ *  Note: this structure is listed for backwards compatibility. */
+typedef struct OMX_OTHER_CONFIG_STATSTYPE {
+    OMX_U32 nSize;            /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    /* what goes here */
+} OMX_OTHER_CONFIG_STATSTYPE;
+
+
+/**
+ * The PortDefinition structure is used to define all of the parameters
+ * necessary for the compliant component to setup an input or an output other
+ * path.
+ */
+typedef struct OMX_OTHER_PORTDEFINITIONTYPE {
+    OMX_OTHER_FORMATTYPE eFormat;  /**< Type of data expected for this channel */
+} OMX_OTHER_PORTDEFINITIONTYPE;
+
+/**  Port format parameter.  This structure is used to enumerate
+  *  the various data input/output format supported by the port.
+  */
+typedef struct OMX_OTHER_PARAM_PORTFORMATTYPE {
+    OMX_U32 nSize; /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_U32 nPortIndex; /**< Indicates which port to set */
+    OMX_U32 nIndex; /**< Indicates the enumeration index for the format from 0x0 to N-1 */
+    OMX_OTHER_FORMATTYPE eFormat; /**< Type of data expected for this channel */
+} OMX_OTHER_PARAM_PORTFORMATTYPE;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */

+ 352 - 0
omx-il/include/khronos/OMX_Types.h

@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** OMX_Types.h - OpenMax IL version 1.1.2
+ *  The OMX_Types header file contains the primitive type definitions used by
+ *  the core, the application and the component.  This file may need to be
+ *  modified to be used on systems that do not have "char" set to 8 bits,
+ *  "short" set to 16 bits and "long" set to 32 bits.
+ */
+
+#ifndef OMX_Types_h
+#define OMX_Types_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/** The OMX_API and OMX_APIENTRY are platform specific definitions used
+ *  to declare OMX function prototypes.  They are modified to meet the
+ *  requirements for a particular platform */
+#ifdef __SYMBIAN32__
+#   ifdef __OMX_EXPORTS
+#       define OMX_API __declspec(dllexport)
+#   else
+#       ifdef _WIN32
+#           define OMX_API __declspec(dllexport)
+#       else
+#           define OMX_API __declspec(dllimport)
+#       endif
+#   endif
+#else
+#   ifdef _WIN32
+#      ifdef __OMX_EXPORTS
+#          define OMX_API __declspec(dllexport)
+#      else
+#          define OMX_API __declspec(dllimport)
+#      endif
+#   else
+#      ifdef __OMX_EXPORTS
+#          define OMX_API
+#      else
+#          define OMX_API extern
+#      endif
+#   endif
+#endif
+
+#ifndef OMX_APIENTRY
+#define OMX_APIENTRY
+#endif
+
+/** OMX_IN is used to identify inputs to an OMX function.  This designation
+    will also be used in the case of a pointer that points to a parameter
+    that is used as an output. */
+#ifndef OMX_IN
+#define OMX_IN
+#endif
+
+/** OMX_OUT is used to identify outputs from an OMX function.  This
+    designation will also be used in the case of a pointer that points
+    to a parameter that is used as an input. */
+#ifndef OMX_OUT
+#define OMX_OUT
+#endif
+
+
+/** OMX_INOUT is used to identify parameters that may be either inputs or
+    outputs from an OMX function at the same time.  This designation will
+    also be used in the case of a pointer that  points to a parameter that
+    is used both as an input and an output. */
+#ifndef OMX_INOUT
+#define OMX_INOUT
+#endif
+
+/** OMX_ALL is used to as a wildcard to select all entities of the same type
+ *  when specifying the index, or referring to a object by an index.  (i.e.
+ *  use OMX_ALL to indicate all N channels). When used as a port index
+ *  for a config or parameter this OMX_ALL denotes that the config or
+ *  parameter applies to the entire component not just one port. */
+#define OMX_ALL 0xFFFFFFFF
+
+/** In the following we define groups that help building doxygen documentation */
+
+/** @defgroup core OpenMAX IL core
+ * Functions and structure related to the OMX IL core
+ */
+
+/** @defgroup comp OpenMAX IL component
+* Functions and structure related to the OMX IL component
+*/
+
+/** @defgroup rpm Resource and Policy Management
+ * Structures for resource and policy management of components
+ */
+
+/** @defgroup buf Buffer Management
+ * Buffer handling functions and structures
+ */
+
+/** @defgroup tun Tunneling
+ * @ingroup core comp
+ * Structures and functions to manage tunnels among component ports
+ */
+
+/** @defgroup cp Content Pipes
+ *  @ingroup core
+ */
+
+/** @defgroup metadata Metadata handling
+ *
+ */
+
+/** OMX_U8 is an 8 bit unsigned quantity that is byte aligned */
+typedef unsigned char OMX_U8;
+
+/** OMX_S8 is an 8 bit signed quantity that is byte aligned */
+typedef signed char OMX_S8;
+
+/** OMX_U16 is a 16 bit unsigned quantity that is 16 bit word aligned */
+typedef unsigned short OMX_U16;
+
+/** OMX_S16 is a 16 bit signed quantity that is 16 bit word aligned */
+typedef signed short OMX_S16;
+
+/** OMX_U32 is a 32 bit unsigned quantity that is 32 bit word aligned */
+typedef unsigned long OMX_U32;
+
+/** OMX_S32 is a 32 bit signed quantity that is 32 bit word aligned */
+typedef signed long OMX_S32;
+
+
+/* Users with compilers that cannot accept the "long long" designation should
+   define the OMX_SKIP64BIT macro.  It should be noted that this may cause
+   some components to fail to compile if the component was written to require
+   64 bit integral types.  However, these components would NOT compile anyway
+   since the compiler does not support the way the component was written.
+*/
+#ifndef OMX_SKIP64BIT
+#ifdef __SYMBIAN32__
+/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */
+typedef unsigned long long OMX_U64;
+
+/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */
+typedef signed long long OMX_S64;
+
+#elif defined(WIN32)
+
+/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */
+typedef unsigned __int64  OMX_U64;
+
+/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */
+typedef signed   __int64  OMX_S64;
+
+#else /* WIN32 */
+
+/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */
+typedef unsigned long long OMX_U64;
+
+/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */
+typedef signed long long OMX_S64;
+
+#endif /* WIN32 */
+#endif
+
+
+/** The OMX_BOOL type is intended to be used to represent a true or a false
+    value when passing parameters to and from the OMX core and components.  The
+    OMX_BOOL is a 32 bit quantity and is aligned on a 32 bit word boundary.
+ */
+typedef enum OMX_BOOL {
+    OMX_FALSE = 0,
+    OMX_TRUE = !OMX_FALSE,
+    OMX_BOOL_MAX = 0x7FFFFFFF
+} OMX_BOOL;
+
+/** The OMX_PTR type is intended to be used to pass pointers between the OMX
+    applications and the OMX Core and components.  This is a 32 bit pointer and
+    is aligned on a 32 bit boundary.
+ */
+typedef void* OMX_PTR;
+
+/** The OMX_STRING type is intended to be used to pass "C" type strings between
+    the application and the core and component.  The OMX_STRING type is a 32
+    bit pointer to a zero terminated string.  The  pointer is word aligned and
+    the string is byte aligned.
+ */
+typedef char* OMX_STRING;
+
+/** The OMX_BYTE type is intended to be used to pass arrays of bytes such as
+    buffers between the application and the component and core.  The OMX_BYTE
+    type is a 32 bit pointer to a zero terminated string.  The  pointer is word
+    aligned and the string is byte aligned.
+ */
+typedef unsigned char* OMX_BYTE;
+
+/** OMX_UUIDTYPE is a very long unique identifier to uniquely identify
+    at runtime.  This identifier should be generated by a component in a way
+    that guarantees that every instance of the identifier running on the system
+    is unique. */
+typedef unsigned char OMX_UUIDTYPE[128];
+
+/** The OMX_DIRTYPE enumeration is used to indicate if a port is an input or
+    an output port.  This enumeration is common across all component types.
+ */
+typedef enum OMX_DIRTYPE {
+    OMX_DirInput,              /**< Port is an input port */
+    OMX_DirOutput,             /**< Port is an output port */
+    OMX_DirMax = 0x7FFFFFFF
+} OMX_DIRTYPE;
+
+/** The OMX_ENDIANTYPE enumeration is used to indicate the bit ordering
+    for numerical data (i.e. big endian, or little endian).
+ */
+typedef enum OMX_ENDIANTYPE {
+    OMX_EndianBig, /**< big endian */
+    OMX_EndianLittle, /**< little endian */
+    OMX_EndianMax = 0x7FFFFFFF
+} OMX_ENDIANTYPE;
+
+
+/** The OMX_NUMERICALDATATYPE enumeration is used to indicate if data
+    is signed or unsigned
+ */
+typedef enum OMX_NUMERICALDATATYPE {
+    OMX_NumericalDataSigned, /**< signed data */
+    OMX_NumericalDataUnsigned, /**< unsigned data */
+    OMX_NumercialDataMax = 0x7FFFFFFF
+} OMX_NUMERICALDATATYPE;
+
+
+/** Unsigned bounded value type */
+typedef struct OMX_BU32 {
+    OMX_U32 nValue; /**< actual value */
+    OMX_U32 nMin;   /**< minimum for value (i.e. nValue >= nMin) */
+    OMX_U32 nMax;   /**< maximum for value (i.e. nValue <= nMax) */
+} OMX_BU32;
+
+
+/** Signed bounded value type */
+typedef struct OMX_BS32 {
+    OMX_S32 nValue; /**< actual value */
+    OMX_S32 nMin;   /**< minimum for value (i.e. nValue >= nMin) */
+    OMX_S32 nMax;   /**< maximum for value (i.e. nValue <= nMax) */
+} OMX_BS32;
+
+
+/** Structure representing some time or duration in microseconds. This structure
+  *  must be interpreted as a signed 64 bit value. The quantity is signed to accommodate
+  *  negative deltas and preroll scenarios. The quantity is represented in microseconds
+  *  to accomodate high resolution timestamps (e.g. DVD presentation timestamps based
+  *  on a 90kHz clock) and to allow more accurate and synchronized delivery (e.g.
+  *  individual audio samples delivered at 192 kHz). The quantity is 64 bit to
+  *  accommodate a large dynamic range (signed 32 bit values would allow only for plus
+  *  or minus 35 minutes).
+  *
+  *  Implementations with limited precision may convert the signed 64 bit value to
+  *  a signed 32 bit value internally but risk loss of precision.
+  */
+#ifndef OMX_SKIP64BIT
+typedef OMX_S64 OMX_TICKS;
+#else
+typedef struct OMX_TICKS {
+    OMX_U32 nLowPart;    /** low bits of the signed 64 bit tick value */
+    OMX_U32 nHighPart;   /** high bits of the signed 64 bit tick value */
+} OMX_TICKS;
+#endif
+#define OMX_TICKS_PER_SECOND 1000000
+
+/** Define the public interface for the OMX Handle.  The core will not use
+    this value internally, but the application should only use this value.
+ */
+typedef void* OMX_HANDLETYPE;
+
+typedef struct OMX_MARKTYPE {
+    OMX_HANDLETYPE hMarkTargetComponent;   /**< The component that will
+                                                generate a mark event upon
+                                                processing the mark. */
+    OMX_PTR pMarkData;   /**< Application specific data associated with
+                              the mark sent on a mark event to disambiguate
+                              this mark from others. */
+} OMX_MARKTYPE;
+
+
+/** OMX_NATIVE_DEVICETYPE is used to map a OMX video port to the
+ *  platform & operating specific object used to reference the display
+ *  or can be used by a audio port for native audio rendering */
+typedef void* OMX_NATIVE_DEVICETYPE;
+
+/** OMX_NATIVE_WINDOWTYPE is used to map a OMX video port to the
+ *  platform & operating specific object used to reference the window */
+typedef void* OMX_NATIVE_WINDOWTYPE;
+
+
+/** Define the OMX IL version that corresponds to this set of header files.
+ *  We also define a combined version that can be used to write or compare
+ *  values of the 32bit nVersion field, assuming a little endian architecture */
+#define OMX_VERSION_MAJOR 1
+#define OMX_VERSION_MINOR 1
+#define OMX_VERSION_REVISION 2
+#define OMX_VERSION_STEP 0
+
+#define OMX_VERSION ((OMX_VERSION_STEP<<24) | (OMX_VERSION_REVISION<<16) | (OMX_VERSION_MINOR<<8) | OMX_VERSION_MAJOR)
+
+
+/** The OMX_VERSIONTYPE union is used to specify the version for
+    a structure or component.  For a component, the version is entirely
+    specified by the component vendor.  Components doing the same function
+    from different vendors may or may not have the same version.  For
+    structures, the version shall be set by the entity that allocates the
+    structure.  For structures specified in the OMX 1.1 specification, the
+    value of the version shall be set to 1.1.0.0 in all cases.  Access to the
+    OMX_VERSIONTYPE can be by a single 32 bit access (e.g. by nVersion) or
+    by accessing one of the structure elements to, for example, check only
+    the Major revision.
+ */
+typedef union OMX_VERSIONTYPE {
+    struct {
+        OMX_U8 nVersionMajor;   /**< Major version accessor element */
+        OMX_U8 nVersionMinor;   /**< Minor version accessor element */
+        OMX_U8 nRevision;       /**< Revision version accessor element */
+        OMX_U8 nStep;           /**< Step version accessor element */
+    } s;
+    OMX_U32 nVersion;           /**< 32 bit value to make accessing the
+                                    version easily done in a single word
+                                    size copy/compare operation */
+} OMX_VERSIONTYPE;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */

+ 1141 - 0
omx-il/include/khronos/OMX_Video.h

@@ -0,0 +1,1141 @@
+/**
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/**
+ *  @file OMX_Video.h - OpenMax IL version 1.1.2
+ *  The structures is needed by Video components to exchange parameters
+ *  and configuration data with OMX components.
+ */
+#ifndef OMX_Video_h
+#define OMX_Video_h
+
+/** @defgroup video OpenMAX IL Video Domain
+ * @ingroup iv
+ * Structures for OpenMAX IL Video domain
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/**
+ * Each OMX header must include all required header files to allow the
+ * header to compile without errors.  The includes below are required
+ * for this header file to compile successfully
+ */
+
+#include <OMX_IVCommon.h>
+
+
+/**
+ * Enumeration used to define the possible video compression codings.
+ * NOTE:  This essentially refers to file extensions. If the coding is
+ *        being used to specify the ENCODE type, then additional work
+ *        must be done to configure the exact flavor of the compression
+ *        to be used.  For decode cases where the user application can
+ *        not differentiate between MPEG-4 and H.264 bit streams, it is
+ *        up to the codec to handle this.
+ */
+typedef enum OMX_VIDEO_CODINGTYPE {
+    OMX_VIDEO_CodingUnused,     /**< Value when coding is N/A */
+    OMX_VIDEO_CodingAutoDetect, /**< Autodetection of coding type */
+    OMX_VIDEO_CodingMPEG2,      /**< AKA: H.262 */
+    OMX_VIDEO_CodingH263,       /**< H.263 */
+    OMX_VIDEO_CodingMPEG4,      /**< MPEG-4 */
+    OMX_VIDEO_CodingWMV,        /**< all versions of Windows Media Video */
+    OMX_VIDEO_CodingRV,         /**< all versions of Real Video */
+    OMX_VIDEO_CodingAVC,        /**< H.264/AVC */
+    OMX_VIDEO_CodingMJPEG,      /**< Motion JPEG */
+    OMX_VIDEO_CodingVP8,        /**< Google VP8, formerly known as On2 VP8 */
+    OMX_VIDEO_CodingVP9,        /**< Google VP9 */
+    OMX_VIDEO_CodingHEVC,       /**< ITU H.265/HEVC */
+    OMX_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_CodingMax = 0x7FFFFFFF
+} OMX_VIDEO_CODINGTYPE;
+
+
+/**
+ * Data structure used to define a video path.  The number of Video paths for
+ * input and output will vary by type of the Video component.
+ *
+ *    Input (aka Source) : zero Inputs, one Output,
+ *    Splitter           : one Input, 2 or more Outputs,
+ *    Processing Element : one Input, one output,
+ *    Mixer              : 2 or more inputs, one output,
+ *    Output (aka Sink)  : one Input, zero outputs.
+ *
+ * The PortDefinition structure is used to define all of the parameters
+ * necessary for the compliant component to setup an input or an output video
+ * path.  If additional vendor specific data is required, it should be
+ * transmitted to the component using the CustomCommand function.  Compliant
+ * components will prepopulate this structure with optimal values during the
+ * GetDefaultInitParams command.
+ *
+ * STRUCT MEMBERS:
+ *  cMIMEType             : MIME type of data for the port
+ *  pNativeRender         : Platform specific reference for a display if a
+ *                          sync, otherwise this field is 0
+ *  nFrameWidth           : Width of frame to be used on channel if
+ *                          uncompressed format is used.  Use 0 for unknown,
+ *                          don't care or variable
+ *  nFrameHeight          : Height of frame to be used on channel if
+ *                          uncompressed format is used. Use 0 for unknown,
+ *                          don't care or variable
+ *  nStride               : Number of bytes per span of an image
+ *                          (i.e. indicates the number of bytes to get
+ *                          from span N to span N+1, where negative stride
+ *                          indicates the image is bottom up
+ *  nSliceHeight          : Height used when encoding in slices
+ *  nBitrate              : Bit rate of frame to be used on channel if
+ *                          compressed format is used. Use 0 for unknown,
+ *                          don't care or variable
+ *  xFramerate            : Frame rate to be used on channel if uncompressed
+ *                          format is used. Use 0 for unknown, don't care or
+ *                          variable.  Units are Q16 frames per second.
+ *  bFlagErrorConcealment : Turns on error concealment if it is supported by
+ *                          the OMX component
+ *  eCompressionFormat    : Compression format used in this instance of the
+ *                          component. When OMX_VIDEO_CodingUnused is
+ *                          specified, eColorFormat is used
+ *  eColorFormat : Decompressed format used by this component
+ *  pNativeWindow : Platform specific reference for a window object if a
+ *                          display sink , otherwise this field is 0x0.
+ */
+typedef struct OMX_VIDEO_PORTDEFINITIONTYPE {
+    OMX_STRING cMIMEType;
+    OMX_NATIVE_DEVICETYPE pNativeRender;
+    OMX_U32 nFrameWidth;
+    OMX_U32 nFrameHeight;
+    OMX_S32 nStride;
+    OMX_U32 nSliceHeight;
+    OMX_U32 nBitrate;
+    OMX_U32 xFramerate;
+    OMX_BOOL bFlagErrorConcealment;
+    OMX_VIDEO_CODINGTYPE eCompressionFormat;
+    OMX_COLOR_FORMATTYPE eColorFormat;
+    OMX_NATIVE_WINDOWTYPE pNativeWindow;
+} OMX_VIDEO_PORTDEFINITIONTYPE;
+
+/**
+ * Port format parameter.  This structure is used to enumerate the various
+ * data input/output format supported by the port.
+ *
+ * STRUCT MEMBERS:
+ *  nSize              : Size of the structure in bytes
+ *  nVersion           : OMX specification version information
+ *  nPortIndex         : Indicates which port to set
+ *  nIndex             : Indicates the enumeration index for the format from
+ *                       0x0 to N-1
+ *  eCompressionFormat : Compression format used in this instance of the
+ *                       component. When OMX_VIDEO_CodingUnused is specified,
+ *                       eColorFormat is used
+ *  eColorFormat       : Decompressed format used by this component
+ *  xFrameRate         : Indicates the video frame rate in Q16 format
+ */
+typedef struct OMX_VIDEO_PARAM_PORTFORMATTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nIndex;
+    OMX_VIDEO_CODINGTYPE eCompressionFormat;
+    OMX_COLOR_FORMATTYPE eColorFormat;
+    OMX_U32 xFramerate;
+} OMX_VIDEO_PARAM_PORTFORMATTYPE;
+
+
+/**
+ * This is a structure for configuring video compression quantization
+ * parameter values.  Codecs may support different QP values for different
+ * frame types.
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version info
+ *  nPortIndex : Port that this structure applies to
+ *  nQpI       : QP value to use for index frames
+ *  nQpP       : QP value to use for P frames
+ *  nQpB       : QP values to use for bidirectional frames
+ */
+typedef struct OMX_VIDEO_PARAM_QUANTIZATIONTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nQpI;
+    OMX_U32 nQpP;
+    OMX_U32 nQpB;
+} OMX_VIDEO_PARAM_QUANTIZATIONTYPE;
+
+
+/**
+ * Structure for configuration of video fast update parameters.
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version info
+ *  nPortIndex : Port that this structure applies to
+ *  bEnableVFU : Enable/Disable video fast update
+ *  nFirstGOB  : Specifies the number of the first macroblock row
+ *  nFirstMB   : specifies the first MB relative to the specified first GOB
+ *  nNumMBs    : Specifies the number of MBs to be refreshed from nFirstGOB
+ *               and nFirstMB
+ */
+typedef struct OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL bEnableVFU;
+    OMX_U32 nFirstGOB;
+    OMX_U32 nFirstMB;
+    OMX_U32 nNumMBs;
+} OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE;
+
+
+/**
+ * Enumeration of possible bitrate control types
+ */
+typedef enum OMX_VIDEO_CONTROLRATETYPE {
+    OMX_Video_ControlRateDisable,
+    OMX_Video_ControlRateVariable,
+    OMX_Video_ControlRateConstant,
+    OMX_Video_ControlRateVariableSkipFrames,
+    OMX_Video_ControlRateConstantSkipFrames,
+    OMX_Video_ControlRateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_Video_ControlRateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_Video_ControlRateMax = 0x7FFFFFFF
+} OMX_VIDEO_CONTROLRATETYPE;
+
+
+/**
+ * Structure for configuring bitrate mode of a codec.
+ *
+ * STRUCT MEMBERS:
+ *  nSize          : Size of the struct in bytes
+ *  nVersion       : OMX spec version info
+ *  nPortIndex     : Port that this struct applies to
+ *  eControlRate   : Control rate type enum
+ *  nTargetBitrate : Target bitrate to encode with
+ */
+typedef struct OMX_VIDEO_PARAM_BITRATETYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_VIDEO_CONTROLRATETYPE eControlRate;
+    OMX_U32 nTargetBitrate;
+} OMX_VIDEO_PARAM_BITRATETYPE;
+
+
+/**
+ * Enumeration of possible motion vector (MV) types
+ */
+typedef enum OMX_VIDEO_MOTIONVECTORTYPE {
+    OMX_Video_MotionVectorPixel,
+    OMX_Video_MotionVectorHalfPel,
+    OMX_Video_MotionVectorQuarterPel,
+    OMX_Video_MotionVectorEighthPel,
+    OMX_Video_MotionVectorKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_Video_MotionVectorVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_Video_MotionVectorMax = 0x7FFFFFFF
+} OMX_VIDEO_MOTIONVECTORTYPE;
+
+
+/**
+ * Structure for configuring the number of motion vectors used as well
+ * as their accuracy.
+ *
+ * STRUCT MEMBERS:
+ *  nSize            : Size of the struct in bytes
+ *  nVersion         : OMX spec version info
+ *  nPortIndex       : port that this structure applies to
+ *  eAccuracy        : Enumerated MV accuracy
+ *  bUnrestrictedMVs : Allow unrestricted MVs
+ *  bFourMV          : Allow use of 4 MVs
+ *  sXSearchRange    : Search range in horizontal direction for MVs
+ *  sYSearchRange    : Search range in vertical direction for MVs
+ */
+typedef struct OMX_VIDEO_PARAM_MOTIONVECTORTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_VIDEO_MOTIONVECTORTYPE eAccuracy;
+    OMX_BOOL bUnrestrictedMVs;
+    OMX_BOOL bFourMV;
+    OMX_S32 sXSearchRange;
+    OMX_S32 sYSearchRange;
+} OMX_VIDEO_PARAM_MOTIONVECTORTYPE;
+
+
+/**
+ * Enumeration of possible methods to use for Intra Refresh
+ */
+typedef enum OMX_VIDEO_INTRAREFRESHTYPE {
+    OMX_VIDEO_IntraRefreshCyclic,
+    OMX_VIDEO_IntraRefreshAdaptive,
+    OMX_VIDEO_IntraRefreshBoth,
+    OMX_VIDEO_IntraRefreshKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_VIDEO_IntraRefreshVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_IntraRefreshMax = 0x7FFFFFFF
+} OMX_VIDEO_INTRAREFRESHTYPE;
+
+
+/**
+ * Structure for configuring intra refresh mode
+ *
+ * STRUCT MEMBERS:
+ *  nSize        : Size of the structure in bytes
+ *  nVersion     : OMX specification version information
+ *  nPortIndex   : Port that this structure applies to
+ *  eRefreshMode : Cyclic, Adaptive, or Both
+ *  nAirMBs      : Number of intra macroblocks to refresh in a frame when
+ *                 AIR is enabled
+ *  nAirRef      : Number of times a motion marked macroblock has to be
+ *                 intra coded
+ *  nCirMBs      : Number of consecutive macroblocks to be coded as "intra"
+ *                 when CIR is enabled
+ */
+typedef struct OMX_VIDEO_PARAM_INTRAREFRESHTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_VIDEO_INTRAREFRESHTYPE eRefreshMode;
+    OMX_U32 nAirMBs;
+    OMX_U32 nAirRef;
+    OMX_U32 nCirMBs;
+} OMX_VIDEO_PARAM_INTRAREFRESHTYPE;
+
+
+/**
+ * Structure for enabling various error correction methods for video
+ * compression.
+ *
+ * STRUCT MEMBERS:
+ *  nSize                   : Size of the structure in bytes
+ *  nVersion                : OMX specification version information
+ *  nPortIndex              : Port that this structure applies to
+ *  bEnableHEC              : Enable/disable header extension codes (HEC)
+ *  bEnableResync           : Enable/disable resynchronization markers
+ *  nResynchMarkerSpacing   : Resynch markers interval (in bits) to be
+ *                            applied in the stream
+ *  bEnableDataPartitioning : Enable/disable data partitioning
+ *  bEnableRVLC             : Enable/disable reversible variable length
+ *                            coding
+ */
+typedef struct OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL bEnableHEC;
+    OMX_BOOL bEnableResync;
+    OMX_U32  nResynchMarkerSpacing;
+    OMX_BOOL bEnableDataPartitioning;
+    OMX_BOOL bEnableRVLC;
+} OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE;
+
+
+/**
+ * Configuration of variable block-size motion compensation (VBSMC)
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  b16x16     : Enable inter block search 16x16
+ *  b16x8      : Enable inter block search 16x8
+ *  b8x16      : Enable inter block search 8x16
+ *  b8x8       : Enable inter block search 8x8
+ *  b8x4       : Enable inter block search 8x4
+ *  b4x8       : Enable inter block search 4x8
+ *  b4x4       : Enable inter block search 4x4
+ */
+typedef struct OMX_VIDEO_PARAM_VBSMCTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL b16x16;
+    OMX_BOOL b16x8;
+    OMX_BOOL b8x16;
+    OMX_BOOL b8x8;
+    OMX_BOOL b8x4;
+    OMX_BOOL b4x8;
+    OMX_BOOL b4x4;
+} OMX_VIDEO_PARAM_VBSMCTYPE;
+
+
+/**
+ * H.263 profile types, each profile indicates support for various
+ * performance bounds and different annexes.
+ *
+ * ENUMS:
+ *  Baseline           : Baseline Profile: H.263 (V1), no optional modes
+ *  H320 Coding        : H.320 Coding Efficiency Backward Compatibility
+ *                       Profile: H.263+ (V2), includes annexes I, J, L.4
+ *                       and T
+ *  BackwardCompatible : Backward Compatibility Profile: H.263 (V1),
+ *                       includes annex F
+ *  ISWV2              : Interactive Streaming Wireless Profile: H.263+
+ *                       (V2), includes annexes I, J, K and T
+ *  ISWV3              : Interactive Streaming Wireless Profile: H.263++
+ *                       (V3), includes profile 3 and annexes V and W.6.3.8
+ *  HighCompression    : Conversational High Compression Profile: H.263++
+ *                       (V3), includes profiles 1 & 2 and annexes D and U
+ *  Internet           : Conversational Internet Profile: H.263++ (V3),
+ *                       includes profile 5 and annex K
+ *  Interlace          : Conversational Interlace Profile: H.263++ (V3),
+ *                       includes profile 5 and annex W.6.3.11
+ *  HighLatency        : High Latency Profile: H.263++ (V3), includes
+ *                       profile 6 and annexes O.1 and P.5
+ */
+typedef enum OMX_VIDEO_H263PROFILETYPE {
+    OMX_VIDEO_H263ProfileBaseline            = 0x01,
+    OMX_VIDEO_H263ProfileH320Coding          = 0x02,
+    OMX_VIDEO_H263ProfileBackwardCompatible  = 0x04,
+    OMX_VIDEO_H263ProfileISWV2               = 0x08,
+    OMX_VIDEO_H263ProfileISWV3               = 0x10,
+    OMX_VIDEO_H263ProfileHighCompression     = 0x20,
+    OMX_VIDEO_H263ProfileInternet            = 0x40,
+    OMX_VIDEO_H263ProfileInterlace           = 0x80,
+    OMX_VIDEO_H263ProfileHighLatency         = 0x100,
+    OMX_VIDEO_H263ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_VIDEO_H263ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_H263ProfileMax                 = 0x7FFFFFFF
+} OMX_VIDEO_H263PROFILETYPE;
+
+
+/**
+ * H.263 level types, each level indicates support for various frame sizes,
+ * bit rates, decoder frame rates.
+ */
+typedef enum OMX_VIDEO_H263LEVELTYPE {
+    OMX_VIDEO_H263Level10  = 0x01,
+    OMX_VIDEO_H263Level20  = 0x02,
+    OMX_VIDEO_H263Level30  = 0x04,
+    OMX_VIDEO_H263Level40  = 0x08,
+    OMX_VIDEO_H263Level45  = 0x10,
+    OMX_VIDEO_H263Level50  = 0x20,
+    OMX_VIDEO_H263Level60  = 0x40,
+    OMX_VIDEO_H263Level70  = 0x80,
+    OMX_VIDEO_H263LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_VIDEO_H263LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_H263LevelMax = 0x7FFFFFFF
+} OMX_VIDEO_H263LEVELTYPE;
+
+
+/**
+ * Specifies the picture type. These values should be OR'd to signal all
+ * pictures types which are allowed.
+ *
+ * ENUMS:
+ *  Generic Picture Types:          I, P and B
+ *  H.263 Specific Picture Types:   SI and SP
+ *  H.264 Specific Picture Types:   EI and EP
+ *  MPEG-4 Specific Picture Types:  S
+ */
+typedef enum OMX_VIDEO_PICTURETYPE {
+    OMX_VIDEO_PictureTypeI   = 0x01,
+    OMX_VIDEO_PictureTypeP   = 0x02,
+    OMX_VIDEO_PictureTypeB   = 0x04,
+    OMX_VIDEO_PictureTypeSI  = 0x08,
+    OMX_VIDEO_PictureTypeSP  = 0x10,
+    OMX_VIDEO_PictureTypeEI  = 0x11,
+    OMX_VIDEO_PictureTypeEP  = 0x12,
+    OMX_VIDEO_PictureTypeS   = 0x14,
+    OMX_VIDEO_PictureTypeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_VIDEO_PictureTypeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_PictureTypeMax = 0x7FFFFFFF
+} OMX_VIDEO_PICTURETYPE;
+
+
+/**
+ * H.263 Params
+ *
+ * STRUCT MEMBERS:
+ *  nSize                    : Size of the structure in bytes
+ *  nVersion                 : OMX specification version information
+ *  nPortIndex               : Port that this structure applies to
+ *  nPFrames                 : Number of P frames between each I frame
+ *  nBFrames                 : Number of B frames between each I frame
+ *  eProfile                 : H.263 profile(s) to use
+ *  eLevel                   : H.263 level(s) to use
+ *  bPLUSPTYPEAllowed        : Indicating that it is allowed to use PLUSPTYPE
+ *                             (specified in the 1998 version of H.263) to
+ *                             indicate custom picture sizes or clock
+ *                             frequencies
+ *  nAllowedPictureTypes     : Specifies the picture types allowed in the
+ *                             bitstream
+ *  bForceRoundingTypeToZero : value of the RTYPE bit (bit 6 of MPPTYPE) is
+ *                             not constrained. It is recommended to change
+ *                             the value of the RTYPE bit for each reference
+ *                             picture in error-free communication
+ *  nPictureHeaderRepetition : Specifies the frequency of picture header
+ *                             repetition
+ *  nGOBHeaderInterval       : Specifies the interval of non-empty GOB
+ *                             headers in units of GOBs
+ */
+typedef struct OMX_VIDEO_PARAM_H263TYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nPFrames;
+    OMX_U32 nBFrames;
+    OMX_VIDEO_H263PROFILETYPE eProfile;
+    OMX_VIDEO_H263LEVELTYPE eLevel;
+    OMX_BOOL bPLUSPTYPEAllowed;
+    OMX_U32 nAllowedPictureTypes;
+    OMX_BOOL bForceRoundingTypeToZero;
+    OMX_U32 nPictureHeaderRepetition;
+    OMX_U32 nGOBHeaderInterval;
+} OMX_VIDEO_PARAM_H263TYPE;
+
+
+/**
+ * MPEG-2 profile types, each profile indicates support for various
+ * performance bounds and different annexes.
+ */
+typedef enum OMX_VIDEO_MPEG2PROFILETYPE {
+    OMX_VIDEO_MPEG2ProfileSimple = 0,  /**< Simple Profile */
+    OMX_VIDEO_MPEG2ProfileMain,        /**< Main Profile */
+    OMX_VIDEO_MPEG2Profile422,         /**< 4:2:2 Profile */
+    OMX_VIDEO_MPEG2ProfileSNR,         /**< SNR Profile */
+    OMX_VIDEO_MPEG2ProfileSpatial,     /**< Spatial Profile */
+    OMX_VIDEO_MPEG2ProfileHigh,        /**< High Profile */
+    OMX_VIDEO_MPEG2ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_VIDEO_MPEG2ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_MPEG2ProfileMax = 0x7FFFFFFF
+} OMX_VIDEO_MPEG2PROFILETYPE;
+
+
+/**
+ * MPEG-2 level types, each level indicates support for various frame
+ * sizes, bit rates, decoder frame rates.  No need
+ */
+typedef enum OMX_VIDEO_MPEG2LEVELTYPE {
+    OMX_VIDEO_MPEG2LevelLL = 0,  /**< Low Level */
+    OMX_VIDEO_MPEG2LevelML,      /**< Main Level */
+    OMX_VIDEO_MPEG2LevelH14,     /**< High 1440 */
+    OMX_VIDEO_MPEG2LevelHL,      /**< High Level */
+    OMX_VIDEO_MPEG2LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_VIDEO_MPEG2LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_MPEG2LevelMax = 0x7FFFFFFF
+} OMX_VIDEO_MPEG2LEVELTYPE;
+
+
+/**
+ * MPEG-2 params
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  nPFrames   : Number of P frames between each I frame
+ *  nBFrames   : Number of B frames between each I frame
+ *  eProfile   : MPEG-2 profile(s) to use
+ *  eLevel     : MPEG-2 levels(s) to use
+ */
+typedef struct OMX_VIDEO_PARAM_MPEG2TYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nPFrames;
+    OMX_U32 nBFrames;
+    OMX_VIDEO_MPEG2PROFILETYPE eProfile;
+    OMX_VIDEO_MPEG2LEVELTYPE eLevel;
+} OMX_VIDEO_PARAM_MPEG2TYPE;
+
+
+/**
+ * MPEG-4 profile types, each profile indicates support for various
+ * performance bounds and different annexes.
+ *
+ * ENUMS:
+ *  - Simple Profile, Levels 1-3
+ *  - Simple Scalable Profile, Levels 1-2
+ *  - Core Profile, Levels 1-2
+ *  - Main Profile, Levels 2-4
+ *  - N-bit Profile, Level 2
+ *  - Scalable Texture Profile, Level 1
+ *  - Simple Face Animation Profile, Levels 1-2
+ *  - Simple Face and Body Animation (FBA) Profile, Levels 1-2
+ *  - Basic Animated Texture Profile, Levels 1-2
+ *  - Hybrid Profile, Levels 1-2
+ *  - Advanced Real Time Simple Profiles, Levels 1-4
+ *  - Core Scalable Profile, Levels 1-3
+ *  - Advanced Coding Efficiency Profile, Levels 1-4
+ *  - Advanced Core Profile, Levels 1-2
+ *  - Advanced Scalable Texture, Levels 2-3
+ */
+typedef enum OMX_VIDEO_MPEG4PROFILETYPE {
+    OMX_VIDEO_MPEG4ProfileSimple           = 0x01,
+    OMX_VIDEO_MPEG4ProfileSimpleScalable   = 0x02,
+    OMX_VIDEO_MPEG4ProfileCore             = 0x04,
+    OMX_VIDEO_MPEG4ProfileMain             = 0x08,
+    OMX_VIDEO_MPEG4ProfileNbit             = 0x10,
+    OMX_VIDEO_MPEG4ProfileScalableTexture  = 0x20,
+    OMX_VIDEO_MPEG4ProfileSimpleFace       = 0x40,
+    OMX_VIDEO_MPEG4ProfileSimpleFBA        = 0x80,
+    OMX_VIDEO_MPEG4ProfileBasicAnimated    = 0x100,
+    OMX_VIDEO_MPEG4ProfileHybrid           = 0x200,
+    OMX_VIDEO_MPEG4ProfileAdvancedRealTime = 0x400,
+    OMX_VIDEO_MPEG4ProfileCoreScalable     = 0x800,
+    OMX_VIDEO_MPEG4ProfileAdvancedCoding   = 0x1000,
+    OMX_VIDEO_MPEG4ProfileAdvancedCore     = 0x2000,
+    OMX_VIDEO_MPEG4ProfileAdvancedScalable = 0x4000,
+    OMX_VIDEO_MPEG4ProfileAdvancedSimple   = 0x8000,
+    OMX_VIDEO_MPEG4ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_VIDEO_MPEG4ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_MPEG4ProfileMax              = 0x7FFFFFFF
+} OMX_VIDEO_MPEG4PROFILETYPE;
+
+
+/**
+ * MPEG-4 level types, each level indicates support for various frame
+ * sizes, bit rates, decoder frame rates.  No need
+ */
+typedef enum OMX_VIDEO_MPEG4LEVELTYPE {
+    OMX_VIDEO_MPEG4Level0  = 0x01,   /**< Level 0 */
+    OMX_VIDEO_MPEG4Level0b = 0x02,   /**< Level 0b */
+    OMX_VIDEO_MPEG4Level1  = 0x04,   /**< Level 1 */
+    OMX_VIDEO_MPEG4Level2  = 0x08,   /**< Level 2 */
+    OMX_VIDEO_MPEG4Level3  = 0x10,   /**< Level 3 */
+    OMX_VIDEO_MPEG4Level4  = 0x20,   /**< Level 4 */
+    OMX_VIDEO_MPEG4Level4a = 0x40,   /**< Level 4a */
+    OMX_VIDEO_MPEG4Level5  = 0x80,   /**< Level 5 */
+    OMX_VIDEO_MPEG4LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_VIDEO_MPEG4LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_MPEG4LevelMax = 0x7FFFFFFF
+} OMX_VIDEO_MPEG4LEVELTYPE;
+
+
+/**
+ * MPEG-4 configuration.  This structure handles configuration options
+ * which are specific to MPEG4 algorithms
+ *
+ * STRUCT MEMBERS:
+ *  nSize                : Size of the structure in bytes
+ *  nVersion             : OMX specification version information
+ *  nPortIndex           : Port that this structure applies to
+ *  nSliceHeaderSpacing  : Number of macroblocks between slice header (H263+
+ *                         Annex K). Put zero if not used
+ *  bSVH                 : Enable Short Video Header mode
+ *  bGov                 : Flag to enable GOV
+ *  nPFrames             : Number of P frames between each I frame (also called
+ *                         GOV period)
+ *  nBFrames             : Number of B frames between each I frame
+ *  nIDCVLCThreshold     : Value of intra DC VLC threshold
+ *  bACPred              : Flag to use ac prediction
+ *  nMaxPacketSize       : Maximum size of packet in bytes.
+ *  nTimeIncRes          : Used to pass VOP time increment resolution for MPEG4.
+ *                         Interpreted as described in MPEG4 standard.
+ *  eProfile             : MPEG-4 profile(s) to use.
+ *  eLevel               : MPEG-4 level(s) to use.
+ *  nAllowedPictureTypes : Specifies the picture types allowed in the bitstream
+ *  nHeaderExtension     : Specifies the number of consecutive video packet
+ *                         headers within a VOP
+ *  bReversibleVLC       : Specifies whether reversible variable length coding
+ *                         is in use
+ */
+typedef struct OMX_VIDEO_PARAM_MPEG4TYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nSliceHeaderSpacing;
+    OMX_BOOL bSVH;
+    OMX_BOOL bGov;
+    OMX_U32 nPFrames;
+    OMX_U32 nBFrames;
+    OMX_U32 nIDCVLCThreshold;
+    OMX_BOOL bACPred;
+    OMX_U32 nMaxPacketSize;
+    OMX_U32 nTimeIncRes;
+    OMX_VIDEO_MPEG4PROFILETYPE eProfile;
+    OMX_VIDEO_MPEG4LEVELTYPE eLevel;
+    OMX_U32 nAllowedPictureTypes;
+    OMX_U32 nHeaderExtension;
+    OMX_BOOL bReversibleVLC;
+} OMX_VIDEO_PARAM_MPEG4TYPE;
+
+
+/**
+ * WMV Versions
+ */
+typedef enum OMX_VIDEO_WMVFORMATTYPE {
+    OMX_VIDEO_WMVFormatUnused = 0x01,   /**< Format unused or unknown */
+    OMX_VIDEO_WMVFormat7      = 0x02,   /**< Windows Media Video format 7 */
+    OMX_VIDEO_WMVFormat8      = 0x04,   /**< Windows Media Video format 8 */
+    OMX_VIDEO_WMVFormat9      = 0x08,   /**< Windows Media Video format 9 */
+    OMX_VIDEO_WMFFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_VIDEO_WMFFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_WMVFormatMax    = 0x7FFFFFFF
+} OMX_VIDEO_WMVFORMATTYPE;
+
+
+/**
+ * WMV Params
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  eFormat    : Version of WMV stream / data
+ */
+typedef struct OMX_VIDEO_PARAM_WMVTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_VIDEO_WMVFORMATTYPE eFormat;
+} OMX_VIDEO_PARAM_WMVTYPE;
+
+
+/**
+ * Real Video Version
+ */
+typedef enum OMX_VIDEO_RVFORMATTYPE {
+    OMX_VIDEO_RVFormatUnused = 0, /**< Format unused or unknown */
+    OMX_VIDEO_RVFormat8,          /**< Real Video format 8 */
+    OMX_VIDEO_RVFormat9,          /**< Real Video format 9 */
+    OMX_VIDEO_RVFormatG2,         /**< Real Video Format G2 */
+    OMX_VIDEO_RVFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_VIDEO_RVFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_RVFormatMax = 0x7FFFFFFF
+} OMX_VIDEO_RVFORMATTYPE;
+
+
+/**
+ * Real Video Params
+ *
+ * STUCT MEMBERS:
+ *  nSize              : Size of the structure in bytes
+ *  nVersion           : OMX specification version information
+ *  nPortIndex         : Port that this structure applies to
+ *  eFormat            : Version of RV stream / data
+ *  nBitsPerPixel      : Bits per pixel coded in the frame
+ *  nPaddedWidth       : Padded width in pixel of a video frame
+ *  nPaddedHeight      : Padded Height in pixels of a video frame
+ *  nFrameRate         : Rate of video in frames per second
+ *  nBitstreamFlags    : Flags which internal information about the bitstream
+ *  nBitstreamVersion  : Bitstream version
+ *  nMaxEncodeFrameSize: Max encoded frame size
+ *  bEnablePostFilter  : Turn on/off post filter
+ *  bEnableTemporalInterpolation : Turn on/off temporal interpolation
+ *  bEnableLatencyMode : When enabled, the decoder does not display a decoded
+ *                       frame until it has detected that no enhancement layer
+ *                       frames or dependent B frames will be coming. This
+ *                       detection usually occurs when a subsequent non-B
+ *                       frame is encountered
+ */
+typedef struct OMX_VIDEO_PARAM_RVTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_VIDEO_RVFORMATTYPE eFormat;
+    OMX_U16 nBitsPerPixel;
+    OMX_U16 nPaddedWidth;
+    OMX_U16 nPaddedHeight;
+    OMX_U32 nFrameRate;
+    OMX_U32 nBitstreamFlags;
+    OMX_U32 nBitstreamVersion;
+    OMX_U32 nMaxEncodeFrameSize;
+    OMX_BOOL bEnablePostFilter;
+    OMX_BOOL bEnableTemporalInterpolation;
+    OMX_BOOL bEnableLatencyMode;
+} OMX_VIDEO_PARAM_RVTYPE;
+
+
+/**
+ * AVC profile types, each profile indicates support for various
+ * performance bounds and different annexes.
+ */
+typedef enum OMX_VIDEO_AVCPROFILETYPE {
+    OMX_VIDEO_AVCProfileBaseline = 0x01,   /**< Baseline profile */
+    OMX_VIDEO_AVCProfileMain     = 0x02,   /**< Main profile */
+    OMX_VIDEO_AVCProfileExtended = 0x04,   /**< Extended profile */
+    OMX_VIDEO_AVCProfileHigh     = 0x08,   /**< High profile */
+    OMX_VIDEO_AVCProfileHigh10   = 0x10,   /**< High 10 profile */
+    OMX_VIDEO_AVCProfileHigh422  = 0x20,   /**< High 4:2:2 profile */
+    OMX_VIDEO_AVCProfileHigh444  = 0x40,   /**< High 4:4:4 profile */
+    OMX_VIDEO_AVCProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_VIDEO_AVCProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_AVCProfileMax      = 0x7FFFFFFF
+} OMX_VIDEO_AVCPROFILETYPE;
+
+
+/**
+ * AVC level types, each level indicates support for various frame sizes,
+ * bit rates, decoder frame rates.  No need
+ */
+typedef enum OMX_VIDEO_AVCLEVELTYPE {
+    OMX_VIDEO_AVCLevel1   = 0x01,     /**< Level 1 */
+    OMX_VIDEO_AVCLevel1b  = 0x02,     /**< Level 1b */
+    OMX_VIDEO_AVCLevel11  = 0x04,     /**< Level 1.1 */
+    OMX_VIDEO_AVCLevel12  = 0x08,     /**< Level 1.2 */
+    OMX_VIDEO_AVCLevel13  = 0x10,     /**< Level 1.3 */
+    OMX_VIDEO_AVCLevel2   = 0x20,     /**< Level 2 */
+    OMX_VIDEO_AVCLevel21  = 0x40,     /**< Level 2.1 */
+    OMX_VIDEO_AVCLevel22  = 0x80,     /**< Level 2.2 */
+    OMX_VIDEO_AVCLevel3   = 0x100,    /**< Level 3 */
+    OMX_VIDEO_AVCLevel31  = 0x200,    /**< Level 3.1 */
+    OMX_VIDEO_AVCLevel32  = 0x400,    /**< Level 3.2 */
+    OMX_VIDEO_AVCLevel4   = 0x800,    /**< Level 4 */
+    OMX_VIDEO_AVCLevel41  = 0x1000,   /**< Level 4.1 */
+    OMX_VIDEO_AVCLevel42  = 0x2000,   /**< Level 4.2 */
+    OMX_VIDEO_AVCLevel5   = 0x4000,   /**< Level 5 */
+    OMX_VIDEO_AVCLevel51  = 0x8000,   /**< Level 5.1 */
+    OMX_VIDEO_AVCLevel52  = 0x10000,  /**< Level 5.2 */
+    OMX_VIDEO_AVCLevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_VIDEO_AVCLevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_AVCLevelMax = 0x7FFFFFFF
+} OMX_VIDEO_AVCLEVELTYPE;
+
+
+/**
+ * AVC loop filter modes
+ *
+ * OMX_VIDEO_AVCLoopFilterEnable               : Enable
+ * OMX_VIDEO_AVCLoopFilterDisable              : Disable
+ * OMX_VIDEO_AVCLoopFilterDisableSliceBoundary : Disabled on slice boundaries
+ */
+typedef enum OMX_VIDEO_AVCLOOPFILTERTYPE {
+    OMX_VIDEO_AVCLoopFilterEnable = 0,
+    OMX_VIDEO_AVCLoopFilterDisable,
+    OMX_VIDEO_AVCLoopFilterDisableSliceBoundary,
+    OMX_VIDEO_AVCLoopFilterKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_VIDEO_AVCLoopFilterVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_AVCLoopFilterMax = 0x7FFFFFFF
+} OMX_VIDEO_AVCLOOPFILTERTYPE;
+
+
+/**
+ * AVC params
+ *
+ * STRUCT MEMBERS:
+ *  nSize                     : Size of the structure in bytes
+ *  nVersion                  : OMX specification version information
+ *  nPortIndex                : Port that this structure applies to
+ *  nSliceHeaderSpacing       : Number of macroblocks between slice header, put
+ *                              zero if not used
+ *  nPFrames                  : Number of P frames between each I frame
+ *  nBFrames                  : Number of B frames between each I frame
+ *  bUseHadamard              : Enable/disable Hadamard transform
+ *  nRefFrames                : Max number of reference frames to use for inter
+ *                              motion search (1-16)
+ *  nRefIdxTrailing           : Pic param set ref frame index (index into ref
+ *                              frame buffer of trailing frames list), B frame
+ *                              support
+ *  nRefIdxForward            : Pic param set ref frame index (index into ref
+ *                              frame buffer of forward frames list), B frame
+ *                              support
+ *  bEnableUEP                : Enable/disable unequal error protection. This
+ *                              is only valid of data partitioning is enabled.
+ *  bEnableFMO                : Enable/disable flexible macroblock ordering
+ *  bEnableASO                : Enable/disable arbitrary slice ordering
+ *  bEnableRS                 : Enable/disable sending of redundant slices
+ *  eProfile                  : AVC profile(s) to use
+ *  eLevel                    : AVC level(s) to use
+ *  nAllowedPictureTypes      : Specifies the picture types allowed in the
+ *                              bitstream
+ *  bFrameMBsOnly             : specifies that every coded picture of the
+ *                              coded video sequence is a coded frame
+ *                              containing only frame macroblocks
+ *  bMBAFF                    : Enable/disable switching between frame and
+ *                              field macroblocks within a picture
+ *  bEntropyCodingCABAC       : Entropy decoding method to be applied for the
+ *                              syntax elements for which two descriptors appear
+ *                              in the syntax tables
+ *  bWeightedPPrediction      : Enable/disable weighted prediction shall not
+ *                              be applied to P and SP slices
+ *  nWeightedBipredicitonMode : Default weighted prediction is applied to B
+ *                              slices
+ *  bconstIpred               : Enable/disable intra prediction
+ *  bDirect8x8Inference       : Specifies the method used in the derivation
+ *                              process for luma motion vectors for B_Skip,
+ *                              B_Direct_16x16 and B_Direct_8x8 as specified
+ *                              in subclause 8.4.1.2 of the AVC spec
+ *  bDirectSpatialTemporal    : Flag indicating spatial or temporal direct
+ *                              mode used in B slice coding (related to
+ *                              bDirect8x8Inference) . Spatial direct mode is
+ *                              more common and should be the default.
+ *  nCabacInitIdx             : Index used to init CABAC contexts
+ *  eLoopFilterMode           : Enable/disable loop filter
+ */
+typedef struct OMX_VIDEO_PARAM_AVCTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nSliceHeaderSpacing;
+    OMX_U32 nPFrames;
+    OMX_U32 nBFrames;
+    OMX_BOOL bUseHadamard;
+    OMX_U32 nRefFrames;
+    OMX_U32 nRefIdx10ActiveMinus1;
+    OMX_U32 nRefIdx11ActiveMinus1;
+    OMX_BOOL bEnableUEP;
+    OMX_BOOL bEnableFMO;
+    OMX_BOOL bEnableASO;
+    OMX_BOOL bEnableRS;
+    OMX_VIDEO_AVCPROFILETYPE eProfile;
+    OMX_VIDEO_AVCLEVELTYPE eLevel;
+    OMX_U32 nAllowedPictureTypes;
+    OMX_BOOL bFrameMBsOnly;
+    OMX_BOOL bMBAFF;
+    OMX_BOOL bEntropyCodingCABAC;
+    OMX_BOOL bWeightedPPrediction;
+    OMX_U32 nWeightedBipredicitonMode;
+    OMX_BOOL bconstIpred ;
+    OMX_BOOL bDirect8x8Inference;
+    OMX_BOOL bDirectSpatialTemporal;
+    OMX_U32 nCabacInitIdc;
+    OMX_VIDEO_AVCLOOPFILTERTYPE eLoopFilterMode;
+} OMX_VIDEO_PARAM_AVCTYPE;
+
+typedef struct OMX_VIDEO_PARAM_PROFILELEVELTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 eProfile;      /**< type is OMX_VIDEO_AVCPROFILETYPE, OMX_VIDEO_H263PROFILETYPE,
+                                 or OMX_VIDEO_MPEG4PROFILETYPE depending on context */
+    OMX_U32 eLevel;        /**< type is OMX_VIDEO_AVCLEVELTYPE, OMX_VIDEO_H263LEVELTYPE,
+                                 or OMX_VIDEO_MPEG4PROFILETYPE depending on context */
+    OMX_U32 nProfileIndex; /**< Used to query for individual profile support information,
+                               This parameter is valid only for
+                               OMX_IndexParamVideoProfileLevelQuerySupported index,
+                               For all other indices this parameter is to be ignored. */
+} OMX_VIDEO_PARAM_PROFILELEVELTYPE;
+
+/**
+ * Structure for dynamically configuring bitrate mode of a codec.
+ *
+ * STRUCT MEMBERS:
+ *  nSize          : Size of the struct in bytes
+ *  nVersion       : OMX spec version info
+ *  nPortIndex     : Port that this struct applies to
+ *  nEncodeBitrate : Target average bitrate to be generated in bps
+ */
+typedef struct OMX_VIDEO_CONFIG_BITRATETYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nEncodeBitrate;
+} OMX_VIDEO_CONFIG_BITRATETYPE;
+
+/**
+ * Defines Encoder Frame Rate setting
+ *
+ * STRUCT MEMBERS:
+ *  nSize            : Size of the structure in bytes
+ *  nVersion         : OMX specification version information
+ *  nPortIndex       : Port that this structure applies to
+ *  xEncodeFramerate : Encoding framerate represented in Q16 format
+ */
+typedef struct OMX_CONFIG_FRAMERATETYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 xEncodeFramerate; /* Q16 format */
+} OMX_CONFIG_FRAMERATETYPE;
+
+typedef struct OMX_CONFIG_INTRAREFRESHVOPTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL IntraRefreshVOP;
+} OMX_CONFIG_INTRAREFRESHVOPTYPE;
+
+typedef struct OMX_CONFIG_MACROBLOCKERRORMAPTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nErrMapSize;           /* Size of the Error Map in bytes */
+    OMX_U8  ErrMap[1];             /* Error map hint */
+} OMX_CONFIG_MACROBLOCKERRORMAPTYPE;
+
+typedef struct OMX_CONFIG_MBERRORREPORTINGTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL bEnabled;
+} OMX_CONFIG_MBERRORREPORTINGTYPE;
+
+typedef struct OMX_PARAM_MACROBLOCKSTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nMacroblocks;
+} OMX_PARAM_MACROBLOCKSTYPE;
+
+
+#ifdef AVS80
+/**
+ * Aspects of color.
+ */
+
+// NOTE: this structure is expected to grow in the future if new color aspects are
+// added to codec bitstreams. OMX component should not require a specific nSize
+// though could verify that nSize is at least the size of the structure at the
+// time of implementation. All new fields will be added at the end of the structure
+// ensuring backward compatibility.
+
+typedef enum OMX_RANGE {
+    RangeUnspecified,
+    RangeFull,
+    RangeLimited,
+    RangeOther = 0xff,
+} OMX_RANGE;
+
+typedef enum OMX_PRIMARIES {
+    PrimariesUnspecified,
+    PrimariesBT709_5,		// Rec.ITU-R BT.709-5 or equivalent
+    PrimariesBT470_6M,		// Rec.ITU-R BT.470-6 System M or equivalent
+    PrimariesBT601_6_625,	// Rec.ITU-R BT.601-6 625 or equivalent
+    PrimariesBT601_6_525,	// Rec.ITU-R BT.601-6 525 or equivalent
+    PrimariesGenericFilm,	// Generic Film
+    PrimariesBT2020,		// Rec.ITU-R BT.2020 or equivalent
+    PrimariesOther = 0xff,
+} OMX_PRIMARIES;
+
+typedef enum OMX_TRANSFER {
+    TransferUnspecified,
+    TransferLinear, 		// Linear transfer characteristics
+    TransferSRGB,			// sRGB or equivalent
+    TransferSMPTE170M,		// SMPTE 170M or equivalent (e.g. BT.601/709/2020)
+    TransferGamma22,		// Assumed display gamma 2.2
+    TransferGamma28,		// Assumed display gamma 2.8
+    TransferST2084, 		// SMPTE ST 2084 for 10/12/14/16 bit systems
+    TransferHLG,			// ARIB STD-B67 hybrid-log-gamma
+    // transfers unlikely to be required by Android
+    TransferSMPTE240M = 0x40, // SMPTE 240M
+    TransferXvYCC,			// IEC 61966-2-4
+    TransferBT1361, 		// Rec.ITU-R BT.1361 extended gamut
+    TransferST428,			// SMPTE ST 428-1
+    TransferOther = 0xff,
+} OMX_TRANSFER;
+
+typedef enum OMX_MATRIXCOEFFS {
+    MatrixUnspecified,
+    MatrixBT709_5,			// Rec.ITU-R BT.709-5 or equivalent
+    MatrixBT470_6M, 		// KR=0.30, KB=0.11 or equivalent
+    MatrixBT601_6,			// Rec.ITU-R BT.601-6 625 or equivalent
+    MatrixSMPTE240M,		// SMPTE 240M or equivalent
+    MatrixBT2020,			// Rec.ITU-R BT.2020 non-constant luminance
+    MatrixBT2020Constant,	// Rec.ITU-R BT.2020 constant luminance
+    MatrixOther = 0xff,
+} OMX_MATRIXCOEFFS;
+
+typedef struct OMX_COLORASPECTS {
+    OMX_RANGE mRange;                // IN/OUT
+    OMX_PRIMARIES mPrimaries;        // IN/OUT
+    OMX_TRANSFER mTransfer;          // IN/OUT
+    OMX_MATRIXCOEFFS mMatrixCoeffs;  // IN/OUT
+} OMX_COLORASPECTS;
+
+typedef struct OMX_CONFIG_DESCRIBECOLORASPECTSPARAMS {
+    OMX_U32  nSize;                // IN
+    OMX_VERSIONTYPE nVersion;      // IN
+    OMX_U32  nPortIndex;           // IN
+    OMX_BOOL bRequestingDataSpace; // IN
+    OMX_BOOL bDataSpaceChanged;    // IN
+    OMX_U32  nPixelFormat;         // IN
+    OMX_U32  nDataSpace;           // OUT
+    OMX_COLORASPECTS sAspects;  // IN/OUT
+} OMX_CONFIG_DESCRIBECOLORASPECTSPARAMS;
+#endif
+
+/**
+ * AVC Slice Mode modes
+ *
+ * OMX_VIDEO_SLICEMODE_AVCDefault   : Normal frame encoding, one slice per frame
+ * OMX_VIDEO_SLICEMODE_AVCMBSlice   : NAL mode, number of MBs per frame
+ * OMX_VIDEO_SLICEMODE_AVCByteSlice : NAL mode, number of bytes per frame
+ */
+typedef enum OMX_VIDEO_AVCSLICEMODETYPE {
+    OMX_VIDEO_SLICEMODE_AVCDefault = 0,
+    OMX_VIDEO_SLICEMODE_AVCMBSlice,
+    OMX_VIDEO_SLICEMODE_AVCByteSlice,
+    OMX_VIDEO_SLICEMODE_AVCKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_VIDEO_SLICEMODE_AVCVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_SLICEMODE_AVCLevelMax = 0x7FFFFFFF
+} OMX_VIDEO_AVCSLICEMODETYPE;
+
+/**
+ * AVC FMO Slice Mode Params
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  nNumSliceGroups : Specifies the number of slice groups
+ *  nSliceGroupMapType : Specifies the type of slice groups
+ *  eSliceMode : Specifies the type of slice
+ */
+typedef struct OMX_VIDEO_PARAM_AVCSLICEFMO {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U8 nNumSliceGroups;
+    OMX_U8 nSliceGroupMapType;
+    OMX_VIDEO_AVCSLICEMODETYPE eSliceMode;
+} OMX_VIDEO_PARAM_AVCSLICEFMO;
+
+/**
+ * AVC IDR Period Configs
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  nIDRPeriod : Specifies periodicity of IDR frames
+ *  nPFrames : Specifies internal of coding Intra frames
+ */
+typedef struct OMX_VIDEO_CONFIG_AVCINTRAPERIOD {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nIDRPeriod;
+    OMX_U32 nPFrames;
+} OMX_VIDEO_CONFIG_AVCINTRAPERIOD;
+
+/**
+ * AVC NAL Size Configs
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  nNaluBytes : Specifies the NAL unit size
+ */
+typedef struct OMX_VIDEO_CONFIG_NALSIZE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nNaluBytes;
+} OMX_VIDEO_CONFIG_NALSIZE;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */
+

+ 401 - 0
omx-il/include/khronos/OMX_VideoExt.h

@@ -0,0 +1,401 @@
+/*
+ * Copyright (c) 2010 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** OMX_VideoExt.h - OpenMax IL version 1.1.2
+ * The OMX_VideoExt header file contains extensions to the
+ * definitions used by both the application and the component to
+ * access video items.
+ */
+
+#ifndef OMX_VideoExt_h
+#define OMX_VideoExt_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Each OMX header shall include all required header files to allow the
+ * header to compile without errors.  The includes below are required
+ * for this header file to compile successfully
+ */
+#include <OMX_Core.h>
+
+/** NALU Formats */
+typedef enum OMX_NALUFORMATSTYPE {
+    OMX_NaluFormatStartCodes = 1,
+    OMX_NaluFormatOneNaluPerBuffer = 2,
+    OMX_NaluFormatOneByteInterleaveLength = 4,
+    OMX_NaluFormatTwoByteInterleaveLength = 8,
+    OMX_NaluFormatFourByteInterleaveLength = 16,
+    OMX_NaluFormatCodingMax = 0x7FFFFFFF
+} OMX_NALUFORMATSTYPE;
+
+/** NAL Stream Format */
+typedef struct OMX_NALSTREAMFORMATTYPE{
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_NALUFORMATSTYPE eNaluFormat;
+} OMX_NALSTREAMFORMATTYPE;
+
+/** VP8 profiles */
+typedef enum OMX_VIDEO_VP8PROFILETYPE {
+    OMX_VIDEO_VP8ProfileMain = 0x01,
+    OMX_VIDEO_VP8ProfileUnknown = 0x6EFFFFFF,
+    OMX_VIDEO_VP8ProfileMax = 0x7FFFFFFF
+} OMX_VIDEO_VP8PROFILETYPE;
+
+/** VP8 levels */
+typedef enum OMX_VIDEO_VP8LEVELTYPE {
+    OMX_VIDEO_VP8Level_Version0 = 0x01,
+    OMX_VIDEO_VP8Level_Version1 = 0x02,
+    OMX_VIDEO_VP8Level_Version2 = 0x04,
+    OMX_VIDEO_VP8Level_Version3 = 0x08,
+    OMX_VIDEO_VP8LevelUnknown = 0x6EFFFFFF,
+    OMX_VIDEO_VP8LevelMax = 0x7FFFFFFF
+} OMX_VIDEO_VP8LEVELTYPE;
+
+/** VP9 profiles */
+typedef enum OMX_VIDEO_VP9PROFILETYPE {
+    OMX_VIDEO_VP9Profile0       = 0x1,
+    OMX_VIDEO_VP9Profile1       = 0x2,
+    OMX_VIDEO_VP9Profile2       = 0x4,
+    OMX_VIDEO_VP9Profile3       = 0x8,
+    // HDR profiles also support passing HDR metadata
+    OMX_VIDEO_VP9Profile2HDR    = 0x1000,
+    OMX_VIDEO_VP9Profile3HDR    = 0x2000,
+    OMX_VIDEO_VP9ProfileUnknown = 0x6EFFFFFF,
+    OMX_VIDEO_VP9ProfileMax     = 0x7FFFFFFF
+} OMX_VIDEO_VP9PROFILETYPE;
+
+/** VP9 levels */
+typedef enum OMX_VIDEO_VP9LEVELTYPE {
+    OMX_VIDEO_VP9Level1       = 0x1,
+    OMX_VIDEO_VP9Level11      = 0x2,
+    OMX_VIDEO_VP9Level2       = 0x4,
+    OMX_VIDEO_VP9Level21      = 0x8,
+    OMX_VIDEO_VP9Level3       = 0x10,
+    OMX_VIDEO_VP9Level31      = 0x20,
+    OMX_VIDEO_VP9Level4       = 0x40,
+    OMX_VIDEO_VP9Level41      = 0x80,
+    OMX_VIDEO_VP9Level5       = 0x100,
+    OMX_VIDEO_VP9Level51      = 0x200,
+    OMX_VIDEO_VP9Level52      = 0x400,
+    OMX_VIDEO_VP9Level6       = 0x800,
+    OMX_VIDEO_VP9Level61      = 0x1000,
+    OMX_VIDEO_VP9Level62      = 0x2000,
+    OMX_VIDEO_VP9LevelUnknown = 0x6EFFFFFF,
+    OMX_VIDEO_VP9LevelMax     = 0x7FFFFFFF
+} OMX_VIDEO_VP9LEVELTYPE;
+
+/** VP8 Param */
+typedef struct OMX_VIDEO_PARAM_VP8TYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_VIDEO_VP8PROFILETYPE eProfile;
+    OMX_VIDEO_VP8LEVELTYPE eLevel;
+    OMX_U32 nDCTPartitions;
+    OMX_BOOL bErrorResilientMode;
+} OMX_VIDEO_PARAM_VP8TYPE;
+
+/** Structure for configuring VP8 reference frames */
+typedef struct OMX_VIDEO_VP8REFERENCEFRAMETYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL bPreviousFrameRefresh;
+    OMX_BOOL bGoldenFrameRefresh;
+    OMX_BOOL bAlternateFrameRefresh;
+    OMX_BOOL bUsePreviousFrame;
+    OMX_BOOL bUseGoldenFrame;
+    OMX_BOOL bUseAlternateFrame;
+} OMX_VIDEO_VP8REFERENCEFRAMETYPE;
+
+/** Structure for querying VP8 reference frame type */
+typedef struct OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL bIsIntraFrame;
+    OMX_BOOL bIsGoldenOrAlternateFrame;
+} OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE;
+
+/** Maximum number of VP8 temporal layers */
+#define OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS 3
+
+/** VP8 temporal layer patterns */
+typedef enum OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE {
+    OMX_VIDEO_VPXTemporalLayerPatternNone = 0,
+    OMX_VIDEO_VPXTemporalLayerPatternWebRTC = 1,
+    OMX_VIDEO_VPXTemporalLayerPatternMax = 0x7FFFFFFF
+} OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE;
+
+/**
+ * Android specific VP8 encoder params
+ *
+ * STRUCT MEMBERS:
+ *  nSize                      : Size of the structure in bytes
+ *  nVersion                   : OMX specification version information
+ *  nPortIndex                 : Port that this structure applies to
+ *  nKeyFrameInterval          : Key frame interval in frames
+ *  eTemporalPattern           : Type of temporal layer pattern
+ *  nTemporalLayerCount        : Number of temporal coding layers
+ *  nTemporalLayerBitrateRatio : Bitrate ratio allocation between temporal
+ *                               streams in percentage
+ *  nMinQuantizer              : Minimum (best quality) quantizer
+ *  nMaxQuantizer              : Maximum (worst quality) quantizer
+ */
+typedef struct OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nKeyFrameInterval;        // distance between consecutive key_frames (including one
+                                      // of the key_frames). 0 means interval is unspecified and
+                                      // can be freely chosen by the codec. 1 means a stream of
+                                      // only key_frames.
+
+    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE eTemporalPattern;
+    OMX_U32 nTemporalLayerCount;
+    OMX_U32 nTemporalLayerBitrateRatio[OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS];
+    OMX_U32 nMinQuantizer;
+    OMX_U32 nMaxQuantizer;
+} OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE;
+
+/** HEVC Profile enum type */
+typedef enum OMX_VIDEO_HEVCPROFILETYPE {
+    OMX_VIDEO_HEVCProfileUnknown      = 0x0,
+    OMX_VIDEO_HEVCProfileMain         = 0x1,
+    OMX_VIDEO_HEVCProfileMain10       = 0x2,
+    // Main10 profile with HDR SEI support.
+    OMX_VIDEO_HEVCProfileMain10HDR10  = 0x1000,
+    OMX_VIDEO_HEVCProfileMax          = 0x7FFFFFFF
+} OMX_VIDEO_HEVCPROFILETYPE;
+
+/** HEVC Level enum type */
+typedef enum OMX_VIDEO_HEVCLEVELTYPE {
+    OMX_VIDEO_HEVCLevelUnknown    = 0x0,
+    OMX_VIDEO_HEVCMainTierLevel1  = 0x1,
+    OMX_VIDEO_HEVCHighTierLevel1  = 0x2,
+    OMX_VIDEO_HEVCMainTierLevel2  = 0x4,
+    OMX_VIDEO_HEVCHighTierLevel2  = 0x8,
+    OMX_VIDEO_HEVCMainTierLevel21 = 0x10,
+    OMX_VIDEO_HEVCHighTierLevel21 = 0x20,
+    OMX_VIDEO_HEVCMainTierLevel3  = 0x40,
+    OMX_VIDEO_HEVCHighTierLevel3  = 0x80,
+    OMX_VIDEO_HEVCMainTierLevel31 = 0x100,
+    OMX_VIDEO_HEVCHighTierLevel31 = 0x200,
+    OMX_VIDEO_HEVCMainTierLevel4  = 0x400,
+    OMX_VIDEO_HEVCHighTierLevel4  = 0x800,
+    OMX_VIDEO_HEVCMainTierLevel41 = 0x1000,
+    OMX_VIDEO_HEVCHighTierLevel41 = 0x2000,
+    OMX_VIDEO_HEVCMainTierLevel5  = 0x4000,
+    OMX_VIDEO_HEVCHighTierLevel5  = 0x8000,
+    OMX_VIDEO_HEVCMainTierLevel51 = 0x10000,
+    OMX_VIDEO_HEVCHighTierLevel51 = 0x20000,
+    OMX_VIDEO_HEVCMainTierLevel52 = 0x40000,
+    OMX_VIDEO_HEVCHighTierLevel52 = 0x80000,
+    OMX_VIDEO_HEVCMainTierLevel6  = 0x100000,
+    OMX_VIDEO_HEVCHighTierLevel6  = 0x200000,
+    OMX_VIDEO_HEVCMainTierLevel61 = 0x400000,
+    OMX_VIDEO_HEVCHighTierLevel61 = 0x800000,
+    OMX_VIDEO_HEVCMainTierLevel62 = 0x1000000,
+    OMX_VIDEO_HEVCHighTierLevel62 = 0x2000000,
+    OMX_VIDEO_HEVCHighTiermax     = 0x7FFFFFFF
+} OMX_VIDEO_HEVCLEVELTYPE;
+
+/** Structure for controlling HEVC video encoding */
+typedef struct OMX_VIDEO_PARAM_HEVCTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_VIDEO_HEVCPROFILETYPE eProfile;
+    OMX_VIDEO_HEVCLEVELTYPE eLevel;
+    OMX_U32 nKeyFrameInterval;        // distance between consecutive I-frames (including one
+                                      // of the I frames). 0 means interval is unspecified and
+                                      // can be freely chosen by the codec. 1 means a stream of
+                                      // only I frames.
+} OMX_VIDEO_PARAM_HEVCTYPE;
+
+/** Structure to define if dependent slice segments should be used */
+typedef struct OMX_VIDEO_SLICESEGMENTSTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL bDepedentSegments;
+    OMX_BOOL bEnableLoopFilterAcrossSlices;
+} OMX_VIDEO_SLICESEGMENTSTYPE;
+
+/** Structure to return timestamps of rendered output frames as well as EOS
+ *  for tunneled components.
+ */
+typedef struct OMX_VIDEO_RENDEREVENTTYPE {
+    OMX_S64 nMediaTimeUs;  // timestamp of rendered video frame
+    OMX_S64 nSystemTimeNs; // system monotonic time at the time frame was rendered
+                           // Use INT64_MAX for nMediaTimeUs to signal that the EOS
+                           // has been reached. In this case, nSystemTimeNs MUST be
+                           // the system time when the last frame was rendered.
+                           // This MUST be done in addition to returning (and
+                           // following) the render information for the last frame.
+} OMX_VIDEO_RENDEREVENTTYPE;
+
+/** Dolby Vision Profile enum type */
+typedef enum OMX_VIDEO_DOLBYVISIONPROFILETYPE {
+    OMX_VIDEO_DolbyVisionProfileUnknown = 0x0,
+    OMX_VIDEO_DolbyVisionProfileDvavPer = 0x1,
+    OMX_VIDEO_DolbyVisionProfileDvavPen = 0x2,
+    OMX_VIDEO_DolbyVisionProfileDvheDer = 0x4,
+    OMX_VIDEO_DolbyVisionProfileDvheDen = 0x8,
+    OMX_VIDEO_DolbyVisionProfileDvheDtr = 0x10,
+    OMX_VIDEO_DolbyVisionProfileDvheStn = 0x20,
+    OMX_VIDEO_DolbyVisionProfileDvheDth = 0x40,
+    OMX_VIDEO_DolbyVisionProfileDvheDtb = 0x80,
+    OMX_VIDEO_DolbyVisionProfileMax     = 0x7FFFFFFF
+} OMX_VIDEO_DOLBYVISIONPROFILETYPE;
+
+/** Dolby Vision Level enum type */
+typedef enum OMX_VIDEO_DOLBYVISIONLEVELTYPE {
+    OMX_VIDEO_DolbyVisionLevelUnknown = 0x0,
+    OMX_VIDEO_DolbyVisionLevelHd24    = 0x1,
+    OMX_VIDEO_DolbyVisionLevelHd30    = 0x2,
+    OMX_VIDEO_DolbyVisionLevelFhd24   = 0x4,
+    OMX_VIDEO_DolbyVisionLevelFhd30   = 0x8,
+    OMX_VIDEO_DolbyVisionLevelFhd60   = 0x10,
+    OMX_VIDEO_DolbyVisionLevelUhd24   = 0x20,
+    OMX_VIDEO_DolbyVisionLevelUhd30   = 0x40,
+    OMX_VIDEO_DolbyVisionLevelUhd48   = 0x80,
+    OMX_VIDEO_DolbyVisionLevelUhd60   = 0x100,
+    OMX_VIDEO_DolbyVisionLevelmax     = 0x7FFFFFFF
+} OMX_VIDEO_DOLBYVISIONLEVELTYPE;
+
+/**
+ * Structure for configuring video compression intra refresh period
+ *
+ * STRUCT MEMBERS:
+ *  nSize               : Size of the structure in bytes
+ *  nVersion            : OMX specification version information
+ *  nPortIndex          : Port that this structure applies to
+ *  nRefreshPeriod      : Intra refreh period in frames. Value 0 means disable intra refresh
+ */
+typedef struct OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nRefreshPeriod;
+} OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE;
+
+/** Maximum number of temporal layers supported by AVC/HEVC */
+#define OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS 8
+
+/** temporal layer patterns */
+typedef enum OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE {
+    OMX_VIDEO_AndroidTemporalLayeringPatternNone = 0,
+    // pattern as defined by WebRTC
+    OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC = 1 << 0,
+    // pattern where frames in any layer other than the base layer only depend on at most the very
+    // last frame from each preceding layer (other than the base layer.)
+    OMX_VIDEO_AndroidTemporalLayeringPatternAndroid = 1 << 1,
+} OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE;
+
+/**
+ * Android specific param for configuration of temporal layering.
+ * Android only supports temporal layering where successive layers each double the
+ * previous layer's framerate.
+ * NOTE: Reading this parameter at run-time SHALL return actual run-time values.
+ *
+ *  nSize                      : Size of the structure in bytes
+ *  nVersion                   : OMX specification version information
+ *  nPortIndex                 : Port that this structure applies to (output port for encoders)
+ *  eSupportedPatterns         : A bitmask of supported layering patterns
+ *  nLayerCountMax             : Max number of temporal coding layers supported
+ *                               by the encoder (must be at least 1, 1 meaning temporal layering
+ *                               is NOT supported)
+ *  nBLayerCountMax            : Max number of layers that can contain B frames
+ *                               (0) to (nLayerCountMax - 1)
+ *  ePattern                   : Layering pattern.
+ *  nPLayerCountActual         : Number of temporal layers to be coded with non-B frames,
+ *                               starting from and including the base-layer.
+ *                               (1 to nLayerCountMax - nBLayerCountActual)
+ *                               If nPLayerCountActual is 1 and nBLayerCountActual is 0, temporal
+ *                               layering is disabled. Otherwise, it is enabled.
+ *  nBLayerCountActual         : Number of temporal layers to be coded with B frames,
+ *                               starting after non-B layers.
+ *                               (0 to nBLayerCountMax)
+ *  bBitrateRatiosSpecified    : Flag to indicate if layer-wise bitrate
+ *                               distribution is specified.
+ *  nBitrateRatios             : Bitrate ratio (100 based) per layer (index 0 is base layer).
+ *                               Honored if bBitrateRatiosSpecified is set.
+ *                               i.e for 4 layers with desired distribution (25% 25% 25% 25%),
+ *                               nBitrateRatio = {25, 50, 75, 100, ... }
+ *                               Values in indices not less than 'the actual number of layers
+ *                               minus 1' MAY be ignored and assumed to be 100.
+ */
+typedef struct OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE eSupportedPatterns;
+    OMX_U32 nLayerCountMax;
+    OMX_U32 nBLayerCountMax;
+    OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE ePattern;
+    OMX_U32 nPLayerCountActual;
+    OMX_U32 nBLayerCountActual;
+    OMX_BOOL bBitrateRatiosSpecified;
+    OMX_U32 nBitrateRatios[OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS];
+} OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE;
+
+/**
+ * Android specific config for changing the temporal-layer count or
+ * bitrate-distribution at run-time.
+ *
+ *  nSize                      : Size of the structure in bytes
+ *  nVersion                   : OMX specification version information
+ *  nPortIndex                 : Port that this structure applies to (output port for encoders)
+ *  ePattern                   : Layering pattern.
+ *  nPLayerCountActual         : Number of temporal layers to be coded with non-B frames.
+ *                               (same OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE limits apply.)
+ *  nBLayerCountActual         : Number of temporal layers to be coded with B frames.
+ *                               (same OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE limits apply.)
+ *  bBitrateRatiosSpecified    : Flag to indicate if layer-wise bitrate
+ *                               distribution is specified.
+ *  nBitrateRatios             : Bitrate ratio (100 based, Q16 values) per layer (0 is base layer).
+ *                               Honored if bBitrateRatiosSpecified is set.
+ *                               (same OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE limits apply.)
+ */
+typedef struct OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE ePattern;
+    OMX_U32 nPLayerCountActual;
+    OMX_U32 nBLayerCountActual;
+    OMX_BOOL bBitrateRatiosSpecified;
+    OMX_U32 nBitrateRatios[OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS];
+} OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* OMX_VideoExt_h */
+/* File EOF */

+ 488 - 0
omx-il/tests/dec_test.c

@@ -0,0 +1,488 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 StarFive Technology Co., Ltd.
+ */
+#include <stdio.h>
+#include <unistd.h>
+#include <signal.h>
+#include <getopt.h>
+#include <fcntl.h>
+#include "libavformat/avformat.h"
+#include <OMX_Core.h>
+#include <OMX_Component.h>
+#include <OMX_Video.h>
+#include <OMX_IndexExt.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+
+#define OMX_INIT_STRUCTURE(a)         \
+    memset(&(a), 0, sizeof(a));       \
+    (a).nSize = sizeof(a);            \
+    (a).nVersion.nVersion = 1;        \
+    (a).nVersion.s.nVersionMajor = 1; \
+    (a).nVersion.s.nVersionMinor = 1; \
+    (a).nVersion.s.nRevision = 1;     \
+    (a).nVersion.s.nStep = 1
+
+typedef struct Message
+{
+    long msg_type;
+    OMX_S32 msg_flag;
+    OMX_BUFFERHEADERTYPE *pBuffer;
+} Message;
+
+typedef struct DecodeTestContext
+{
+    OMX_HANDLETYPE hComponentDecoder;
+    char sOutputFilePath[64];
+    char sInputFilePath[64];
+    char sOutputFormat[64];
+    OMX_U32 ScaleWidth;
+    OMX_U32 ScaleHeight;
+    OMX_BUFFERHEADERTYPE *pInputBufferArray[64];
+    OMX_BUFFERHEADERTYPE *pOutputBufferArray[64];
+    AVFormatContext *avContext;
+    OMX_STATETYPE comState;
+    int msgid;
+} DecodeTestContext;
+DecodeTestContext *decodeTestContext;
+static OMX_S32 FillInputBuffer(DecodeTestContext *decodeTestContext, OMX_BUFFERHEADERTYPE *pInputBuffer);
+
+static OMX_BOOL disableEVnt;
+
+static OMX_ERRORTYPE event_handler(
+    OMX_HANDLETYPE hComponent,
+    OMX_PTR pAppData,
+    OMX_EVENTTYPE eEvent,
+    OMX_U32 nData1,
+    OMX_U32 nData2,
+    OMX_PTR pEventData)
+{
+    DecodeTestContext *pDecodeTestContext = (DecodeTestContext *)pAppData;
+
+    switch (eEvent)
+    {
+    case OMX_EventPortSettingsChanged:
+    {
+        OMX_PARAM_PORTDEFINITIONTYPE pOutputPortDefinition;
+        OMX_INIT_STRUCTURE(pOutputPortDefinition);
+        pOutputPortDefinition.nPortIndex = 1;
+        OMX_GetParameter(pDecodeTestContext->hComponentDecoder, OMX_IndexParamPortDefinition, &pOutputPortDefinition);
+        OMX_U32 nOutputBufferSize = pOutputPortDefinition.nBufferSize;
+        OMX_U32 nOutputBufferCount = pOutputPortDefinition.nBufferCountMin;
+
+        printf("enable output port and alloc buffer\n");
+        OMX_SendCommand(pDecodeTestContext->hComponentDecoder, OMX_CommandPortEnable, 1, NULL);
+
+        for (int i = 0; i < nOutputBufferCount; i++)
+        {
+            OMX_BUFFERHEADERTYPE *pBuffer = NULL;
+            OMX_AllocateBuffer(hComponent, &pBuffer, 1, NULL, nOutputBufferSize);
+            pDecodeTestContext->pOutputBufferArray[i] = pBuffer;
+            OMX_FillThisBuffer(hComponent, pBuffer);
+        }
+    }
+    break;
+    case OMX_EventBufferFlag:
+    {
+        Message data;
+        data.msg_type = 1;
+        data.msg_flag = -1;
+        if (msgsnd(pDecodeTestContext->msgid, (void *)&data, sizeof(data) - sizeof(data.msg_type), 0) == -1)
+        {
+            fprintf(stderr, "msgsnd failed\n");
+        }
+    }
+    break;
+    case OMX_EventCmdComplete:
+    {
+        switch ((OMX_COMMANDTYPE)(nData1))
+        {
+        case OMX_CommandStateSet:
+        {
+            pDecodeTestContext->comState = (OMX_STATETYPE)(nData2);
+        }
+        case OMX_CommandPortDisable:
+        {
+            if (nData2 == 1)
+                disableEVnt = OMX_TRUE;
+        }
+        break;
+        default:
+        break;
+        }
+    }
+    break;
+    default:
+        break;
+    }
+    return OMX_ErrorNone;
+}
+
+static void help()
+{
+    printf("video_dec_test - omx video hardware decode unit test case\r\n\r\n");
+    printf("Usage:\r\n\r\n");
+    printf("./video_dec_test -i <input file>      input file\r\n");
+    printf("                 -o <output file>     output file\r\n");
+    printf("                 -f <format>          i420/nv12/nv21\r\n");
+    printf("                 --scaleW=<width>     (optional) scale width down. ceil8(width/8) <= scaledW <= width\r\n");
+    printf("                 --scaleH=<heitht>    (optional) scale height down, ceil8(height/8) <= scaledH <= height\r\n\r\n");
+    printf("./video_dec_test --help: show this message\r\n");
+}
+
+static OMX_ERRORTYPE fill_output_buffer_done_handler(
+    OMX_HANDLETYPE hComponent,
+    OMX_PTR pAppData,
+    OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    DecodeTestContext *pDecodeTestContext = (DecodeTestContext *)pAppData;
+
+    Message data;
+    data.msg_type = 1;
+    if ((pBuffer->nFlags) & (OMX_BUFFERFLAG_EOS == OMX_BUFFERFLAG_EOS))
+    {
+        data.msg_flag = -1;
+    }
+    else
+    {
+        data.msg_flag = 1;
+        data.pBuffer = pBuffer;
+    }
+    if (msgsnd(pDecodeTestContext->msgid, (void *)&data, sizeof(data) - sizeof(data.msg_type), 0) == -1)
+    {
+        fprintf(stderr, "msgsnd failed\n");
+    }
+
+    return OMX_ErrorNone;
+}
+
+static OMX_ERRORTYPE empty_buffer_done_handler(
+    OMX_HANDLETYPE hComponent,
+    OMX_PTR pAppData,
+    OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    DecodeTestContext *pDecodeTestContext = (DecodeTestContext *)pAppData;
+    Message data;
+    data.msg_type = 1;
+    data.msg_flag = 0;
+    data.pBuffer = pBuffer;
+    if (msgsnd(pDecodeTestContext->msgid, (void *)&data, sizeof(data) - sizeof(data.msg_type), 0) == -1)
+    {
+        fprintf(stderr, "msgsnd failed\n");
+    }
+    return OMX_ErrorNone;
+}
+
+static void signal_handle(int sig)
+{
+    printf("[%s,%d]: receive sig=%d \n", __FUNCTION__, __LINE__, sig);
+    Message data;
+    data.msg_type = 1;
+    data.msg_flag = -1;
+    if (msgsnd(decodeTestContext->msgid, (void *)&data, sizeof(data) - sizeof(data.msg_type), 0) == -1)
+    {
+        fprintf(stderr, "msgsnd failed\n");
+    }
+}
+
+static OMX_S32 FillInputBuffer(DecodeTestContext *decodeTestContext, OMX_BUFFERHEADERTYPE *pInputBuffer)
+{
+    AVFormatContext *avFormatContext = decodeTestContext->avContext;
+    AVPacket *avpacket;
+    OMX_S32 error;
+    avpacket = av_packet_alloc();
+    error = av_read_frame(avFormatContext, avpacket);
+    if (error < 0)
+    {
+        if (error == AVERROR_EOF || avFormatContext->pb->eof_reached == OMX_TRUE)
+        {
+            pInputBuffer->nFlags = 0x1;
+            pInputBuffer->nFilledLen = 0;
+            return 0;
+        }
+        else
+        {
+            printf("%s:%d failed to av_read_frame, error: %s\n",
+                    __FUNCTION__, __LINE__, av_err2str(error));
+            return 0;
+        }
+    }
+    pInputBuffer->nFlags = 0x10;
+    pInputBuffer->nFilledLen = avpacket->size;
+    if(!pInputBuffer->pBuffer || !avpacket->data)
+        return 0;
+    memcpy(pInputBuffer->pBuffer, avpacket->data, avpacket->size);
+    return avpacket->size;
+}
+
+int main(int argc, char **argv)
+{
+    printf("=============================\r\n");
+    OMX_S32 error;
+    FILE *fb;
+    decodeTestContext = malloc(sizeof(DecodeTestContext));
+    memset(decodeTestContext, 0, sizeof(DecodeTestContext));
+
+    OMX_S32 msgid = -1;
+    msgid = msgget(IPC_PRIVATE, 0666 | IPC_CREAT);
+    if (msgid < 0)
+    {
+        perror("get ipc_id error");
+        return -1;
+    }
+    decodeTestContext->msgid = msgid;
+    struct option longOpt[] = {
+        {"output", required_argument, NULL, 'o'},
+        {"input", required_argument, NULL, 'i'},
+        {"format", required_argument, NULL, 'f'},
+        {"scaleW", required_argument, NULL, 'w'},
+        {"scaleH", required_argument, NULL, 'h'},
+        {"help", no_argument, NULL, '0'},
+        {NULL, no_argument, NULL, 0},
+    };
+    char *shortOpt = "i:o:f:w:h:";
+    OMX_U32 c;
+    OMX_S32 l;
+
+    if (argc == 0)
+    {
+        help();
+        return -1;
+    }
+
+    while ((c = getopt_long(argc, argv, shortOpt, longOpt, (int *)&l)) != -1)
+    {
+        switch (c)
+        {
+        case 'i':
+            printf("input: %s\r\n", optarg);
+            if (access(optarg, R_OK) != -1)
+            {
+                memcpy(decodeTestContext->sInputFilePath, optarg, strlen(optarg));
+            }
+            else
+            {
+                printf("input file not exist!\r\n");
+                return -1;
+            }
+            break;
+        case 'o':
+            printf("output: %s\r\n", optarg);
+            memcpy(decodeTestContext->sOutputFilePath, optarg, strlen(optarg));
+            break;
+        case 'f':
+            printf("format: %s\r\n", optarg);
+            memcpy(decodeTestContext->sOutputFormat, optarg, strlen(optarg));
+            break;
+        case 'w':
+            printf("ScaleWidth: %s\r\n", optarg);
+            decodeTestContext->ScaleWidth = atoi(optarg);
+            break;
+        case 'h':
+            printf("ScaleHeight: %s\r\n", optarg);
+            decodeTestContext->ScaleHeight = atoi(optarg);
+            break;
+        case '0':
+        default:
+            help();
+            return -1;
+        }
+    }
+
+    if (decodeTestContext->sInputFilePath == NULL || decodeTestContext->sOutputFilePath == NULL)
+    {
+        help();
+        return -1;
+    }
+    /*ffmpeg init*/
+    printf("init ffmpeg\r\n");
+    AVFormatContext *avContext = NULL;
+    AVCodecParameters *codecParameters = NULL;
+    AVInputFormat *fmt = NULL;
+    OMX_S32 videoIndex;
+    if ((avContext = avformat_alloc_context()) == NULL)
+    {
+        printf("avformat_alloc_context fail\r\n");
+        return -1;
+    }
+    avContext->flags |= AV_CODEC_FLAG_TRUNCATED;
+
+    printf("avformat_open_input\r\n");
+    if ((error = avformat_open_input(&avContext, decodeTestContext->sInputFilePath, fmt, NULL)))
+    {
+        printf("%s:%d failed to av_open_input_file error(%s), %s\n",
+               __FILE__, __LINE__, av_err2str(error), decodeTestContext->sInputFilePath);
+        return -1;
+    }
+
+    printf("avformat_find_stream_info\r\n");
+    if ((error = avformat_find_stream_info(avContext, NULL)) < 0)
+    {
+        printf("%s:%d failed to avformat_find_stream_info. error(%s)\n",
+               __FUNCTION__, __LINE__, av_err2str(error));
+        return -1;
+    }
+
+    printf("av_find_best_stream\r\n");
+    videoIndex = av_find_best_stream(avContext, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
+    if (videoIndex < 0)
+    {
+        printf("%s:%d failed to av_find_best_stream.\n", __FUNCTION__, __LINE__);
+        return -1;
+    }
+    printf("video index = %ld\r\n", videoIndex);
+    decodeTestContext->avContext = avContext;
+    /*get video info*/
+    codecParameters = avContext->streams[videoIndex]->codecpar;
+    printf("codec_id = %d, width = %d, height = %d\r\n", (int)codecParameters->codec_id,
+           codecParameters->width, codecParameters->height);
+
+    /*omx init*/
+    OMX_HANDLETYPE hComponentDecoder  = NULL;
+    OMX_CALLBACKTYPE callbacks;
+    int ret = OMX_ErrorNone;
+    signal(SIGINT, signal_handle);
+    printf("init omx\r\n");
+    ret = OMX_Init();
+    if (ret != OMX_ErrorNone)
+    {
+        printf("[%s,%d]: run OMX_Init failed. ret is %d \n", __FUNCTION__, __LINE__, ret);
+        return 1;
+    }
+
+    callbacks.EventHandler = event_handler;
+    callbacks.FillBufferDone = fill_output_buffer_done_handler;
+    callbacks.EmptyBufferDone = empty_buffer_done_handler;
+    printf("get handle\r\n");
+    if (codecParameters->codec_id == AV_CODEC_ID_H264)
+    {
+        OMX_GetHandle(&hComponentDecoder, "OMX.sf.video_decoder.avc", decodeTestContext, &callbacks);
+    }
+    else if (codecParameters->codec_id == AV_CODEC_ID_HEVC)
+    {
+        OMX_GetHandle(&hComponentDecoder, "OMX.sf.video_decoder.hevc", decodeTestContext, &callbacks);
+    }
+    if (hComponentDecoder == NULL)
+    {
+        printf("could not get handle\r\n");
+        return 0;
+    }
+    decodeTestContext->hComponentDecoder = hComponentDecoder;
+     
+    OMX_PARAM_PORTDEFINITIONTYPE pOutputPortDefinition;
+    OMX_INIT_STRUCTURE(pOutputPortDefinition);
+    pOutputPortDefinition.nPortIndex = 1;
+    OMX_GetParameter(decodeTestContext->hComponentDecoder, OMX_IndexParamPortDefinition, &pOutputPortDefinition);
+    pOutputPortDefinition.format.video.nFrameWidth
+                = decodeTestContext->ScaleWidth? decodeTestContext->ScaleWidth:codecParameters->width;
+    pOutputPortDefinition.format.video.nFrameHeight
+                = decodeTestContext->ScaleHeight? decodeTestContext->ScaleHeight:codecParameters->height;
+    if (strstr(decodeTestContext->sOutputFormat, "nv12") != NULL)
+    {
+        pOutputPortDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+    }
+    else if (strstr(decodeTestContext->sOutputFormat, "nv21") != NULL)
+    {
+        pOutputPortDefinition.format.video.eColorFormat = OMX_COLOR_FormatYVU420SemiPlanar;
+    }
+    else if (strstr(decodeTestContext->sOutputFormat, "i420") != NULL)
+    {
+        pOutputPortDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
+    }
+    else
+    {
+        printf("Unsupported color format!\r\n");
+        goto end;
+    }
+    OMX_SetParameter(hComponentDecoder, OMX_IndexParamPortDefinition, &pOutputPortDefinition);
+
+    disableEVnt = OMX_FALSE;
+    OMX_SendCommand(hComponentDecoder, OMX_CommandPortDisable, 1, NULL);
+    printf("wait for output port disable\r\n");
+    while (!disableEVnt);
+    printf("output port disabled\r\n");
+
+    OMX_SendCommand(hComponentDecoder, OMX_CommandStateSet, OMX_StateIdle, NULL);
+
+    OMX_PARAM_PORTDEFINITIONTYPE pInputPortDefinition;
+    OMX_INIT_STRUCTURE(pInputPortDefinition);
+    pInputPortDefinition.nPortIndex = 0;
+    OMX_GetParameter(hComponentDecoder, OMX_IndexParamPortDefinition, &pInputPortDefinition);
+    pInputPortDefinition.format.video.nFrameWidth = codecParameters->width;
+    pInputPortDefinition.format.video.nFrameHeight = codecParameters->height;
+    OMX_SetParameter(hComponentDecoder, OMX_IndexParamPortDefinition, &pInputPortDefinition);
+    /*Alloc input buffer*/
+    OMX_U32 nInputWidth = codecParameters->width;
+    OMX_U32 nInputHeight = codecParameters->height;
+    OMX_U32 nInputBufferSize = nInputWidth * nInputHeight * 2;
+    OMX_U32 nInputBufferCount = pInputPortDefinition.nBufferCountActual;
+    for (int i = 0; i < nInputBufferCount; i++)
+    {
+        OMX_BUFFERHEADERTYPE *pBuffer = NULL;
+        OMX_AllocateBuffer(hComponentDecoder, &pBuffer, 0, NULL, nInputBufferSize);
+        decodeTestContext->pInputBufferArray[i] = pBuffer;
+    }
+
+    printf("wait for Component idle\r\n");
+    while (decodeTestContext->comState != OMX_StateIdle);
+    printf("Component in idle\r\n");
+
+    for (int i = 0; i < nInputBufferCount; i++)
+    {
+        /*Fill Input Buffer*/
+        FillInputBuffer(decodeTestContext, decodeTestContext->pInputBufferArray[i]);
+        OMX_EmptyThisBuffer(hComponentDecoder, decodeTestContext->pInputBufferArray[i]);
+    }
+
+    fb = fopen(decodeTestContext->sOutputFilePath, "wb+");
+
+    OMX_SendCommand(hComponentDecoder, OMX_CommandStateSet, OMX_StateExecuting, NULL);
+
+    /*wait until decode finished*/
+    Message data;
+    while (OMX_TRUE)
+    {
+        if (msgrcv(msgid, (void *)&data, BUFSIZ, 0, 0) == -1)
+        {
+            fprintf(stderr, "msgrcv failed with errno: %d\n", errno);
+            goto end;
+        }
+        switch (data.msg_flag)
+        {
+        case 0:
+        {
+            OMX_BUFFERHEADERTYPE *pBuffer = data.pBuffer;
+            FillInputBuffer(decodeTestContext, pBuffer);
+            OMX_EmptyThisBuffer(decodeTestContext->hComponentDecoder, pBuffer);
+        }
+        break;
+        case 1:
+        {
+            OMX_BUFFERHEADERTYPE *pBuffer = data.pBuffer;
+            fwrite(pBuffer->pBuffer, 1, pBuffer->nFilledLen, fb);
+            if ((pBuffer->nFlags) & (OMX_BUFFERFLAG_EOS == OMX_BUFFERFLAG_EOS))
+            {
+                goto end;
+            }
+            else
+            {
+                OMX_FillThisBuffer(decodeTestContext->hComponentDecoder, pBuffer);
+            }
+        }
+        break;
+        case 2:
+            break;
+        default:
+            goto end;
+        }
+    }
+
+end:
+    /*free resource*/
+    fclose(fb);
+    OMX_FreeHandle(hComponentDecoder);
+    OMX_Deinit();
+}

+ 497 - 0
omx-il/tests/enc_test.c

@@ -0,0 +1,497 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 StarFive Technology Co., Ltd.
+ */
+#include <stdio.h>
+#include <unistd.h>
+#include <signal.h>
+#include <getopt.h>
+#include <fcntl.h>
+#include <OMX_Core.h>
+#include <OMX_Component.h>
+#include <OMX_Video.h>
+#include <OMX_IndexExt.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define OMX_INIT_STRUCTURE(a)         \
+    memset(&(a), 0, sizeof(a));       \
+    (a).nSize = sizeof(a);            \
+    (a).nVersion.nVersion = 1;        \
+    (a).nVersion.s.nVersionMajor = 1; \
+    (a).nVersion.s.nVersionMinor = 1; \
+    (a).nVersion.s.nRevision = 1;     \
+    (a).nVersion.s.nStep = 1
+
+typedef struct Message
+{
+    long msg_type;
+    OMX_S32 msg_flag;
+    OMX_BUFFERHEADERTYPE *pBuffer;
+} Message;
+
+typedef struct EncodeTestContext
+{
+    OMX_HANDLETYPE hComponentEncoder;
+    char sOutputFilePath[64];
+    char sInputFilePath[64];
+    FILE *pInputFile;
+    char sInputFormat[64];
+    char sOutputFormat[64];
+    OMX_U32 nFrameBufferSize;
+    OMX_U32 nBitrate;
+    OMX_U32 nFrameRate;
+    OMX_U32 nNumPFrame;
+    OMX_STATETYPE comState;
+    OMX_BUFFERHEADERTYPE *pInputBufferArray[64];
+    OMX_BUFFERHEADERTYPE *pOutputBufferArray[64];
+    int msgid;
+} EncodeTestContext;
+EncodeTestContext *encodeTestContext;
+static OMX_S32 FillInputBuffer(EncodeTestContext *encodeTestContext, OMX_BUFFERHEADERTYPE *pInputBuffer);
+
+static OMX_BOOL disableEVnt;
+
+static OMX_ERRORTYPE event_handler(
+    OMX_HANDLETYPE hComponent,
+    OMX_PTR pAppData,
+    OMX_EVENTTYPE eEvent,
+    OMX_U32 nData1,
+    OMX_U32 nData2,
+    OMX_PTR pEventData)
+{
+    EncodeTestContext *pEncodeTestContext = (EncodeTestContext *)pAppData;
+
+    switch (eEvent)
+    {
+    case OMX_EventPortSettingsChanged:
+    {
+        OMX_PARAM_PORTDEFINITIONTYPE pOutputPortDefinition;
+        OMX_INIT_STRUCTURE(pOutputPortDefinition);
+        pOutputPortDefinition.nPortIndex = 1;
+        OMX_GetParameter(pEncodeTestContext->hComponentEncoder, OMX_IndexParamPortDefinition, &pOutputPortDefinition);
+        OMX_U32 nOutputBufferSize = pOutputPortDefinition.nBufferSize;
+        OMX_U32 nOutputBufferCount = pOutputPortDefinition.nBufferCountMin;
+
+        printf("enable output port and alloc buffer\n");
+        OMX_SendCommand(pEncodeTestContext->hComponentEncoder, OMX_CommandPortEnable, 1, NULL);
+
+        for (int i = 0; i < nOutputBufferCount; i++)
+        {
+            OMX_BUFFERHEADERTYPE *pBuffer = NULL;
+            OMX_AllocateBuffer(hComponent, &pBuffer, 1, NULL, nOutputBufferSize);
+            pEncodeTestContext->pOutputBufferArray[i] = pBuffer;
+            OMX_FillThisBuffer(hComponent, pBuffer);
+        }
+    }
+    break;
+    case OMX_EventBufferFlag:
+    {
+        Message data;
+        data.msg_type = 1;
+        data.msg_flag = -1;
+        if (msgsnd(pEncodeTestContext->msgid, (void *)&data, sizeof(data) - sizeof(data.msg_type), 0) == -1)
+        {
+            fprintf(stderr, "msgsnd failed\n");
+        }
+    }
+    break;
+    case OMX_EventCmdComplete:
+    {
+        switch ((OMX_COMMANDTYPE)(nData1))
+        {
+        case OMX_CommandStateSet:
+        {
+            pEncodeTestContext->comState = (OMX_STATETYPE)(nData2);
+        }
+        case OMX_CommandPortDisable:
+        {
+            if (nData2 == 1)
+                disableEVnt = OMX_TRUE;
+        }
+        break;
+        default:
+        break;
+        }
+    }
+    break;
+    default:
+        break;
+    }
+    return OMX_ErrorNone;
+}
+
+static void help()
+{
+    printf("video_enc_test - omx video hardware encode unit test case\r\n\r\n");
+    printf("Usage:\r\n\r\n");
+    printf("./video_enc_test -i <input file>       input file \r\n");
+    printf("                 -o <output file>      output file \r\n");
+    printf("                 -w <width>            input width \r\n");
+    printf("                 -h <height>           input hight \r\n");
+    printf("                 -s <Srcformat>        stream format h264/h265 \r\n");
+    printf("                 -c <cformat>          color format i420/nv12/nv21 \r\n");
+    printf("                 -b <bitrate>          (optional) set bit rate \r\n");
+    printf("                 -v <frame rate>       (optional) set frame rate \r\n");
+    printf("                 -g <num>              (optional) Number of P frames between each I frame for h264 only \r\n\r\n");
+    printf("./video_enc_test --help: show this message\r\n");
+}
+
+static OMX_ERRORTYPE fill_output_buffer_done_handler(
+    OMX_HANDLETYPE hComponent,
+    OMX_PTR pAppData,
+    OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    EncodeTestContext *pEncodeTestContext = (EncodeTestContext *)pAppData;
+
+    Message data;
+    data.msg_type = 1;
+    if ((pBuffer->nFlags) & (OMX_BUFFERFLAG_EOS == OMX_BUFFERFLAG_EOS))
+    {
+        data.msg_flag = -1;
+    }
+    else
+    {
+        data.msg_flag = 1;
+        data.pBuffer = pBuffer;
+    }
+    if (msgsnd(pEncodeTestContext->msgid, (void *)&data, sizeof(data) - sizeof(data.msg_type), 0) == -1)
+    {
+        fprintf(stderr, "msgsnd failed\n");
+    }
+
+    return OMX_ErrorNone;
+}
+
+static OMX_ERRORTYPE empty_buffer_done_handler(
+    OMX_HANDLETYPE hComponent,
+    OMX_PTR pAppData,
+    OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    EncodeTestContext *pEncodeTestContext = (EncodeTestContext *)pAppData;
+    Message data;
+    data.msg_type = 1;
+    data.msg_flag = 0;
+    data.pBuffer = pBuffer;
+    if (msgsnd(pEncodeTestContext->msgid, (void *)&data, sizeof(data) - sizeof(data.msg_type), 0) == -1)
+    {
+        fprintf(stderr, "msgsnd failed\n");
+    }
+    return OMX_ErrorNone;
+}
+
+static void signal_handle(int sig)
+{
+    printf("[%s,%d]: receive sig=%d \n", __FUNCTION__, __LINE__, sig);
+
+    OMX_FreeHandle(encodeTestContext->hComponentEncoder);
+    OMX_Deinit();
+    exit(0);
+    // Message data;
+    // data.msg_type = 1;
+    // data.msg_flag = -1;
+    // if (msgsnd(encodeTestContext->msgid, (void *)&data, sizeof(data) - sizeof(data.msg_type), 0) == -1)
+    // {
+    //     fprintf(stderr, "msgsnd failed\n");
+    // }
+}
+
+static OMX_S32 FillInputBuffer(EncodeTestContext *encodeTestContext, OMX_BUFFERHEADERTYPE *pInputBuffer)
+{
+    FILE *fp = encodeTestContext->pInputFile;
+    OMX_U32 size = encodeTestContext->nFrameBufferSize;
+    OMX_U32 count;
+
+    count = fread(pInputBuffer->pBuffer, 1, size, fp);
+    if (count < size)
+    {
+        Message data;
+        data.msg_type = 1;
+        data.msg_flag = -1;
+        pInputBuffer->nFlags = 0x1;
+        pInputBuffer->nFilledLen = 0;
+        count = 0;
+
+        if (msgsnd(encodeTestContext->msgid, (void *)&data, sizeof(data) - sizeof(data.msg_type), 0) == -1)
+        {
+            fprintf(stderr, "msgsnd failed\n");
+        }
+    }
+    else
+    {
+        pInputBuffer->nFlags = 0x10;
+        pInputBuffer->nFilledLen = size;
+    }
+
+    return count;
+}
+
+int main(int argc, char **argv)
+{
+    FILE *fb;
+    printf("=============================\r\n");
+    encodeTestContext = malloc(sizeof(EncodeTestContext));
+    memset(encodeTestContext, 0, sizeof(EncodeTestContext));
+
+    OMX_S32 msgid = -1;
+    msgid = msgget(IPC_PRIVATE, 0666 | IPC_CREAT);
+    if (msgid < 0)
+    {
+        perror("get ipc_id error");
+        return -1;
+    }
+    encodeTestContext->msgid = msgid;
+    struct option longOpt[] = {
+        {"output", required_argument, NULL, 'o'},
+        {"input", required_argument, NULL, 'f'},
+        {"colorformat", required_argument, NULL, 'c'},
+        {"streamformat", required_argument, NULL, 's'},
+        {"bitrate", required_argument, NULL, 'b'},
+        {"framerate", required_argument, NULL, 'v'},
+        {"width", required_argument, NULL, 'w'},
+        {"height", required_argument, NULL, 'h'},
+        {"gop", required_argument, NULL, 'g'},
+        {"help", no_argument, NULL, 0},
+        {NULL, no_argument, NULL, 0},
+    };
+    char *shortOpt = "i:o:f:s:w:h:b:v:c:g:";
+    OMX_U32 c;
+    OMX_S32 l;
+
+    if (argc == 0)
+    {
+        help();
+        return 0;
+    }
+    OMX_U32 width = 0;
+    OMX_U32 height = 0;
+    while ((c = getopt_long(argc, argv, shortOpt, longOpt, (int *)&l)) != -1)
+    {
+        switch (c)
+        {
+        case 'i':
+            printf("input: %s\r\n", optarg);
+            if (access(optarg, R_OK) != -1)
+            {
+                memcpy(encodeTestContext->sInputFilePath, optarg, strlen(optarg));
+                encodeTestContext->pInputFile = fopen(optarg, "r");
+            }
+            else
+            {
+                printf("input file not exist!\r\n");
+                return -1;
+            }
+            break;
+        case 'o':
+            printf("output: %s\r\n", optarg);
+            memcpy(encodeTestContext->sOutputFilePath, optarg, strlen(optarg));
+            break;
+        case 'c':
+            printf("color format: %s\r\n", optarg);
+            memcpy(encodeTestContext->sInputFormat, optarg, strlen(optarg));
+            break;
+        case 's':
+            printf("stream format: %s\r\n", optarg);
+            memcpy(encodeTestContext->sOutputFormat, optarg, strlen(optarg));
+            break;
+        case 'w':
+            printf("width: %s\r\n", optarg);
+            width = atoi(optarg);
+            break;
+        case 'h':
+            printf("height: %s\r\n", optarg);
+            height = atoi(optarg);
+            break;
+        case 'b':
+            printf("bit rate: %s\r\n", optarg);
+            encodeTestContext->nBitrate = atoi(optarg);
+            break;
+        case 'v':
+            printf("frame rate: %s\r\n", optarg);
+            encodeTestContext->nFrameRate = atoi(optarg);
+            break;
+        case 'g':
+            printf("P frames: %s\r\n", optarg);
+            encodeTestContext->nNumPFrame = atoi(optarg);
+            break;
+        case 0:
+        default:
+            help();
+            return 0;
+        }
+    }
+
+    encodeTestContext->nFrameBufferSize = width * height * 3 / 2;
+    if (encodeTestContext->sInputFilePath == NULL ||
+        encodeTestContext->sOutputFilePath == NULL ||
+        encodeTestContext->nFrameBufferSize == 0 ||
+        encodeTestContext->pInputFile == NULL)
+    {
+        help();
+        return -1;
+    }
+
+    /*omx init*/
+    OMX_HANDLETYPE hComponentEncoder = NULL;
+    OMX_CALLBACKTYPE callbacks;
+    int ret = OMX_ErrorNone;
+    signal(SIGINT, signal_handle);
+    printf("init omx\r\n");
+    ret = OMX_Init();
+    if (ret != OMX_ErrorNone)
+    {
+        printf("[%s,%d]: run OMX_Init failed. ret is %d \n", __FUNCTION__, __LINE__, ret);
+        return 1;
+    }
+
+    callbacks.EventHandler = event_handler;
+    callbacks.FillBufferDone = fill_output_buffer_done_handler;
+    callbacks.EmptyBufferDone = empty_buffer_done_handler;
+    printf("get handle %s\r\n", encodeTestContext->sOutputFormat);
+    if (strstr(encodeTestContext->sOutputFormat, "h264") != NULL)
+    {
+        OMX_GetHandle(&hComponentEncoder, "OMX.sf.video_encoder.avc", encodeTestContext, &callbacks);
+    }
+    else if (strstr(encodeTestContext->sOutputFormat, "h265") != NULL)
+    {
+        OMX_GetHandle(&hComponentEncoder, "OMX.sf.video_encoder.hevc", encodeTestContext, &callbacks);
+    }
+    if (hComponentEncoder == NULL)
+    {
+        printf("could not get handle\r\n");
+        return 0;
+    }
+    encodeTestContext->hComponentEncoder = hComponentEncoder;
+
+    OMX_PARAM_PORTDEFINITIONTYPE pInputPortDefinition;
+    OMX_INIT_STRUCTURE(pInputPortDefinition);
+    pInputPortDefinition.nPortIndex = 0;
+    OMX_GetParameter(hComponentEncoder, OMX_IndexParamPortDefinition, &pInputPortDefinition);
+    pInputPortDefinition.format.video.nFrameWidth = width;
+    pInputPortDefinition.format.video.nFrameHeight = height;
+    if (strstr(encodeTestContext->sInputFormat, "i420") != NULL)
+    {
+        pInputPortDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
+    }
+    else if (strstr(encodeTestContext->sInputFormat, "nv12") != NULL)
+    {
+        pInputPortDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+    }
+    else if (strstr(encodeTestContext->sInputFormat, "nv21") != NULL)
+    {
+        pInputPortDefinition.format.video.eColorFormat = OMX_COLOR_FormatYVU420SemiPlanar;
+    }
+    else
+    {
+        printf("unsupported color format: %s\r\n", encodeTestContext->sInputFormat);
+        goto end;
+    }
+    if(encodeTestContext->nFrameRate){
+        pInputPortDefinition.format.video.xFramerate = encodeTestContext->nFrameRate;
+    }
+    OMX_SetParameter(hComponentEncoder, OMX_IndexParamPortDefinition, &pInputPortDefinition);
+    OMX_GetParameter(hComponentEncoder, OMX_IndexParamPortDefinition, &pInputPortDefinition);
+
+    OMX_PARAM_PORTDEFINITIONTYPE pOutputPortDefinition;
+    OMX_INIT_STRUCTURE(pOutputPortDefinition);
+    pOutputPortDefinition.nPortIndex = 1;
+    OMX_GetParameter(hComponentEncoder, OMX_IndexParamPortDefinition, &pOutputPortDefinition);
+    pOutputPortDefinition.format.video.nFrameWidth = width;
+    pOutputPortDefinition.format.video.nFrameHeight = height;
+    pOutputPortDefinition.format.video.nBitrate = encodeTestContext->nBitrate;
+    OMX_SetParameter(hComponentEncoder, OMX_IndexParamPortDefinition, &pOutputPortDefinition);
+
+    if(encodeTestContext->nNumPFrame){
+        OMX_VIDEO_PARAM_AVCTYPE avcType;
+        OMX_INIT_STRUCTURE(avcType);
+        avcType.nPortIndex = 1;
+        OMX_GetParameter(hComponentEncoder, OMX_IndexParamVideoAvc, &avcType);
+        avcType.nPFrames = encodeTestContext->nNumPFrame;
+        OMX_SetParameter(hComponentEncoder, OMX_IndexParamVideoAvc, &avcType);
+    }
+
+    /*Alloc input buffer*/
+    OMX_U32 nInputBufferSize = pInputPortDefinition.nBufferSize;
+    OMX_U32 nInputBufferCount = pInputPortDefinition.nBufferCountActual;
+
+    disableEVnt = OMX_FALSE;
+    OMX_SendCommand(hComponentEncoder, OMX_CommandPortDisable, 1, NULL);
+    printf("wait for output port disable\r\n");
+    while (!disableEVnt);
+    printf("output port disabled\r\n");
+
+    OMX_SendCommand(hComponentEncoder, OMX_CommandStateSet, OMX_StateIdle, NULL);
+
+    for (int i = 0; i < nInputBufferCount; i++)
+    {
+        OMX_BUFFERHEADERTYPE *pBuffer = NULL;
+        OMX_AllocateBuffer(hComponentEncoder, &pBuffer, 0, NULL, nInputBufferSize);
+        encodeTestContext->pInputBufferArray[i] = pBuffer;
+    }
+
+    printf("wait for Component idle\r\n");
+    while (encodeTestContext->comState != OMX_StateIdle);
+    printf("Component in idle\r\n");
+
+    for (int i = 0; i < nInputBufferCount; i++)
+    {
+        /*Fill Input Buffer*/
+        FillInputBuffer(encodeTestContext, encodeTestContext->pInputBufferArray[i]);
+        OMX_EmptyThisBuffer(hComponentEncoder, encodeTestContext->pInputBufferArray[i]);
+    }
+
+    fb = fopen(encodeTestContext->sOutputFilePath, "wb+");
+
+    OMX_SendCommand(hComponentEncoder, OMX_CommandStateSet, OMX_StateExecuting, NULL);
+
+    /*wait until decode finished*/
+    Message data;
+    while (OMX_TRUE)
+    {
+        if (msgrcv(msgid, (void *)&data, BUFSIZ, 0, 0) == -1)
+        {
+            fprintf(stderr, "msgrcv failed with errno: %d\n", errno);
+            goto end;
+        }
+        switch (data.msg_flag)
+        {
+        case 0:
+        {
+            OMX_BUFFERHEADERTYPE *pBuffer = data.pBuffer;
+            FillInputBuffer(encodeTestContext, pBuffer);
+            OMX_EmptyThisBuffer(encodeTestContext->hComponentEncoder, pBuffer);
+        }
+        break;
+        case 1:
+        {
+            OMX_BUFFERHEADERTYPE *pBuffer = data.pBuffer;
+            fwrite(pBuffer->pBuffer, 1, pBuffer->nFilledLen, fb);
+            if ((pBuffer->nFlags) & (OMX_BUFFERFLAG_EOS == OMX_BUFFERFLAG_EOS))
+            {
+                goto end;
+            }
+            else
+            {
+                OMX_FillThisBuffer(encodeTestContext->hComponentEncoder, pBuffer);
+            }
+        }
+        break;
+        case 2:
+            break;
+        default:
+            goto end;
+        }
+    }
+
+end:
+    /*free resource*/
+    fclose(fb);
+    fclose(encodeTestContext->pInputFile);
+    OMX_FreeHandle(hComponentEncoder);
+    OMX_Deinit();
+}

+ 590 - 0
omx-il/tests/mjpeg_dec_test.c

@@ -0,0 +1,590 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 StarFive Technology Co., Ltd.
+ */
+#include <stdio.h>
+#include <unistd.h>
+#include <signal.h>
+#include <getopt.h>
+#include <fcntl.h>
+#include "libavformat/avformat.h"
+#include <OMX_Image.h>
+#include <OMX_Core.h>
+#include <OMX_Component.h>
+#include <OMX_Video.h>
+#include <OMX_IndexExt.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+
+#define OMX_INIT_STRUCTURE(a)         \
+    memset(&(a), 0, sizeof(a));       \
+    (a).nSize = sizeof(a);            \
+    (a).nVersion.nVersion = 1;        \
+    (a).nVersion.s.nVersionMajor = 1; \
+    (a).nVersion.s.nVersionMinor = 1; \
+    (a).nVersion.s.nRevision = 1;     \
+    (a).nVersion.s.nStep = 1
+
+typedef struct Message
+{
+    long msg_type;
+    OMX_S32 msg_flag;
+    OMX_BUFFERHEADERTYPE *pBuffer;
+} Message;
+
+typedef struct DecodeTestContext
+{
+    OMX_HANDLETYPE hComponentDecoder;
+    char sOutputFilePath[64];
+    char sInputFilePath[64];
+    char sOutputFormat[64];
+    OMX_BUFFERHEADERTYPE *pInputBufferArray[64];
+    OMX_BUFFERHEADERTYPE *pOutputBufferArray[64];
+    AVFormatContext *avContext;
+    int msgid;
+    OMX_S32 RoiLeft;
+    OMX_S32 RoiTop;
+    OMX_U32 RoiWidth;
+    OMX_U32 RoiHeight;
+    OMX_U32 Rotation;
+    OMX_U32 Mirror;
+    OMX_U32 ScaleFactorH;
+    OMX_U32 ScaleFactorV;
+} DecodeTestContext;
+DecodeTestContext *decodeTestContext;
+static OMX_S32 FillInputBuffer(DecodeTestContext *decodeTestContext, OMX_BUFFERHEADERTYPE *pInputBuffer);
+
+static OMX_ERRORTYPE event_handler(
+    OMX_HANDLETYPE hComponent,
+    OMX_PTR pAppData,
+    OMX_EVENTTYPE eEvent,
+    OMX_U32 nData1,
+    OMX_U32 nData2,
+    OMX_PTR pEventData)
+{
+    DecodeTestContext *pDecodeTestContext = (DecodeTestContext *)pAppData;
+
+    switch (eEvent)
+    {
+    case OMX_EventPortSettingsChanged:
+    {
+        OMX_PARAM_PORTDEFINITIONTYPE pOutputPortDefinition;
+        OMX_INIT_STRUCTURE(pOutputPortDefinition);
+        pOutputPortDefinition.nPortIndex = 1;
+        OMX_GetParameter(pDecodeTestContext->hComponentDecoder, OMX_IndexParamPortDefinition, &pOutputPortDefinition);
+        OMX_U32 nOutputBufferSize = pOutputPortDefinition.nBufferSize;
+        OMX_U32 nOutputBufferCount = pOutputPortDefinition.nBufferCountMin;
+        printf("allocate %lu output buffers size %lu\r\n", nOutputBufferCount, nOutputBufferSize);
+        for (int i = 0; i < nOutputBufferCount; i++)
+        {
+            OMX_BUFFERHEADERTYPE *pBuffer = NULL;
+            OMX_AllocateBuffer(hComponent, &pBuffer, 1, NULL, nOutputBufferSize);
+            pDecodeTestContext->pOutputBufferArray[i] = pBuffer;
+            OMX_FillThisBuffer(hComponent, pBuffer);
+        }
+    }
+    break;
+    case OMX_EventBufferFlag:
+    {
+        Message data;
+        data.msg_type = 1;
+        data.msg_flag = -1;
+        if (msgsnd(pDecodeTestContext->msgid, (void *)&data, sizeof(data) - sizeof(data.msg_type), 0) == -1)
+        {
+            fprintf(stderr, "msgsnd failed\n");
+        }
+    }
+    break;
+    default:
+        break;
+    }
+    return OMX_ErrorNone;
+}
+
+static void help()
+{
+    printf("omx_mjpeg_dec_test - omx mjpg hardware decode unit test case\r\n\r\n");
+    printf("Usage:\r\n\r\n");
+    printf("./omx_mjpeg_dec_test -i <input file>               input file \r\n");
+    printf("                     -o <output file>              output file\r\n");
+    printf("                     -f <format>                   nv12/nv21/i420/i422/nv16/nv61/yuyv/yvyu/uyvy/vyuy/i444/yuv444packed \r\n");
+    printf("                     --roi=<x>,<y>,<w>,<h>         (optional) roi coord and width/height(from left top)\r\n");
+    printf("                     --mirror=<0/1/2/3>            (optional) mirror 0(none), 1(V), 2(H), 3(VH)\r\n");
+    printf("                     --scaleH=<0/1/2/3>            (optional) Horizontal downscale: 0(none), 1(1/2), 2(1/4), 3(1/8)\r\n");
+    printf("                     --scaleV=<0/1/2/3>            (optional) Vertical downscale  : 0(none), 1(1/2), 2(1/4), 3(1/8)\r\n");
+    printf("                     --rotation=<0/90/180/270>     (optional) rotation 0, 90, 180, 270\r\n\r\n");
+    printf("./omx_mjpeg_dec_test --help: show this message\r\n");
+}
+
+static OMX_ERRORTYPE fill_output_buffer_done_handler(
+    OMX_HANDLETYPE hComponent,
+    OMX_PTR pAppData,
+    OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    DecodeTestContext *pDecodeTestContext = (DecodeTestContext *)pAppData;
+
+    Message data;
+    data.msg_type = 1;
+    if ((pBuffer->nFlags) & (OMX_BUFFERFLAG_EOS == OMX_BUFFERFLAG_EOS))
+    {
+        data.msg_flag = -1;
+    }
+    else
+    {
+        data.msg_flag = 1;
+        data.pBuffer = pBuffer;
+    }
+    if (msgsnd(pDecodeTestContext->msgid, (void *)&data, sizeof(data) - sizeof(data.msg_type), 0) == -1)
+    {
+        fprintf(stderr, "msgsnd failed\n");
+    }
+
+    return OMX_ErrorNone;
+}
+
+static OMX_ERRORTYPE empty_buffer_done_handler(
+    OMX_HANDLETYPE hComponent,
+    OMX_PTR pAppData,
+    OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    DecodeTestContext *pDecodeTestContext = (DecodeTestContext *)pAppData;
+    Message data;
+    data.msg_type = 1;
+    data.msg_flag = 0;
+    data.pBuffer = pBuffer;
+    if (msgsnd(pDecodeTestContext->msgid, (void *)&data, sizeof(data) - sizeof(data.msg_type), 0) == -1)
+    {
+        fprintf(stderr, "msgsnd failed\n");
+    }
+    return OMX_ErrorNone;
+}
+
+static void signal_handle(int sig)
+{
+    printf("[%s,%d]: receive sig=%d \n", __FUNCTION__, __LINE__, sig);
+    Message data;
+    data.msg_type = 1;
+    data.msg_flag = -1;
+    if (msgsnd(decodeTestContext->msgid, (void *)&data, sizeof(data) - sizeof(data.msg_type), 0) == -1)
+    {
+        fprintf(stderr, "msgsnd failed\n");
+    }
+}
+
+static OMX_S32 FillInputBuffer(DecodeTestContext *decodeTestContext, OMX_BUFFERHEADERTYPE *pInputBuffer)
+{
+    AVFormatContext *avFormatContext = decodeTestContext->avContext;
+    AVPacket *avpacket;
+    OMX_S32 error;
+    avpacket = av_packet_alloc();
+    error = av_read_frame(avFormatContext, avpacket);
+    if (error < 0)
+    {
+        if (error == AVERROR_EOF || avFormatContext->pb->eof_reached == OMX_TRUE)
+        {
+            pInputBuffer->nFlags = 0x1;
+            pInputBuffer->nFilledLen = 0;
+            return 0;
+        }
+        else
+        {
+            printf("%s:%d failed to av_read_frame, error: %s\n",
+                    __FUNCTION__, __LINE__, av_err2str(error));
+            return 0;
+        }
+    }
+    pInputBuffer->nFlags = 0x10;
+    pInputBuffer->nFilledLen = avpacket->size;
+    memcpy(pInputBuffer->pBuffer, avpacket->data, avpacket->size);
+    printf("%s, address = %p, size = %lu, flag = %lx\r\n",
+        __FUNCTION__, pInputBuffer->pBuffer, pInputBuffer->nFilledLen, pInputBuffer->nFlags);
+    return avpacket->size;
+}
+
+int main(int argc, char **argv)
+{
+    printf("=============================\r\n");
+    OMX_S32 error;
+    FILE *fb;
+    decodeTestContext = malloc(sizeof(DecodeTestContext));
+    memset(decodeTestContext, 0, sizeof(DecodeTestContext));
+
+    OMX_S32 msgid = -1;
+    msgid = msgget(IPC_PRIVATE, 0666 | IPC_CREAT);
+    if (msgid < 0)
+    {
+        perror("get ipc_id error");
+        return -1;
+    }
+    decodeTestContext->msgid = msgid;
+    struct option longOpt[] = {
+        {"output", required_argument, NULL, 'o'},
+        {"input", required_argument, NULL, 'i'},
+        {"format", required_argument, NULL, 'f'},
+        {"roi", required_argument, NULL, 'c'},
+        {"rotation", required_argument, NULL, 'r'},
+        {"mirror", required_argument, NULL, 'm'},
+        {"scaleH", required_argument, NULL, 'H'},
+        {"scaleV", required_argument, NULL, 'V'},
+        {"help", no_argument, NULL, 0},
+        {NULL, no_argument, NULL, 0},
+    };
+    char *shortOpt = "i:o:f:c:r:m:H:V:";
+    OMX_U32 c;
+    OMX_S32 l;
+    OMX_STRING val;
+
+    // if (argc == 0)
+    // {
+    //     help();
+    //     return;
+    // }
+
+    while ((c = getopt_long(argc, argv, shortOpt, longOpt, (int *)&l)) != -1)
+    {
+        switch (c)
+        {
+        case 'i':
+            printf("input: %s\r\n", optarg);
+            if (access(optarg, R_OK) != -1)
+            {
+                memcpy(decodeTestContext->sInputFilePath, optarg, strlen(optarg));
+            }
+            else
+            {
+                printf("input file not exist!\r\n");
+                return -1;
+            }
+            break;
+        case 'o':
+            printf("output: %s\r\n", optarg);
+            memcpy(decodeTestContext->sOutputFilePath, optarg, strlen(optarg));
+            break;
+        case 'f':
+            printf("format: %s\r\n", optarg);
+            memcpy(decodeTestContext->sOutputFormat, optarg, strlen(optarg));
+            break;
+        case 'c':
+            printf("ROI: %s\r\n", optarg);
+            val = strtok(optarg, ",");
+            if (val == NULL) {
+                printf("Invalid ROI option: %s\n", optarg);
+                return -1;
+            }
+            else {
+                decodeTestContext->RoiLeft = atoi(val);
+            }
+            val = strtok(NULL, ",");
+            if (val == NULL) {
+                printf("Invalid ROI option: %s\n", optarg);
+                return -1;
+            }
+            else {
+                decodeTestContext->RoiTop = atoi(val);
+            }
+            val = strtok(NULL, ",");
+            if (val == NULL) {
+                printf("Invalid ROI option: %s\n", optarg);
+                return -1;
+            }
+            else {
+                decodeTestContext->RoiWidth = atoi(val);
+            }
+            val = strtok(NULL, ",");
+            if (val == NULL) {
+                printf("Invalid ROI option: %s\n", optarg);
+                return -1;
+            }
+            else {
+                decodeTestContext->RoiHeight = atoi(val);
+            }
+            break;
+        case 'r':
+            printf("rotation: %s\r\n", optarg);
+            decodeTestContext->Rotation = atoi(optarg);
+            break;
+        case 'm':
+            printf("mirror: %s\r\n", optarg);
+            decodeTestContext->Mirror = atoi(optarg);
+            break;
+        case 'H':
+            printf("scaleH: %s\r\n", optarg);
+            decodeTestContext->ScaleFactorH = atoi(optarg);
+            break;
+        case 'V':
+            printf("scaleV: %s\r\n", optarg);
+            decodeTestContext->ScaleFactorV = atoi(optarg);
+            break;
+        case 0:
+        default:
+            help();
+            return -1;
+        }
+    }
+
+    if (decodeTestContext->sInputFilePath == NULL || decodeTestContext->sOutputFilePath == NULL)
+    {
+        help();
+        return -1;
+    }
+    /*ffmpeg init*/
+    printf("init ffmpeg\r\n");
+    AVFormatContext *avContext = NULL;
+    AVCodecParameters *codecParameters = NULL;
+    AVInputFormat *fmt = NULL;
+    OMX_S32 imageIndex;
+    if ((avContext = avformat_alloc_context()) == NULL)
+    {
+        printf("avformat_alloc_context fail\r\n");
+        return -1;
+    }
+    avContext->flags |= AV_CODEC_FLAG_TRUNCATED;
+
+    printf("avformat_open_input\r\n");
+    if ((error = avformat_open_input(&avContext, decodeTestContext->sInputFilePath, fmt, NULL)))
+    {
+        printf("%s:%d failed to av_open_input_file error(%s), %s\n",
+               __FILE__, __LINE__, av_err2str(error), decodeTestContext->sInputFilePath);
+        return -1;
+    }
+
+    printf("avformat_find_stream_info\r\n");
+    if ((error = avformat_find_stream_info(avContext, NULL)) < 0)
+    {
+        printf("%s:%d failed to avformat_find_stream_info. error(%s)\n",
+               __FUNCTION__, __LINE__, av_err2str(error));
+        return -1;
+    }
+
+    printf("av_find_best_stream\r\n");
+    imageIndex = av_find_best_stream(avContext, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
+    if (imageIndex < 0)
+    {
+        printf("%s:%d failed to av_find_best_stream.\n", __FUNCTION__, __LINE__);
+        return -1;
+    }
+    printf("image index = %lu\r\n", imageIndex);
+    decodeTestContext->avContext = avContext;
+    /*get image info*/
+    codecParameters = avContext->streams[imageIndex]->codecpar;
+    printf("codec_id = %d, width = %d, height = %d\r\n", (int)codecParameters->codec_id,
+           codecParameters->width, codecParameters->height);
+
+    /*omx init*/
+    OMX_HANDLETYPE hComponentDecoder = NULL;
+    OMX_CALLBACKTYPE callbacks;
+    int ret = OMX_ErrorNone;
+    signal(SIGINT, signal_handle);
+    printf("init omx\r\n");
+    ret = OMX_Init();
+    if (ret != OMX_ErrorNone)
+    {
+        printf("[%s,%d]: run OMX_Init failed. ret is %d \n", __FUNCTION__, __LINE__, ret);
+        return 1;
+    }
+
+    callbacks.EventHandler = event_handler;
+    callbacks.FillBufferDone = fill_output_buffer_done_handler;
+    callbacks.EmptyBufferDone = empty_buffer_done_handler;
+    printf("get handle by codec id = %d\r\n", codecParameters->codec_id);
+    if (codecParameters->codec_id == AV_CODEC_ID_MJPEG)
+    {
+        OMX_GetHandle(&hComponentDecoder, "OMX.sf.video_decoder.mjpeg", decodeTestContext, &callbacks);
+    }
+
+    if (hComponentDecoder == NULL)
+    {
+        printf("could not get handle\r\n");
+        return 0;
+    }
+    decodeTestContext->hComponentDecoder = hComponentDecoder;
+
+    OMX_PARAM_PORTDEFINITIONTYPE pOutputPortDefinition;
+    OMX_INIT_STRUCTURE(pOutputPortDefinition);
+    pOutputPortDefinition.nPortIndex = 1;
+    OMX_GetParameter(decodeTestContext->hComponentDecoder, OMX_IndexParamPortDefinition, &pOutputPortDefinition);
+    pOutputPortDefinition.format.video.nFrameWidth = codecParameters->width;
+    pOutputPortDefinition.format.video.nFrameHeight = codecParameters->height;
+    if (strstr(decodeTestContext->sOutputFormat, "nv12") != NULL)
+    {
+        pOutputPortDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+    }
+    else if (strstr(decodeTestContext->sOutputFormat, "nv21") != NULL)
+    {
+        pOutputPortDefinition.format.video.eColorFormat = OMX_COLOR_FormatYVU420SemiPlanar;
+    }
+    else if (strstr(decodeTestContext->sOutputFormat, "i420") != NULL)
+    {
+        pOutputPortDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
+    }
+    else if (strstr(decodeTestContext->sOutputFormat, "i422") != NULL)
+    {
+        pOutputPortDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV422Planar;
+    }
+    else if (strstr(decodeTestContext->sOutputFormat, "nv16") != NULL)
+    {
+        pOutputPortDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV422SemiPlanar;
+    }
+    else if (strstr(decodeTestContext->sOutputFormat, "nv61") != NULL)
+    {
+        pOutputPortDefinition.format.video.eColorFormat = OMX_COLOR_FormatYVU422SemiPlanar;
+    }
+    else if (strstr(decodeTestContext->sOutputFormat, "yuyv") != NULL)
+    {
+        pOutputPortDefinition.format.video.eColorFormat = OMX_COLOR_FormatYCbYCr;
+    }
+    else if (strstr(decodeTestContext->sOutputFormat, "yvyu") != NULL)
+    {
+        pOutputPortDefinition.format.video.eColorFormat = OMX_COLOR_FormatYCrYCb;
+    }
+    else if (strstr(decodeTestContext->sOutputFormat, "uyvy") != NULL)
+    {
+        pOutputPortDefinition.format.video.eColorFormat = OMX_COLOR_FormatCbYCrY;
+    }
+    else if (strstr(decodeTestContext->sOutputFormat, "vyuy") != NULL)
+    {
+        pOutputPortDefinition.format.video.eColorFormat = OMX_COLOR_FormatCrYCbY;
+    }
+    else if (strstr(decodeTestContext->sOutputFormat, "i444") != NULL)
+    {
+        pOutputPortDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV444Planar;
+    }
+    else if (strstr(decodeTestContext->sOutputFormat, "yuv444packed") != NULL)
+    {
+        pOutputPortDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV444Interleaved;
+    }
+    else
+    {
+        printf("Unsupported color format!\r\n");
+        goto end;
+    }
+    OMX_SetParameter(hComponentDecoder, OMX_IndexParamPortDefinition, &pOutputPortDefinition);
+
+    /* Set Roi config setting*/
+    if(decodeTestContext->RoiWidth && decodeTestContext->RoiHeight)
+    {
+        OMX_CONFIG_RECTTYPE RectConfig;
+        OMX_INIT_STRUCTURE(RectConfig);
+        RectConfig.nPortIndex = 1;
+        OMX_GetConfig(hComponentDecoder, OMX_IndexConfigCommonOutputCrop, &RectConfig);
+        RectConfig.nLeft = decodeTestContext->RoiLeft;
+        RectConfig.nTop = decodeTestContext->RoiTop;
+        RectConfig.nWidth = decodeTestContext->RoiWidth;
+        RectConfig.nHeight = decodeTestContext->RoiHeight;
+        OMX_SetConfig(hComponentDecoder, OMX_IndexConfigCommonOutputCrop, &RectConfig);
+    }
+
+    /* Set Rotation config setting*/
+    if(decodeTestContext->Rotation)
+    {
+        OMX_CONFIG_ROTATIONTYPE RotatConfig;
+        OMX_INIT_STRUCTURE(RotatConfig);
+        RotatConfig.nPortIndex = 1;
+        OMX_GetConfig(hComponentDecoder, OMX_IndexConfigCommonRotate, &RotatConfig);
+        RotatConfig.nRotation = decodeTestContext->Rotation;
+        OMX_SetConfig(hComponentDecoder, OMX_IndexConfigCommonRotate, &RotatConfig);
+    }
+
+    /* Set Mirror config setting*/
+    if(decodeTestContext->Mirror)
+    {
+        OMX_CONFIG_MIRRORTYPE MirrorConfig;
+        OMX_INIT_STRUCTURE(MirrorConfig);
+        MirrorConfig.nPortIndex = 1;
+        OMX_GetConfig(hComponentDecoder, OMX_IndexConfigCommonMirror, &MirrorConfig);
+        MirrorConfig.eMirror = decodeTestContext->Mirror;
+        OMX_SetConfig(hComponentDecoder, OMX_IndexConfigCommonMirror, &MirrorConfig);
+    }
+
+    /* Set Scale config setting*/
+    if(decodeTestContext->ScaleFactorH || decodeTestContext->ScaleFactorV)
+    {
+        OMX_CONFIG_SCALEFACTORTYPE ScaleConfig;
+        OMX_INIT_STRUCTURE(ScaleConfig);
+        ScaleConfig.nPortIndex = 1;
+        OMX_GetConfig(hComponentDecoder, OMX_IndexConfigCommonScale, &ScaleConfig);
+        /* in Q16 format */
+        ScaleConfig.xWidth = (1 << 16) >> (decodeTestContext->ScaleFactorH & 0x3);
+        ScaleConfig.xHeight = (1 << 16) >> (decodeTestContext->ScaleFactorV & 0x3);
+        OMX_SetConfig(hComponentDecoder, OMX_IndexConfigCommonScale, &ScaleConfig);
+    }
+
+    OMX_SendCommand(hComponentDecoder, OMX_CommandStateSet, OMX_StateIdle, NULL);
+
+    OMX_PARAM_PORTDEFINITIONTYPE pInputPortDefinition;
+    OMX_INIT_STRUCTURE(pInputPortDefinition);
+    pInputPortDefinition.nPortIndex = 0;
+    OMX_GetParameter(hComponentDecoder, OMX_IndexParamPortDefinition, &pInputPortDefinition);
+    pInputPortDefinition.format.image.nFrameWidth = codecParameters->width;
+    pInputPortDefinition.format.image.nFrameHeight = codecParameters->height;
+    OMX_SetParameter(hComponentDecoder, OMX_IndexParamPortDefinition, &pInputPortDefinition);
+    /*Alloc input buffer*/
+    OMX_U32 nInputWidth = codecParameters->width;
+    OMX_U32 nInputHeight = codecParameters->height;
+    OMX_U32 nInputBufferSize = nInputWidth * nInputHeight * 2;
+    OMX_U32 nInputBufferCount = pInputPortDefinition.nBufferCountActual;
+    for (int i = 0; i < nInputBufferCount; i++)
+    {
+        OMX_BUFFERHEADERTYPE *pBuffer = NULL;
+        OMX_AllocateBuffer(hComponentDecoder, &pBuffer, 0, NULL, nInputBufferSize);
+        decodeTestContext->pInputBufferArray[i] = pBuffer;
+        /*Fill Input Buffer*/
+        FillInputBuffer(decodeTestContext, pBuffer);
+        OMX_EmptyThisBuffer(hComponentDecoder, pBuffer);
+    }
+
+    fb = fopen(decodeTestContext->sOutputFilePath, "wb+");
+
+    OMX_SendCommand(hComponentDecoder, OMX_CommandStateSet, OMX_StateExecuting, NULL);
+
+    /*wait until decode finished*/
+    Message data;
+    while (OMX_TRUE)
+    {
+        if (msgrcv(msgid, (void *)&data, BUFSIZ, 0, 0) == -1)
+        {
+            fprintf(stderr, "msgrcv failed with errno: %d\n", errno);
+            goto end;
+        }
+        switch (data.msg_flag)
+        {
+        case 0:
+        {
+            OMX_BUFFERHEADERTYPE *pBuffer = data.pBuffer;
+            FillInputBuffer(decodeTestContext, pBuffer);
+            OMX_EmptyThisBuffer(decodeTestContext->hComponentDecoder, pBuffer);
+        }
+        break;
+        case 1:
+        {
+            OMX_BUFFERHEADERTYPE *pBuffer = data.pBuffer;
+            printf("write %lu buffers to file\r\n", pBuffer->nFilledLen);
+            size_t size = fwrite(pBuffer->pBuffer, 1, pBuffer->nFilledLen, fb);
+            int error = ferror(fb);
+            printf("write error = %d\r\n", error);
+            printf("write %lu buffers finish\r\n", size);
+            if ((pBuffer->nFlags) & (OMX_BUFFERFLAG_EOS == OMX_BUFFERFLAG_EOS))
+            {
+                goto end;
+            }
+            else
+            {
+                OMX_FillThisBuffer(decodeTestContext->hComponentDecoder, pBuffer);
+            }
+        }
+        break;
+        case 2:
+            break;
+        default:
+            goto end;
+        }
+    }
+
+end:
+    /*free resource*/
+    fclose(fb);
+    OMX_FreeHandle(hComponentDecoder);
+    OMX_Deinit();
+}

+ 41 - 0
wave420l/code/WaveEncDriver_buildroot.mak

@@ -0,0 +1,41 @@
+# 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 ARCH=riscv
+export SUBARCH=riscv
+export CROSS_COMPILE=riscv64-buildroot-linux-gnu-
+
+DRV_PATH  := $(shell pwd)/vdi/linux/driver
+EXTRA_CFLAGS +=	$(DEBFLAGS) -I$(LDDINCDIR)
+
+ifneq ($(KERNELRELEASE),)
+# call from kernel build system
+
+obj-m	:= venc.o
+
+else
+
+default:
+	$(MAKE) -C $(KERNELDIR)	M=$(DRV_PATH) LDDINCDIR=$(DRV_PATH)/../include modules
+
+endif
+
+
+
+clean:
+	rm -rf $(DRV_PATH)/*.o $(DRV_PATH)/*~ $(DRV_PATH)/core $(DRV_PATH)/.depend $(DRV_PATH)/.*.cmd $(DRV_PATH)/*.ko $(DRV_PATH)/*.mod.c $(DRV_PATH)/modules.order $(DRV_PATH)/.tmp_versions $(DRV_PATH)/*.dwo $(DRV_PATH)/.*.dwo
+
+depend .depend dep:
+	$(CC) $(CFLAGS)	-M *.c > .depend
+
+
+ifeq (.depend,$(wildcard .depend))
+include	.depend
+endif

+ 275 - 0
wave420l/code/WaveEncoder_buildroot.mak

@@ -0,0 +1,275 @@
+# ----------------------------------------------------------------------
+#
+# Project: C&M Video encoder sample
+#
+# ----------------------------------------------------------------------
+.PHONY: create_dir force_dependency
+BUILD_CONFIGURATION = RiscvLinux
+USE_FFMPEG  = yes
+USE_PTHREAD = yes
+
+UNAME = $(shell uname -a)
+ifneq (,$(findstring i386, $(UNAME)))
+    USE_32BIT = yes
+endif
+
+
+ifeq ($(USE_32BIT), yes)
+PLATFORM    = nativelinux
+else
+PLATFORM    = nativelinux_64bit
+endif
+
+CROSS_CC_PREFIX = 
+VDI_C           = vdi/linux/vdi.c
+VDI_OSAL_C      = vdi/linux/vdi_osal.c
+MM_C            = 
+PLATFORM_FLAGS  = 
+
+ifeq ("$(BUILD_CONFIGURATION)", "NonOS")
+    CROSS_CC_PREFIX = arm-none-eabi-
+    VDI_C           = vdi/nonos/vdi.c
+    VDI_OSAL_C      = vdi/nonos/vdi_osal.c
+    MM_C            = vdi/mm.c
+    USE_FFMPEG      = no
+    USE_PTHREAD     = no
+    PLATFORM        = none
+    DEFINES         = -DLIB_C_STUB
+    PLATFORM_FLAGS  = 
+endif
+ifeq ("$(BUILD_CONFIGURATION)", "EmbeddedLinux")
+    CROSS_CC_PREFIX = arm-none-linux-gnueabi-
+    PLATFORM        = armlinux
+endif
+
+ifeq ("$(BUILD_CONFIGURATION)", "RiscvLinux")
+    CROSS_CC_PREFIX = riscv64-buildroot-linux-gnu-
+    PLATFORM        = riscvlinux
+    USE_FFMPEG  	= no
+    USE_PTHREAD 	= yes
+    MM_C            = vdi/mm.c
+endif
+
+CC  = $(CROSS_CC_PREFIX)gcc
+CXX = $(CROSS_CC_PREFIX)g++
+LINKING=$(CC)
+AR  = $(CROSS_CC_PREFIX)ar
+
+INCLUDES = -I./theoraparser/include -I./vpuapi -I./ffmpeg/include -I./sample/helper -I./vdi
+DEFINES += -DWAVE420
+
+
+CFLAGS  += -g -I. -Wl,--fatal-warning $(INCLUDES) $(DEFINES) $(PLATFORM_FLAGS)
+ARFLAGS += cru
+
+LDFLAGS  += $(PLATFORM_FLAGS) -L./theoraparser/
+#LDLIBS   += -ltheoraparser
+
+
+ifeq ($(USE_FFMPEG), yes)
+LDLIBS  += -lavformat -lavcodec -lavutil
+LDFLAGS += -L./ffmpeg/lib/$(PLATFORM)
+ifneq ($(USE_32BIT), yes)
+LDLIBS  += -lz
+endif #USE_32BIT
+endif #USE_FFMPEG
+
+ifeq ($(USE_PTHREAD), yes)
+LDLIBS  += -lpthread
+endif
+LDLIBS  += -lm
+
+
+TARGET=libsfenc.so
+MAKEFILE=Wave420Enc.mak
+OBJDIR=obj
+ALLOBJS=*.o
+ALLDEPS=*.dep
+ALLLIBS=*.a
+RM=rm -f
+MKDIR=mkdir -p
+
+SOURCES = sample/helper/main_helper.c                       \
+          sample/helper/vpuhelper.c                         \
+          sample/helper/bitstream/bitstreamfeeder.c         \
+          sample/helper/bitstream/bitstreamreader.c         \
+          sample/helper/bitstream/binaryreader.c            \
+          sample/helper/bitstream/bsfeeder_fixedsize_impl.c \
+          sample/helper/bitstream/bsfeeder_framesize_impl.c \
+          sample/helper/bitstream/bsfeeder_size_plus_es_impl.c \
+          sample/helper/comparator/bin_comparator_impl.c    \
+          sample/helper/comparator/comparator.c             \
+          sample/helper/comparator/md5_comparator_impl.c    \
+          sample/helper/comparator/yuv_comparator_impl.c    \
+          sample/helper/display/fbdev_impl.c                \
+          sample/helper/display/hdmi_impl.c                 \
+          sample/helper/display/simplerenderer.c            \
+          sample/helper/misc/cfgParser.c                    \
+          sample/helper/misc/cnm_fpga.c                     \
+          sample/helper/misc/cnm_video_helper.c             \
+          sample/helper/misc/container.c                    \
+          sample/helper/misc/datastructure.c                \
+          sample/helper/misc/platform.c                     \
+          sample/helper/misc/pbu.c                          \
+          sample/helper/misc/debug.c                        \
+          sample/helper/yuv/yuvfeeder.c                     \
+          sample/helper/yuv/yuvLoaderfeeder.c               
+SOURCES += $(VDI_C)                                         \
+          $(VDI_OSAL_C)                                     \
+          $(MM_C)                                           \
+          vpuapi/product.c                                  \
+          vpuapi/vpuapifunc.c                               \
+          vpuapi/vpuapi.c                                   \
+          vpuapi/coda9/coda9.c                              \
+          vpuapi/wave/common/common.c                       \
+          vpuapi/wave/coda7q/coda7q.c                       \
+          vpuapi/wave/wave4/wave4.c                         \
+          vpuapi/wave/wave5/wave5.c
+
+
+OBJECTNAMES=$(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCES)))
+OBJECTPATHS=$(addprefix $(OBJDIR)/,$(notdir $(OBJECTNAMES)))
+
+$(TARGET): create_dir $(OBJECTPATHS) #libtheoraparser.a
+	$(LINKING) -fPIC -shared -o $@ $(LDFLAGS) -Wl,-gc-section -Wl,--start-group $(OBJECTPATHS) $(LDLIBS) -Wl,--end-group
+
+-include $(OBJECTPATHS:.o=.dep)
+
+clean: 
+	$(RM) $(TARGET)
+	$(RM) $(OBJDIR)/$(ALLOBJS)
+	$(RM) $(OBJDIR)/$(ALLDEPS)
+	$(RM) theoraparser/$(ALLOBJS)
+	$(RM) theoraparser/$(ALLLIBS)
+	$(RM) theoraparser/$(ALLDEPS)
+
+#libtheoraparser.a: force_dependency
+#	cd theoraparser; make
+
+$(OBJDIR)/main_helper.o : sample/helper/main_helper.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/vpuhelper.o : sample/helper/vpuhelper.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+
+$(OBJDIR)/bitstreamfeeder.o : sample/helper/bitstream/bitstreamfeeder.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/bitstreamreader.o : sample/helper/bitstream/bitstreamreader.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/binaryreader.o : sample/helper/bitstream/binaryreader.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/bsfeeder_fixedsize_impl.o : sample/helper/bitstream/bsfeeder_fixedsize_impl.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/bsfeeder_framesize_impl.o : sample/helper/bitstream/bsfeeder_framesize_impl.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/bsfeeder_size_plus_es_impl.o : sample/helper/bitstream/bsfeeder_size_plus_es_impl.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/bin_comparator_impl.o : sample/helper/comparator/bin_comparator_impl.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/comparator.o : sample/helper/comparator/comparator.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/md5_comparator_impl.o : sample/helper/comparator/md5_comparator_impl.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/yuv_comparator_impl.o : sample/helper/comparator/yuv_comparator_impl.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+
+$(OBJDIR)/fbdev_impl.o : sample/helper/display/fbdev_impl.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/hdmi_impl.o : sample/helper/display/hdmi_impl.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/mixer.o : sample/helper/display/mixer.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/simplerenderer.o : sample/helper/display/simplerenderer.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+
+$(OBJDIR)/cfgParser.o : sample/helper/misc/cfgParser.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/cnm_fpga.o : sample/helper/misc/cnm_fpga.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/cnm_video_helper.o : sample/helper/misc/cnm_video_helper.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/container.o : sample/helper/misc/container.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/datastructure.o : sample/helper/misc/datastructure.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/platform.o : sample/helper/misc/platform.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/pbu.o : sample/helper/misc/pbu.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/yuvfeeder.o : sample/helper/yuv/yuvfeeder.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/yuvLoaderfeeder.o : sample/helper/yuv/yuvLoaderfeeder.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/debug.o : sample/helper/misc/debug.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+
+
+
+$(OBJDIR)/vdi.o : $(VDI_C) $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/vdi_osal.o : $(VDI_OSAL_C) $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+ifneq ("$(MM_C)", "")
+$(OBJDIR)/mm.o : $(MM_C) $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+endif
+
+$(OBJDIR)/product.o : vpuapi/product.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/vpuapifunc.o : vpuapi/vpuapifunc.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/vpuapi.o : vpuapi/vpuapi.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/coda9.o : vpuapi/coda9/coda9.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/common.o : vpuapi/wave/common/common.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/coda7q.o : vpuapi/wave/coda7q/coda7q.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/wave4.o : vpuapi/wave/wave4/wave4.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+$(OBJDIR)/wave5.o : vpuapi/wave/wave5/wave5.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+create_dir:
+ifeq (,$(findstring $(OBJDIR),$(wildcard $(OBJDIR) )))
+	-mkdir -p $(OBJDIR)
+endif
+
+force_dependency : 
+	true
+

+ 76 - 0
wave420l/code/cfg/encoder_defconfig.cfg

@@ -0,0 +1,76 @@
+BitstreamFile : inter_8b_11.cfg.265
+InputFile : mix_1920x1080_8b_9frm.yuv
+SourceWidth : 1920
+SourceHeight : 1080
+InputBitDepth : 8
+FrameRate : 30
+FrameSkip : 0
+FramesToBeEncoded : 30
+IntraPeriod : 0
+DecodingRefreshType : 1
+GopPreset : 0
+GOPSize : 1
+Frame1: P 1 1 0 0 0
+IntraNxN : 1
+IntraTransSkip : 1
+StrongIntraSmoothing : 1
+ConstrainedIntraPred : 0
+IntraCtuRefreshMode : 0
+IntraCtuRefreshArg : 0
+MaxNumMerge : 2
+DisableCoefClear : 0
+EnTemporalMVP : 1
+QP : 30
+CbQpOffset : 0
+CrQpOffset : 0
+ScalingList : 0
+IndeSliceMode : 0
+IndeSliceArg : 0
+DeSliceMode : 0
+DeSliceArg : 0
+EnDBK : 1
+EnSAO : 1
+LFCrossSliceBoundaryFlag : 1
+BetaOffsetDiv2 : 0
+TcOffsetDiv2 : 0
+WaveFrontSynchro : 0
+LosslessCoding : 0
+UseAsLongTermRefPeriod : 0
+RefLongTermPeriod : 0
+RateControl : 0
+EncBitrate : 0
+VbvBufferSize : 3000
+CULevelRateControl : 1
+EnHvsQp : 1
+BitAllocMode : 0
+EnRoi : 0
+RcInitialQp : 63
+MinQp : 8
+MaxQp : 51
+RoiQpMapFile :  /nstream/new_server/ctu_mode/roi_map.dat
+EnNoiseReductionY : 0
+EnNoiseReductionCb : 0
+EnNoiseReductionCr : 0
+EnNoiseEst : 0
+NoiseSigmaY : 0
+NoiseSigmaCb : 0
+NoiseSigmaCr : 0
+IntraNoiseWeightY : 7
+IntraNoiseWeightCb : 7
+IntraNoiseWeightCr : 7
+InterNoiseWeightY : 4
+InterNoiseWeightCb : 4
+InterNoiseWeightCr : 4
+EnBgDetect : 1
+BgThDiff : 0
+BgThMeanDiff : 1
+BgLambdaQp : 32
+BgDeltaQp : 3
+TileNumColumns : 1
+TileNumRows : 1
+TileUniformSpace : 1
+WeightedPred : 0
+WpParamFile : ""
+ScalingListFile : /nstream/new_server/user_data/default_scaling_list.txt
+EnModeMap : 0
+ModeMapFile : 0

+ 1 - 1
wave420l/code/config.h

@@ -34,7 +34,7 @@
 #if defined(PLATFORM_NON_OS) || defined (ANDROID) || defined(MFHMFT_EXPORTS) || defined(PLATFORM_QNX)
 //#define SUPPORT_FFMPEG_DEMUX
 #else
-#define SUPPORT_FFMPEG_DEMUX
+//#define SUPPORT_FFMPEG_DEMUX
 #endif
 
 //------------------------------------------------------------------------------

+ 4 - 0
wave420l/code/sample/helper/bitstream/bitstreamfeeder.c

@@ -86,9 +86,11 @@ extern Int32 BSFeederFrameSize_Act(
     BSChunk*    packet
     );
 
+#ifdef SUPPORT_FFMPEG_DEMUX
 extern BOOL BSFeederFrameSize_Rewind(
     void*       feeder
     );
+#endif
 
 extern void* BSFeederSizePlusEs_Create(
     const char* path
@@ -445,9 +447,11 @@ BOOL BitstreamFeeder_Rewind(
     case FEEDING_METHOD_FIXED_SIZE:
         success = BSFeederFixedSize_Rewind(bsf->actualFeeder);
         break;
+#ifdef SUPPORT_FFMPEG_DEMUX
     case FEEDING_METHOD_FRAME_SIZE:
         success = BSFeederFrameSize_Rewind(bsf->actualFeeder);
         break;
+#endif
     case FEEDING_METHOD_SIZE_PLUS_ES:
         success = BSFeederSizePlusEs_Rewind(bsf->actualFeeder);
         break;

+ 101 - 0
wave420l/code/sample/helper/bitstream/bitstreamreader.c

@@ -163,3 +163,104 @@ BOOL BitstreamReader_Destroy(
     return TRUE;
 }
 
+BitstreamReader BufferStreamReader_Create(
+    Uint32      type,
+    EndianMode  endian,
+    EncHandle*  handle
+    )
+{
+    AbstractBitstreamReader* reader;
+
+    reader = (AbstractBitstreamReader*)osal_malloc(sizeof(AbstractBitstreamReader));
+
+    reader->handle  = handle;
+    reader->type    = type;
+    reader->endian  = endian;
+
+    return reader;
+}
+
+Uint32 BufferStreamReader_Act(
+    BitstreamReader reader,
+    PhysicalAddress bitstreamBuffer,
+    Uint32          bitstreamBufferSize,
+    Uint32          streamReadSize,
+    Uint8*          pBuffer,
+    Comparator      comparator
+    )
+{
+    AbstractBitstreamReader* absReader = (AbstractBitstreamReader*)reader;
+    EncHandle       *handle;
+    RetCode         ret = RETCODE_SUCCESS;
+    PhysicalAddress paRdPtr;
+    PhysicalAddress paWrPtr;
+    int             size = 0;
+    Int32           loadSize = 0;
+    PhysicalAddress paBsBufStart = bitstreamBuffer;
+    PhysicalAddress paBsBufEnd   = bitstreamBuffer+bitstreamBufferSize;
+    Uint32          coreIdx;
+
+    if (reader == NULL) {
+
+        VLOG(ERR, "%s:%d Invalid handle\n", __FUNCTION__, __LINE__);
+        return 0;
+    }
+
+    handle = absReader->handle;
+    coreIdx = VPU_HANDLE_CORE_INDEX(*handle);
+
+    ret = VPU_EncGetBitstreamBuffer(*handle, &paRdPtr, &paWrPtr, &size);
+    if (size > 0) {
+        if (streamReadSize > 0) {
+            if ((Uint32)size < streamReadSize) {
+                loadSize = size;
+            }
+            else {
+                loadSize = streamReadSize;
+            }
+        }
+        else {
+            loadSize = size;
+        }
+
+        if (absReader->type == BUFFER_MODE_TYPE_RINGBUFFER) {
+            if ((paRdPtr+loadSize) > paBsBufEnd) {
+                Uint32   room;
+                room = paBsBufEnd - paRdPtr;
+                vdi_read_memory(coreIdx, paRdPtr, pBuffer, room,  absReader->endian);
+                vdi_read_memory(coreIdx, paBsBufStart, pBuffer+room, (loadSize-room), absReader->endian);
+            }
+            else {
+                vdi_read_memory(coreIdx, paRdPtr, pBuffer, loadSize, absReader->endian);
+            }
+        }
+        else {
+            /* Linebuffer */
+            vdi_read_memory(coreIdx, paRdPtr, pBuffer, loadSize, absReader->endian);
+        }
+
+        ret = VPU_EncUpdateBitstreamBuffer(*handle, loadSize);
+        if( ret != RETCODE_SUCCESS ) {
+            VLOG(ERR, "VPU_EncUpdateBitstreamBuffer failed Error code is 0x%x \n", ret );
+            return 0;
+        }
+    }
+
+    return loadSize;
+}
+
+BOOL BufferStreamReader_Destroy(
+    BitstreamReader reader
+    )
+{
+    AbstractBitstreamReader* absReader = (AbstractBitstreamReader*)reader;
+
+    if (reader == NULL) {
+        VLOG(ERR, "%s:%d Invalid handle\n", __FUNCTION__, __LINE__);
+        return FALSE;
+    }
+
+    osal_free(absReader);
+
+    return TRUE;
+}

+ 1 - 0
wave420l/code/sample/helper/bitstream/bsfeeder_framesize_impl.c

@@ -713,6 +713,7 @@ void* BSFeederFrameSize_Create(
 
     if (standard == STD_THO || standard == STD_VP3) {
         theora_parser_init((void**)&ffmpegReader->theora);
+        fuck
     }
 
     return (void*)ffmpegReader;

+ 5 - 5
wave420l/code/sample/helper/main_helper.c

@@ -1287,9 +1287,9 @@ Int32 writeHrdRbsp(int coreIdx, TestEncConfig *encConfig, EncOpenParam *encOP, v
 #ifdef TEST_ENCODE_CUSTOM_HEADER
 Int32 writeCustomHeader(int coreIdx, EncOpenParam *encOP, vpu_buffer_t *vbCustomHeader, hrd_t *hrd)
 {
-    Int32 rbspBitSize;
+    Uint32 rbspBitSize;
     Uint8 *pRbspBuf;
-    Int32 rbspByteSize;
+    Uint32 rbspByteSize;
     vui_t vui;
 
     encOP->encodeVuiRbsp = 1;
@@ -1429,7 +1429,7 @@ Int32 writeCustomHeader(int coreIdx, EncOpenParam *encOP, vpu_buffer_t *vbCustom
             }
         }
 
-        EncodeVUI(&hrd, &vui, pRbspBuf, VUI_HRD_RBSP_BUF_SIZE, &rbspByteSize, &rbspBitSize, encOP->frameRateInfo);
+        EncodeVUI(hrd, &vui, pRbspBuf, VUI_HRD_RBSP_BUF_SIZE, &rbspByteSize, &rbspBitSize, encOP->frameRateInfo);
         encOP->vuiRbspDataSize = rbspBitSize;
         vdi_write_memory(coreIdx, encOP->vuiRbspDataAddr, pRbspBuf,  rbspByteSize, encOP->streamEndian);
         osal_free(pRbspBuf);
@@ -1483,7 +1483,7 @@ Int32 writeSeiNalData(EncHandle handle, int streamEndian, PhysicalAddress prefix
         buffering_period_sei.nal_initial_cpb_removal_delay[0] = 2229;
         buffering_period_sei.nal_initial_cpb_removal_offset[0] = 0;
 
-        seiByteSize = EncodePrefixSEI(&active_parameter_sei, &pic_timing_sei, &buffering_period_sei, &hrd, pSeiBuf, SEI_NAL_DATA_BUF_SIZE);
+        seiByteSize = EncodePrefixSEI(&active_parameter_sei, &pic_timing_sei, &buffering_period_sei, hrd, pSeiBuf, SEI_NAL_DATA_BUF_SIZE);
         seiDataEnc.prefixSeiDataSize = seiByteSize;
         vdi_write_memory(handle->coreIdx, seiDataEnc.prefixSeiNalAddr, pSeiBuf, seiDataEnc.prefixSeiDataSize, streamEndian);
 
@@ -1937,7 +1937,7 @@ BOOL TestMachineSetup(
 
     osal_init_keyboard();
 
-    InitializeDebugEnv(machine->testEnvOptions);
+    InitializeDebugEnv(0, machine->testEnvOptions);
 
     return success;
 }

+ 49 - 16
wave420l/code/sample/helper/main_helper.h

@@ -10,6 +10,7 @@
 #include "vpuapifunc.h"
 #include "vpuapi.h"
 #include "vputypes.h"
+#include "misc/debug.h"
 #ifdef PLATFORM_QNX
     #include <sys/stat.h>
 #endif
@@ -249,11 +250,11 @@ typedef struct {
     int IntraDcVlcThr;
     int VopQuant;
 
-    int frameCroppingFlag;
-    int frameCropLeft;
-    int frameCropRight;
-    int frameCropTop;
-    int frameCropBottom;
+    int frameCroppingFlag;
+    int frameCropLeft;
+    int frameCropRight;
+    int frameCropTop;
+    int frameCropBottom;
 
     // H.264 ONLY
     int ConstIntraPredFlag;
@@ -841,6 +842,7 @@ BOOL BitstreamFeeder_SetAutoUpdate(
 /************************************************************************/
 #define SOURCE_YUV                  0
 #define SOURCE_YUV_WITH_LOADER      2
+#define SOURCE_YUV_WITH_BUFFER      3
 
 #define JPEG_CREATE      0x01        //!<< This command is followed by yuvInfo structure.
 typedef struct {
@@ -990,6 +992,34 @@ BOOL BitstreamReader_Destroy(
     BitstreamReader reader
     );
 
+/*!
+ * \param   type                0: Linebuffer, 1: Ringbuffer
+ * \param   path                output filepath.
+ * \param   endian              Endianness of bitstream buffer
+ * \param   handle              Pointer of encoder handle
+ */
+BitstreamReader BufferStreamReader_Create(
+    Uint32    type,
+    EndianMode  endian,
+    EncHandle*  handle
+    );
+
+/*!
+ * \param   bitstreamBuffer     base address of bitstream buffer
+ * \param   bitstreamBufferSize size of bitstream buffer
+ */
+Uint32 BufferStreamReader_Act(
+    BitstreamReader reader,
+    PhysicalAddress bitstreamBuffer,
+    Uint32        bitstreamBufferSize,
+    Uint32        defaultsize,
+    Uint8*          pBuffer,
+    Comparator      comparator
+    );
+
+BOOL BufferStreamReader_Destroy(
+    BitstreamReader reader
+    );
 /************************************************************************/
 /* Binary Reader                                                           */
 /************************************************************************/
@@ -1484,11 +1514,11 @@ typedef struct ObserverStruct {
 
 #define MAX_OBSERVERS           100
 typedef struct TestMachine_struct {
-    Uint32          coreIdx;
-    Uint32          testEnvOptions;             /*!<< See debug.h */
-    BOOL            reset;
-    Listener        observers[MAX_OBSERVERS];
-    Uint32          numObservers;
+    Uint32          coreIdx;
+    Uint32          testEnvOptions;             /*!<< See debug.h */
+    BOOL            reset;
+    Listener        observers[MAX_OBSERVERS];
+    Uint32          numObservers;
 } TestMachine;
 
 /************************************************************************/
@@ -1560,13 +1590,13 @@ extern Listener decOutputInformation;
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
-
-BOOL TestMachineSetup(
-    TestMachine* machine
+
+BOOL TestMachineSetup(
+    TestMachine* machine
     );
-
-void TestMachineCleanUp(
-    TestMachine* machine
+
+void TestMachineCleanUp(
+    TestMachine* machine
     );
 
 struct option* ConvertOptions(
@@ -1797,6 +1827,9 @@ Int32 writeSeiNalData(
     PhysicalAddress prefixSeiNalAddr,
     hrd_t *hrd
     );
+int calcScale(int x);
+BOOL EncodeVUI(hrd_t *hrd, vui_t *vui, Uint8 *pBuffer, Uint32 bufferSize, Uint32 *pByteSize, Uint32 *pBitSize, double dframeRate);
+Uint32 EncodePrefixSEI( sei_active_parameter_t *sap, sei_pic_timing_t *spt, sei_buffering_period_t *sbp, hrd_t *hrd, Uint8 *pBuffer, Uint32 bufferSize);
 #endif
 void setEncBgMode(
     EncParam *encParam, 

+ 1 - 1
wave420l/code/sample/helper/misc/debug.h

@@ -17,7 +17,7 @@
 #define _DEBUG_H_
 
 #include "config.h"
-#include "main_helper.h"
+#include "../main_helper.h"
 
 enum {
     CNMQC_ENV_NONE,

+ 110 - 2
wave420l/code/sample/helper/yuv/yuvfeeder.c

@@ -47,6 +47,104 @@ BOOL loaderYuvFeeder_Configure(
     YuvInfo        yuv
 );
 
+static BOOL bufferYuvFeeder_Create(
+    YuvFeederImpl *impl,
+    const char*   path,
+    Uint32        packed,
+    Uint32        fbStride,
+    Uint32        fbHeight)
+{
+    yuvContext*   ctx;
+
+    if ((ctx=(yuvContext*)osal_malloc(sizeof(yuvContext))) == NULL) {
+
+        return FALSE;
+    }
+
+    osal_memset(ctx, 0, sizeof(yuvContext));
+
+    impl->context = ctx;
+
+    return TRUE;
+}
+
+static BOOL bufferYuvFeeder_Destory(
+    YuvFeederImpl *impl
+    )
+{
+    yuvContext*    ctx = (yuvContext*)impl->context;
+
+    osal_free(ctx);
+    return TRUE;
+}
+
+
+static BOOL bufferYuvFeeder_Feed(
+    YuvFeederImpl*  impl,
+    Int32           coreIdx,
+    FrameBuffer*    fb,
+    size_t          picWidth,
+    size_t          picHeight,
+    void*           arg
+    )
+{
+    yuvContext* ctx = (yuvContext*)impl->context;
+    Uint8*      pYuv = arg;
+    size_t      frameSize;
+    size_t      frameSizeY;
+    size_t      frameSizeC;
+    Int32       bitdepth=0;
+    Int32       yuv3p4b=0;
+    Int32       packedFormat=0;
+    Uint32      outWidth=0;
+    Uint32      outHeight=0;
+
+    CalcYuvSize(fb->format, picWidth, picHeight, fb->cbcrInterleave, &frameSizeY, &frameSizeC, &frameSize, &bitdepth, &packedFormat, &yuv3p4b);
+
+
+    if (fb->mapType == LINEAR_FRAME_MAP ) {
+        outWidth  = (yuv3p4b&&packedFormat==0) ? ((picWidth+31)/32)*32  : picWidth;
+        outHeight = (yuv3p4b) ? ((picHeight+7)/8)*8 : picHeight;
+
+        if ( yuv3p4b  && packedFormat) {
+            outWidth = ((picWidth*2)+2)/3*4;
+        }
+        else if(packedFormat) {
+            outWidth *= 2;           // 8bit packed mode(YUYV) only. (need to add 10bit cases later)
+            if (bitdepth != 0)      // 10bit packed
+                outWidth *= 2;
+        }
+        LoadYuvImageBurstFormat(coreIdx, pYuv, outWidth, outHeight, fb, ctx->srcPlanar);
+    }
+    else {
+        TiledMapConfig  mapConfig;
+
+        osal_memset((void*)&mapConfig, 0x00, sizeof(TiledMapConfig));
+        if (arg != NULL) {
+            osal_memcpy((void*)&mapConfig, arg, sizeof(TiledMapConfig));
+        }
+
+        LoadTiledImageYuvBurst(coreIdx, pYuv, picWidth, picHeight, fb, mapConfig);
+    }
+
+    return TRUE;
+}
+
+static BOOL bufferYuvFeeder_Configure(
+    YuvFeederImpl* impl,
+    Uint32         cmd,
+    YuvInfo        yuv
+    )
+{
+    yuvContext* ctx = (yuvContext*)impl->context;
+    UNREFERENCED_PARAMETER(cmd);
+
+    ctx->fbStride       = yuv.srcStride;
+    ctx->cbcrInterleave = yuv.cbcrInterleave;
+    ctx->srcPlanar      = yuv.srcPlanar;
+
+    return TRUE;
+}
 
 static BOOL yuvYuvFeeder_Create(
     YuvFeederImpl *impl,
@@ -190,8 +288,8 @@ YuvFeeder YuvFeeder_Create(
     YuvFeederImpl     *impl;
     BOOL              success = FALSE;
 
-    if (srcFilePath == NULL) {
-        VLOG(ERR, "%s:%d src path is NULL\n", __FUNCTION__, __LINE__);
+    if ((type != SOURCE_YUV_WITH_BUFFER) && (srcFilePath == NULL)) {
+        VLOG(ERR, "%s:%d src path is NULL, tpye %d\n", __FUNCTION__, __LINE__, type);
         return NULL;
     }
 
@@ -217,6 +315,16 @@ YuvFeeder YuvFeeder_Create(
             impl->Configure(impl, 0, yuvInfo);
         }
         break;
+    case SOURCE_YUV_WITH_BUFFER:
+        impl = osal_malloc(sizeof(YuvFeederImpl));
+        impl->Create    = &bufferYuvFeeder_Create;
+        impl->Feed      = &bufferYuvFeeder_Feed;
+        impl->Destroy   = &bufferYuvFeeder_Destory;
+        impl->Configure = &bufferYuvFeeder_Configure;
+        if ((success=impl->Create(impl, srcFilePath, yuvInfo.packedFormat, yuvInfo.srcStride, yuvInfo.srcHeight)) == TRUE) {
+            impl->Configure(impl, 0, yuvInfo);
+        }
+        break;
     default:
         VLOG(ERR, "%s:%d Unknown YuvFeeder Type\n", __FUNCTION__, __LINE__);
         success = FALSE;

+ 2 - 0
wave420l/code/vpuapi/coda9/coda9.h

@@ -156,6 +156,8 @@ extern RetCode Coda9VpuEncGiveCommand(
     CodecCommand    cmd, 
     void*           param
     );
+
+extern RetCode Coda9VpuDecCpbFlush(CodecInst* instance);
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

+ 1 - 0
wave420l/code/vpuapi/vpuapi.c

@@ -17,6 +17,7 @@
 #include "vpuapifunc.h"
 #include "product.h"
 #include "wave/common/common_regdefine.h"
+#include "wave/wave5/wave5.h"
             
 
 #ifdef BIT_CODE_FILE_PATH

+ 5 - 5
wave420l/code/vpuapi/wave/common/common.c

@@ -1099,11 +1099,11 @@ RetCode Wave4VpuDecFlush(CodecInst* instance, FramebufferIndex* framebufferIndex
 
 RetCode Wave4VpuEncFiniSeq(CodecInst* instance)
 {
-    EncInfo*    pEncInfo = VPU_HANDLE_TO_ENCINFO(instance);
-
-
-    VpuWriteReg(instance->coreIdx, W4_ADDR_WORK_BASE, pEncInfo->vbWork.phys_addr);
-    VpuWriteReg(instance->coreIdx, W4_WORK_SIZE,      pEncInfo->vbWork.size);
+    EncInfo*    pEncInfo = VPU_HANDLE_TO_ENCINFO(instance);
+
+
+    VpuWriteReg(instance->coreIdx, W4_ADDR_WORK_BASE, pEncInfo->vbWork.phys_addr);
+    VpuWriteReg(instance->coreIdx, W4_WORK_SIZE,      pEncInfo->vbWork.size);
     VpuWriteReg(instance->coreIdx, W4_WORK_PARAM,     0);
 
     Wave4BitIssueCommand(instance, FINI_SEQ);

+ 41 - 0
wave511/code/WaveDecDriver_buildroot.mak

@@ -0,0 +1,41 @@
+# 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 ARCH=riscv
+export SUBARCH=riscv
+export CROSS_COMPILE=riscv64-buildroot-linux-gnu-
+
+DRV_PATH  := $(shell pwd)/vdi/linux/driver
+EXTRA_CFLAGS +=	$(DEBFLAGS) -I$(LDDINCDIR) -Wall
+
+ifneq ($(KERNELRELEASE),)
+# call from kernel build system
+
+obj-m	:= vdec.o
+
+else
+
+default:
+	$(MAKE) -C $(KERNELDIR)	M=$(DRV_PATH) LDDINCDIR=$(DRV_PATH)/../include modules
+
+endif
+
+
+
+clean:
+	rm -rf $(DRV_PATH)/*.o $(DRV_PATH)/*~ $(DRV_PATH)/core $(DRV_PATH)/.depend $(DRV_PATH)/.*.cmd $(DRV_PATH)/*.ko $(DRV_PATH)/*.mod.c $(DRV_PATH)/modules.order $(DRV_PATH)/.tmp_versions $(DRV_PATH)/*.dwo $(DRV_PATH)/.*.dwo
+
+depend .depend dep:
+	$(CC) $(CFLAGS)	-M *.c > .depend
+
+
+ifeq (.depend,$(wildcard .depend))
+include	.depend
+endif

+ 1 - 1
wave511/code/WaveDecode-ffmpeg.mak

@@ -93,7 +93,7 @@ CFLAGS  += -DSUPPORT_FFMPEG_DEMUX
 LDLIBS  += -lavformat -lavcodec -lavutil -lswresample
 LDFLAGS += -L./ffmpeg/lib/$(PLATFORM)
 ifneq ($(USE_32BIT), yes)
-LDLIBS  += -lz
+#LDLIBS  += -lz
 endif #USE_32BIT
 endif #USE_FFMPEG
 

+ 168 - 0
wave511/code/WaveDecode_buildroot.mak

@@ -0,0 +1,168 @@
+# ----------------------------------------------------------------------
+#
+# Project: C&M Video decoder sample
+#
+# ----------------------------------------------------------------------
+.PHONY: CREATE_DIR
+BUILD_CONFIGURATION := EmbeddedRiscvLinux
+
+PRODUCT := WAVE511
+#PRODUCT := WAVE521C
+
+$(shell cp sample_v2/component_list_decoder.h sample_v2/component/component_list.h)
+
+USE_PTHREAD = yes
+USE_RTL_SIM = no
+LINT_HOME   = etc/lint
+
+UNAME = $(shell uname -a)
+ifneq (,$(findstring i386, $(UNAME)))
+    USE_32BIT = yes
+endif
+
+ifeq ($(RTL_SIM), 1)
+USE_RTL_SIM = yes
+endif
+
+REFC    := 0
+
+ifeq ($(USE_32BIT), yes)
+PLATFORM    = nativelinux
+else
+PLATFORM    = nativelinux_64bit
+endif
+
+CROSS_CC_PREFIX =
+VDI_C           = vdi/linux/vdi.c
+VDI_OSAL_C      = vdi/linux/vdi_osal.c
+MM_C            =
+PLATFORM_FLAGS  =
+
+VDI_VPATH       = vdi/linux
+ifeq ("$(BUILD_CONFIGURATION)", "NonOS")
+    CROSS_CC_PREFIX = arm-none-eabi-
+    VDI_C           = vdi/nonos/vdi.c
+    VDI_OSAL_C      = vdi/nonos/vdi_osal.c
+    MM_C            = vdi/mm.c
+    USE_PTHREAD     = no
+    PLATFORM        = none
+    DEFINES         = -DLIB_C_STUB
+    PLATFORM_FLAGS  =
+    VDI_VPATH       = vdi/nonos
+    NONOS_RULE      = options_nonos.lnt
+endif
+ifeq ("$(BUILD_CONFIGURATION)", "EmbeddedLinux")
+    CROSS_CC_PREFIX = arm-none-linux-gnueabi-
+    PLATFORM        = armlinux
+endif
+
+ifeq ("$(BUILD_CONFIGURATION)", "EmbeddedRiscvLinux")
+    CROSS_CC_PREFIX = riscv64-buildroot-linux-gnu-
+    PLATFORM        = riscvlinux
+endif
+CC  = $(CROSS_CC_PREFIX)gcc
+CXX = $(CROSS_CC_PREFIX)g++
+LINKER=$(CC)
+AR  = $(CROSS_CC_PREFIX)ar
+
+INCLUDES = -I./vpuapi -I./ffmpeg/include -I./sample_v2/helper -I./sample_v2/helper/misc -I./sample_v2/component -I./vdi -I../
+INCLUDES += -I./sample_v2/component_decoder
+ifeq ($(USE_RTL_SIM), yes)
+DEFINES += -DCNM_SIM_PLATFORM -DCNM_SIM_DPI_INTERFACE -DSUPPORT_DECODER
+DEFINES += -D$(PRODUCT) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
+else
+DEFINES += -D$(PRODUCT) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
+endif	# USE_SIM_PLATFORM
+DEFINES += -DUSE_FEEDING_METHOD_BUFFER
+
+CFLAGS  += -g -I. -Wl,--fatal-warning $(INCLUDES) $(DEFINES) $(PLATFORM_FLAGS)
+ifeq ($(USE_RTL_SIM), yes)
+ifeq ($(IUS), 1)
+CFLAGS  += -fPIC # ncverilog is 64bit version
+endif
+endif
+ARFLAGS += cru
+
+LDFLAGS  = $(PLATFORM_FLAGS)
+
+ifeq ($(USE_PTHREAD), yes)
+LDLIBS  += -lpthread
+endif
+LDLIBS  += -lm
+
+BUILDLIST=DECTEST
+MAKEFILE=WaveDecode.mak
+DECTEST=libsfdec.so
+
+OBJDIR=obj
+ALLOBJS=*.o
+ALLDEPS=*.dep
+ALLLIBS=*.a
+RM=rm -f
+MKDIR=mkdir -p
+
+SOURCES_COMMON =main_helper.c                   vpuhelper.c                 bitstreamfeeder.c           \
+                bitstreamreader.c               bsfeeder_fixedsize_impl.c   bsfeeder_framesize_impl.c   \
+                bsfeeder_size_plus_es_impl.c    bin_comparator_impl.c       comparator.c                \
+                md5_comparator_impl.c           yuv_comparator_impl.c       bsfeeder_buffer_impl.c   \
+                cfgParser.c                     decoder_listener.c          \
+                cnm_video_helper.c              container.c                 \
+                datastructure.c                 debug.c                     \
+                bw_monitor.c                    pf_monitor.c                \
+                cnm_app.c                       cnm_task.c                  component.c                 \
+                component_dec_decoder.c         component_dec_feeder.c      component_dec_renderer.c    \
+                product.c                       vpuapifunc.c                vpuapi.c                    \
+                coda9.c                         wave5.c                     \
+                $(VDI_C)                        $(VDI_OSAL_C)               $(MM_C)
+
+
+
+VPATH  = sample_v2:
+VPATH += sample_v2/component_encoder:
+VPATH += sample_v2/component_decoder:
+VPATH += sample_v2/helper:
+VPATH += sample_v2/helper/bitstream:
+VPATH += sample_v2/helper/comparator:
+VPATH += sample_v2/helper/display:sample_v2/helper/misc:sample_v2/helper/yuv:sample_v2/component:
+VPATH += vdi:
+VPATH += $(VDI_VPATH):vpuapi:vpuapi/coda9:vpuapi/wave
+
+VPATH2=$(patsubst %,-I%,$(subst :, ,$(VPATH)))
+
+OBJECTNAMES_COMMON=$(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCES_COMMON)))
+OBJECTPATHS_COMMON=$(addprefix $(OBJDIR)/,$(notdir $(OBJECTNAMES_COMMON)))
+
+SOURCES_DECTEST = sample_v2/main_dec_test.c
+ifeq ($(USE_RTL_SIM), yes)
+	SOURCES_DECTEST += sample/main_sim.c
+endif
+
+OBJECTNAMES_DECTEST=$(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCES_DECTEST)))
+OBJECTPATHS_DECTEST=$(addprefix $(OBJDIR)/,$(notdir $(OBJECTNAMES_DECTEST))) $(OBJECTPATHS_COMMON)
+
+all: $(BUILDLIST)
+
+ifeq ($(USE_RTL_SIM), yes)
+DECTEST: CREATE_DIR $(OBJECTPATHS_COMMON)
+else
+DECTEST: CREATE_DIR $(OBJECTPATHS_COMMON)
+	$(LINKER) -fPIC -shared -o $(DECTEST) $(LDFLAGS) -Wl,-gc-section -Wl,--start-group $(OBJECTPATHS_COMMON) $(LDLIBS) -Wl,--end-group
+endif
+
+-include $(OBJECTPATHS:.o=.dep)
+
+clean:
+	$(RM) $(DECTEST)
+	$(RM) $(OBJDIR)/$(ALLOBJS)
+	$(RM) $(OBJDIR)/$(ALLDEPS)
+
+CREATE_DIR:
+	-mkdir -p $(OBJDIR)
+
+obj/%.o: %.c $(MAKEFILE)
+	$(CC) -fPIC -shared $(CFLAGS) -Wall -Werror -c $< -o $@ -MD -MF $(@:.o=.dep)
+
+
+lint:
+	"$(LINT_HOME)/flint" -i"$(LINT_HOME)" $(DEFINES) $(INCLUDES) $(VPATH2) linux_std.lnt $(HAPS_RULE) $(NONOS_RULE)  $(SOURCES_COMMON)
+

+ 11 - 0
wave511/code/build_env.sh

@@ -0,0 +1,11 @@
+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-
+
+
+

+ 2 - 0
wave511/code/cp.sh

@@ -0,0 +1,2 @@
+#!/bin/bash
+sudo cp -rdvp vdec_driver/ /home/nfs/rootfs/root

+ 7 - 2
wave511/code/sample_v2/component/cnm_app.h

@@ -26,9 +26,14 @@
 #ifndef __CNM_APP_H__
 #define __CNM_APP_H__
 
-#include "vputypes.h"
-#include "component.h"
 
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "wave511/vpuapi/vputypes.h"
+    #include "wave511/sample_v2/component/component.h"
+#else
+    #include "vputypes.h"
+    #include "component.h"
+#endif
 typedef void*       CNMTask;
 
 typedef enum {

+ 5 - 1
wave511/code/sample_v2/component/cnm_app_internal.h

@@ -26,7 +26,11 @@
 #ifndef __CNM_APP_INTERNAL_H__
 #define __CNM_APP_INTERNAL_H__
 
-#include "vputypes.h"
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "wave511/vpuapi/vputypes.h"
+#else
+    #include "vputypes.h"
+#endif
 
 #define MAX_TASKS_IN_APP            8
 #define MAX_COMPONENTS_IN_TASK      6

+ 4 - 1
wave511/code/sample_v2/component/component.c

@@ -26,6 +26,7 @@
 #include <string.h>
 #include "component.h"
 #include "cnm_app.h"
+#include <sys/prctl.h>
 
 #ifdef PLATFORM_NON_OS
 BOOL supportThread = FALSE;
@@ -367,6 +368,7 @@ static void DoYourJob(ComponentImpl* com)
     /* Check if connected components are terminated */
     sinkComponent = (ComponentImpl*)com->sinkPort.connectedComponent;
     if (sinkComponent && sinkComponent->terminate == TRUE) {
+        printf("%s skin terminate\r\n",com->name);
         com->terminate = TRUE;
     }
 
@@ -378,11 +380,12 @@ static void DoYourJob(ComponentImpl* com)
 static void DoThreadWork(void* arg)
 {
     ComponentImpl* com = (ComponentImpl*)arg;
-
+    prctl(PR_SET_NAME, com->name);
     while (com->terminate == FALSE) {
         DoYourJob(com);
         osal_msleep(2); // To yield schedule
     }
+    ComponentNotifyListeners(com, COMPONENT_EVENT_TERMINATED, NULL);
 
     com->state = COMPONENT_STATE_TERMINATED;
 }

+ 49 - 3
wave511/code/sample_v2/component/component.h

@@ -26,9 +26,16 @@
 #ifndef _COMPONENT_H_
 #define _COMPONENT_H_
 
-#include "config.h"
-#include "vpuapifunc.h"
-#include "main_helper.h"
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "wave511/config.h"
+    #include "wave511/vpuapi/vpuapifunc.h"
+    #include "wave511/sample_v2/helper/main_helper.h"
+#else
+    #include "config.h"
+    #include "vpuapifunc.h"
+    #include "main_helper.h"
+#endif
+
 
 #define MAX_QUEUE_NUM 5
 
@@ -137,6 +144,40 @@ typedef struct PortContainerClock {
     Uint32  type;
 } PortContainerClock;
 
+/** @ingroup buf */
+typedef struct PortContainerExternal
+{
+    Uint32 nSize;              /**< size of the structure in bytes */
+    Uint8* pBuffer;            /**< Pointer to actual block of memory
+                                     that is acting as the buffer */
+    Uint32 nAllocLen;          /**< size of the buffer allocated, in bytes */
+    Uint32 nFilledLen;         /**< number of bytes currently in the
+                                     buffer */
+    Uint32 nOffset;            /**< start offset of valid data in bytes from
+                                     the start of the buffer */
+    void*  pAppPrivate;        /**< pointer to any data the application
+                                     wants to associate with this buffer */
+    Uint32 nBufferIndex;
+    Uint32 nTickCount;         /**< Optional entry that the component and
+                                     application can update with a tick count
+                                     when they access the component.  This
+                                     value should be in microseconds.  Since
+                                     this is a value relative to an arbitrary
+                                     starting point, this value cannot be used
+                                     to determine absolute time.  This is an
+                                     optional entry and not all components
+                                     will update it.*/
+    Uint64 nTimeStamp;       /**< Timestamp corresponding to the sample
+                                     starting at the first logical sample
+                                     boundary in the buffer. Timestamps of
+                                     successive samples within the buffer may
+                                     be inferred by adding the duration of the
+                                     of the preceding buffer to the timestamp
+                                     of the preceding buffer.*/
+    Uint32  nFlags;           /**< buffer specific flags */
+    Uint32  index;
+} PortContainerExternal;
+
 typedef struct PortContainerES {
     Uint32          packetNo;
     BOOL            consumed;
@@ -298,6 +339,7 @@ typedef struct {
 /* ------------------------------------------------ */
 #define COMPONENT_EVENT_SLEEP                   (1ULL<<0)       /*!<< The third parameter of listener is NULL. */
 #define COMPONENT_EVENT_WAKEUP                  (1ULL<<1)       /*!<< The third parameter of listener is NULL. */
+#define COMPONENT_EVENT_TERMINATED              (1ULL<<2)
 #define COMPONENT_EVENT_COMMON_ALL              0xffffULL
 /* ------------------------------------------------ */
 /* ---------------- DECODER EVENTS ---------------- */
@@ -313,6 +355,8 @@ typedef struct {
 #define COMPONENT_EVENT_DEC_DECODED_ALL         (1ULL<<24)      /*!<< The third parameter of listener is a pointer of CNMComListenerDecClose . */
 #define COMPONENT_EVENT_DEC_CLOSE               (1ULL<<25)      /*!<< The third parameter of listener is NULL. */
 #define COMPONENT_EVENT_DEC_RESET_DONE          (1ULL<<26)      /*!<< The third parameter of listener is NULL. */
+#define COMPONENT_EVENT_DEC_EMPTY_BUFFER_DONE   (1ULL<<27)
+#define COMPONENT_EVENT_DEC_FILL_BUFFER_DONE    (1ULL<<28)
 #define COMPONENT_EVENT_DEC_ALL                 0xffff0000ULL
 
 /* ------------------------------------------------ */
@@ -398,6 +442,8 @@ typedef struct CNMComListenerDecClose {
 #define COMPONENT_EVENT_ENC_ENCODED_ALL             (1ULL<<42)      /*!<< The third parameter of listener is a pointer of EncHandle. */
 #define COMPONENT_EVENT_ENC_RESET                   (1ULL<<43)      /*!<< The third parameter of listener is a pointer of EncHandle. */
 #define COMPONENT_EVENT_CODA9_ENC_MAKE_HEADER       (1ULL<<44)      /*!<< The third parameter of listener is a pointer of CNMComListenerEncDone. */
+#define COMPONENT_EVENT_ENC_EMPTY_BUFFER_DONE       (1ULL<<45)
+#define COMPONENT_EVENT_ENC_FILL_BUFFER_DONE        (1ULL<<46)
 #define COMPONENT_EVENT_ENC_ALL                     0xffff00000000ULL
 
 /* ------------------------------------------------ */

+ 3 - 1
wave511/code/sample_v2/component_decoder/component_dec_decoder.c

@@ -375,7 +375,6 @@ static BOOL DoReset(ComponentImpl* com)
     return TRUE;
 }
 
-
 static BOOL Decode(ComponentImpl* com, PortContainerES* in, PortContainerDisplay* out)
 {
     DecoderContext*                 ctx           = (DecoderContext*)com->context;
@@ -590,6 +589,9 @@ static CNMComponentParamRet GetParameterDecoder(ComponentImpl* from, ComponentIm
         else {
             fbNum->linearNum = 0;
         }
+#ifdef USE_FEEDING_METHOD_BUFFER
+        fbNum->linearNum = 10;
+#endif
         break;
     case GET_PARAM_DEC_BITSTREAM_BUF_POS:
         if (ctx->state < DEC_STATE_INIT_SEQ) return CNM_COMPONENT_PARAM_NOT_READY;

+ 43 - 0
wave511/code/sample_v2/component_decoder/component_dec_feeder.c

@@ -221,6 +221,32 @@ static BOOL ExecuteFeeder(ComponentImpl* com, PortContainer* in, PortContainer*
 
     if (com->pause) return TRUE;
 
+#ifdef USE_FEEDING_METHOD_BUFFER
+extern void BSFeederBuffer_SetData(
+    void*       feeder,
+    char*       address,
+    Uint32       size);
+extern void*  BitstreamFeeder_GetActualFeeder(void *feeder);
+extern void BSFeederBuffer_SetEos(void* feeder);
+extern BOOL BSFeederBuffer_GetEos(void* feeder);
+
+    void *actualFeeder = BitstreamFeeder_GetActualFeeder(bsFeeder);
+    PortContainerExternal *input = NULL;
+    if (BSFeederBuffer_GetEos(actualFeeder) == FALSE) {
+        input = (PortContainerExternal *)ComponentPortPeekData(&com->srcPort);
+        if (input == NULL) {
+            return TRUE;
+        }
+        BSFeederBuffer_SetData(actualFeeder, (char *)input->pBuffer, input->nFilledLen);
+        if ((input->nFlags & 0x1) == 0x1)
+        {
+            BSFeederBuffer_SetEos(actualFeeder);
+        }
+    } else {
+        BSFeederBuffer_SetData(actualFeeder, 0, 0);
+    }
+#endif
+
     eos = BitstreamFeeder_IsEos(bsFeeder);
 
     if (config->bitstreamMode == BS_MODE_PIC_END) {
@@ -228,6 +254,14 @@ static BOOL ExecuteFeeder(ComponentImpl* com, PortContainer* in, PortContainer*
         wrPtr    = bsBuffer->phys_addr;
         room     = bsBuffer->size;
         container->size = BitstreamFeeder_Act(bsFeeder, bsBuffer, wrPtr, (Uint32)room, &ctx->nextWrPtr);
+#ifdef USE_FEEDING_METHOD_BUFFER
+        if (input != NULL) {
+            ComponentPortGetData(&com->srcPort);
+            ComponentNotifyListeners(com, COMPONENT_EVENT_DEC_EMPTY_BUFFER_DONE, (void *)input);
+            // do not use input var under next line because this data already be droped.
+            (void)input;
+        }
+#endif
     }
     else {
         ParamDecBitstreamBufPos bsPos;
@@ -256,6 +290,15 @@ static BOOL ExecuteFeeder(ComponentImpl* com, PortContainer* in, PortContainer*
                 ctx->dropCount--;
                 ctx->nextWrPtr = wrPtr;
             }
+#ifdef USE_FEEDING_METHOD_BUFFER
+            eos = BitstreamFeeder_IsEos(bsFeeder);
+            if (eos == TRUE) {
+                ComponentPortGetData(&com->srcPort);
+                ComponentNotifyListeners(com, COMPONENT_EVENT_DEC_EMPTY_BUFFER_DONE, (void *)input);
+                // do not use input var under next line because this data already be droped.
+                (void)input;
+            }
+#endif
         }
         else {
             if (ctx->loopCount > 0) {

+ 177 - 14
wave511/code/sample_v2/component_decoder/component_dec_renderer.c

@@ -44,6 +44,11 @@ typedef struct {
     osal_mutex_t                lock;
     char                        outputPath[256];
     FILE*                       fpOutput[OUTPUT_FP_NUMBER];
+    BOOL                        MemoryOptimization;
+    int                         totalBufferNumber;
+    int                         currentBufferNumber;
+    FrameBuffer                 pLinearFrame[MAX_REG_FRAME];
+    vpu_buffer_t                pLinearFbMem[MAX_REG_FRAME];
 } RendererContext;
 
 typedef struct SequenceMemInfo {
@@ -175,6 +180,12 @@ static BOOL ReallocateFrameBuffers(ComponentImpl* com, ParamDecReallocFB* param)
     return TRUE;
 }
 
+void Render_DecClrDispFlag(void *context, int index)
+{
+    RendererContext* ctx = (RendererContext*)context;
+    VPU_DecClrDispFlag(ctx->handle, index);
+}
+
 static void DisplayFrame(RendererContext* ctx, DecOutputInfo* result)
 {
     Int32 productID = ctx->testDecConfig.productId;
@@ -226,6 +237,69 @@ static BOOL FlushFrameBuffers(ComponentImpl* com, Uint32* flushedIndexes)
 
     return TRUE;
 }
+
+
+
+void SetRenderTotalBufferNumber(ComponentImpl* com, Uint32 number)
+{
+    RendererContext*     ctx            = (RendererContext*)com->context;
+    ctx->fbCount.linearNum = ctx->totalBufferNumber = number;
+}
+
+void* AllocateFrameBuffer2(ComponentImpl* com, Uint32 size)
+{
+    RendererContext*     ctx            = (RendererContext*)com->context;
+    int i = 0;
+
+    if (ctx->handle == NULL) {
+        ctx->MemoryOptimization = FALSE;
+        return NULL;
+    }
+    for (i = 0;i < MAX_REG_FRAME; i ++){
+        if (ctx->pLinearFbMem[i].phys_addr == 0)
+        {
+            VLOG(INFO, "Found empty frame at index %d\r\n", i);
+            break;
+        }
+    }
+    if (i == MAX_REG_FRAME)
+    {
+        VLOG(ERR, "Could not found empty frame at index\r\n");
+        return NULL;
+    }
+    // TODO: Adjust ctx->fbCount
+    void *ret = AllocateDecFrameBuffer2(ctx->handle, &ctx->testDecConfig, size, &ctx->pLinearFrame[i], &ctx->pLinearFbMem[i]);
+    ctx->currentBufferNumber ++;
+    return ret;
+}
+
+BOOL AttachDMABuffer(ComponentImpl* com, Uint64 virtAddress, Uint32 size)
+{
+    BOOL ret = FALSE;
+    RendererContext*     ctx            = (RendererContext*)com->context;
+    int i = 0;
+
+    if (ctx->handle == NULL) {
+        ctx->MemoryOptimization = FALSE;
+        return FALSE;
+    }
+    for (i = 0;i < MAX_REG_FRAME; i ++){
+        if (ctx->pLinearFbMem[i].phys_addr == 0)
+        {
+            VLOG(INFO, "Found empty frame at index %d\r\n", i);
+            break;
+        }
+    }
+    if (i == MAX_REG_FRAME)
+    {
+        VLOG(ERR, "Could not found empty frame at index\r\n");
+        return FALSE;
+    }
+    ret = AttachDecDMABuffer(ctx->handle, &ctx->testDecConfig, virtAddress, size, &ctx->pLinearFrame[i], &ctx->pLinearFbMem[i]);
+    ctx->currentBufferNumber ++;
+    return ret;
+}
+
 static BOOL AllocateFrameBuffer(ComponentImpl* com)
 {
     RendererContext*     ctx            = (RendererContext*)com->context;
@@ -250,6 +324,9 @@ static BOOL AllocateFrameBuffer(ComponentImpl* com)
             __FUNCTION__, __LINE__, compressedNum, linearNum);
         return FALSE;
     }
+    if (ctx->MemoryOptimization){
+        linearNum = 0;
+    }
 
     if (AllocateDecFrameBuffer(ctx->handle, &ctx->testDecConfig, compressedNum, linearNum, ctx->pFrame, ctx->pFbMem, &ctx->framebufStride) == FALSE) {
         VLOG(INFO, "%s:%d Failed to AllocateDecFrameBuffer()\n", __FUNCTION__, __LINE__);
@@ -296,6 +373,23 @@ static CNMComponentParamRet GetParameterRenderer(ComponentImpl* from, ComponentI
         container->consumed = TRUE;
         break;
     case GET_PARAM_RENDERER_FRAME_BUF:
+        if (ctx->MemoryOptimization){
+            if (ctx->currentBufferNumber < ctx->totalBufferNumber) return CNM_COMPONENT_PARAM_NOT_READY;
+            int i = 0;
+            for (i = 0;i < MAX_REG_FRAME; i ++) {
+                if (ctx->pFbMem[i].phys_addr == 0) {
+                    break;
+                }
+            }
+            VLOG(INFO, "The start index of LINEAR buffer = %d\n", i);
+            for (int j = 0; j < MAX_REG_FRAME; j ++) {
+                if (ctx->pLinearFbMem[j].phys_addr != 0) {
+                    memcpy(&ctx->pFbMem[i + j], &ctx->pLinearFbMem[j], sizeof(vpu_buffer_t));
+                    memcpy(&ctx->pFrame[i + j], &ctx->pLinearFrame[j], sizeof(FrameBuffer));
+                }
+            }
+        }
+        //TODO: Adjust Liner number
         allocFb = (ParamDecFrameBuffer*)data;
         allocFb->stride        = ctx->framebufStride;
         allocFb->linearNum     = ctx->fbCount.linearNum;
@@ -353,7 +447,6 @@ static CNMComponentParamRet SetParameterRenderer(ComponentImpl* from, ComponentI
 }
 
 
-
 static BOOL ExecuteRenderer(ComponentImpl* com, PortContainer* in, PortContainer* out)
 {
     RendererContext*        ctx               = (RendererContext*)com->context;
@@ -364,26 +457,83 @@ static BOOL ExecuteRenderer(ComponentImpl* com, PortContainer* in, PortContainer
     if (TRUE == com->pause) {
         return TRUE;
     }
-
+#ifdef USE_FEEDING_METHOD_BUFFER
+    PortContainerExternal *output = (PortContainerExternal*)ComponentPortPeekData(&com->sinkPort);
+    if (output == NULL) {
+        in->reuse = TRUE;
+        return TRUE;
+    }
+#endif
     in->reuse = TRUE;
 
-
     indexFrameDisplay = srcData->decInfo.indexFrameDisplay;
 
     if (indexFrameDisplay == DISPLAY_IDX_FLAG_SEQ_END) {
+
+        while ((output = (PortContainerExternal*)ComponentPortGetData(&com->sinkPort)) != NULL)
+        {
+            output->nFlags = 0x1;
+            output->nFilledLen = 0;
+            ComponentNotifyListeners(com, COMPONENT_EVENT_DEC_FILL_BUFFER_DONE, (void *)output);
+        }
         com->terminate = TRUE;
+        ComponentNotifyListeners(com, COMPONENT_EVENT_DEC_DECODED_ALL, NULL);
     }
     else if (indexFrameDisplay >= 0) {
-        if (strlen((const char*)decConfig->outputPath) > 0) {
-            VpuRect      rcDisplay  = {0,};
-            TiledMapType mapType    = srcData->decInfo.dispFrame.mapType;
-
-            rcDisplay.right  = srcData->decInfo.dispPicWidth;
-            rcDisplay.bottom = srcData->decInfo.dispPicHeight;
-            if (decConfig->scaleDownWidth > 0 || decConfig->scaleDownHeight > 0) {
-                rcDisplay.right  = VPU_CEIL(srcData->decInfo.dispPicWidth, 16);
+        VpuRect      rcDisplay  = {0,};
+        TiledMapType mapType    = srcData->decInfo.dispFrame.mapType;
+
+        rcDisplay.right  = srcData->decInfo.dispPicWidth;
+        rcDisplay.bottom = srcData->decInfo.dispPicHeight;
+
+#ifdef USE_FEEDING_METHOD_BUFFER
+        Uint32 width, height, bpp;
+        size_t sizeYuv;
+        Uint32 count = 0, total_count = 0;
+        if (ctx->MemoryOptimization){
+            uint8_t *dmaBuffer = NULL;
+            if (FALSE ==GetYUVFromFrameBuffer2(NULL, &dmaBuffer, output->nFilledLen, ctx->handle, &srcData->decInfo.dispFrame, rcDisplay, &width, &height, &bpp, &sizeYuv)) {
+                VLOG(ERR, "GetYUVFromFrameBuffer2 FAIL!\n");
+            }
+            total_count = Queue_Get_Cnt(com->sinkPort.inputQ);
+            while (output->pBuffer != dmaBuffer)
+            {
+                output = (PortContainerExternal*)ComponentPortGetData(&com->sinkPort);
+                Queue_Enqueue(com->sinkPort.inputQ, (void *)output);
+                output = (PortContainerExternal*)ComponentPortPeekData(&com->sinkPort);
+                VLOG(INFO, "pBuffer = %p, dmaBuffer = %p, index = %d/%d\n", output->pBuffer, dmaBuffer, count, total_count);
+                if (count >= total_count)
+                {
+                    VLOG(ERR, "A wrong Frame Found\n");
+                    output->nFilledLen = 0;
+                    break;
+                }
+                count ++;
             }
+        } else {
+            if (FALSE ==GetYUVFromFrameBuffer2(output->pBuffer, NULL, output->nFilledLen, ctx->handle, &srcData->decInfo.dispFrame, rcDisplay, &width, &height, &bpp, &sizeYuv)) {
+                VLOG(ERR, "GetYUVFromFrameBuffer2 FAIL!\n");
+            }
+        }
+        output->nFilledLen = sizeYuv;
+        output->index = srcData->decInfo.indexFrameDisplay;
+
+        if(srcData->last)
+            output->nFlags |= 0x1;
 
+        if(ComponentPortGetData(&com->sinkPort))
+        {
+            ComponentNotifyListeners(com, COMPONENT_EVENT_DEC_FILL_BUFFER_DONE, (void *)output);
+        }
+        (void)DisplayFrame;
+        (void)decConfig;
+        (void)mapType;
+#else
+        if (decConfig->scaleDownWidth > 0 || decConfig->scaleDownHeight > 0) {
+            rcDisplay.right  = VPU_CEIL(srcData->decInfo.dispPicWidth, 16);
+        }
+
+        if (strlen((const char*)decConfig->outputPath) > 0) {
             if (ctx->fpOutput[0] == NULL) {
                 if (OpenDisplayBufferFile(decConfig->bitFormat, decConfig->outputPath, rcDisplay, mapType, ctx->fpOutput) == FALSE) {
                     return FALSE;
@@ -391,15 +541,23 @@ static BOOL ExecuteRenderer(ComponentImpl* com, PortContainer* in, PortContainer
             }
             SaveDisplayBufferToFile(ctx->handle, decConfig->bitFormat, srcData->decInfo.dispFrame, rcDisplay, ctx->fpOutput);
         }
-
         DisplayFrame(ctx, &srcData->decInfo);
-        osal_msleep(ctx->displayPeriodTime);
+#endif
+        //osal_msleep(ctx->displayPeriodTime);
     }
 
     srcData->consumed = TRUE;
     srcData->reuse    = FALSE;
 
     if (srcData->last == TRUE) {
+        ComponentNotifyListeners(com, COMPONENT_EVENT_DEC_DECODED_ALL, NULL);
+        while ((output = (PortContainerExternal*)ComponentPortGetData(&com->sinkPort)) != NULL)
+        {
+            output->nFlags = 0x1;
+            output->nFilledLen = 0;
+            VLOG(ERR, "Flush output port\r\n");
+            ComponentNotifyListeners(com, COMPONENT_EVENT_DEC_FILL_BUFFER_DONE, (void *)output);
+        }
         com->terminate = TRUE;
     }
 
@@ -423,6 +581,7 @@ static BOOL PrepareRenderer(ComponentImpl* com, BOOL* done)
     if ((ret=AllocateFrameBuffer(com)) == FALSE || ctx->fbAllocated == FALSE) {
         return ret;
     }
+    ComponentNotifyListeners(com, COMPONENT_EVENT_DEC_REGISTER_FB, &ctx->pFrame[0]);
     // Nothing to do
     *done = TRUE;
     return TRUE;
@@ -469,6 +628,8 @@ static Component CreateRenderer(ComponentImpl* com, CNMComponentConfig* componen
     osal_memset(com->context, 0, sizeof(RendererContext));
     ctx = com->context;
 
+    osal_memset(ctx->pLinearFbMem, 0, sizeof(ctx->pLinearFbMem));
+    osal_memset(ctx->pLinearFrame, 0, sizeof(ctx->pLinearFrame));
     osal_memcpy((void*)&ctx->testDecConfig, (void*)&componentParam->testDecConfig, sizeof(TestDecConfig));
     if (componentParam->testDecConfig.fps > 0)
         ctx->displayPeriodTime = (1000 / componentParam->testDecConfig.fps);
@@ -478,7 +639,9 @@ static Component CreateRenderer(ComponentImpl* com, CNMComponentConfig* componen
     ctx->seqMemQ           = Queue_Create(10, sizeof(SequenceMemInfo));
     ctx->lock              = osal_mutex_create();
     ctx->ppuQ              = Queue_Create(MAX_REG_FRAME, sizeof(FrameBuffer));
-
+    ctx->MemoryOptimization = FALSE;
+    ctx->totalBufferNumber = 10;
+    ctx->currentBufferNumber = 0;
     return (Component)com;
 }
 

+ 2 - 2
wave511/code/sample_v2/component_decoder/decoder_listener.c

@@ -459,7 +459,7 @@ void DecoderListener(Component com, Uint64 event, void* data, void* context)
 {
 #if defined(SUPPORT_MULTI_INSTANCE_TEST) || defined(SUPPORT_LOOK_AHEAD_RC)
 #else
-    int key=0;
+    /* int key=0;
     if (osal_kbhit()) {
         key = osal_getch();
         osal_flush_ch();
@@ -476,7 +476,7 @@ void DecoderListener(Component com, Uint64 event, void* data, void* context)
         default:
             break;
         }
-    }
+    } */
 #endif
     switch (event) {
     case COMPONENT_EVENT_DEC_OPEN:

+ 7 - 2
wave511/code/sample_v2/component_decoder/decoder_listener.h

@@ -23,8 +23,13 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-#include "cnm_app.h"
-#include "misc/bw_monitor.h"
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "wave511/sample_v2/component/cnm_app.h"
+    #include "wave511/sample_v2/helper/misc/bw_monitor.h"
+#else
+    #include "cnm_app.h"
+    #include "misc/bw_monitor.h"
+#endif
 
 
 #ifdef __cplusplus

+ 2 - 2
wave511/code/sample_v2/component_encoder/encoder_listener.c

@@ -169,7 +169,7 @@ void EncoderListener(Component com, Uint64 event, void* data, void* context)
     EncHandle   handle;
 #if defined(SUPPORT_MULTI_INSTANCE_TEST) || defined(SUPPORT_LOOK_AHEAD_RC)
 #else
-    int         key=0;
+    /* int         key=0;
 
     if (osal_kbhit()) {
         key = osal_getch();
@@ -180,7 +180,7 @@ void EncoderListener(Component com, Uint64 event, void* data, void* context)
                 return;
             }
         }
-    }
+    } */
 #endif
     switch (event) {
     case COMPONENT_EVENT_ENC_OPEN:

+ 7 - 2
wave511/code/sample_v2/component_encoder/encoder_listener.h

@@ -23,8 +23,13 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-#include "cnm_app.h"
-#include "misc/bw_monitor.h"
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "wave511/sample_v2/component/cnm_app.h"
+    #include "wave511/sample_v2/helper/misc/bw_monitor.h"
+#else
+    #include "cnm_app.h"
+    #include "misc/bw_monitor.h"
+#endif
 
 #ifdef __cplusplus
 extern "C" {

+ 50 - 0
wave511/code/sample_v2/helper/bitstream/bitstreamfeeder.c

@@ -47,6 +47,12 @@ typedef struct {
     int             sequenceHeaderSize;
 } BitstreamFeeder;
 
+void*  BitstreamFeeder_GetActualFeeder(void *feeder)
+{
+    BitstreamFeeder*    handle = (BitstreamFeeder*) feeder;
+    return handle->actualFeeder;
+}
+
 static void BitstreamFeeder_DummyObserver(
     void*   handle,
     void*   es,
@@ -123,6 +129,29 @@ extern Int32 BSFeederFrameSize_GetStandard(
     void*       feeder
     );
 
+extern void* BSFeederBuffer_Create(
+    const char* path,
+    CodStd      codecId
+    );
+
+extern BOOL BSFeederBuffer_Destroy(
+    void* feeder
+    );
+
+extern Int32 BSFeederBuffer_Act(
+    void*       feeder,
+    BSChunk*    chunk
+    );
+
+extern BOOL BSFeederBuffer_Rewind(
+    void*       feeder
+    );
+
+extern void BSFeederBuffer_SetFeedingSize(
+    void*   feeder,
+    Uint32  feedingSize
+    );
+
 /**
 * Abstract Bitstream Feeader Functions
 */
@@ -148,6 +177,11 @@ void* BitstreamFeeder_Create(
     case FEEDING_METHOD_SIZE_PLUS_ES:
         feeder = BSFeederSizePlusEs_Create(path, codecId);
         break;
+#ifdef USE_FEEDING_METHOD_BUFFER
+    case FEEDING_METHOD_BUFFER:
+        feeder = BSFeederBuffer_Create(path, codecId);
+        break;
+#endif
     default:
         feeder = NULL;
         break;
@@ -250,6 +284,11 @@ Uint32 BitstreamFeeder_Act(
         case FEEDING_METHOD_SIZE_PLUS_ES:
             feedingSize = BSFeederSizePlusEs_Act(bsf->actualFeeder, &chunk);
             break;
+#ifdef USE_FEEDING_METHOD_BUFFER
+        case FEEDING_METHOD_BUFFER:
+            feedingSize = BSFeederBuffer_Act(bsf->actualFeeder, &chunk);
+            break;
+#endif
         default:
             VLOG(ERR, "%s:%d Invalid method(%d)\n", __FUNCTION__, __LINE__, bsf->method);
             osal_free(chunk.data);
@@ -352,6 +391,9 @@ Int32 BitstreamFeeder_GetStandard(
         break;
     case FEEDING_METHOD_FIXED_SIZE:
     case FEEDING_METHOD_SIZE_PLUS_ES:
+#ifdef USE_FEEDING_METHOD_BUFFER
+    case FEEDING_METHOD_BUFFER:
+#endif
     default:
         VLOG(ERR, "%s:%d Invalid return value (%d),  method(%d)\n", __FUNCTION__, __LINE__, -1, bsf->method);
         break;
@@ -391,6 +433,11 @@ BOOL BitstreamFeeder_Destroy(
     case FEEDING_METHOD_SIZE_PLUS_ES:
         BSFeederSizePlusEs_Destroy(bsf->actualFeeder);
         break;
+#ifdef USE_FEEDING_METHOD_BUFFER
+    case FEEDING_METHOD_BUFFER:
+        BSFeederBuffer_Destroy(bsf->actualFeeder);
+        break;
+#endif
     default:
         VLOG(ERR, "%s:%d Invalid method(%d)\n", __FUNCTION__, __LINE__, bsf->method);
         break;
@@ -427,6 +474,9 @@ BOOL BitstreamFeeder_Rewind(
     case FEEDING_METHOD_SIZE_PLUS_ES:
         success = BSFeederSizePlusEs_Rewind(bsf->actualFeeder);
         break;
+#ifdef USE_FEEDING_METHOD_BUFFER
+    case FEEDING_METHOD_BUFFER:
+#endif
     default:
         VLOG(ERR, "%s:%d Invalid method(%d)\n", __FUNCTION__, __LINE__, bsf->method);
         break;

+ 125 - 0
wave511/code/sample_v2/helper/bitstream/bsfeeder_buffer_impl.c

@@ -0,0 +1,125 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <errno.h>
+
+#include "vpuapifunc.h"
+#include "main_helper.h"
+
+#define MAX_FEEDING_SIZE        0x400000        /* 4MBytes */
+#define DEFAULT_FEEDING_SIZE    0x20000         /* 128KBytes */
+
+typedef struct FeederFixedContext {
+    void*           address;
+    Uint32          size;
+    Uint32          offset;
+    Uint32          feedingSize;
+    BOOL            eos;
+} FeederFixedContext;
+
+void* BSFeederBuffer_Create(
+    const char* path,
+    CodStd      codecId
+    )
+{
+    FeederFixedContext*  context=NULL;
+
+    UNREFERENCED_PARAMETER(codecId);
+
+    context = (FeederFixedContext*)osal_malloc(sizeof(FeederFixedContext));
+    if (context == NULL) {
+        VLOG(ERR, "%s:%d failed to allocate memory\n", __FUNCTION__, __LINE__);
+        return NULL;
+    }
+
+    context->feedingSize = DEFAULT_FEEDING_SIZE;
+    context->eos         = FALSE;
+    context->offset = 0;
+    return (void*)context;
+}
+
+BOOL BSFeederBuffer_Destroy(
+    void* feeder
+    )
+{
+    FeederFixedContext* context = (FeederFixedContext*)feeder;
+
+    if (context == NULL) {
+        VLOG(ERR, "%s:%d Null handle\n", __FUNCTION__, __LINE__);
+        return FALSE;
+    }
+
+    osal_free(context);
+
+    return TRUE;
+}
+
+void BSFeederBuffer_SetData(
+    void*       feeder,
+    char*       address,
+    Uint32       size)
+{
+    FeederFixedContext*  context = (FeederFixedContext*)feeder;
+    context->address = address;
+    context->size = size;
+}
+
+void BSFeederBuffer_SetEos(void*       feeder)
+{
+    FeederFixedContext*  context = (FeederFixedContext*)feeder;
+    context->eos = TRUE;
+}
+
+BOOL BSFeederBuffer_GetEos(void*       feeder)
+{
+    FeederFixedContext*  context = (FeederFixedContext*)feeder;
+    return context->eos;
+}
+
+Int32 BSFeederBuffer_Act(
+    void*       feeder,
+    BSChunk*    chunk
+    )
+{
+    FeederFixedContext*  context = (FeederFixedContext*)feeder;
+
+    if (context == NULL) {
+        VLOG(ERR, "%s:%d Null handle\n", __FUNCTION__, __LINE__);
+        return 0;
+    }
+    // Due to memory performance, memset is temporarily commented
+    // osal_memset(chunk->data, 0x00, chunk->size);
+    if (context->size == 0) {
+        chunk->eos = TRUE;
+        return 0;
+    }
+
+    do {
+        osal_memcpy(chunk->data, context->address, context->size);
+    } while (FALSE);
+
+    return context->size;
+}
+
+BOOL BSFeederBuffer_Rewind(
+    void*       feeder
+    )
+{
+    FeederFixedContext*  context = (FeederFixedContext*)feeder;
+
+    context->eos = FALSE;
+
+    return TRUE;
+}
+
+void BSFeederBuffer_SetFeedingSize(
+    void*   feeder,
+    Uint32  feedingSize
+    )
+{
+    FeederFixedContext*  context = (FeederFixedContext*)feeder;
+    if (feedingSize > 0) {
+        context->feedingSize = feedingSize;
+    }
+}
+

+ 94 - 9
wave511/code/sample_v2/helper/main_helper.c

@@ -1118,6 +1118,82 @@ void ReleaseVideoMemory(
     }
 }
 
+BOOL AllocateLinerBuffer(
+    DecHandle       decHandle,
+    vpu_buffer_t    *pvb,
+    Uint32          size
+)
+{
+    Uint32 coreIndex = VPU_HANDLE_CORE_INDEX(decHandle);
+    if (vdi_allocate_dma_memory(coreIndex, pvb, DEC_FB_LINEAR, decHandle->instIndex) < 0) {
+        VLOG(ERR, "%s:%d fail to allocate frame buffer\n", __FUNCTION__, __LINE__);
+        return FALSE;
+    }
+    return TRUE;
+}
+
+FrameBufferAllocInfo frameBufferAllocInfo;
+
+void *AllocateDecFrameBuffer2(DecHandle decHandle, TestDecConfig* config, Uint32 size, FrameBuffer* retFbArray, vpu_buffer_t* retFbAddrs)
+{
+    RetCode                 ret;
+    vpu_buffer_t            *vb = retFbAddrs;
+    Uint32                  coreIndex = VPU_HANDLE_CORE_INDEX(decHandle);
+
+    vb->size = size;
+    frameBufferAllocInfo.num = 1;
+
+    vdi_allocate_dma_memory(coreIndex, vb, DEC_FB_LINEAR, decHandle->instIndex);
+    VLOG(INFO, "base = %lx virt_addr = %lx phys_addr = %lx\r\n", vb->base, vb->virt_addr, vb->phys_addr);
+    retFbArray->bufY  = vb->phys_addr;
+    retFbArray->bufCb = (PhysicalAddress)-1;
+    retFbArray->bufCr = (PhysicalAddress)-1;
+    retFbArray->updateFbInfo = TRUE;
+    retFbArray->size  = size;
+    // width = 0 not effect right now
+    retFbArray->width = 0;
+    ret = VPU_DecAllocateFrameBuffer(decHandle, frameBufferAllocInfo, retFbArray);
+    if (ret != RETCODE_SUCCESS) {
+        VLOG(ERR, "%s:%d failed to VPU_DecAllocateFrameBuffer() ret:%d\n",
+            __FUNCTION__, __LINE__, ret);
+        ReleaseVideoMemory(decHandle, vb, 1);
+        return NULL;
+    }
+    return (void *)vb->virt_addr;
+}
+
+BOOL AttachDecDMABuffer(DecHandle decHandle, TestDecConfig* config, Uint64 virtAddress, Uint32 size, FrameBuffer* retFbArray, vpu_buffer_t* retFbAddrs)
+{
+    RetCode                 ret;
+    Uint32                  coreIndex = VPU_HANDLE_CORE_INDEX(decHandle);
+    vpu_buffer_t            *vb = retFbAddrs;
+
+    vb->virt_addr = virtAddress;
+    vb->size = size;
+    frameBufferAllocInfo.num = 1;
+
+    vdi_virt_to_phys(coreIndex, vb);
+
+    vdi_attach_dma_memory(coreIndex, vb);
+    VLOG(INFO, "base addr = %lx virt addr= %lx phys addr = %x\r\n", vb->base, vb->virt_addr, vb->phys_addr);
+
+    retFbArray->bufY  = vb->phys_addr;
+    retFbArray->bufCb = (PhysicalAddress)-1;
+    retFbArray->bufCr = (PhysicalAddress)-1;
+    retFbArray->updateFbInfo = TRUE;
+    retFbArray->size  = size;
+    // width = 0 not effect right now
+    retFbArray->width = 0;
+    ret = VPU_DecAllocateFrameBuffer(decHandle, frameBufferAllocInfo, retFbArray);
+    if (ret != RETCODE_SUCCESS) {
+        VLOG(ERR, "%s:%d failed to VPU_DecAllocateFrameBuffer() ret:%d\n",
+            __FUNCTION__, __LINE__, ret);
+        ReleaseVideoMemory(decHandle, vb, 1);
+        return FALSE;
+    }
+    return TRUE;
+}
+
 BOOL AllocateDecFrameBuffer(
     DecHandle       decHandle,
     TestDecConfig*  config,
@@ -1182,7 +1258,13 @@ BOOL AllocateDecFrameBuffer(
             return FALSE;
         }
     }
-
+#ifdef USE_FEEDING_METHOD_BUFFER
+    *retStride     = seqInfo.picWidth;
+    framebufStride = CalcStride(seqInfo.picWidth, seqInfo.picHeight, format, config->cbcrInterleave, config->mapType, FALSE);
+    framebufHeight = seqInfo.picHeight;
+    framebufSize   = VPU_GetFrameBufSize(decHandle, decHandle->coreIdx, framebufStride, framebufHeight,
+                                            config->mapType, format, config->cbcrInterleave, pDramCfg);
+#else
     if (config->bitFormat == STD_VP9) {
         framebufStride = CalcStride(VPU_ALIGN64(seqInfo.picWidth), seqInfo.picHeight, format, config->cbcrInterleave, config->mapType, TRUE);
         framebufHeight = VPU_ALIGN64(seqInfo.picHeight);
@@ -1211,7 +1293,7 @@ BOOL AllocateDecFrameBuffer(
         framebufSize   = VPU_GetFrameBufSize(decHandle, decHandle->coreIdx, framebufStride, framebufHeight,
                                              config->mapType, format, config->cbcrInterleave, pDramCfg);
     }
-
+#endif
     osal_memset((void*)&fbAllocInfo, 0x00, sizeof(fbAllocInfo));
     osal_memset((void*)retFbArray,   0x00, sizeof(FrameBuffer)*totalFbCount);
     fbAllocInfo.format          = format;
@@ -1308,6 +1390,15 @@ BOOL AllocateDecFrameBuffer(
         }
         framebufSize = VPU_GetFrameBufSize(decHandle, coreIndex, linearStride, fbHeight, (TiledMapType)mapType, outFormat, config->cbcrInterleave, pDramCfg);
 
+        fbAllocInfo.nv21    = config->nv21;
+        fbAllocInfo.format  = outFormat;
+        fbAllocInfo.num     = linearFbCount;
+        fbAllocInfo.mapType = (TiledMapType)mapType;
+        fbAllocInfo.stride  = linearStride;
+        fbAllocInfo.height  = fbHeight;
+#ifdef USE_FEEDING_METHOD_BUFFER
+        memcpy(&frameBufferAllocInfo, &fbAllocInfo, sizeof(frameBufferAllocInfo));
+#endif
         for (idx=linearFbStartIdx; idx<totalFbCount; idx++) {
             pvb = &retFbAddrs[idx];
             pvb->size = framebufSize;
@@ -1324,13 +1415,6 @@ BOOL AllocateDecFrameBuffer(
             retFbArray[idx].width = picWidth;
         }
 
-        fbAllocInfo.nv21    = config->nv21;
-        fbAllocInfo.format  = outFormat;
-        fbAllocInfo.num     = linearFbCount;
-        fbAllocInfo.mapType = (TiledMapType)mapType;
-        fbAllocInfo.stride  = linearStride;
-        fbAllocInfo.height  = fbHeight;
-
         ret = VPU_DecAllocateFrameBuffer(decHandle, fbAllocInfo, &retFbArray[linearFbStartIdx]);
         if (ret != RETCODE_SUCCESS) {
             VLOG(ERR, "%s:%d failed to VPU_DecAllocateFrameBuffer() ret:%d\n",
@@ -1338,6 +1422,7 @@ BOOL AllocateDecFrameBuffer(
             ReleaseVideoMemory(decHandle, retFbAddrs, totalFbCount);
             return FALSE;
         }
+
     }
 
     return TRUE;

+ 51 - 5
wave511/code/sample_v2/helper/main_helper.h

@@ -26,10 +26,18 @@
 #ifndef _MAIN_HELPER_H_
 #define _MAIN_HELPER_H_
 
-#include "config.h"
-#include "vpuapifunc.h"
-#include "vpuapi.h"
-#include "vputypes.h"
+
+#ifdef USE_FEEDING_METHOD_BUFFER
+   #include "wave511/config.h"
+   #include "wave511/vpuapi/vpuapifunc.h"
+   #include "wave511/vpuapi/vpuapi.h"
+   #include "wave511/vpuapi/vputypes.h"
+#else
+    #include "config.h"
+    #include "vpuapifunc.h"
+    #include "vpuapi.h"
+    #include "vputypes.h"
+#endif
 #ifdef PLATFORM_QNX
     #include <sys/stat.h>
 #endif
@@ -575,6 +583,18 @@ Uint8* GetYUVFromFrameBuffer(
     size_t*		retSize
     );
 
+BOOL GetYUVFromFrameBuffer2(
+    Uint8*          pYuv,
+    Uint8**         pYuv2,
+    Uint32          size,
+    DecHandle       decHandle,
+    FrameBuffer*    fb,
+    VpuRect         rcFrame,
+    Uint32*         retWidth,
+    Uint32*         retHeight,
+    Uint32*         retBpp,
+    size_t*         retSize
+    );
 /************************************************************************/
 /* Queue                                                                */
 /************************************************************************/
@@ -793,6 +813,9 @@ typedef enum {
     FEEDING_METHOD_FIXED_SIZE,
     FEEDING_METHOD_FRAME_SIZE,
     FEEDING_METHOD_SIZE_PLUS_ES,
+#ifdef USE_FEEDING_METHOD_BUFFER
+    FEEDING_METHOD_BUFFER,
+#endif
     FEEDING_METHOD_MAX
 } FeedingMethod;
 
@@ -896,7 +919,9 @@ BOOL BitstreamFeeder_SetHook(
 /************************************************************************/
 #define SOURCE_YUV                  0
 #define SOURCE_YUV_WITH_LOADER      2
-
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #define SOURCE_YUV_WITH_BUFFER  4
+#endif
 typedef struct {
     Uint32   cbcrInterleave;
     Uint32   nv21;
@@ -1395,6 +1420,23 @@ void ReleaseVideoMemory(
     Uint32        count
     );
 
+void *AllocateDecFrameBuffer2(
+    DecHandle decHandle,
+    TestDecConfig* config,
+    Uint32 size,
+    FrameBuffer* retFbArray,
+    vpu_buffer_t* retFbAddrs
+    );
+
+BOOL AttachDecDMABuffer(
+    DecHandle decHandle,
+    TestDecConfig* config,
+    Uint64 virtAddress,
+    Uint32 size,
+    FrameBuffer* retFbArray,
+    vpu_buffer_t* retFbAddrs
+    );
+
 BOOL AllocateDecFrameBuffer(
     DecHandle       decHandle,
     TestDecConfig*  config,
@@ -1402,6 +1444,10 @@ BOOL AllocateDecFrameBuffer(
     Uint32          linearFbCount,
     FrameBuffer*    retFbArray,
     vpu_buffer_t*   retFbAddrs,
+#if 0
+    vpu_buffer_t*   inFbAddrs,
+    Uint32          inFbCount,
+#endif
     Uint32*         retStride
     );
 

+ 325 - 0
wave511/code/sample_v2/helper/misc/cnm_video_helper.c

@@ -193,6 +193,23 @@ static void LoadSrcYUV(
     Uint32          srcWidthC,
     Uint32          srcHeightC,
     Uint32          chroma_stride);
+void LoadSrcYUV2(
+    Uint32          coreIdx,
+    TiledMapConfig  mapCfg,
+    Uint8*          pSrc,
+    Uint8**         pSrc2,
+    FrameBuffer*    fbSrc,
+    VpuRect         cropRect,
+    BOOL            enableCrop,
+    Uint32          is10bit,
+    Uint32          is3pxl4byte,
+    Uint32          isMSB,
+    Uint32          srcWidthY,
+    Uint32          srcHeightY,
+    Uint32          srcWidthC,
+    Uint32          srcHeightC,
+    Uint32          chroma_stride
+    );
 
 static void DePackedYUV(
     Uint32          is10bit,
@@ -1046,6 +1063,174 @@ Uint32 StoreYuvImageBurst(
     return totSize;
 }
 
+Uint32 StoreYuvImageBurst2(
+    Uint32          coreIdx,
+    FrameBuffer     *fbSrc,
+    TiledMapConfig  mapCfg,
+    Uint8           *pDst,
+    Uint8           **pDst2,
+    VpuRect         cropRect,
+    BOOL            enableCrop
+    )
+{
+    int      interLeave  = fbSrc->cbcrInterleave;
+    BOOL     nv21        = fbSrc->nv21;
+    Uint32   totSize = 0;
+    Uint32   is422;
+    Uint32   isPack;
+    Uint32   PackMode;
+    Uint32   is10bit;
+    Uint32   isMSB;
+    Uint32   is3pxl4byte;
+
+    Uint32   srcWidthY;
+    Uint32   srcHeightY;
+    Uint32   srcWidthC;
+    Uint32   srcHeightC;
+    Uint32   chroma_stride;
+
+    Uint32   dstWidthY;
+    Uint32   dstHeightY;
+    Uint32   dstWidthC;
+    Uint32   dstHeightC;
+
+    Uint32   DstSize = 0;
+    Uint32   SrcSize = 0;
+    //Uint8*   pSrc = NULL;
+
+    Uint8*   pSrcFormat;
+    Uint8*   pDstFormat = NULL;
+    Uint32   deFormatSize = 0;
+    Uint8*   pFormat = NULL;
+
+    Uint8*   pSrcInterLeave;
+    Uint8*   pDstInterLeave = NULL;
+    Uint32   InterLeaveSize = 0;
+    Uint8*   pInterLeave = NULL;
+
+    Uint8*   pSrcPack;
+    Uint8*   pDstPack = NULL;
+    Uint32   PackSize = 0;
+    Uint8*   pPack = NULL;
+
+    Uint8*   pSrc422;
+    Uint8*   pDst422 = NULL;
+
+    Uint8*   pSrcSwap;
+    Uint8*   pDstSwap;
+
+    GeneratePicParam(fbSrc, cropRect, enableCrop,
+        &is422, &isPack, &PackMode, &is10bit, &isMSB, &is3pxl4byte,
+        &srcWidthY, &srcHeightY, &srcWidthC, &srcHeightC, &chroma_stride,
+        &dstWidthY, &dstHeightY, &dstWidthC, &dstHeightC);
+
+     //1. Source YUV memory allocation
+    SrcSize = srcWidthY*srcHeightY + srcWidthC*srcHeightC;
+    if (interLeave != TRUE)
+        SrcSize += srcWidthC*srcHeightC;
+    //pSrc = (Uint8*)osal_malloc(SrcSize);
+    //if (!pSrc)
+    //    return 0;
+
+    //2. Destination YUV size
+    DstSize = dstWidthY*dstHeightY + dstWidthC*dstHeightC * 2;
+    totSize = DstSize;
+
+    //3. Source YUV Load
+    LoadSrcYUV2(coreIdx, mapCfg, pDst, pDst2, fbSrc, cropRect, enableCrop,
+        is10bit, is3pxl4byte, isMSB,
+        srcWidthY, srcHeightY, srcWidthC, srcHeightC, chroma_stride);
+
+    //4.    osal_memcpy and termination for 8bit, 420, normal(non packed) YUV
+    //SrcYUV => DstYUV
+#if defined(SAVE_YUV)
+    //osal_memcpy(pDst, pSrc, SrcSize);
+    totSize = SrcSize;
+
+    //osal_free(pSrc);
+    return totSize;
+#else
+    // if dec video format is I420 NV21 NV12, just dump it
+    if (is10bit != TRUE  && is422 != TRUE && isPack != TRUE) {
+        //osal_memcpy(pDst, pSrc, SrcSize);
+        //osal_free(pSrc);
+        return totSize;
+    }
+#endif
+
+    //5. deFormat
+    //all format for 10bit => 1 pixel 2byte LSB
+    if (is10bit == TRUE) {
+        if (is3pxl4byte == TRUE) {
+            deFormatSize = dstWidthY*srcHeightY + (dstWidthC*srcHeightY * 2);
+            pFormat      = (Uint8*)osal_malloc(deFormatSize);
+        }
+        pSrcFormat = pDst;
+        pDstFormat = (is3pxl4byte == TRUE) ? pFormat : pDst;
+
+        DeFormatYUV( is3pxl4byte, isMSB, interLeave, srcWidthY, srcHeightY, srcWidthC, srcHeightC,
+            dstWidthY, dstWidthC, pSrcFormat, pDstFormat);
+    }
+
+    //6. dePack or interleave
+    //Pack => Normal
+    //interleave => Normal
+    if (isPack) {
+        //pPack allocation
+        PackSize = dstWidthY*dstHeightY + dstWidthC*dstHeightY * 2;
+        pPack    = (Uint8*)osal_malloc(PackSize);
+        if ( !pPack )
+            return 0;
+        pSrcPack = pDst; //3pixel4byte no support
+        pDstPack = pPack;
+
+        DePackedYUV(is10bit, PackMode, srcWidthY, srcHeightY, pSrcPack,
+            dstWidthY, dstHeightY, dstWidthC, dstHeightY/*Pack : 422*/, pDstPack);
+    }
+    else if (interLeave == TRUE) {
+        pSrcInterLeave = (is10bit) ? pDstFormat : pDst;
+        if (is422) {
+            InterLeaveSize = dstWidthY*srcHeightY + dstWidthC*srcHeightC * 2;
+            pInterLeave    = (Uint8*)osal_malloc(InterLeaveSize);
+            if ( !pInterLeave )
+                return 0;
+            pDstInterLeave = pInterLeave;
+        }
+        else
+            pDstInterLeave = pDst;
+
+        DeInterLeave(is10bit, nv21, dstWidthY, srcHeightY, dstWidthC*2, srcHeightC, pSrcInterLeave, pDstInterLeave);
+    }
+
+    //7. 422 => 420
+    if (is422 || isPack) {
+        pSrc422 =  (isPack) ?      pDstPack         :
+                   ((interLeave) ? pDstInterLeave   :
+                   ((is10bit) ?    pDstFormat       : pDst));
+        pDst422 = pDst;
+
+        Convert422to420(pSrc422, dstWidthY, dstHeightY, dstWidthC, dstHeightC, pDst422);
+    }
+
+    //8.byte swap for short-type for Windows
+    if (is10bit) {
+        pSrcSwap = (is422 || isPack) ?     pDst422        :
+                   ((interLeave == TRUE) ? pDstInterLeave : pDstFormat);
+        pDstSwap = pDst;
+        ByteSwap10bit(DstSize, pSrcSwap, pDstSwap);
+    }
+
+    //9: free memories
+    //osal_free(pSrc);
+    if (pFormat != NULL)
+        osal_free(pFormat);
+    if (pPack != NULL)
+        osal_free(pPack);
+    if (pInterLeave != NULL)
+        osal_free(pInterLeave);
+    return totSize;
+}
+
 static void DeInterLeave(
     Uint32   is10bit,
     BOOL     nv21,
@@ -1899,6 +2084,82 @@ void LoadSrcYUV(
     if (pCr)
         osal_free(pCr);
 }
+
+void LoadSrcYUV2(
+    Uint32          coreIdx,
+    TiledMapConfig  mapCfg,
+    Uint8*          pSrc,
+    Uint8**         pSrc2,
+    FrameBuffer*    fbSrc,
+    VpuRect         cropRect,
+    BOOL            enableCrop,
+    Uint32          is10bit,
+    Uint32          is3pxl4byte,
+    Uint32          isMSB,
+    Uint32          srcWidthY,
+    Uint32          srcHeightY,
+    Uint32          srcWidthC,
+    Uint32          srcHeightC,
+    Uint32          chroma_stride
+    )
+{
+    Uint32      pix_addr;
+    Uint8*      rowBufferY;
+
+    Int32       baseY;
+
+    Uint8       *pY = NULL;
+    Uint8       *pCb = NULL;
+    Uint8       *pCr = NULL;
+
+    int         interLeave  = fbSrc->cbcrInterleave;
+    Uint32      stride      = fbSrc->stride;
+#ifdef SAVE_YUV
+    EndianMode  endian      = 31;
+#else
+    EndianMode  endian      = (EndianMode)fbSrc->endian;
+#endif
+
+    //base address
+    baseY  = fbSrc->bufY;
+
+    VLOG(DEBUG, "%s %d baseY = %x stride = %d srcHeightY = %d endian = %d\r\n",
+        __FUNCTION__, __LINE__, baseY, stride, srcHeightY, endian);
+
+
+    int ret = vdi_read_memory2(coreIdx, fbSrc->bufY, &pY, stride * srcHeightY, endian);
+
+#if defined(SAVE_YUV)
+#else
+    // not used here for 8bit
+    if (is10bit) {
+        DePxlOrder(stride, srcHeightY, chroma_stride, srcHeightC,
+            interLeave, is10bit, is3pxl4byte, isMSB, pY, pCb, pCr);
+    }
+#endif
+
+    pix_addr = fbSrc->bufY + 0xffffffff00000000;
+    rowBufferY = pY + (pix_addr - baseY);
+    VLOG(DEBUG, "%s %d ret = %d, pix_addr = %lx,  pY = %p, rowBufferY = %p pSrc = %p pSrc2 = %p\n",
+        __FUNCTION__, __LINE__, ret, pix_addr, pY, rowBufferY, pSrc, pSrc2);
+    if (pSrc) {
+        osal_memcpy(pSrc, rowBufferY, srcHeightY*srcWidthY*3/2);
+    }
+    if (pSrc2) {
+        *pSrc2 = rowBufferY;
+    }
+    // following code store output buffers
+#if 0
+    {
+        void *virt_addr = vdi_map_virt2(coreIdx, srcHeightY*srcWidthY*3/2, fbSrc->bufY);
+        VLOG(INFO, "------=-==-=-=-==%p, %d\r\n", virt_addr, srcHeightY*srcWidthY*3/2);
+        FILE *fb = fopen("./out_vpu.bcp", "ab+");
+        fwrite(virt_addr, 1, srcHeightY*srcWidthY*3/2, fb);
+        fclose(fb);
+    }
+#endif
+}
+
 BOOL CalcYuvSize_412(
     Int32   format,
     Int32   picWidth,
@@ -2951,6 +3212,70 @@ Uint8* GetYUVFromFrameBuffer(
     return pYuv;
 }
 
+BOOL GetYUVFromFrameBuffer2(
+    Uint8*          pYuv,
+    Uint8**         pYuv2,
+    Uint32          size,
+    DecHandle       decHandle,
+    FrameBuffer*    fb,
+    VpuRect         rcFrame,
+    Uint32*         retWidth,
+    Uint32*         retHeight,
+    Uint32*         retBpp,
+    size_t*         retSize
+    )
+{
+    Uint32          coreIdx = VPU_HANDLE_CORE_INDEX(decHandle);
+    size_t          frameSizeY;                                         // the size of luma
+    size_t          frameSizeC;                                         // the size of chroma
+    size_t          frameSize;                                          // the size of frame
+    Uint32          Bpp = 1;                                            //!<< Byte per pixel
+    Uint32          picWidth, picHeight;
+    TiledMapConfig  mapCfg;
+
+    if (pYuv == NULL && pYuv2 == NULL) {
+        return FALSE;
+    }
+    picWidth  = rcFrame.right - rcFrame.left;
+    picHeight = rcFrame.bottom - rcFrame.top;
+
+    CalcYuvSize_412(fb->format, picWidth, fb->height, fb->cbcrInterleave, &frameSizeY, &frameSizeC, &frameSize, NULL, NULL, NULL);
+    if (size < frameSize) {
+        VLOG(ERR, "Buffer is not long enough, expect:%d, give:%d\n", frameSize, size);
+        *retSize = 0;
+        return FALSE;
+    }
+    switch (fb->format) {
+    case FORMAT_422_P10_16BIT_MSB:
+    case FORMAT_422_P10_16BIT_LSB:
+    case FORMAT_420_P10_16BIT_LSB:
+    case FORMAT_420_P10_16BIT_MSB:
+        Bpp = 2;
+        break;
+    case FORMAT_420_P10_32BIT_LSB:
+    case FORMAT_420_P10_32BIT_MSB:
+        picWidth = (picWidth/3)*4 + ((picWidth%3) ? 4 : 0);
+        Bpp = 1;
+        break;
+    case FORMAT_422:
+    case FORMAT_422_P10_32BIT_MSB:
+    case FORMAT_422_P10_32BIT_LSB:
+        break;
+    default:
+        Bpp = 1;
+        break;
+    }
+
+    VPU_DecGiveCommand(decHandle, GET_TILEDMAP_CONFIG, &mapCfg);
+    *retSize = StoreYuvImageBurst2(coreIdx, fb, mapCfg, pYuv, pYuv2, rcFrame, TRUE);
+
+    *retWidth  = picWidth;
+    *retHeight = picHeight;
+    *retBpp    = Bpp;
+
+    return TRUE;
+}
+
 void PrepareDecoderTest(
     DecHandle decHandle
     )

+ 1 - 1
wave511/code/sample_v2/helper/misc/datastructure.c

@@ -97,7 +97,7 @@ BOOL Queue_Enqueue(
     if (queue->count == queue->size) {
         if (queue->lock)
             osal_mutex_unlock(queue->lock);
-        return -1;
+        return FALSE;
     }
     offset = queue->rear * queue->itemSize;
 

+ 8 - 2
wave511/code/sample_v2/helper/misc/debug.h

@@ -26,8 +26,14 @@
 #ifndef _DEBUG_H_
 #define _DEBUG_H_
 
-#include "config.h"
-#include "main_helper.h"
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "wave511/config.h"
+    #include "wave511/sample_v2/helper/main_helper.h"
+#else
+    #include "config.h"
+    #include "main_helper.h"
+#endif
+
 
 enum {
     CNMQC_ENV_NONE,

+ 6 - 1
wave511/code/sample_v2/helper/misc/pbu.h

@@ -26,7 +26,12 @@
 #ifndef __PBU_H__
 #define __PBU_H__
 
-#include <vputypes.h>
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "wave511/vpuapi/vputypes.h"
+#else
+    #include <vputypes.h>
+#endif
+
 
 typedef void* spp_enc_context;
 

+ 298 - 0
wave511/code/vdi/linux/driver/vdec-starfive.h

@@ -0,0 +1,298 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 StarFive Technology Co., Ltd.
+ */
+#ifndef __VDEC_STARFIVE_H__
+#define __VDEC_STARFIVE_H__
+
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+#include <linux/reset-controller.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/clk-provider.h>
+
+#define VDEC_ID_NUM 5
+
+struct starfive_vdec_data {
+	struct device *dev;
+
+	struct clk *clk_vdec_id[VDEC_ID_NUM];
+	struct reset_control *rst_vdec_id[VDEC_ID_NUM];
+
+};
+
+static struct starfive_vdec_data *sf_vdec = NULL;
+
+const char vdec_data_id[VDEC_ID_NUM][15] = {
+	"vdecbrg_main",
+	"vdec_axi",
+	"vdec_bclk",
+	"vdec_cclk",
+	"vdec_apb",
+};
+
+void starfive_vdec_rst_status(void)
+{
+	int i;
+	int rst_state;
+	for (i = 0; i < VDEC_ID_NUM; i++) {		
+		rst_state = reset_control_status(sf_vdec->rst_vdec_id[i]);
+		dev_dbg(sf_vdec->dev, "status_rst%d:%d", i, rst_state);
+	}
+	return;
+}
+
+void starfive_vdec_clk_status(void)
+{
+	int i;
+	int clk_state;
+	for (i = 0; i < VDEC_ID_NUM; i++) {		
+		clk_state = __clk_is_enabled(sf_vdec->clk_vdec_id[i]);
+		dev_dbg(sf_vdec->dev, "status_clk%d:%d", i, clk_state);
+	}
+	return;
+}
+
+void starfive_vdec_rst_exit(void)
+{
+	int i;
+	int ret;
+	for (i = 1; i < VDEC_ID_NUM; i++) {
+		/* Assert the reset of "vdecbrg_main" could crash*/
+		ret = reset_control_assert(sf_vdec->rst_vdec_id[i]);
+		if (ret) {
+			dev_err(sf_vdec->dev, "VDEC reset assert failed:\n");
+			dev_err(sf_vdec->dev, vdec_data_id[i]);
+		}		
+	}
+	return;
+}
+
+void starfive_vdec_clk_exit(void)
+{
+	int i;
+	for (i = 1; i < VDEC_ID_NUM; i++) {
+		clk_disable_unprepare(sf_vdec->clk_vdec_id[i]);
+	}
+	return;
+}
+
+static int starfive_vdec_clk_init(void)
+{
+	int ret = 0;
+	int i;
+	for (i = 0; i < VDEC_ID_NUM; i++) {
+		ret = clk_prepare_enable(sf_vdec->clk_vdec_id[i]);
+		if (ret) {
+			dev_err(sf_vdec->dev, "VDEC enable clock failed:\n");
+			dev_err(sf_vdec->dev, vdec_data_id[i]);
+			goto init_clk_failed;
+		}
+	}
+
+	return 0;
+
+init_clk_failed:
+	for(; i > 1 ; i--) {
+		clk_disable_unprepare(sf_vdec->clk_vdec_id[i-1]);
+	}
+
+	return ret;
+
+}
+
+static int starfive_vdec_get_clk(void)
+{
+	int ret = 0;
+	int i;
+	for ( i = 0; i < VDEC_ID_NUM ; i++) {
+		sf_vdec->clk_vdec_id[i] = devm_clk_get(sf_vdec->dev, vdec_data_id[i]);
+		if (IS_ERR(sf_vdec->clk_vdec_id[i])) {
+			dev_err(sf_vdec->dev, "VDEC get clock failed:\n");
+			dev_err(sf_vdec->dev,  vdec_data_id[i]);
+			ret = PTR_ERR(sf_vdec->clk_vdec_id[i]);
+			goto get_clk_failed;
+		}
+	}
+
+	return 0;
+
+get_clk_failed:
+	for( ; i > 0 ; i--) {
+		devm_clk_put(sf_vdec->dev, sf_vdec->clk_vdec_id[i-1]);
+	}
+
+	return ret;
+}
+
+static int starfive_vdec_reset_init(void)
+{
+    int ret = 0;
+	int i;
+	for (i = 0; i < VDEC_ID_NUM ; i++) {
+		ret = reset_control_deassert(sf_vdec->rst_vdec_id[i]);
+    	if (ret) {
+			dev_err(sf_vdec->dev, "VDEC deassert reset failed:\n");
+			dev_err(sf_vdec->dev, vdec_data_id[i]);
+       	 	goto init_reset_failed;
+		}
+	}
+
+	return 0;
+
+init_reset_failed:
+	for (; i > 1 ; i--) {
+		reset_control_assert(sf_vdec->rst_vdec_id[i-1]);
+	}
+
+	return ret;
+}
+
+static int starfive_vdec_get_resets(void)
+{	
+    int ret = 0;
+	int i;
+	for (i = 0; i < VDEC_ID_NUM ; i++) {
+		sf_vdec->rst_vdec_id[i] = devm_reset_control_get_exclusive(sf_vdec->dev, vdec_data_id[i]);
+		if (IS_ERR(sf_vdec->rst_vdec_id[i])) {
+			dev_err(sf_vdec->dev, "VDEC get reset failed:\n");
+			dev_err(sf_vdec->dev,  vdec_data_id[i]);
+			ret = PTR_ERR(sf_vdec->rst_vdec_id[i]);
+			goto get_resets_failed;
+		}
+	}
+
+	return 0;
+
+get_resets_failed:
+	for (; i > 0; i--) {
+		reset_control_put(sf_vdec->rst_vdec_id[i-1]);
+	}
+
+	return ret;
+}
+
+
+int starfive_vdec_data_init(struct device *dev)
+{
+	int ret = 0;
+
+	if (sf_vdec == NULL){
+		sf_vdec = devm_kzalloc(dev, sizeof(*sf_vdec), GFP_KERNEL);
+		if (!sf_vdec)
+			return -ENOMEM;
+		sf_vdec->dev = dev;
+
+		ret = starfive_vdec_get_clk();
+		if (ret) {
+			dev_err(sf_vdec->dev, "failed to get vdec clock\n");
+			return ret;
+		}
+
+		ret = starfive_vdec_get_resets();
+		if (ret) {
+			dev_err(sf_vdec->dev, "failed to get vdec resets\n");
+			return ret;
+		}		
+	}
+
+	return 0;
+}
+
+int starfive_vdec_clk_enable(struct device *dev)
+{
+    int ret = 0;
+
+	ret = starfive_vdec_data_init(dev);
+	if (ret)
+		return ret;
+
+	ret = starfive_vdec_clk_init();
+	if (ret) {
+		dev_err(sf_vdec->dev, "failed to enable vdec clock\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+int starfive_vdec_clk_disable(struct device *dev)
+{
+    int ret = 0;
+
+	ret = starfive_vdec_data_init(dev);
+	if (ret)
+		return ret;
+
+	starfive_vdec_clk_exit();
+
+	return 0;
+	
+}
+
+int starfive_vdec_rst_deassert(struct device *dev)
+{
+    int ret = 0;
+
+	ret = starfive_vdec_data_init(dev);
+	if (ret)
+		return ret;
+
+	ret = starfive_vdec_reset_init();
+	if (ret) {
+		dev_err(sf_vdec->dev, "failed to deassert vdec resets\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+int starfive_vdec_rst_assert(struct device *dev)
+{
+    int ret = 0;
+	ret = starfive_vdec_data_init(dev);
+	if (ret)
+		return ret;
+    
+	starfive_vdec_rst_exit();
+
+	return 0;
+	
+}
+
+
+int starfive_vdec_clk_rst_init(struct platform_device *pdev)
+{
+    int ret = 0;
+
+	ret = starfive_vdec_data_init(&pdev->dev);
+	if (ret)
+		return ret;
+
+	ret = starfive_vdec_clk_init();
+	if (ret) {
+		dev_err(sf_vdec->dev, "failed to enable vdec clock\n");
+		return ret;
+	} 
+
+	starfive_vdec_rst_exit();
+	mdelay(1);
+	ret = starfive_vdec_reset_init();
+	if (ret) {
+		dev_err(sf_vdec->dev, "failed to set vdec reset\n");
+		goto init_failed;
+	}
+
+	dev_info(sf_vdec->dev, "success to init VDEC clock & reset.");
+    return 0;
+
+init_failed:
+    starfive_vdec_clk_exit();
+    return ret;
+
+}
+
+#endif

+ 61 - 0
wave511/code/vdi/linux/driver/vdec.c

@@ -668,6 +668,67 @@ static long vpu_ioctl(struct file *filp, u_int cmd, u_long arg)
     struct vpu_drv_context_t *dev = (struct vpu_drv_context_t *)filp->private_data;
 
     switch (cmd) {
+    case VDI_IOCTL_GET_PHYSICAL_MEMORY:
+        {
+            vpudrv_buffer_pool_t *vbp = NULL;
+            void *user_address = NULL;
+            struct task_struct *my_struct = NULL;
+            struct mm_struct *mm = NULL;
+            unsigned long address = 0;
+            pgd_t *pgd = NULL;
+            if ((ret = down_interruptible(&s_vpu_sem)) == 0) {
+                vbp = kzalloc(sizeof(*vbp), GFP_KERNEL);
+                if (!vbp) {
+                    up(&s_vpu_sem);
+                    return -ENOMEM;
+                }
+                ret = copy_from_user(&(vbp->vb), (vpudrv_buffer_t *)arg, sizeof(vpudrv_buffer_t));
+                if (ret) {
+                    kfree(vbp);
+                    up(&s_vpu_sem);
+                    return -EFAULT;
+                }
+
+                user_address = (void *)vbp->vb.virt_addr;
+                my_struct = get_current();
+                mm = my_struct->mm;
+                address = (unsigned long)user_address;
+                pgd = pgd_offset(mm, address);
+
+                if (!pgd_none(*pgd) && !pgd_bad(*pgd)) {
+                    p4d_t *p4d = p4d_offset(pgd, address);
+                    pud_t *pud = pud_offset(p4d, address);
+                    if (!pud_none(*pud) && !pud_bad(*pud)) {
+                        pmd_t *pmd = pmd_offset(pud, address);
+                        if (!pmd_none(*pmd) && !pmd_bad(*pmd)) {
+                            pte_t *pte = pte_offset_map(pmd, address);
+                            if (!pte_none(*pte)) {
+                                struct page *pg = pte_page(*pte);
+                                unsigned long phys = page_to_phys(pg);
+                                unsigned long virt = (unsigned long)phys_to_virt(phys);
+                                printk("phy address = %lx, virt = %lx\r\n", phys, virt);
+                                vbp->vb.phys_addr = phys;
+                                vbp->vb.base = virt;
+                            }
+                            pte_unmap(pte);
+                        }
+                    }
+                }
+                ret = copy_to_user((void __user *)arg, &(vbp->vb), sizeof(vpudrv_buffer_t));
+                if (ret) {
+                    kfree(vbp);
+                    ret = -EFAULT;
+                    up(&s_vpu_sem);
+                    break;
+                }
+                vbp->filp = filp;
+                spin_lock(&s_vpu_lock);
+                list_add(&vbp->list, &s_vbp_head);
+                spin_unlock(&s_vpu_lock);
+                up(&s_vpu_sem);
+            }
+        }
+        break;
     case VDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY:
         {
             vpudrv_buffer_pool_t *vbp;

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