Procházet zdrojové kódy

vpu: porting wave511 multimedia feature

port starfive feature for starfive omx-il supporting

Signed-off-by: Som Qin <som.qin@starfivetech.com>
Som Qin před 1 rokem
rodič
revize
ab08365cc0
45 změnil soubory, kde provedl 1963 přidání a 79 odebrání
  1. 41 0
      wave511/code/WaveDecDriver_buildroot.mak
  2. 1 1
      wave511/code/WaveDecode-ffmpeg.mak
  3. 168 0
      wave511/code/WaveDecode_buildroot.mak
  4. 11 0
      wave511/code/build_env.sh
  5. 2 0
      wave511/code/cp.sh
  6. 7 2
      wave511/code/sample_v2/component/cnm_app.h
  7. 5 1
      wave511/code/sample_v2/component/cnm_app_internal.h
  8. 2 1
      wave511/code/sample_v2/component/component.c
  9. 45 3
      wave511/code/sample_v2/component/component.h
  10. 3 1
      wave511/code/sample_v2/component_decoder/component_dec_decoder.c
  11. 43 0
      wave511/code/sample_v2/component_decoder/component_dec_feeder.c
  12. 172 14
      wave511/code/sample_v2/component_decoder/component_dec_renderer.c
  13. 2 2
      wave511/code/sample_v2/component_decoder/decoder_listener.c
  14. 7 2
      wave511/code/sample_v2/component_decoder/decoder_listener.h
  15. 2 2
      wave511/code/sample_v2/component_encoder/encoder_listener.c
  16. 7 2
      wave511/code/sample_v2/component_encoder/encoder_listener.h
  17. 50 0
      wave511/code/sample_v2/helper/bitstream/bitstreamfeeder.c
  18. 125 0
      wave511/code/sample_v2/helper/bitstream/bsfeeder_buffer_impl.c
  19. 94 9
      wave511/code/sample_v2/helper/main_helper.c
  20. 51 5
      wave511/code/sample_v2/helper/main_helper.h
  21. 325 0
      wave511/code/sample_v2/helper/misc/cnm_video_helper.c
  22. 1 1
      wave511/code/sample_v2/helper/misc/datastructure.c
  23. 8 2
      wave511/code/sample_v2/helper/misc/debug.h
  24. 6 1
      wave511/code/sample_v2/helper/misc/pbu.h
  25. 298 0
      wave511/code/vdi/linux/driver/vdec-starfive.h
  26. 61 0
      wave511/code/vdi/linux/driver/vdec.c
  27. 1 0
      wave511/code/vdi/linux/driver/vpu.h
  28. 50 0
      wave511/code/vdi/linux/driver_test/Makefile
  29. 193 0
      wave511/code/vdi/linux/driver_test/dma_test.c
  30. 85 4
      wave511/code/vdi/linux/vdi.c
  31. 3 2
      wave511/code/vdi/linux/vdi_osal.c
  32. 5 1
      wave511/code/vdi/mm.h
  33. 14 4
      wave511/code/vdi/vdi.h
  34. 15 2
      wave511/code/vdi/vdi_osal.h
  35. 1 0
      wave511/code/vpuapi/coda9/coda9.c
  36. 8 2
      wave511/code/vpuapi/coda9/coda9.h
  37. 7 2
      wave511/code/vpuapi/coda9/coda9_vpuconfig.h
  38. 8 2
      wave511/code/vpuapi/product.h
  39. 4 1
      wave511/code/vpuapi/vpuapi.c
  40. 13 5
      wave511/code/vpuapi/vpuapi.h
  41. 1 1
      wave511/code/vpuapi/vpuapifunc.c
  42. 5 1
      wave511/code/vpuapi/vpuapifunc.h
  43. 5 1
      wave511/code/vpuapi/vputypes.h
  44. 1 0
      wave511/code/vpuapi/wave/wave5.c
  45. 7 2
      wave511/code/vpuapi/wave/wave5.h

+ 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

+ 2 - 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;
@@ -378,7 +379,7 @@ 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

+ 45 - 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,37 @@ 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 */
+    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 */
+} PortContainerExternal;
+
 typedef struct PortContainerES {
     Uint32          packetNo;
     BOOL            consumed;
@@ -313,6 +351,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 +438,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) {

+ 172 - 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,79 @@ 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->nFlags = srcData->decInfo.indexFrameDisplay;
+        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 +537,22 @@ 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) {
+        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 +576,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 +623,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 +634,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 = TRUE;
+    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;

+ 1 - 0
wave511/code/vdi/linux/driver/vpu.h

@@ -22,6 +22,7 @@
 #define VDI_IOCTL_GET_REGISTER_INFO         _IO(VDI_IOCTL_MAGIC, 12)
 #define VDI_IOCTL_GET_FREE_MEM_SIZE         _IO(VDI_IOCTL_MAGIC, 13)
 #define VDI_IOCTL_FLUSH_DCACHE				_IO(VDI_IOCTL_MAGIC, 14)
+#define VDI_IOCTL_GET_PHYSICAL_MEMORY       _IO(VDI_IOCTL_MAGIC, 15)
 
 #define DRAM_MEM2SYS(addr) ((addr) > 0x40000000 && (addr) < 0x43FFFFFFF ? ((addr)+0x400000000):(addr))
 #define ioremap_nocache ioremap

+ 50 - 0
wave511/code/vdi/linux/driver_test/Makefile

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

+ 193 - 0
wave511/code/vdi/linux/driver_test/dma_test.c

@@ -0,0 +1,193 @@
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/of.h>
+#include <linux/wait.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/uaccess.h>
+#include <linux/cdev.h>
+#include <linux/slab.h>
+#include <linux/of_address.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/sched.h>
+#include <linux/sched/signal.h>
+#include <linux/version.h>
+#include <linux/kfifo.h>
+#include <linux/kthread.h>
+#include <asm/io.h>
+#include <mach-u74/starfive_u74.h>
+
+#define VPU_PLATFORM_DEVICE_NAME "dma_test"
+
+
+struct device *vpu_dev;
+
+static int vpu_mmap(struct file *fp, struct vm_area_struct *vm)
+{
+	return 0;
+}
+
+static int vpu_open(struct inode *inode, struct file *filp)
+{
+    return 0;
+}
+
+/*static int vpu_ioctl(struct inode *inode, struct file *filp, u_int cmd, u_long arg) // for kernel 2.6.9 of C&M*/
+static long vpu_ioctl(struct file *filp, u_int cmd, u_long arg)
+{
+   
+    return 0;
+}
+
+static ssize_t vpu_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
+{
+
+    return -1;
+}
+
+static ssize_t vpu_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
+{
+    return -1;
+}
+
+static int vpu_release(struct inode *inode, struct file *filp)
+{
+   return 0;
+}
+
+static int vpu_fasync(int fd, struct file *filp, int mode)
+{
+	return 0;
+}
+
+struct file_operations vpu_fops = {
+    .owner = THIS_MODULE,
+    .open = vpu_open,
+    .read = vpu_read,
+    .write = vpu_write,
+    /*.ioctl = vpu_ioctl, // for kernel 2.6.9 of C&M*/
+    .unlocked_ioctl = vpu_ioctl,
+    .release = vpu_release,
+    .fasync = vpu_fasync,
+    .mmap = vpu_mmap,
+};
+
+
+struct dma_addr_t{
+	unsigned long phy;
+	unsigned long base;
+	int size;
+};
+struct dma_addr_t dma_addr[10] = {0};
+
+static int vpu_probe(struct platform_device *pdev)
+{
+    int err = 0;
+	int i = 0;
+
+    printk("[VPUDRV] dma_test vpu_probe\n");
+	if(pdev){
+		vpu_dev = &pdev->dev;
+		dev_info(vpu_dev,"device init.\n");
+	}
+    
+#if 0   //use reserved dma space
+	err = of_reserved_mem_device_init(vpu_dev);
+	if(err) {
+		dev_err(vpu_dev, "Could not get reserved memory\n");
+		goto ERROR_PROVE_DEVICE;
+	  }
+	 
+	  /* Allocate memory */
+	  dma_set_coherent_mask(vpu_dev, 0xFFFFFFFF);
+#endif
+	 for(i = 0;i<10;i++)
+	 {
+		 dma_addr[i].size = 10485760;	 
+	 }
+
+	 //alloc
+	for(i=0;i<10;i++){
+		dma_addr[i].base = (unsigned long)dma_alloc_coherent(vpu_dev, PAGE_ALIGN(dma_addr[i].size), (dma_addr_t *) (&dma_addr[i].phy), GFP_DMA | GFP_KERNEL);
+		printk("dma_alloc_coherent, physaddr:0x%lx,  virtual_addr:0x%lx size=%d \n",dma_addr[i].phy,dma_addr[i].base,dma_addr[i].size);
+	}
+	  
+	  //free
+	for(i=0;i<10;i++){	
+		dma_free_coherent(vpu_dev, PAGE_ALIGN(dma_addr[i].size), (void *)dma_addr[i].base, dma_addr[i].phy);
+		printk(" dma_free_coherent, physaddr:0x%lx,  virtual_addr:0x%lx size=%d \n",dma_addr[i].phy,dma_addr[i].base,dma_addr[i].size);
+	}
+
+    return 0;
+ERROR_PROVE_DEVICE:
+	printk("ERROR_PROVE_DEVICE\n");
+	return -1;
+}
+
+
+static int vpu_remove(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static int vpu_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	return 0;
+}
+
+static int vpu_suspend(struct device *dev)
+{
+	return 0;
+}
+static int  vpu_resume(struct device *dev)
+{
+	return 0;
+}
+
+static int vpu_resume(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static const struct of_device_id cm_vpu_match[] = {
+    {
+        .compatible = "stf,dma_test",
+    },
+    {
+    },
+};
+MODULE_DEVICE_TABLE(of, cm_vpu_match);
+
+static const struct dev_pm_ops vpu_pm_ops = {
+	SET_RUNTIME_PM_OPS(vpu_suspend, vpu_resume, NULL)
+};
+
+static const struct of_device_id dw_dma_of_id_table[] = {
+	{ .compatible = "stf,dma_test"},
+	{}
+};
+MODULE_DEVICE_TABLE(of, dw_dma_of_id_table);
+
+static struct platform_driver vpu_driver = {
+    .driver = {
+           .name = VPU_PLATFORM_DEVICE_NAME,
+           .of_match_table = cm_vpu_match,
+		   	.pm = &vpu_pm_ops,
+    },
+    .probe = vpu_probe,
+    .remove = vpu_remove,
+    .suspend = vpu_suspend,
+    .resume = vpu_resume,
+};
+
+module_platform_driver(vpu_driver);
+
+MODULE_AUTHOR("dma test.");
+MODULE_DESCRIPTION("dma test.");
+MODULE_LICENSE("GPL");

+ 85 - 4
wave511/code/vdi/linux/vdi.c

@@ -54,8 +54,8 @@
 typedef pthread_mutex_t	MUTEX_HANDLE;
 
 
-#define SUPPORT_INTERRUPT
-#define VDI_SRAM_BASE_ADDR          	0x00000000    // if we can know the sram address in SOC directly for vdi layer. it is possible to set in vdi layer without allocation from driver
+#    define SUPPORT_INTERRUPT
+#        define VDI_SRAM_BASE_ADDR          0x00000000    // if we can know the sram address in SOC directly for vdi layer. it is possible to set in vdi layer without allocation from driver
 #define VDI_SYSTEM_ENDIAN                   VDI_LITTLE_ENDIAN
 #define VDI_128BIT_BUS_SYSTEM_ENDIAN        VDI_128BIT_LITTLE_ENDIAN
 
@@ -946,6 +946,84 @@ int vdi_read_memory(unsigned long core_idx, PhysicalAddress addr, unsigned char
     return len;
 }
 
+// return the vpudrv_buffer_t virt addr, not copy data
+int vdi_read_memory2(unsigned long core_idx, PhysicalAddress addr, unsigned char **ppdata, int len, int endian)
+{
+    vdi_info_t *vdi;
+    vpudrv_buffer_t vdb;
+    unsigned long offset;
+    int i;
+
+#ifdef SUPPORT_MULTI_CORE_IN_ONE_DRIVER
+    core_idx = 0;
+#endif
+    if (core_idx >= MAX_NUM_VPU_CORE)
+        return -1;
+
+    vdi = &s_vdi_info[core_idx];
+
+    if(!vdi || vdi->vpu_fd==-1 || vdi->vpu_fd == 0x00)
+        return -1;
+
+    osal_memset(&vdb, 0x00, sizeof(vpudrv_buffer_t));
+
+    for (i=0; i<MAX_VPU_BUFFER_POOL; i++)
+    {
+        if (vdi->vpu_buffer_pool[i].inuse == 1)
+        {
+            vdb = vdi->vpu_buffer_pool[i].vdb;
+            if (addr >= vdb.phys_addr && addr < (vdb.phys_addr + vdb.size))
+                break;
+        }
+    }
+
+    if (!vdb.size)
+        return -1;
+
+    offset = addr - (unsigned long)vdb.phys_addr;
+    vdi_flush_ddr(core_idx,(unsigned long )(vdb.phys_addr+offset),len,1);
+    *ppdata = (unsigned char *)(vdb.virt_addr + offset);
+    swap_endian(core_idx, *ppdata, len,  endian);
+
+    return len;
+}
+
+void* vdi_map_virt2(unsigned long core_idx, int size, PhysicalAddress bufY)
+{
+    vdi_info_t *vdi = &s_vdi_info[core_idx];
+    void *virt_addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, vdi->vpu_fd, bufY);
+    return virt_addr;
+}
+
+int vdi_virt_to_phys(unsigned long core_idx, vpu_buffer_t *vb)
+{
+    vdi_info_t *vdi;
+    vpudrv_buffer_t vdb;
+
+#ifdef SUPPORT_MULTI_CORE_IN_ONE_DRIVER
+    core_idx = 0;
+#endif
+    if (core_idx >= MAX_NUM_VPU_CORE)
+        return -1;
+
+    vdi = &s_vdi_info[core_idx];
+
+    if(!vdi || vdi->vpu_fd==-1 || vdi->vpu_fd == 0x00)
+        return -1;
+
+    osal_memset(&vdb, 0x00, sizeof(vpudrv_buffer_t));
+    vdb.virt_addr = vb->virt_addr;
+    if (ioctl(vdi->vpu_fd, VDI_IOCTL_GET_PHYSICAL_MEMORY, &vdb) < 0)
+    {
+        VLOG(ERR, "[VDI] fail to GET_PHYSICAL_MEMORY\n");
+        return -1;
+    }
+    vb->phys_addr = (unsigned long)vdb.phys_addr;
+    vb->base = (unsigned long)vdb.base;
+    VLOG(INFO, "get phy = %#x vb->phy = %#x, base=%lx\n", vdb.phys_addr, vb->phys_addr, vb->base);
+    return 0;
+}
+
 int vdi_allocate_dma_memory(unsigned long core_idx, vpu_buffer_t *vb, int memTypes, int instIndex)
 {
     vdi_info_t *vdi;
@@ -1066,7 +1144,7 @@ int vdi_attach_dma_memory(unsigned long core_idx, vpu_buffer_t *vb)
     }
     vmem_unlock(vdi);
 
-    //VLOG(INFO, "[VDI] vdi_attach_dma_memory, physaddr=0x%lx, virtaddr=0x%lx, size=%d, index=%d\n", vb->phys_addr, vb->virt_addr, vb->size, i);
+    VLOG(INFO, "[VDI] vdi_attach_dma_memory, physaddr=0x%#x, virtaddr=0x%lx, size=%d, index=%d\n", vb->phys_addr, vb->virt_addr, vb->size, i);
 
     return 0;
 }
@@ -1132,7 +1210,10 @@ void vdi_free_dma_memory(unsigned long core_idx, vpu_buffer_t *vb, int memTypes,
     vmem_lock(vdi);
     for (i=0; i<MAX_VPU_BUFFER_POOL; i++)
     {
-        if (vdi->vpu_buffer_pool[i].vdb.phys_addr == vb->phys_addr)
+        /* add more constraints for finding the correct buffer */
+        if ((vdi->vpu_buffer_pool[i].vdb.phys_addr == vb->phys_addr)
+			&& (vdi->vpu_buffer_pool[i].vdb.size == vb->size)
+			&& (vdi->vpu_buffer_pool[i].vdb.virt_addr == vb->virt_addr))
         {
             vdi->vpu_buffer_pool[i].inuse = 0;
             vdi->vpu_buffer_pool_count--;

+ 3 - 2
wave511/code/vdi/linux/vdi_osal.c

@@ -25,6 +25,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <unistd.h>
 #include <string.h>
 #include <stdarg.h>
 #include <errno.h>
@@ -52,7 +53,7 @@ static int peek_character = -1;
 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 = MAX_LOG_LEVEL;
+static int max_log_level = ERR;
 static FILE *fpLog  = NULL;
 
 #if defined(SUPPORT_SW_UART) || defined(SUPPORT_SW_UART_V2)
@@ -61,7 +62,7 @@ static pthread_mutex_t s_log_mutex;
 
 int InitLog()
 {
-	fpLog = osal_fopen("ErrorLog.txt", "w");
+	fpLog = osal_fopen("/tmp/DecoderErrorLog.txt", "w");
 #if defined(SUPPORT_SW_UART) || defined(SUPPORT_SW_UART_V2)
 	pthread_mutex_init(&s_log_mutex, NULL);
 #endif

+ 5 - 1
wave511/code/vdi/mm.h

@@ -26,7 +26,11 @@
 #ifndef __CNM_VIDEO_MEMORY_ALLOCATOR_H_
 #define __CNM_VIDEO_MEMORY_ALLOCATOR_H_
 
-#include "vputypes.h"
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "wave511/vpuapi/vputypes.h"
+#else
+    #include <vputypes.h>
+#endif
 
 typedef struct _video_mm_info_struct {
 unsigned long   total_pages; 

+ 14 - 4
wave511/code/vdi/vdi.h

@@ -26,9 +26,17 @@
 #ifndef _VDI_H_
 #define _VDI_H_
 
-#include "mm.h"
-#include "vpuconfig.h"
-#include "vputypes.h"
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "wave511/vdi/mm.h"
+    #include "wave511/vpuapi/vpuconfig.h"
+    #include "wave511/vpuapi/vputypes.h"
+#else
+    #include "mm.h"
+    #include "vpuconfig.h"
+    #include "vputypes.h"
+#endif
+
+
 
 /************************************************************************/
 /* COMMON REGISTERS                                                     */
@@ -107,7 +115,8 @@ extern "C" {
     void vdi_free_dma_memory(unsigned long core_idx, vpu_buffer_t *vb, int memTypes, int instIndex);
     int vdi_get_sram_memory(unsigned long core_idx, vpu_buffer_t *vb);
     int vdi_dettach_dma_memory(unsigned long core_idx, vpu_buffer_t *vb);
-
+    void* vdi_map_virt2(unsigned long core_idx, int size, PhysicalAddress bufY);
+    int vdi_virt_to_phys(unsigned long core_idx, vpu_buffer_t *vb);
 
 #ifdef SUPPORT_MULTI_INST_INTR
     int vdi_wait_interrupt(unsigned long coreIdx, unsigned int instIdx, int timeout);
@@ -142,6 +151,7 @@ extern "C" {
     int vdi_clear_memory(unsigned long core_idx, PhysicalAddress addr, int len, int endian);
     int vdi_write_memory(unsigned long core_idx, PhysicalAddress addr, unsigned char *data, int len, int endian);
     int vdi_read_memory(unsigned long core_idx, PhysicalAddress addr, unsigned char *data, int len, int endian);
+    int vdi_read_memory2(unsigned long core_idx, PhysicalAddress addr, unsigned char **ppdata, int len, int endian);
 
 
     int vdi_lock(unsigned long core_idx);

+ 15 - 2
wave511/code/vdi/vdi_osal.h

@@ -29,9 +29,22 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <ctype.h>
-#include "vputypes.h"
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "wave511/vpuapi/vputypes.h"
+#else
+    #include "vputypes.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] 	      */

+ 1 - 0
wave511/code/vpuapi/coda9/coda9.c

@@ -26,6 +26,7 @@
 #include "coda9_vpuconfig.h"
 #include "product.h"
 #include "coda9_regdefine.h"
+#include "misc/debug.h"
 
 static void LoadBitCode(Uint32 coreIdx, PhysicalAddress codeBase, const Uint16 *codeWord, int codeSize)
 {

+ 8 - 2
wave511/code/vpuapi/coda9/coda9.h

@@ -26,8 +26,14 @@
 #ifndef __CODA9_FUNCTION_H__
 #define __CODA9_FUNCTION_H__
 
-#include "vpuapi.h"
-#include "../product.h"
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "wave511/vpuapi/vpuapi.h"
+    #include "wave511/vpuapi/product.h"
+#else
+    #include "vpuapi.h"
+    #include "../product.h"
+#endif
+
 
 #ifdef __cplusplus
 extern "C" {

+ 7 - 2
wave511/code/vpuapi/coda9/coda9_vpuconfig.h

@@ -26,8 +26,13 @@
 #ifndef __CODA9_VPU_CONFIG_H__
 #define __CODA9_VPU_CONFIG_H__
 
-#include "vpuconfig.h"
-#include "vputypes.h"
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "wave511/vpuapi/vpuconfig.h"
+    #include "wave511/vpuapi/vputypes.h"
+#else
+    #include "vpuconfig.h"
+    #include "vputypes.h"
+#endif
 
 
 #if MAX_DEC_PIC_WIDTH > 1920		// 4K		

+ 8 - 2
wave511/code/vpuapi/product.h

@@ -26,8 +26,14 @@
 #ifndef __VPUAPI_PRODUCT_ABSTRACT_H__
 #define __VPUAPI_PRODUCT_ABSTRACT_H__
 
-#include "vpuapi.h"
-#include "vpuapifunc.h"
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "wave511/vpuapi/vpuapi.h"
+    #include "wave511/vpuapi/vpuapifunc.h"
+#else
+    #include "vpuapi.h"
+    #include "vpuapifunc.h"
+#endif
+
 
 #define IS_CODA_DECODER_HANDLE(_inst)      (_inst->codecMode < AVC_ENC)
 

+ 4 - 1
wave511/code/vpuapi/vpuapi.c

@@ -27,7 +27,7 @@
 #include "product.h"
 #include "wave/wave5_regdefine.h"
 #include "wave/wave5.h"
-
+#include "misc/debug.h"
 
 
 #define W5_RET_DEC_DISPLAY_SIZE (W5_REG_BASE + 0x01D8)      // [FIX ME] delete ? or not?
@@ -184,11 +184,14 @@ static RetCode InitializeVPU(Uint32 coreIdx, const Uint16* code, Uint32 size)
         }
     }
 
+    /* force to reset vpu, so that the vpu in a clean state */
+#if 0
     if (VPU_IsInit(coreIdx) != 0) {
         ProductVpuReInit(coreIdx, (void *)code, size);
         LeaveLock(coreIdx);
         return RETCODE_CALLED_BEFORE;
     }
+#endif
 
     InitCodecInstancePool(coreIdx);
 

+ 13 - 5
wave511/code/vpuapi/vpuapi.h

@@ -26,11 +26,19 @@
 #ifndef VPUAPI_H_INCLUDED
 #define VPUAPI_H_INCLUDED
 
-#include "vpuconfig.h"
-#include "vputypes.h"
-#include "../vdi/vdi.h"
-#include "../vdi/vdi_osal.h"
-#include "vpuerror.h"
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "wave511/vpuapi/vpuconfig.h"
+    #include "wave511/vpuapi/vputypes.h"
+    #include "wave511/vdi/vdi.h"
+    #include "wave511/vdi/vdi_osal.h"
+    #include "wave511/vpuapi/vpuerror.h"
+#else
+    #include "vpuconfig.h"
+    #include "vputypes.h"
+    #include "../vdi/vdi.h"
+    #include "../vdi/vdi_osal.h"
+    #include "vpuerror.h"
+#endif
 
 
 

+ 1 - 1
wave511/code/vpuapi/vpuapifunc.c

@@ -29,7 +29,7 @@
 #include "coda9/coda9_regdefine.h"
 #include "coda9/coda9_vpuconfig.h"
 #include "wave/wave5_regdefine.h"
-
+#include "misc/debug.h"
 
 #ifndef MIN
 #define MIN(a, b)       (((a) < (b)) ? (a) : (b))

+ 5 - 1
wave511/code/vpuapi/vpuapifunc.h

@@ -26,7 +26,11 @@
 #ifndef VPUAPI_UTIL_H_INCLUDED
 #define VPUAPI_UTIL_H_INCLUDED
 
-#include "vpuapi.h"
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "wave511/vpuapi/vpuapi.h"
+#else
+    #include "vpuapi.h"
+#endif
 
 // COD_STD
 enum {

+ 5 - 1
wave511/code/vpuapi/vputypes.h

@@ -27,7 +27,11 @@
 #define _VPU_TYPES_H_
 
 #include <stdint.h>
-#include "vpuconfig.h"
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "wave511/vpuapi/vputypes.h"
+#else
+    #include "vputypes.h"
+#endif
 
 #define STATIC          static
 /**

+ 1 - 0
wave511/code/vpuapi/wave/wave5.c

@@ -27,6 +27,7 @@
 #include "wave/wave5.h"
 #include "vpuerror.h"
 #include "wave/wave5_regdefine.h"
+#include "misc/debug.h"
 
 Uint32 Wave5VpuIsInit(Uint32 coreIdx)
 {

+ 7 - 2
wave511/code/vpuapi/wave/wave5.h

@@ -26,8 +26,13 @@
 #ifndef __WAVE5_FUNCTION_H__
 #define __WAVE5_FUNCTION_H__
 
-#include "vpuapi.h"
-#include "product.h"
+#ifdef USE_FEEDING_METHOD_BUFFER
+    #include "wave511/vpuapi/vpuapi.h"
+    #include "wave511/vpuapi/product.h"
+#else
+    #include "vpuapi.h"
+    #include "product.h"
+#endif
 
 #define WAVE5_TEMPBUF_OFFSET                (1024*1024)
 #define WAVE5_TEMPBUF_SIZE                  (1024*1024)