libdvr: add am_aucpu_test [1/1]

PD#SWPL-162671

Problem:
add am_aucpu_test

Solution:
add am_aucpu_test

Verify:
verified at BM201

Change-Id: I70eb32866b151cf307d77c934b6a5152826c7909
Signed-off-by: chuangcheng.peng <chuangcheng.peng@amlogic.com>
diff --git a/test/am_aucpu_test/Android.bp b/test/am_aucpu_test/Android.bp
new file mode 100644
index 0000000..98041ff
--- /dev/null
+++ b/test/am_aucpu_test/Android.bp
@@ -0,0 +1,31 @@
+
+
+package {
+    // See: http://go/android-license-faq
+    default_applicable_licenses: [
+        "Android-Apache-2.0",
+    ],
+}
+
+cc_binary {
+    name: "am_aucpu_test",
+    vendor: true,
+
+    srcs: [
+        "am_dmx_test.c",
+        "am_inject.c",
+        "am_dmx.c",
+        "linux_dvb.c",
+    ],
+
+    //LOCAL_MULTILIB := 32
+
+    cflags: [
+        "-DANDROID",
+        "-DAMLINUX",
+    ],
+    //LOCAL_C_INCLUDES :=  $(LOCAL_PATH)/../../android/ndk/include
+
+    shared_libs: ["libc"],
+
+}
diff --git a/test/am_aucpu_test/Android.mk b/test/am_aucpu_test/Android.mk
new file mode 100644
index 0000000..50ce230
--- /dev/null
+++ b/test/am_aucpu_test/Android.mk
@@ -0,0 +1,22 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_VENDOR_MODULE := true
+
+LOCAL_SRC_FILES:= am_dmx_test.c am_inject.c am_dmx.c linux_dvb.c
+
+LOCAL_MODULE:= am_aucpu_test
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+
+LOCAL_MODULE_TAGS := optional
+
+#LOCAL_MULTILIB := 32
+
+LOCAL_CFLAGS+=-DANDROID -DAMLINUX -DCHIP_8226M -DLINUX_DVB_FEND
+#LOCAL_C_INCLUDES :=  $(LOCAL_PATH)/../../android/ndk/include
+
+LOCAL_SHARED_LIBRARIES :=  libc
+
+include $(BUILD_EXECUTABLE)
+
diff --git a/test/am_aucpu_test/Makefile b/test/am_aucpu_test/Makefile
new file mode 100644
index 0000000..87aa441
--- /dev/null
+++ b/test/am_aucpu_test/Makefile
@@ -0,0 +1,28 @@
+CROSS_COMPILE ?= /opt/gcc-linaro-6.3.1-2017.02-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
+CC = $(CROSS_COMPILE)gcc
+
+OUTPUT = am_aucpu_test
+INSTALL ?= ./
+
+OBJS = $(patsubst %.c,%.o,$(SRC_FILES))
+
+SRC_FILES = am_dmx_test.c am_inject.c am_dmx.c linux_dvb.c
+
+CFLAGS := -c -Wall -I./
+
+LDFLAGS := -lpthread -static -lc -ldl
+
+all : $(OBJS) $(OUTPUT)
+
+$(OBJS) : %.o : %.c
+	$(CC) $(CFLAGS) -c $< -o $@
+
+$(OUTPUT) : $(OBJS)
+	$(CC) -o $@ $^ $(LDFLAGS)
+
+install:
+	cp -rf $(OUTPUT) $(INSTALL)
+	rm -f $(OUTPUT) *.o
+
+clean:
+	@rm -f $(OBJS)
diff --git a/test/am_aucpu_test/am_adp_internal.h b/test/am_aucpu_test/am_adp_internal.h
new file mode 100644
index 0000000..9fd77ff
--- /dev/null
+++ b/test/am_aucpu_test/am_adp_internal.h
@@ -0,0 +1,38 @@
+/***************************************************************************
+ * Copyright (c) 2014 Amlogic, Inc. All rights reserved.
+ *
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ */
+/**\file
+ * \brief AMLogic adaptor layer 内部头文件
+ *
+ * \author Gong Ke <ke.gong@amlogic.com>
+ * \date 2010-07-05: create the document
+ ***************************************************************************/
+
+#ifndef _AM_ADP_INTERNAL_H
+#define _AM_ADP_INTERNAL_H
+
+//#include <am_thread.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/****************************************************************************
+ * Data definitions
+ ***************************************************************************/
+
+/**\brief ADP全局锁*/
+extern pthread_mutex_t am_gAdpLock;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/test/am_aucpu_test/am_dmx.c b/test/am_aucpu_test/am_dmx.c
new file mode 100644
index 0000000..908762c
--- /dev/null
+++ b/test/am_aucpu_test/am_dmx.c
@@ -0,0 +1,863 @@
+#ifdef _FORTIFY_SOURCE
+#undef _FORTIFY_SOURCE
+#endif
+/***************************************************************************
+ * Copyright (c) 2014 Amlogic, Inc. All rights reserved.
+ *
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ */
+/**\file
+ * \brief
+ *
+ * \author Gong Ke <ke.gong@amlogic.com>
+ * \date 2010-05-21: create the document
+ ***************************************************************************/
+
+#define AM_DEBUG_LEVEL 1
+
+//#include <am_debug.h>
+#include "am_mem.h"
+#include "am_dmx_internal.h"
+#include "am_adp_internal.h"
+#include <string.h>
+#include <assert.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+//#include "am_misc.h"
+
+/****************************************************************************
+ * Macro definitions
+ ***************************************************************************/
+
+//#define DMX_WAIT_CB /*Wait callback function stop in API*/
+
+#define DMX_SYNC
+
+#define DMX_BUF_SIZE       (4096)
+#define DMX_POLL_TIMEOUT   (200)
+#define DMX_DEV_COUNT      (32)
+
+#define DMX_CHAN_ISSET_FILTER(chan,fid)    ((chan)->filter_mask[(fid)>>3]&(1<<((fid)&3)))
+#define DMX_CHAN_SET_FILTER(chan,fid)      ((chan)->filter_mask[(fid)>>3]|=(1<<((fid)&3)))
+#define DMX_CHAN_CLR_FILTER(chan,fid)      ((chan)->filter_mask[(fid)>>3]&=~(1<<((fid)&3)))
+
+/****************************************************************************
+ * Static data
+ ***************************************************************************/
+
+#ifdef EMU_DEMUX
+extern const AM_DMX_Driver_t emu_dmx_drv;
+#define HW_DMX_DRV emu_dmx_drv
+#else
+extern const AM_DMX_Driver_t linux_dvb_dmx_drv;
+#define HW_DMX_DRV linux_dvb_dmx_drv
+#endif
+//extern const AM_DMX_Driver_t dvr_dmx_drv;
+//#define SW_DMX_DRV dvr_dmx_drv
+
+static AM_DMX_Device_t dmx_devices[DMX_DEV_COUNT] =
+{
+#ifdef EMU_DEMUX
+{
+.drv = &emu_dmx_drv,
+.src = AM_DMX_SRC_TS0
+},
+{
+.drv = &emu_dmx_drv,
+.src = AM_DMX_SRC_TS0
+}
+#else
+{
+.drv = &linux_dvb_dmx_drv,
+.src = AM_DMX_SRC_TS0
+},
+{
+.drv = &linux_dvb_dmx_drv,
+.src = AM_DMX_SRC_TS0
+},
+{
+.drv = &linux_dvb_dmx_drv,
+.src = AM_DMX_SRC_TS0
+},
+{
+.drv = &linux_dvb_dmx_drv,
+.src = AM_DMX_SRC_TS0
+}
+#endif
+};
+static void init_dmx_dev() {
+	static int init_dmx_dev_flag = 0;
+	int i = 0;
+
+	if (!init_dmx_dev_flag) {
+		init_dmx_dev_flag = 1;
+
+		for (i = 0; i < DMX_DEV_COUNT; i++) {
+			dmx_devices[i].drv = &linux_dvb_dmx_drv;
+			dmx_devices[i].src = AM_DMX_SRC_TS0;
+		}
+	}
+}
+/****************************************************************************
+ * Static functions
+ ***************************************************************************/
+
+/**\brief 根据设备号取得设备结构指针*/
+static AM_INLINE AM_ErrorCode_t dmx_get_dev(int dev_no, AM_DMX_Device_t **dev)
+{
+	if (dev_no < 0 || dev_no >= DMX_DEV_COUNT) {
+		printf("invalid demux device number %d, must in(%d~%d)", dev_no, 0, DMX_DEV_COUNT-1);
+		return AM_DMX_ERR_INVALID_DEV_NO;
+	}
+
+	*dev = &dmx_devices[dev_no];
+	return AM_SUCCESS;
+}
+
+/**\brief 根据设备号取得设备结构并检查设备是否已经打开*/
+static AM_INLINE AM_ErrorCode_t dmx_get_opened_dev(int dev_no, AM_DMX_Device_t **dev)
+{
+	AM_TRY(dmx_get_dev(dev_no, dev));
+
+	if ((*dev)->open_count <= 0) {
+		printf("demux device %d has not been opened", dev_no);
+		return AM_DMX_ERR_INVALID_DEV_NO;
+	}
+
+	return AM_SUCCESS;
+}
+
+/**\brief 根据ID取得对应filter结构,并检查设备是否在使用*/
+static AM_INLINE AM_ErrorCode_t dmx_get_used_filter(AM_DMX_Device_t *dev, int filter_id, AM_DMX_Filter_t **pf)
+{
+	AM_DMX_Filter_t *filter;
+
+	if (filter_id < 0 || filter_id >= DMX_FILTER_COUNT) {
+		printf("invalid filter id, must in %d~%d", 0, DMX_FILTER_COUNT-1);
+		return AM_DMX_ERR_INVALID_ID;
+	}
+
+	filter = &dev->filters[filter_id];
+
+	if (!filter->used)
+	{
+		printf("filter %d has not been allocated", filter_id);
+		return AM_DMX_ERR_NOT_ALLOCATED;
+	}
+
+	*pf = filter;
+	return AM_SUCCESS;
+}
+
+/**\brief 数据检测线程*/
+static void* dmx_data_thread(void *arg)
+{
+	AM_DMX_Device_t *dev = (AM_DMX_Device_t*)arg;
+	uint8_t *sec_buf;
+	uint8_t *sec;
+	int sec_len;
+	AM_DMX_FilterMask_t mask;
+	AM_ErrorCode_t ret;
+
+#define BUF_SIZE (4096)
+
+	sec_buf = (uint8_t*)malloc(BUF_SIZE);
+
+        while (dev->enable_thread) {
+                AM_DMX_FILTER_MASK_CLEAR(&mask);
+                int id;
+
+                ret = dev->drv->poll(dev, &mask, DMX_POLL_TIMEOUT);
+                if (ret == AM_SUCCESS) {
+                        if (AM_DMX_FILTER_MASK_ISEMPTY(&mask))
+                                continue;
+
+#if defined(DMX_WAIT_CB) || defined(DMX_SYNC)
+                        pthread_mutex_lock(&dev->lock);
+                        dev->flags |= DMX_FL_RUN_CB;
+                        pthread_mutex_unlock(&dev->lock);
+#endif
+
+                        for (id = 0; id < DMX_FILTER_COUNT; id++) {
+                                AM_DMX_Filter_t *filter = &dev->filters[id];
+                                AM_DMX_DataCb cb;
+                                void *data;
+
+                                if (!AM_DMX_FILTER_MASK_ISSET(&mask, id))
+                                        continue;
+
+                                if (!filter->enable || !filter->used)
+                                        continue;
+
+                                sec_len = BUF_SIZE;
+
+#ifndef DMX_WAIT_CB
+                                pthread_mutex_lock(&dev->lock);
+#endif
+                                if (!filter->enable || !filter->used) {
+                                        ret = AM_FAILURE;
+                                } else {
+                                        cb = filter->cb;
+                                        data = filter->user_data;
+                                        ret = dev->drv->read(dev, filter, sec_buf, &sec_len);
+                                }
+#ifndef DMX_WAIT_CB
+                                pthread_mutex_unlock(&dev->lock);
+#endif
+                                if (ret == AM_DMX_ERR_TIMEOUT) {
+                                        sec = NULL;
+                                        sec_len = 0;
+                                } else if (ret != AM_SUCCESS) {
+                                        continue;
+                                } else {
+                                        sec = sec_buf;
+                                }
+
+                                if (cb) {
+                                        if (id && sec)
+                                                printf("filter %d data callback len fd:%ld len:%d, %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
+                                                       id, (long)filter->drv_data, sec_len,
+                                                       sec[0], sec[1], sec[2], sec[3], sec[4],
+                                                       sec[5], sec[6], sec[7], sec[8], sec[9]);
+                                        cb(dev->dev_no, id, sec, sec_len, data);
+                                        if (id && sec)
+                                                printf("filter %d data callback ok", id);
+                                }
+                        }
+#if defined(DMX_WAIT_CB) || defined(DMX_SYNC)
+                        pthread_mutex_lock(&dev->lock);
+                        dev->flags &= ~DMX_FL_RUN_CB;
+                        pthread_mutex_unlock(&dev->lock);
+                        pthread_cond_broadcast(&dev->cond);
+#endif
+                } else {
+                        usleep(10000);
+                }
+        }
+
+        if (sec_buf) {
+                free(sec_buf);
+        }
+
+        return NULL;
+}
+
+/**\brief 等待回调函数停止运行*/
+static AM_INLINE AM_ErrorCode_t dmx_wait_cb(AM_DMX_Device_t *dev)
+{
+#ifdef DMX_WAIT_CB
+        if (dev->thread != pthread_self()) {
+                while (dev->flags & DMX_FL_RUN_CB)
+                        pthread_cond_wait(&dev->cond, &dev->lock);
+        }
+#else
+        UNUSED(dev);
+#endif
+        return AM_SUCCESS;
+}
+
+/**\brief 停止Section过滤器*/
+static AM_ErrorCode_t dmx_stop_filter(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter)
+{
+	AM_ErrorCode_t ret = AM_SUCCESS;
+
+        if (!filter->used || !filter->enable) {
+                return ret;
+        }
+
+        if (dev->drv->enable_filter) {
+                ret = dev->drv->enable_filter(dev, filter, AM_FALSE);
+        }
+
+        if (ret >= 0) {
+                filter->enable = AM_FALSE;
+        }
+
+        return ret;
+}
+
+/**\brief 释放过滤器*/
+static int dmx_free_filter(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter)
+{
+	AM_ErrorCode_t ret = AM_SUCCESS;
+
+        if (!filter->used)
+                return ret;
+
+        ret = dmx_stop_filter(dev, filter);
+
+        if (ret == AM_SUCCESS) {
+                if (dev->drv->free_filter) {
+                        ret = dev->drv->free_filter(dev, filter);
+                }
+        }
+
+        if (ret == AM_SUCCESS) {
+                filter->used = AM_FALSE;
+        }
+
+        return ret;
+}
+
+/****************************************************************************
+ * API functions
+ ***************************************************************************/
+
+/**\brief 打开解复用设备
+ * \param dev_no 解复用设备号
+ * \param[in] para 解复用设备开启参数
+ * \return
+ *   - AM_SUCCESS 成功
+ *   - 其他值 错误代码(见am_dmx.h)
+ */
+AM_ErrorCode_t AM_DMX_Open(int dev_no, const AM_DMX_OpenPara_t *para)
+{
+	AM_DMX_Device_t *dev;
+	AM_ErrorCode_t ret = AM_SUCCESS;
+
+	assert(para);
+
+	init_dmx_dev();
+
+	AM_TRY(dmx_get_dev(dev_no, &dev));
+
+//	pthread_mutex_lock(&am_gAdpLock);
+
+        if (dev->open_count > 0) {
+                printf("demux device %d has already been opened", dev_no);
+                dev->open_count++;
+                ret = AM_SUCCESS;
+                goto final;
+        }
+
+        dev->dev_no = dev_no;
+
+        if (para->use_sw_filter) {
+                //		dev->drv = &SW_DMX_DRV;
+        } else {
+                dev->drv = &HW_DMX_DRV;
+        }
+
+        if (dev->drv->open) {
+                ret = dev->drv->open(dev, para);
+        }
+
+        if (ret == AM_SUCCESS) {
+                pthread_mutex_init(&dev->lock, NULL);
+                pthread_cond_init(&dev->cond, NULL);
+                dev->enable_thread = AM_TRUE;
+                dev->flags = 0;
+
+                if (pthread_create(&dev->thread, NULL, dmx_data_thread, dev)) {
+                        pthread_mutex_destroy(&dev->lock);
+                        pthread_cond_destroy(&dev->cond);
+                        ret = AM_DMX_ERR_CANNOT_CREATE_THREAD;
+                }
+        }
+
+        if (ret == AM_SUCCESS) {
+                dev->open_count = 1;
+        }
+final:
+//	pthread_mutex_unlock(&am_gAdpLock);
+
+	return ret;
+}
+
+/**\brief 关闭解复用设备
+ * \param dev_no 解复用设备号
+ * \return
+ *   - AM_SUCCESS 成功
+ *   - 其他值 错误代码(见am_dmx.h)
+ */
+AM_ErrorCode_t AM_DMX_Close(int dev_no)
+{
+	AM_DMX_Device_t *dev;
+	AM_ErrorCode_t ret = AM_SUCCESS;
+	int i;
+
+	AM_TRY(dmx_get_opened_dev(dev_no, &dev));
+
+//	pthread_mutex_lock(&am_gAdpLock);
+
+        if (dev->open_count == 1) {
+                dev->enable_thread = AM_FALSE;
+                pthread_join(dev->thread, NULL);
+
+                for (i = 0; i < DMX_FILTER_COUNT; i++) {
+                        dmx_free_filter(dev, &dev->filters[i]);
+                }
+
+                if (dev->drv->close) {
+                        dev->drv->close(dev);
+                }
+
+                pthread_mutex_destroy(&dev->lock);
+                pthread_cond_destroy(&dev->cond);
+        }
+        dev->open_count--;
+
+        //	pthread_mutex_unlock(&am_gAdpLock);
+
+	return ret;
+}
+
+/**\brief 分配一个过滤器
+ * \param dev_no 解复用设备号
+ * \param[out] fhandle 返回过滤器句柄
+ * \return
+ *   - AM_SUCCESS 成功
+ *   - 其他值 错误代码(见am_dmx.h)
+ */
+AM_ErrorCode_t AM_DMX_AllocateFilter(int dev_no, int *fhandle)
+{
+	AM_DMX_Device_t *dev;
+	AM_ErrorCode_t ret = AM_SUCCESS;
+	int fid;
+
+	assert(fhandle);
+
+	AM_TRY(dmx_get_opened_dev(dev_no, &dev));
+
+	pthread_mutex_lock(&dev->lock);
+
+        for (fid = 0; fid < DMX_FILTER_COUNT; fid++) {
+                if (!dev->filters[fid].used)
+                        break;
+        }
+
+        if (fid >= DMX_FILTER_COUNT) {
+                printf("no free section filter");
+                ret = AM_DMX_ERR_NO_FREE_FILTER;
+        }
+
+        if (ret == AM_SUCCESS) {
+                dmx_wait_cb(dev);
+
+                dev->filters[fid].id = fid;
+                if (dev->drv->alloc_filter) {
+                        ret = dev->drv->alloc_filter(dev, &dev->filters[fid]);
+                }
+        }
+
+        if (ret == AM_SUCCESS) {
+                dev->filters[fid].used = AM_TRUE;
+                *fhandle = fid;
+        }
+
+        pthread_mutex_unlock(&dev->lock);
+
+	return ret;
+}
+
+/**\brief 设定Section过滤器
+ * \param dev_no 解复用设备号
+ * \param fhandle 过滤器句柄
+ * \param[in] params Section过滤器参数
+ * \return
+ *   - AM_SUCCESS 成功
+ *   - 其他值 错误代码(见am_dmx.h)
+ */
+AM_ErrorCode_t AM_DMX_SetSecFilter(int dev_no, int fhandle, const struct dmx_sct_filter_params *params)
+{
+	AM_DMX_Device_t *dev;
+	AM_DMX_Filter_t *filter;
+	AM_ErrorCode_t ret = AM_SUCCESS;
+
+	assert(params);
+
+	AM_TRY(dmx_get_opened_dev(dev_no, &dev));
+
+        if (!dev->drv->set_sec_filter) {
+                printf("demux do not support set_sec_filter");
+                return AM_DMX_ERR_NOT_SUPPORTED;
+        }
+
+        pthread_mutex_lock(&dev->lock);
+
+	ret = dmx_get_used_filter(dev, fhandle, &filter);
+
+        if (ret == AM_SUCCESS) {
+                dmx_wait_cb(dev);
+                ret = dmx_stop_filter(dev, filter);
+        }
+
+        if (ret == AM_SUCCESS) {
+                ret = dev->drv->set_sec_filter(dev, filter, params);
+                printf("set sec filter %d PID: %d filter: %02x:%02x %02x:%02x %02x:%02x %02x:%02x %02x:%02x %02x:%02x %02x:%02x %02x:%02x",
+                       fhandle, params->pid,
+                       params->filter.filter[0], params->filter.mask[0],
+                       params->filter.filter[1], params->filter.mask[1],
+                       params->filter.filter[2], params->filter.mask[2],
+                       params->filter.filter[3], params->filter.mask[3],
+                       params->filter.filter[4], params->filter.mask[4],
+                       params->filter.filter[5], params->filter.mask[5],
+                       params->filter.filter[6], params->filter.mask[6],
+                       params->filter.filter[7], params->filter.mask[7]);
+        }
+
+        pthread_mutex_unlock(&dev->lock);
+
+	return ret;
+}
+
+/**\brief 设定PES过滤器
+ * \param dev_no 解复用设备号
+ * \param fhandle 过滤器句柄
+ * \param[in] params PES过滤器参数
+ * \return
+ *   - AM_SUCCESS 成功
+ *   - 其他值 错误代码(见am_dmx.h)
+ */
+AM_ErrorCode_t AM_DMX_SetPesFilter(int dev_no, int fhandle, const struct dmx_pes_filter_params *params)
+{
+	AM_DMX_Device_t *dev;
+	AM_DMX_Filter_t *filter;
+	AM_ErrorCode_t ret = AM_SUCCESS;
+
+	assert(params);
+
+	AM_TRY(dmx_get_opened_dev(dev_no, &dev));
+
+        if (!dev->drv->set_pes_filter) {
+                printf("demux do not support set_pes_filter");
+                return AM_DMX_ERR_NOT_SUPPORTED;
+        }
+
+        pthread_mutex_lock(&dev->lock);
+
+	ret = dmx_get_used_filter(dev, fhandle, &filter);
+
+        if (ret == AM_SUCCESS) {
+                dmx_wait_cb(dev);
+                ret = dmx_stop_filter(dev, filter);
+        }
+
+        if (ret == AM_SUCCESS) {
+                ret = dev->drv->set_pes_filter(dev, filter, params);
+                printf("set pes filter %d PID %d", fhandle, params->pid);
+        }
+
+        pthread_mutex_unlock(&dev->lock);
+
+	return ret;
+}
+AM_ErrorCode_t AM_DMX_GetSTC(int dev_no, int fhandle)
+{
+	AM_DMX_Device_t *dev;
+	AM_DMX_Filter_t *filter;
+	AM_ErrorCode_t ret = AM_SUCCESS;
+
+	AM_TRY(dmx_get_opened_dev(dev_no, &dev));
+	printf("%s line:%d\n", __FUNCTION__, __LINE__);
+        if (!dev->drv->get_stc) {
+                printf("demux do not support set_pes_filter");
+                return AM_DMX_ERR_NOT_SUPPORTED;
+        }
+
+        pthread_mutex_lock(&dev->lock);
+
+        ret = dmx_get_used_filter(dev, fhandle, &filter);
+
+        if (ret == AM_SUCCESS) {
+                ret = dev->drv->get_stc(dev, filter);
+        }
+
+        pthread_mutex_unlock(&dev->lock);
+	printf("%s line:%d\n", __FUNCTION__, __LINE__);
+
+	return ret;
+}
+
+
+/**\brief 释放一个过滤器
+ * \param dev_no 解复用设备号
+ * \param fhandle 过滤器句柄
+ * \return
+ *   - AM_SUCCESS 成功
+ *   - 其他值 错误代码(见am_dmx.h)
+ */
+AM_ErrorCode_t AM_DMX_FreeFilter(int dev_no, int fhandle)
+{
+	AM_DMX_Device_t *dev;
+	AM_DMX_Filter_t *filter;
+	AM_ErrorCode_t ret = AM_SUCCESS;
+
+	AM_TRY(dmx_get_opened_dev(dev_no, &dev));
+
+	pthread_mutex_lock(&dev->lock);
+
+	ret = dmx_get_used_filter(dev, fhandle, &filter);
+
+        if (ret == AM_SUCCESS) {
+                dmx_wait_cb(dev);
+                ret = dmx_free_filter(dev, filter);
+        }
+
+        pthread_mutex_unlock(&dev->lock);
+
+	return ret;
+}
+
+/**\brief 让一个过滤器开始运行
+ * \param dev_no 解复用设备号
+ * \param fhandle 过滤器句柄
+ * \return
+ *   - AM_SUCCESS 成功
+ *   - 其他值 错误代码(见am_dmx.h)
+ */
+AM_ErrorCode_t AM_DMX_StartFilter(int dev_no, int fhandle)
+{
+	AM_DMX_Device_t *dev;
+	AM_DMX_Filter_t *filter = NULL;
+	AM_ErrorCode_t ret = AM_SUCCESS;
+
+	AM_TRY(dmx_get_opened_dev(dev_no, &dev));
+
+	pthread_mutex_lock(&dev->lock);
+
+	ret = dmx_get_used_filter(dev, fhandle, &filter);
+
+        if (!filter->enable) {
+                if (ret == AM_SUCCESS) {
+                        if (dev->drv->enable_filter) {
+                                ret = dev->drv->enable_filter(dev, filter, AM_TRUE);
+                        }
+                }
+
+                if (ret == AM_SUCCESS) {
+                        filter->enable = AM_TRUE;
+                }
+        }
+
+        pthread_mutex_unlock(&dev->lock);
+
+	return ret;
+}
+
+/**\brief 停止一个过滤器
+ * \param dev_no 解复用设备号
+ * \param fhandle 过滤器句柄
+ * \return
+ *   - AM_SUCCESS 成功
+ *   - 其他值 错误代码(见am_dmx.h)
+ */
+AM_ErrorCode_t AM_DMX_StopFilter(int dev_no, int fhandle)
+{
+	AM_DMX_Device_t *dev;
+	AM_DMX_Filter_t *filter = NULL;
+	AM_ErrorCode_t ret = AM_SUCCESS;
+
+	AM_TRY(dmx_get_opened_dev(dev_no, &dev));
+
+	pthread_mutex_lock(&dev->lock);
+
+	ret = dmx_get_used_filter(dev, fhandle, &filter);
+
+        if (ret == AM_SUCCESS) {
+                if (filter->enable) {
+                        dmx_wait_cb(dev);
+                        ret = dmx_stop_filter(dev, filter);
+                }
+        }
+
+        pthread_mutex_unlock(&dev->lock);
+
+	return ret;
+}
+
+/**\brief 设置一个过滤器的缓冲区大小
+ * \param dev_no 解复用设备号
+ * \param fhandle 过滤器句柄
+ * \param size 缓冲区大小
+ * \return
+ *   - AM_SUCCESS 成功
+ *   - 其他值 错误代码(见am_dmx.h)
+ */
+AM_ErrorCode_t AM_DMX_SetBufferSize(int dev_no, int fhandle, int size)
+{
+	AM_DMX_Device_t *dev;
+	AM_DMX_Filter_t *filter;
+	AM_ErrorCode_t ret = AM_SUCCESS;
+
+	AM_TRY(dmx_get_opened_dev(dev_no, &dev));
+
+	pthread_mutex_lock(&dev->lock);
+
+        if (!dev->drv->set_buf_size) {
+                printf("do not support set_buf_size");
+                ret = AM_DMX_ERR_NOT_SUPPORTED;
+        }
+
+        if (ret == AM_SUCCESS)
+                ret = dmx_get_used_filter(dev, fhandle, &filter);
+
+        if (ret == AM_SUCCESS)
+                ret = dev->drv->set_buf_size(dev, filter, size);
+
+        pthread_mutex_unlock(&dev->lock);
+
+	return ret;
+}
+
+/**\brief 取得一个过滤器对应的回调函数和用户参数
+ * \param dev_no 解复用设备号
+ * \param fhandle 过滤器句柄
+ * \param[out] cb 返回过滤器对应的回调函数
+ * \param[out] data 返回用户参数
+ * \return
+ *   - AM_SUCCESS 成功
+ *   - 其他值 错误代码(见am_dmx.h)
+ */
+AM_ErrorCode_t AM_DMX_GetCallback(int dev_no, int fhandle, AM_DMX_DataCb *cb, void **data)
+{
+	AM_DMX_Device_t *dev;
+	AM_DMX_Filter_t *filter;
+	AM_ErrorCode_t ret = AM_SUCCESS;
+
+	AM_TRY(dmx_get_opened_dev(dev_no, &dev));
+
+	pthread_mutex_lock(&dev->lock);
+
+	ret = dmx_get_used_filter(dev, fhandle, &filter);
+
+        if (ret == AM_SUCCESS) {
+                if (cb)
+                        *cb = filter->cb;
+
+                if (data)
+                        *data = filter->user_data;
+        }
+
+        pthread_mutex_unlock(&dev->lock);
+
+	return ret;
+}
+
+/**\brief 设置一个过滤器对应的回调函数和用户参数
+ * \param dev_no 解复用设备号
+ * \param fhandle 过滤器句柄
+ * \param[in] cb 回调函数
+ * \param[in] data 回调函数的用户参数
+ * \return
+ *   - AM_SUCCESS 成功
+ *   - 其他值 错误代码(见am_dmx.h)
+ */
+AM_ErrorCode_t AM_DMX_SetCallback(int dev_no, int fhandle, AM_DMX_DataCb cb, void *data)
+{
+	AM_DMX_Device_t *dev;
+	AM_DMX_Filter_t *filter;
+	AM_ErrorCode_t ret = AM_SUCCESS;
+
+	AM_TRY(dmx_get_opened_dev(dev_no, &dev));
+
+	pthread_mutex_lock(&dev->lock);
+
+	ret = dmx_get_used_filter(dev, fhandle, &filter);
+
+        if (ret == AM_SUCCESS) {
+                dmx_wait_cb(dev);
+
+                filter->cb = cb;
+                filter->user_data = data;
+        }
+
+        pthread_mutex_unlock(&dev->lock);
+
+	return ret;
+}
+
+/**\brief 设置解复用设备的输入源
+ * \param dev_no 解复用设备号
+ * \param src 输入源
+ * \return
+ *   - AM_SUCCESS 成功
+ *   - 其他值 错误代码(见am_dmx.h)
+ */
+AM_ErrorCode_t AM_DMX_SetSource(int dev_no, AM_DMX_Source_t src)
+{
+	AM_DMX_Device_t *dev;
+	AM_ErrorCode_t ret = AM_SUCCESS;
+
+	AM_TRY(dmx_get_opened_dev(dev_no, &dev));
+
+	pthread_mutex_lock(&dev->lock);
+        if (!dev->drv->set_source) {
+                printf("do not support set_source");
+                ret = AM_DMX_ERR_NOT_SUPPORTED;
+        }
+
+        if (ret == AM_SUCCESS) {
+                ret = dev->drv->set_source(dev, src);
+        }
+
+        pthread_mutex_unlock(&dev->lock);
+
+        if (ret == AM_SUCCESS) {
+                //		pthread_mutex_lock(&am_gAdpLock);
+                dev->src = src;
+                //		pthread_mutex_unlock(&am_gAdpLock);
+        }
+
+        return ret;
+}
+
+/**\brief DMX同步,可用于等待回调函数执行完毕
+ * \param dev_no 解复用设备号
+ * \return
+ *   - AM_SUCCESS 成功
+ *   - 其他值 错误代码(见am_dmx.h)
+ */
+AM_ErrorCode_t AM_DMX_Sync(int dev_no)
+{
+	AM_DMX_Device_t *dev;
+	AM_ErrorCode_t ret = AM_SUCCESS;
+
+	AM_TRY(dmx_get_opened_dev(dev_no, &dev));
+
+	pthread_mutex_lock(&dev->lock);
+        if (dev->thread != pthread_self()) {
+                while (dev->flags & DMX_FL_RUN_CB)
+                        pthread_cond_wait(&dev->cond, &dev->lock);
+        }
+        pthread_mutex_unlock(&dev->lock);
+
+	return ret;
+}
+
+AM_ErrorCode_t AM_DMX_GetScrambleStatus(int dev_no, AM_Bool_t dev_status[2])
+{
+#if 0
+        char buf[32];
+        char class_file[64];
+        int vflag, aflag;
+        int i;
+
+        dev_status[0] = dev_status[1] = AM_FALSE;
+        snprintf(class_file, sizeof(class_file), "/sys/class/dmx/demux%d_scramble", dev_no);
+        for (i = 0; i < 5; i++) {
+                if (AM_FileRead(class_file, buf, sizeof(buf)) == AM_SUCCESS) {
+                        sscanf(buf, "%d %d", &vflag, &aflag);
+                        if (!dev_status[0])
+                                dev_status[0] = vflag ? AM_TRUE : AM_FALSE;
+                        if (!dev_status[1])
+                                dev_status[1] = aflag ? AM_TRUE : AM_FALSE;
+                        // AM_DEBUG(1, "AM_DMX_GetScrambleStatus video scramble %d, audio scramble %d\n", vflag, aflag);
+                        if (dev_status[0] && dev_status[1]) {
+                                return AM_SUCCESS;
+                        }
+                        usleep(10 * 1000);
+                } else {
+                        printf("AM_DMX_GetScrambleStatus read scramble status failed\n");
+                        return AM_FAILURE;
+                }
+        }
+#endif
+        return AM_SUCCESS;
+}
+
+
diff --git a/test/am_aucpu_test/am_dmx.h b/test/am_aucpu_test/am_dmx.h
new file mode 100644
index 0000000..4128d9e
--- /dev/null
+++ b/test/am_aucpu_test/am_dmx.h
@@ -0,0 +1,230 @@
+/***************************************************************************
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * Description:
+ */
+/**\file
+ * \brief Demux module
+ *
+ * Basic data structures definition in "linux/dvb/dmx.h"
+ *
+ * \author Gong Ke <ke.gong@amlogic.com>
+ * \date 2010-05-21: create the document
+ ***************************************************************************/
+
+#ifndef _AM_DMX_H
+#define _AM_DMX_H
+
+#include "am_types.h"
+/*add for config define for linux dvb *.h*/
+//#include "am_config.h"
+#include "dmx.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/****************************************************************************
+ * Macro definitions
+ ***************************************************************************/
+
+/****************************************************************************
+ * Error code definitions
+ ****************************************************************************/
+
+/**\brief Error code of the demux module*/
+enum AM_DMX_ErrorCode
+{
+	AM_DMX_ERROR_BASE=AM_ERROR_BASE(AM_MOD_DMX),
+	AM_DMX_ERR_INVALID_DEV_NO,          /**< Invalid device number*/
+	AM_DMX_ERR_INVALID_ID,              /**< Invalid filer handle*/
+	AM_DMX_ERR_BUSY,                    /**< The device has already been opened*/
+	AM_DMX_ERR_NOT_ALLOCATED,           /**< The device has not been allocated*/
+	AM_DMX_ERR_CANNOT_CREATE_THREAD,    /**< Cannot create new thread*/
+	AM_DMX_ERR_CANNOT_OPEN_DEV,         /**< Cannot open device*/
+	AM_DMX_ERR_NOT_SUPPORTED,           /**< Not supported*/
+	AM_DMX_ERR_NO_FREE_FILTER,          /**< No free filter*/
+	AM_DMX_ERR_NO_MEM,                  /**< Not enough memory*/
+	AM_DMX_ERR_TIMEOUT,                 /**< Timeout*/
+	AM_DMX_ERR_SYS,                     /**< System error*/
+	AM_DMX_ERR_NO_DATA,                 /**< No data received*/
+	AM_DMX_ERR_END
+};
+
+/****************************************************************************
+ * Type definitions
+ ***************************************************************************/
+
+/**\brief Input source of the demux*/
+typedef enum
+{
+	AM_DMX_SRC_TS0,                    /**< TS input port 0*/
+	AM_DMX_SRC_TS1,                    /**< TS input port 1*/
+	AM_DMX_SRC_TS2,                    /**< TS input port 2*/
+	AM_DMX_SRC_TS3,                    /**< TS input port 3*/
+	AM_DMX_SRC_HIU,                     /**< HIU input (memory)*/
+	AM_DMX_SRC_HIU1
+} AM_DMX_Source_t;
+
+/**\brief Demux device open parameters*/
+typedef struct
+{
+	AM_Bool_t use_sw_filter;           /**< M_TURE to use DVR software filters.*/
+	int       dvr_fifo_no;             /**< Async fifo number if use software filters.*/
+	int       dvr_buf_size;            /**< Async fifo buffer size if use software filters.*/
+} AM_DMX_OpenPara_t;
+
+/**\brief Filter received data callback function
+ * \a fandle is the filter's handle.
+ * \a data is the received data buffer pointer.
+ * \a len is the data length.
+ * If \a data == null, means timeout.
+ */
+typedef void (*AM_DMX_DataCb) (int dev_no, int fhandle, const uint8_t *data, int len, void *user_data);
+
+
+/****************************************************************************
+ * Function prototypes
+ ***************************************************************************/
+
+/**\brief Open a demux device
+ * \param dev_no Demux device number
+ * \param[in] para Demux device's open parameters
+ * \retval AM_SUCCESS On success
+ * \return Error code
+ */
+extern AM_ErrorCode_t AM_DMX_Open(int dev_no, const AM_DMX_OpenPara_t *para);
+
+/**\brief Close a demux device
+ * \param dev_no Demux device number
+ * \retval AM_SUCCESS On success
+ * \return Error code
+ */
+extern AM_ErrorCode_t AM_DMX_Close(int dev_no);
+
+/**\brief Allocate a filter
+ * \param dev_no Demux device number
+ * \param[out] fhandle Return the allocated filter's handle
+ * \retval AM_SUCCESS On success
+ * \return Error Code
+ */
+extern AM_ErrorCode_t AM_DMX_AllocateFilter(int dev_no, int *fhandle);
+
+/**\brief Set a section filter's parameters
+ * \param dev_no Demux device number
+ * \param fhandle Filter handle
+ * \param[in] params Section filter's parameters
+ * \retval AM_SUCCESS On success
+ * \return Error code
+ */
+extern AM_ErrorCode_t AM_DMX_SetSecFilter(int dev_no, int fhandle, const struct dmx_sct_filter_params *params);
+
+/**\brief Set a PES filter's parameters
+ * \param dev_no Demux device number
+ * \param fhandle Filter handle
+ * \param[in] params PES filter's parameters
+ * \retval AM_SUCCESS On success
+ * \return Error code
+ */
+extern AM_ErrorCode_t AM_DMX_SetPesFilter(int dev_no, int fhandle, const struct dmx_pes_filter_params *params);
+
+/**\brief Release an unused filter
+ * \param dev_no Demux device number
+ * \param fhandle Filter handle
+ * \retval AM_SUCCESS On success
+ * \return Error code
+ */
+extern AM_ErrorCode_t AM_DMX_FreeFilter(int dev_no, int fhandle);
+
+/**\brief Start filtering
+ * \param dev_no Demux device number
+ * \param fhandle Filter handle
+ * \retval AM_SUCCESS On success
+ * \return Error code
+ */
+extern AM_ErrorCode_t AM_DMX_StartFilter(int dev_no, int fhandle);
+
+/**\brief Stop filtering
+ * \param dev_no Demux device number
+ * \param fhandle Filter handle
+ * \retval AM_SUCCESS On success
+ * \return Error code
+ */
+extern AM_ErrorCode_t AM_DMX_StopFilter(int dev_no, int fhandle);
+
+/**\brief Set the ring queue buffer size of a filter
+ * \param dev_no Demux device number
+ * \param fhandle Filter handle
+ * \param size Ring queue buffer size in bytes
+ * \retval AM_SUCCESS On success
+ * \return Error code
+ */
+extern AM_ErrorCode_t AM_DMX_SetBufferSize(int dev_no, int fhandle, int size);
+
+/**\brief Get a filter's data callback function
+ * \param dev_no Demux device number
+ * \param fhandle Filter handle
+ * \param[out] cb Return the data callback function of the filter
+ * \param[out] data Return the user defined parameter of the callback function
+ * \retval AM_SUCCESS On success
+ * \return Error code
+ */
+extern AM_ErrorCode_t AM_DMX_GetCallback(int dev_no, int fhandle, AM_DMX_DataCb *cb, void **data);
+
+/**\brief Set a filter's data callback function
+ * \param dev_no Demux device number
+ * \param fhandle Filter handle
+ * \param[in] cb New data callback function
+ * \param[in] data User defined parameter of the callback function
+ * \retval AM_SUCCESS On success
+ * \return Error code
+ */
+extern AM_ErrorCode_t AM_DMX_SetCallback(int dev_no, int fhandle, AM_DMX_DataCb cb, void *data);
+
+/**\brief Set the demux's input source
+ * \param dev_no Demux device number
+ * \param src Input source
+ * \retval AM_SUCCESS On success
+ * \return Error code
+ */
+extern AM_ErrorCode_t AM_DMX_SetSource(int dev_no, AM_DMX_Source_t src);
+
+/**\cond */
+/**\brief Sync the demux data
+ * \param dev_no Demux device number
+ * \retval AM_SUCCESS On success
+ * \return Error code
+ */
+extern AM_ErrorCode_t AM_DMX_Sync(int dev_no);
+/**\endcond */
+
+/**
+ * Get the scramble status of the AV channels in the demux
+ * \param dev_no Demux device number
+ * \param[out] dev_status Return the AV channels's scramble status.
+ * dev_status[0] is the video status, dev_status[1] is the audio status.
+ * AM_TRUE means the channel is scrambled, AM_FALSE means the channel is not scrambled.
+ * \retval AM_SUCCESS On success
+ * \return Error code
+ */
+extern AM_ErrorCode_t AM_DMX_GetScrambleStatus(int dev_no, AM_Bool_t dev_status[2]);
+
+extern AM_ErrorCode_t AM_DMX_GetSTC(int dev_no, int fhandle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/test/am_aucpu_test/am_dmx_internal.h b/test/am_aucpu_test/am_dmx_internal.h
new file mode 100644
index 0000000..54a0101
--- /dev/null
+++ b/test/am_aucpu_test/am_dmx_internal.h
@@ -0,0 +1,109 @@
+/***************************************************************************
+ * Copyright (c) 2014 Amlogic, Inc. All rights reserved.
+ *
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ */
+/**\file
+ * \brief 解复用设备
+ *
+ * \author Gong Ke <ke.gong@amlogic.com>
+ * \date 2010-05-21: create the document
+ ***************************************************************************/
+
+#ifndef _AM_DMX_INTERNAL_H
+#define _AM_DMX_INTERNAL_H
+
+#include "am_dmx.h"
+#include "am_util.h"
+//#include <am_thread.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/****************************************************************************
+ * Macro definitions
+ ***************************************************************************/
+
+#define DMX_FILTER_COUNT      (32)
+
+#define DMX_FL_RUN_CB         (1)
+
+/****************************************************************************
+ * Type definitions
+ ***************************************************************************/
+
+/**\brief 解复用设备*/
+typedef struct AM_DMX_Device AM_DMX_Device_t;
+
+/**\brief 过滤器*/
+typedef struct AM_DMX_Filter AM_DMX_Filter_t;
+
+/**\brief 过滤器位屏蔽*/
+typedef uint32_t AM_DMX_FilterMask_t;
+
+#define AM_DMX_FILTER_MASK_ISEMPTY(m)    (!(*(m)))
+#define AM_DMX_FILTER_MASK_CLEAR(m)      (*(m)=0)
+#define AM_DMX_FILTER_MASK_ISSET(m,i)    (*(m)&(1<<(i)))
+#define AM_DMX_FILTER_MASK_SET(m,i)      (*(m)|=(1<<(i)))
+
+/**\brief 解复用设备驱动*/
+typedef struct
+{
+	AM_ErrorCode_t (*open)(AM_DMX_Device_t *dev, const AM_DMX_OpenPara_t *para);
+	AM_ErrorCode_t (*close)(AM_DMX_Device_t *dev);
+	AM_ErrorCode_t (*alloc_filter)(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter);
+	AM_ErrorCode_t (*free_filter)(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter);
+	AM_ErrorCode_t (*set_sec_filter)(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter, const struct dmx_sct_filter_params *params);
+	AM_ErrorCode_t (*set_pes_filter)(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter, const struct dmx_pes_filter_params *params);
+	AM_ErrorCode_t (*enable_filter)(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter, AM_Bool_t enable);
+	AM_ErrorCode_t (*set_buf_size)(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter, int size);
+	AM_ErrorCode_t (*poll)(AM_DMX_Device_t *dev, AM_DMX_FilterMask_t *mask, int timeout);
+	AM_ErrorCode_t (*read)(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter, uint8_t *buf, int *size);
+	AM_ErrorCode_t (*set_source)(AM_DMX_Device_t *dev, AM_DMX_Source_t src);
+	AM_ErrorCode_t (*get_stc)(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter);
+} AM_DMX_Driver_t;
+
+/**\brief Section过滤器*/
+struct AM_DMX_Filter
+{
+	void      *drv_data; /**< 驱动私有数据*/
+	AM_Bool_t  used;     /**< 此Filter是否已经分配*/
+	AM_Bool_t  enable;   /**< 此Filter设备是否使能*/
+	int        id;       /**< Filter ID*/
+	AM_DMX_DataCb       cb;        /**< 解复用数据回调函数*/
+	void               *user_data; /**< 数据回调函数用户参数*/
+};
+
+/**\brief 解复用设备*/
+struct AM_DMX_Device
+{
+	int                 dev_no;  /**< 设备号*/
+	const AM_DMX_Driver_t *drv;  /**< 设备驱动*/
+	void               *drv_data;/**< 驱动私有数据*/
+	AM_DMX_Filter_t     filters[DMX_FILTER_COUNT];   /**< 设备中的Filter*/
+	int                 open_count; /**< 设备已经打开次数*/
+	AM_Bool_t           enable_thread; /**< 数据线程已经运行*/
+	int                 flags;   /**< 线程运行状态控制标志*/
+	pthread_t           thread;  /**< 数据检测线程*/
+	pthread_mutex_t     lock;    /**< 设备保护互斥体*/
+	pthread_cond_t      cond;    /**< 条件变量*/
+	AM_DMX_Source_t     src;     /**< TS输入源*/
+};
+
+
+/****************************************************************************
+ * Function prototypes
+ ***************************************************************************/
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/test/am_aucpu_test/am_dmx_test.c b/test/am_aucpu_test/am_dmx_test.c
new file mode 100644
index 0000000..db6f0b9
--- /dev/null
+++ b/test/am_aucpu_test/am_dmx_test.c
@@ -0,0 +1,681 @@
+#ifdef _FORTIFY_SOURCE
+#undef _FORTIFY_SOURCE
+#endif
+/***************************************************************************
+ * Copyright (c) 2014 Amlogic, Inc. All rights reserved.
+ *
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ */
+/**\file
+ * \brief
+ *
+ * \author Gong Ke <ke.gong@amlogic.com>
+ * \date 2010-06-07: create the document
+ ***************************************************************************/
+
+#define AM_DEBUG_LEVEL 5
+
+//#include <am_debug.h>
+#include "am_util.h"
+#include "am_dmx.h"
+#include <string.h>
+#include <unistd.h>
+#include "dmx.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+#define FEND_DEV_NO   (0)
+
+#define  PAT_TEST
+#define  EIT_TEST
+#define  NIT_TEST
+#define  BAT_TEST
+
+
+static int s_last_num =-1;
+
+int freq = 0;
+int layer = -1;
+int src=0;
+int dmx=0;
+int timeout = 60*3;
+
+static int bat=0;
+static int nit=0;
+static int user=0;
+static int pat=0;
+static int eit=0;
+static int pall=0;
+static int media_type=0;
+
+#define USER_MAX 10
+static int u_pid[USER_MAX]={[0 ... USER_MAX-1] = -1};
+static int u_para[USER_MAX]={[0 ... USER_MAX-1] = 0};
+static char *u_ext[USER_MAX]={[0 ... USER_MAX-1] = NULL};
+static int u_bs[USER_MAX]={[0 ... USER_MAX-1] = 0};
+static int u_para_g;
+static FILE *fp[USER_MAX];
+static FILE *fp_e[USER_MAX];
+
+//static AM_PES_Handle_t h_pes[USER_MAX];
+static char *u_path_g;
+static char u_path_g_b[256];
+static char *u_input_g;
+static char u_input_g_file[256];
+
+/*
+   u_para format:
+	d1 - 0:sec 1:pes
+	d2 - 1:crc : sec only
+	d3 - 1:print
+	d4 - 1:swfilter
+	d5 - 1:ts_tap :pes only
+	d6 - 1:w2file
+*/
+#define UPARA_TYPE      0xf
+#define UPARA_CRC       0xf0
+#define UPARA_PR        0xf00
+#define UPARA_SF        0xf000
+#define UPARA_DMX_TAP   0xf0000
+#define UPARA_FILE      0xf00000
+#define UPARA_PES2ES    0xf000000
+#define UPARA_SUB 		0x20000000
+#define UPARA_ES 		0x40000000
+#define UPARA_PCR 		0x80000000
+
+#define get_upara(_i) (u_para[(_i)]? u_para[(_i)] : u_para_g)
+
+#if 0
+static void pes_cb(AM_PES_Handle_t handle, uint8_t *buf, int size) {
+	int u = (int)(long)AM_PES_GetUserData(handle);
+	printf("pes cb u=%d b=%p, s:%d\n", u, buf, size);
+	int ret = fwrite(buf, 1, size, fp_e[u-1]);
+	if (ret != size)
+		printf("data w lost\n");
+
+}
+#endif
+
+extern int inject_file(int dvr_no, char *inject_name);
+extern int inject_file_and_rec_close(void);
+
+static void dump_bytes(int dev_no, int fid, const uint8_t *data, int len, void *user_data)
+{
+	int u = (int)(long)user_data;
+
+	if (pall) {
+		int i;
+		printf("data:\n");
+		for (i = 0; i < len; i++)
+		{
+			printf("%02x ", data[i]);
+			if (((i + 1) % 16) == 0)
+				printf("\n");
+		}
+		if ((i % 16) != 0)
+			printf("\n");
+	}
+
+	int ret = fwrite(data, 1, len, fp[u -1]);
+	fflush(fp[u - 1]);
+#if 0
+        if (bat & UPARA_PR) {
+                if (data[0] == 0x4a) {
+                        printf("sec:tabid:0x%02x,bunqid:0x%02x%02x,section num:%4d,lat_section_num:%4d\n", data[0],
+                               data[3], data[4], data[6], data[7]);
+                }
+
+        } else if (nit & UPARA_PR) {
+
+                if (data[0] == 0x40) {
+                        printf("section:%8d,max:%8d\n", data[6], data[7]);
+                        if ((data[6] != s_last_num + 1) && (s_last_num != -1)) // ��һ�����߲�����
+                        {
+                                if (s_last_num == data[7]) // ��һ����MAX
+                                {
+                                        if (data[6] != 0) // ��һ��MAX ������� 0
+                                        {
+                                                printf("##drop packet,tabid:0x%4x,cur:%8d,last:%8d,max:%8d\n", data[0],
+                                                       data[6], s_last_num, data[7]);
+                                                // stop_section_flag =1;
+                                        } else {
+                                        }
+                                } else // ��һ������
+                                {
+                                        printf("##drop packet,tabid:%4x,cur:%8d,last:%8d,max:%8d\n", data[0],
+                                               data[6], s_last_num, data[7]);
+                                        // stop_section_flag =1;
+                                }
+
+                        } else {
+                                // printf("section:%8d,",sectiondata->m_pucData[6]);
+                        }
+                        s_last_num = data[6];
+                }
+        } else if (pat & UPARA_PR) {
+                if (data[0] == 0x0)
+                        printf("%02x: %02x %02x %02x %02x %02x %02x %02x %02x\n", data[0], data[1], data[2], data[3], data[4],
+                               data[5], data[6], data[7], data[8]);
+        } else {
+                if (!user_data) {
+                        printf("%02x %02x %02x %02x %02x %02x %02x %02x %02x\n", data[0], data[1], data[2], data[3], data[4],
+                               data[5], data[6], data[7], data[8]);
+                        return;
+                }
+
+                if (get_upara(u - 1) & UPARA_PR)
+                        printf("[%d:%d %d] %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", u - 1, u_pid[u - 1], len,
+                               data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8]);
+                if (get_upara(u - 1) & UPARA_FILE) {
+                        {
+                                int ret = fwrite(data, 1, len, fp[u - 1]);
+                                if (ret != len)
+                                        printf("data w lost\n");
+                        }
+#if 0
+			if (get_upara(u-1)&UPARA_PES2ES) {
+				if (!h_pes[u-1]) {
+					AM_PES_Para_t para = {.packet = pes_cb, .user_data = (void*)(long)u, .payload_only = AM_TRUE,};
+					AM_PES_Create(&h_pes[u-1], &para);
+				}
+				AM_PES_Decode(h_pes[u-1], data, len);
+			}
+#endif
+                }
+        }
+#endif
+}
+
+static int get_section(int dmx, int timeout)
+{
+#ifdef PAT_TEST
+	int fid;
+#endif
+
+#ifdef EIT_TEST
+	int fid_eit_pf, fid_eit_opf;
+#endif
+
+#ifdef NIT_TEST
+	int fid_nit;
+#endif
+#ifdef BAT_TEST
+	int fid_bat;
+#endif
+
+	int fid_user[USER_MAX];
+	int i;
+	int pcr_flag = 0;
+
+	struct dmx_sct_filter_params param;
+	struct dmx_pes_filter_params pparam;
+#ifdef PAT_TEST
+        if (pat & 0xf) {
+                printf("start pat...\n");
+                AM_TRY(AM_DMX_AllocateFilter(dmx, &fid));
+                AM_TRY(AM_DMX_SetCallback(dmx, fid, dump_bytes, (void *)(long)0x01));
+        }
+#endif
+
+#ifdef EIT_TEST
+        if (eit & 0xf) {
+                printf("start eit...\n");
+                AM_TRY(AM_DMX_AllocateFilter(dmx, &fid_eit_pf));
+                AM_TRY(AM_DMX_SetCallback(dmx, fid_eit_pf, dump_bytes, NULL));
+                AM_TRY(AM_DMX_AllocateFilter(dmx, &fid_eit_opf));
+                AM_TRY(AM_DMX_SetCallback(dmx, fid_eit_opf, dump_bytes, NULL));
+        }
+#endif
+
+#ifdef NIT_TEST
+        if (nit & 0xf) {
+                printf("start nit...\n");
+                AM_TRY(AM_DMX_AllocateFilter(dmx, &fid_nit));
+                AM_TRY(AM_DMX_SetCallback(dmx, fid_nit, dump_bytes, NULL));
+        }
+#endif
+
+#ifdef BAT_TEST
+        if (bat & 0xf) {
+                printf("start bat...\n");
+                AM_TRY(AM_DMX_AllocateFilter(dmx, &fid_bat));
+                AM_TRY(AM_DMX_SetCallback(dmx, fid_bat, dump_bytes, NULL));
+        }
+#endif
+
+#ifdef PAT_TEST
+        if (pat & 0xf) {
+                memset(&param, 0, sizeof(param));
+                param.pid = 0;
+                param.filter.filter[0] = 0;
+                param.filter.mask[0] = 0xff;
+                // param.filter.filter[2] = 0x08;
+                // param.filter.mask[2] = 0xff;
+                param.flags = DMX_CHECK_CRC;
+                if (media_type) {
+                        param.flags |= DMX_MEM_SEC_LEVEL1;
+                        param.flags |= ((media_type & 0xff) << DMX_AUDIO_FORMAT_BIT);
+                }
+                if (pat & UPARA_SF)
+                        param.flags |= 0x100;
+                AM_TRY(AM_DMX_SetSecFilter(dmx, fid, &param));
+        }
+#endif
+
+#ifdef EIT_TEST
+        if (eit & 0xf) {
+        memset(&param, 0, sizeof(param));
+        param.pid = 0x12;
+        param.filter.filter[0] = 0x4E;
+        param.filter.mask[0] = 0xff;
+        param.flags = DMX_CHECK_CRC;
+        if (eit & UPARA_SF)
+                param.flags |= 0x100;
+        AM_TRY(AM_DMX_SetSecFilter(dmx, fid_eit_pf, &param));
+
+        memset(&param, 0, sizeof(param));
+        param.pid = 0x12;
+        param.filter.filter[0] = 0x4F;
+        param.filter.mask[0] = 0xff;
+        param.flags = DMX_CHECK_CRC;
+        if (eit & UPARA_SF)
+                param.flags |= 0x100;
+        AM_TRY(AM_DMX_SetSecFilter(dmx, fid_eit_opf, &param));
+        }
+#endif
+
+#ifdef NIT_TEST
+	if (nit & 0xF) {
+	memset(&param, 0, sizeof(param));
+	param.pid = 0x10;
+	param.filter.filter[0] = 0x40;
+	param.filter.mask[0] = 0xff;
+	if (nit & UPARA_CRC)
+		param.flags = DMX_CHECK_CRC;
+	if (nit & UPARA_SF)
+		param.flags |= 0x100;
+	AM_TRY(AM_DMX_SetSecFilter(dmx, fid_nit, &param));
+	}
+#endif
+
+#ifdef BAT_TEST
+        if (bat & 0xF) {
+        memset(&param, 0, sizeof(param));
+        param.pid = 0x11;
+        param.filter.filter[0] = 0x4a;
+        param.filter.mask[0] = 0xff;
+        if (bat & UPARA_CRC)
+                param.flags = DMX_CHECK_CRC;
+        if (bat & UPARA_SF)
+                param.flags |= 0x100;
+        AM_TRY(AM_DMX_SetSecFilter(dmx, fid_bat, &param));
+        }
+#endif
+
+
+#ifdef PAT_TEST
+	if (pat & 0xF) {
+	AM_TRY(AM_DMX_SetBufferSize(dmx, fid, 32*1024));
+
+	char name[32];
+	sprintf(name, "%s/u_%d.dump", u_path_g, 0);
+	fprintf(stderr, "path=%s\n", name);
+	fp[0] = fopen(name, "wb");
+	if (fp[0])
+		fprintf(stderr, "file open:[%s]\n", name);
+
+	sprintf(name, "%s/u_%d.es.dump", u_path_g, 0);
+	fp_e[0] = fopen(name, "wb");
+	if (fp_e[0])
+		fprintf(stderr, "file open:[%s]\n", name);
+
+	AM_TRY(AM_DMX_StartFilter(dmx, fid));
+	}
+#endif
+#ifdef EIT_TEST
+	if (eit & 0xF) {
+	AM_TRY(AM_DMX_SetBufferSize(dmx, fid_eit_pf, 32*1024));
+	AM_TRY(AM_DMX_StartFilter(dmx, fid_eit_pf));
+	AM_TRY(AM_DMX_SetBufferSize(dmx, fid_eit_opf, 32*1024));
+	//AM_TRY(AM_DMX_StartFilter(dmx, fid_eit_opf));
+	}
+#endif
+
+#ifdef NIT_TEST
+	if (nit & 0xF) {
+	AM_TRY(AM_DMX_SetBufferSize(dmx, fid_nit, 32*1024));
+	AM_TRY(AM_DMX_StartFilter(dmx, fid_nit));
+	}
+#endif
+
+#ifdef BAT_TEST
+	if (bat & 0xF) {
+	AM_TRY(AM_DMX_SetBufferSize(dmx, fid_bat, 64*1024));
+	AM_TRY(AM_DMX_StartFilter(dmx, fid_bat));
+	}
+#endif
+
+	for (i = 0; i < USER_MAX; i++) {
+        if (u_pid[i] != -1) {
+                printf("set %d\n", __LINE__);
+                AM_TRY(AM_DMX_AllocateFilter(dmx, &fid_user[i]));
+                printf("set %d\n", __LINE__);
+
+                AM_TRY(AM_DMX_SetCallback(dmx, fid_user[i], dump_bytes, (void *)(long)(i + 1)));
+                printf("set %d\n", __LINE__);
+
+                if (u_bs[i]) {
+                                AM_TRY(AM_DMX_SetBufferSize(dmx, fid_user[i], u_bs[i]));
+                                printf("buffersize => %d\n", u_bs[i]);
+                }
+                printf("set %d\n", __LINE__);
+
+                if (get_upara(i) & UPARA_TYPE) { /*pes*/
+                                memset(&pparam, 0, sizeof(pparam));
+                                pparam.pid = u_pid[i];
+                                if (get_upara(i) & UPARA_PCR) {
+                                        pparam.pes_type = DMX_PES_PCR0;
+                                        printf("set %d\n", __LINE__);
+                                        pcr_flag = 1;
+                                } else if (get_upara(i) & UPARA_SUB) {
+                                        pparam.pes_type = DMX_PES_SUBTITLE0;
+                                        printf("set subtitle filter\n");
+                                        if (media_type) {
+                                                pparam.flags |= ((media_type & 0xff) << DMX_AUDIO_FORMAT_BIT);
+                                                pparam.flags |= DMX_MEM_SEC_LEVEL1;
+                                                printf("media type:%d\n", media_type);
+                                        }
+                                } else
+                                        pparam.pes_type = DMX_PES_AUDIO0; // DMX_PES_OTHER;
+
+                                pparam.input = DMX_IN_FRONTEND;
+                                pparam.output = DMX_OUT_TAP;
+                                if (get_upara(i) & UPARA_DMX_TAP)
+                                        pparam.output = DMX_OUT_TSDEMUX_TAP;
+                                if (get_upara(i) & UPARA_SF)
+                                        pparam.flags |= 0x100;
+                                if (get_upara(i) & UPARA_ES) {
+                                        pparam.flags |= DMX_ES_OUTPUT;
+                                        pparam.flags |= DMX_MEM_SEC_LEVEL1;
+                                        pparam.flags |= ((media_type & 0xff) << DMX_AUDIO_FORMAT_BIT);
+                                        printf("audio type:%d\n", media_type);
+                                        printf("set flag:0x%0x\n", pparam.flags);
+                                }
+                                printf("%s %d %d %d\n", __func__, __LINE__, pparam.flags, pparam.output);
+                                AM_TRY(AM_DMX_SetPesFilter(dmx, fid_user[i], &pparam));
+                } else { /*sct*/
+                                int v[16] = {[0 ... 15] = 0};
+                                int m[16] = {[0 ... 15] = 0};
+                                int ii;
+                                memset(&param, 0, sizeof(param));
+                                param.pid = u_pid[i];
+                                if (u_ext[i]) {
+                                        sscanf(u_ext[i], "%x:%x,%x:%x,%x:%x,%x:%x"
+                                                         ",%x:%x,%x:%x,%x:%x,%x:%x"
+                                                         ",%x:%x,%x:%x,%x:%x,%x:%x"
+                                                         ",%x:%x,%x:%x,%x:%x,%x:%x",
+                                               &v[0], &m[0], &v[1], &m[1],
+                                               &v[2], &m[2], &v[3], &m[3],
+                                               &v[4], &m[4], &v[5], &m[5],
+                                               &v[6], &m[6], &v[7], &m[7],
+                                               &v[8], &m[8], &v[9], &m[9],
+                                               &v[10], &m[10], &v[11], &m[11],
+                                               &v[12], &m[12], &v[13], &m[13],
+                                               &v[14], &m[14], &v[15], &m[15]);
+                                        for (ii = 0; ii < 16; ii++) {
+                                                if (m[ii]) {
+                                                        param.filter.filter[ii] = v[ii];
+                                                        param.filter.mask[ii] = m[ii];
+                                                        printf("ext%d: [%d]%x:%x\n", i, ii, v[ii], m[ii]);
+                                                }
+                                        }
+                                }
+                                if (get_upara(i) & UPARA_CRC)
+                                        param.flags = DMX_CHECK_CRC;
+                                if (get_upara(i) & UPARA_SF)
+                                        param.flags |= 0x100;
+                                AM_TRY(AM_DMX_SetSecFilter(dmx, fid_user[i], &param));
+                }
+
+                fprintf(stderr, "%s %d\n", __func__, __LINE__);
+
+                if (get_upara(i) & UPARA_FILE) {
+                                fprintf(stderr, "%s %d\n", __func__, __LINE__);
+                                char name[32];
+                                sprintf(name, "%s/u_%d.dump", u_path_g, i);
+                                fprintf(stderr, "%s %d name=%s i=%d\n", __func__, __LINE__, name, i);
+                                fp[i] = fopen(name, "wb");
+                                if (fp[i])
+                                        fprintf(stderr, "file open:[%s]\n", name);
+                                sprintf(name, "%s/u_%d.es.dump", u_path_g, i);
+                                fp_e[i] = fopen(name, "wb");
+                                if (fp_e[i])
+                                        fprintf(stderr, "file open:[%s]\n", name);
+                }
+                printf("%s %d\n", __func__, __LINE__);
+
+                AM_TRY(AM_DMX_StartFilter(dmx, fid_user[i]));
+        }
+        }
+
+//	sleep(1);
+	if (pcr_flag == 1) {
+		printf("get stc:\n");
+		AM_DMX_GetSTC(dmx, fid_user[0]);
+	}
+	sleep(timeout);
+
+#ifdef PAT_TEST
+	if (pat & 0xF) {
+	AM_TRY(AM_DMX_StopFilter(dmx, fid));
+	AM_TRY(AM_DMX_FreeFilter(dmx, fid));
+
+	fclose(fp[0]);
+	fclose(fp_e[0]);
+	}
+#endif
+#ifdef EIT_TEST
+	if (eit & 0xF) {
+	AM_TRY(AM_DMX_StopFilter(dmx, fid_eit_pf));
+	AM_TRY(AM_DMX_FreeFilter(dmx, fid_eit_pf));
+	AM_TRY(AM_DMX_StopFilter(dmx, fid_eit_opf));
+	AM_TRY(AM_DMX_FreeFilter(dmx, fid_eit_opf));
+	}
+#endif
+#ifdef NIT_TEST
+        if (nit & 0xF) {
+        AM_TRY(AM_DMX_StopFilter(dmx, fid_nit));
+        AM_TRY(AM_DMX_FreeFilter(dmx, fid_nit));
+        }
+#endif
+#ifdef BAT_TEST
+	if (bat & 0xF) {
+	AM_TRY(AM_DMX_StopFilter(dmx, fid_bat));
+	AM_TRY(AM_DMX_FreeFilter(dmx, fid_bat));
+	}
+#endif
+
+	for (i = 0; i < USER_MAX; i++) {
+		if (u_pid[i] != -1) {
+			AM_TRY(AM_DMX_StopFilter(dmx, fid_user[i]));
+			AM_TRY(AM_DMX_FreeFilter(dmx, fid_user[i]));
+			if ((get_upara(i) & UPARA_FILE) && fp[i])
+				fclose(fp[i]);
+		}
+	}
+
+	return 0;
+}
+
+#if 0
+static int setlayer(int layer/*1/2/4/7*/)
+{
+	AM_ErrorCode_t ret;
+
+	struct dtv_property p = {.cmd=DTV_ISDBT_LAYER_ENABLED, .u.data = layer};
+	struct dtv_properties props = {.num=1, .props=&p};
+	printf("AM FEND SetProp layer:%d\n", props.props[0].u.data);
+	ret = AM_FEND_SetProp(FEND_DEV_NO, &props);
+	return 0;
+}
+#endif
+
+int get_para(char *argv)
+{
+#define CASE(name, len, type, var)                            \
+        if (!strncmp(argv, name "=", (len) + 1)) {            \
+                sscanf(&argv[(len) + 1], type, &var);         \
+                printf("param[" name "] => " type "\n", var); \
+        }
+#define CASESTR(name, len, type, var)                         \
+        if (!strncmp(argv, name "=", (len) + 1)) {            \
+                var = &argv[(len) + 1];                       \
+                printf("param[" name "] => " type "\n", var); \
+        }
+
+        CASE("freq",      4, "%i", freq)
+	else CASE("src",  3, "%i", src)
+	else CASE("dmx",  3, "%i", dmx)
+	else CASE("pat",  3, "%x", pat)
+	else CASE("eit",  3, "%x", eit)
+	else CASE("layer",5, "%i", layer)
+	else CASE("bat",  3, "%x", bat)
+	else CASE("nit",  3, "%x", nit)
+	else CASE("timeout", 7, "%i", timeout)
+	else CASE("pall", 4, "%i", pall)
+	else CASE("m_type", 6, "%i", media_type)
+	else CASE("pid0", 4, "%i", u_pid[0])
+	else CASE("pid1", 4, "%i", u_pid[1])
+	else CASE("pid2", 4, "%i", u_pid[2])
+	else CASE("pid3", 4, "%i", u_pid[3])
+	else CASE("pid4", 4, "%i", u_pid[4])
+	else CASE("para0", 5, "%x", u_para[0])
+	else CASE("para1", 5, "%x", u_para[1])
+	else CASE("para2", 5, "%x", u_para[2])
+	else CASE("para3", 5, "%x", u_para[3])
+	else CASE("para4", 5, "%x", u_para[4])
+	else CASESTR("ext0", 4, "%s", u_ext[0])
+	else CASESTR("ext1", 4, "%s", u_ext[1])
+	else CASESTR("ext2", 4, "%s", u_ext[2])
+	else CASESTR("ext3", 4, "%s", u_ext[3])
+	else CASESTR("ext4", 4, "%s", u_ext[4])
+	else CASE("bs0", 3, "%i", u_bs[0])
+	else CASE("bs1", 3, "%i", u_bs[1])
+	else CASE("bs2", 3, "%i", u_bs[2])
+	else CASE("bs3", 3, "%i", u_bs[3])
+	else CASE("bs4", 3, "%i", u_bs[4])
+	else CASE("para", 4, "%x", u_para_g)
+	else CASESTR("path", 4, "%s", u_path_g)
+	else CASESTR("input", 4, "%s", u_input_g)
+
+	if (u_path_g) {
+		char *e = strchr(u_path_g, ' ');
+		if (e) {
+			int l = e - u_path_g;
+			memcpy(u_path_g_b, u_path_g, l);
+			u_path_g_b[l] = '\0';
+			u_path_g = u_path_g_b;
+		}
+	}
+
+	if (u_input_g) {
+                memcpy(u_input_g_file, u_input_g + 1, strlen(u_input_g) - 1);
+        }
+
+        return 0;
+}
+
+int main(int argc, char **argv)
+{
+	AM_DMX_OpenPara_t para;
+//	AM_FEND_OpenPara_t fpara;
+//	struct dvb_frontend_parameters p;
+//	fe_status_t status;
+	int ret=0;
+	int i;
+
+//	memset(&fpara, 0, sizeof(fpara));
+
+        if (argc == 1) {
+                printf(
+			"Usage:%s [freq=] [src=] [dmx=] [layer=] [timeout=] [pat=] [eit=] [bat=] [nit=] [pidx=] [parax=] [para=] [extx=] [bsx=] [out=]\n"
+			"  default   - src:0 dmx:0 layer:-1 parax:0\n"
+			"  x         - 0~4\n"
+			"  para      - d6->|111111|<-d1\n"
+			"    d1 - 0:sec 1:pes (means enable for pat/eit/bat/nit)\n"
+			"    d2 - 1:crc : sec only\n"
+			"    d3 - 1:print\n"
+			"    d4 - 1:swfilter\n"
+			"    d5 - 1:ts tap : pes only\n"
+			"    d6 - 1:w2file\n"
+			"    d7 - 1:convert pes to es format, pes only\n"
+			"  ext       - tid....\n"
+			"    eg. 0x82:0xff,0x02:0xff\n"
+			"    up to 16 filter data:mask(s)\n"
+			"  bs        - buffersize\n"
+			"  path      - output path\n"
+			, argv[0]);
+		return 0;
+        }
+
+        for (i = 1; i < argc; i++)
+                get_para(argv[i]);
+
+#if 0
+        if (freq > 0) {
+                AM_TRY(AM_FEND_Open(FEND_DEV_NO, &fpara));
+
+                p.frequency = freq;
+#if 0
+		p.inversion = INVERSION_AUTO;
+		p.u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
+		p.u.ofdm.code_rate_HP = FEC_AUTO;
+		p.u.ofdm.code_rate_LP = FEC_AUTO;
+		p.u.ofdm.constellation = QAM_AUTO;
+		p.u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;
+		p.u.ofdm.hierarchy_information = HIERARCHY_AUTO;
+		p.u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
+#else
+		p.u.qam.symbol_rate = 6875000;
+		p.u.qam.fec_inner = FEC_AUTO;
+		p.u.qam.modulation = QAM_64;
+#endif
+
+		AM_TRY(AM_FEND_Lock(FEND_DEV_NO, &p, &status));
+
+                if (status & FE_HAS_LOCK)
+                        printf("locked\n");
+                else
+                        printf("unlocked\n");
+        }
+
+        if (layer != -1)
+		setlayer(layer);
+#endif
+
+	memset(&para, 0, sizeof(para));
+	//para.use_sw_filter = AM_TRUE;
+	//para.dvr_fifo_no = 1;
+	AM_TRY(AM_DMX_Open(dmx, &para));
+
+	printf("TS SRC = %d\n", src);
+	if (src == 1 && u_input_g) {
+		printf("inject file :%s\n",u_input_g_file);
+		inject_file(dmx, u_input_g_file);
+	}
+	get_section(dmx, timeout);
+
+	AM_DMX_Close(dmx);
+
+#if 0
+        if (freq)
+                AM_FEND_Close(FEND_DEV_NO);
+#endif
+	if (src == 1 && u_input_g)
+		inject_file_and_rec_close();
+	return ret;
+}
+
diff --git a/test/am_aucpu_test/am_inject.c b/test/am_aucpu_test/am_inject.c
new file mode 100644
index 0000000..cfebaac
--- /dev/null
+++ b/test/am_aucpu_test/am_inject.c
@@ -0,0 +1,239 @@
+#ifdef _FORTIFY_SOURCE
+#undef _FORTIFY_SOURCE
+#endif
+/***************************************************************************
+ *  Copyright C 2009 by Amlogic, Inc. All Rights Reserved.
+ */
+/**\file
+ * \brief DVR测试程序
+ *
+ * \author Xia Lei Peng <leipeng.xia@amlogic.com>
+ * \date 2010-12-10: create the document
+ ***************************************************************************/
+
+#define AM_DEBUG_LEVEL 1
+
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+//#include <am_debug.h>
+#include <stdio.h>
+#include "am_dmx.h"
+#include <errno.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+/****************************************************************************
+ * Macro definitions
+ ***************************************************************************/
+#ifdef CHIP_8226H
+#define DVR_DEV_COUNT      (2)
+#elif defined(CHIP_8226M) || defined(CHIP_8626X)
+#define DVR_DEV_COUNT      (3)
+#else
+#define DVR_DEV_COUNT      (2)
+#endif
+
+#undef DVR_DEV_COUNT
+#define DVR_DEV_COUNT      (2)
+
+#define FEND_DEV_NO 0
+#define AV_DEV_NO 0
+#define PLAY_DMX_DEV_NO 1
+
+#define DMX_DEV_NO 0
+#define DVR_DEV_NO 0
+#define ASYNC_FIFO 0
+
+typedef struct
+{
+	int id;
+	int ofd;
+	pthread_t thread;
+	int running;
+	int fd;
+}DVRData;
+
+static DVRData data_threads[DVR_DEV_COUNT];
+
+static int dvr_data_write(int fd, uint8_t *buf, int size)
+{
+	int ret;
+	int left = size;
+	uint8_t *p = buf;
+
+	while (left > 0)
+	{
+//		printf("write start\n");
+		ret = write(fd, p, left);
+//		printf("write end\n");
+		if (ret == -1)
+		{
+			if (errno != EINTR)
+			{
+				printf("Write DVR data failed: %s", strerror(errno));
+				break;
+			}
+			ret = 0;
+		} else {
+//			printf("%s write cnt:%d\n",__FUNCTION__,ret);
+		}
+
+		left -= ret;
+		p += ret;
+	}
+
+	return (size - left);
+}
+
+static void handle_signal(int signal)
+{
+	int i;
+	UNUSED(signal);
+
+	exit(0);
+}
+
+static void init_signal_handler()
+{
+	struct sigaction act;
+	act.sa_handler = handle_signal;
+	sigaction(SIGINT, &act, NULL);
+}
+
+static int inject_running=0;
+static int inject_loop=0;
+static void* inject_entry(void *arg)
+{
+	DVRData *dvr_data = (DVRData *)arg;
+	int sock = dvr_data->ofd;
+	int fd = dvr_data->fd;
+	uint8_t buf[50*188];
+	int len, left=0, send, ret;
+	int cnt=50;
+	struct timeval start_tv;
+	struct timeval now_tv;
+	unsigned int diff_time = 0;
+	unsigned int total_len = 0;
+
+	gettimeofday(&start_tv, NULL);
+	printf("inject thread start");
+	while (inject_running) {
+		len = sizeof(buf) - left;
+		ret = read(sock, buf+left, len);
+		if (ret > 0) {
+//			printf("recv %d bytes\n", ret);
+/*			if (!cnt){
+				cnt=50;
+				printf("recv %d\n", ret);
+			}
+			cnt--; */
+			left += ret;
+			total_len += ret;
+		} else {
+			if (inject_loop && ((ret == 0) || (errno == EAGAIN))) {
+				printf("loop\n");
+				lseek(sock, 0, SEEK_SET);
+				left=0;
+				continue;
+			} else {
+				fprintf(stderr, "read file failed [%d:%s] ret=%d left=%d\n", errno, strerror(errno), ret, left);
+				break;
+			}
+		}
+		if (left) {
+#if 0
+			gettimeofday(&now_tv, NULL);
+			if (now_tv.tv_usec < start_tv.tv_usec) {
+				diff_time = (now_tv.tv_sec - 1 - start_tv.tv_sec) * 1000 + (now_tv.tv_usec + 1*1000*1000 - start_tv.tv_usec) / 1000;
+			} else {
+				diff_time = (now_tv.tv_sec - start_tv.tv_sec) * 1000 + (now_tv.tv_usec - start_tv.tv_usec) / 1000;
+			}
+
+			if ( diff_time != 0 && total_len/1024/1024*8*1000/diff_time > 4) {
+				usleep(20*1000);
+			}
+#endif
+			usleep(50*1000);
+			send = left;
+			send = dvr_data_write(fd, buf, send);
+//			printf("write %d bytes\n", send);
+			if (send) {
+				left -= send;
+				if (left)
+					memmove(buf, buf+send, left);
+				//AM_DEBUG(1, "inject %d bytes", send);
+			}
+		}
+	}
+	printf("inject thread end");
+	inject_running = -1;
+	return NULL;
+}
+
+#ifdef LINUX
+#define DVR_DEVICE "/dev/dvb/adapter0/dvr"
+#else
+#define DVR_DEVICE "/dev/dvb0.dvr"
+#endif
+
+int inject_file(int dvr_no, char *inject_name)
+{
+	int loop = 0;
+	int ofd;
+	char dev_name[32];
+	int fd;
+	int ret;
+
+	pthread_t th;
+
+	printf("inject file name=%s to dvr%d\n", inject_name, dvr_no);
+
+	init_signal_handler();
+	snprintf(dev_name, sizeof(dev_name), DVR_DEVICE"%d", dvr_no);
+
+	fd = open(dev_name, O_WRONLY);
+	if (fd == -1)
+	{
+		printf("cannot open \"%s\" (%s)", dev_name, strerror(errno));
+		return -1;
+	}
+//	fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK, 0);
+
+	ret = ioctl(fd, DMX_SET_INPUT, INPUT_LOCAL);
+	printf("DMX_SET_INPUT ret:%d, %s\n", ret, strerror(errno));
+
+	data_threads[0].id =0;
+	data_threads[0].fd = fd;
+
+	data_threads[0].running = 0;
+
+	ofd = open(inject_name, O_RDWR, S_IRUSR);
+	if (ofd == -1) {
+		printf("cannot open \"%s\" (%s)", inject_name, strerror(errno));
+		return -1;
+	}
+	data_threads[0].ofd = ofd;
+
+	inject_loop = loop;
+	inject_running = 1;
+	pthread_create(&th, NULL, inject_entry, (void*)(long)&data_threads[0]);
+
+	return 0;
+}
+int inject_file_and_rec_close(void) {
+
+	inject_running = 0;
+
+	do {}while((inject_running != -1));
+
+	close(data_threads[0].fd);
+	close(data_threads[0].ofd);
+	return 0;
+}
+
diff --git a/test/am_aucpu_test/am_mem.h b/test/am_aucpu_test/am_mem.h
new file mode 100644
index 0000000..8182b71
--- /dev/null
+++ b/test/am_aucpu_test/am_mem.h
@@ -0,0 +1,162 @@
+/***************************************************************************
+ * Copyright (c) 2014 Amlogic, Inc. All rights reserved.
+ *
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ */
+/**\file
+ * \brief 内存分配
+ *封装动态内存分配函数,支持memwatch内存检查
+ * \author Gong Ke <ke.gong@amlogic.com>
+ * \date 2010-05-12: create the document
+ ***************************************************************************/
+
+#ifndef _AM_MEM_H
+#define _AM_MEM_H
+
+#include <string.h>
+#include "am_util.h"
+//#include <memwatch.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/****************************************************************************
+ * Macro definitions
+ ***************************************************************************/
+
+#ifdef AM_DEBUG
+#define AM_MEM_ERROR_DEBUG(_s)        AM_DEBUG(1, "cannot allocate %d bytes memory", _s)
+#else
+#define AM_MEM_ERROR_DEBUG(_s)
+#endif
+
+/**\brief 内存缓冲区分配*/
+#define AM_MEM_Alloc(_size) \
+	({\
+	void *_ptr = malloc(_size);\
+	if (!_ptr) {\
+		AM_MEM_ERROR_DEBUG(_size);\
+	}\
+	_ptr;\
+	})
+
+/**\brief 重新设定缓冲区大小*/
+#define AM_MEM_Realloc(_old,_size) \
+	({\
+	void *_ptr=realloc(_old,_size);\
+	if (!_ptr) {\
+		AM_MEM_ERROR_DEBUG(_size);\
+	}\
+	_ptr;\
+	})
+
+/**\brief 内存缓冲区释放*/
+#define AM_MEM_Free(_ptr) \
+	AM_MACRO_BEGIN\
+	if (_ptr) free(_ptr);\
+	AM_MACRO_END
+
+/**\brief 分配内存并复制字符串*/
+#define AM_MEM_Strdup(_str) \
+	({\
+	void *_ptr = strdup(_str);\
+	if (!_ptr) {\
+		AM_MEM_ERROR_DEBUG(strlen(_str));\
+	}\
+	_ptr;\
+	})
+
+/**\brief 分配内存并将缓冲区清0*/
+#define AM_MEM_Alloc0(_size) \
+	({\
+	void *_ptr = AM_MEM_Alloc((_size));\
+	if(_ptr) memset(_ptr, 0, (_size));\
+	_ptr;\
+	})
+
+/**\brief 根据类型_type的大小分配内存*/
+#define AM_MEM_ALLOC_TYPE(_type)       AM_MEM_Alloc(sizeof(_type))
+
+/**\brief 分配_n个类型_type大小的内存*/
+#define AM_MEM_ALLOC_TYPEN(_type,_n)   AM_MEM_Alloc(sizeof(_type)*(_n))
+
+/**\brief 根据类型_type的大小分配内存,并清0*/
+#define AM_MEM_ALLOC_TYPE0(_type)      AM_MEM_Alloc0(sizeof(_type))
+
+/**\brief 分配_n个类型_type大小的内存,并清0*/
+#define AM_MEM_ALLOC_TYPEN0(_type,_n)  AM_MEM_Alloc0(sizeof(_type)*(_n))
+
+/**\brief 从内存池分配一个缓冲区并清0*/
+#define AM_MEM_PoolAlloc0(_pool,_size) \
+	({\
+	void *_ptr = AM_MEM_PoolAlloc(_pool,_size);\
+	if(_ptr) memset(_ptr, 0, _size);\
+	_ptr;\
+	})
+
+/**\brief 根据类型_type的大小从内存池分配内存*/
+#define AM_MEM_POOL_ALLOC_TYPE(_pool,_type)       AM_MEM_PoolAlloc(_pool,sizeof(_type))
+
+/**\brief 从内存池分配_n个类型_type大小的内存*/
+#define AM_MEM_POOL_ALLOC_TYPEN(_pool,_type,_n)   AM_MEM_PoolAlloc(_pool,sizeof(_type)*(_n))
+
+/**\brief 根据类型_type的大小从内存池分配内存,并清0*/
+#define AM_MEM_POOL_ALLOC_TYPE0(_pool,_type)      AM_MEM_PoolAlloc0(_pool,sizeof(_type))
+
+/**\brief 从内存池分配_n个类型_type大小的内存,并清0*/
+#define AM_MEM_POOL_ALLOC_TYPEN0(_pool,_type,_n)  AM_MEM_PoolAlloc0(_pool,sizeof(_type)*(_n))
+
+/****************************************************************************
+ * Type definitions
+ ***************************************************************************/
+
+/**\brief 内存缓冲池
+ *内存缓冲池在多次分配但统一释放的情况下提高分配效率。
+ *内存缓冲池每次调用malloc分配一个较大的内存,此后所有的小内存块直接在缓冲池内分配。
+ */
+typedef struct
+{
+	int        pool_size;   /**< 每次分配的内存大小*/
+	void      *pools;       /**< 内存块链表*/
+} AM_MEM_Pool_t;
+
+/****************************************************************************
+ * Function prototypes
+ ***************************************************************************/
+
+/**\brief 初始化一个缓冲池
+ * \param[out] pool 需要初始化的缓冲池结构
+ * \param pool_size 每次调用系统分配函数分配的内存大小
+ */
+extern void AM_MEM_PoolInit(AM_MEM_Pool_t *pool, int pool_size);
+
+/**\brief 从缓冲池分配内存
+ * \param[in,out] pool 缓冲池指针
+ * \param size 要分配的内存大小
+ * \return
+ *   - 返回分配内存的指针
+ *   - 如果分配失败返回NULL
+ */
+extern void* AM_MEM_PoolAlloc(AM_MEM_Pool_t *pool, int size);
+
+/**\brief 将缓冲池内全部以分配的内存标记,但不调用系统free()
+ * \param[in,out] pool 缓冲池指针
+ */
+extern void AM_MEM_PoolClear(AM_MEM_Pool_t *pool);
+
+/**\brief 将缓冲池内全部以分配的内存标记,调用系统free()释放全部资源
+ * \param[in,out] pool 缓冲池指针
+ */
+extern void AM_MEM_PoolFree(AM_MEM_Pool_t *pool);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/test/am_aucpu_test/am_types.h b/test/am_aucpu_test/am_types.h
new file mode 100644
index 0000000..f6c44e6
--- /dev/null
+++ b/test/am_aucpu_test/am_types.h
@@ -0,0 +1,118 @@
+/***************************************************************************
+ * Copyright (c) 2014 Amlogic, Inc. All rights reserved.
+ *
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ */
+/**\file
+ * \brief Basic datatypes
+ * \author Gong Ke <ke.gong@amlogic.com>
+ * \date 2010-05-19: create the document
+ ***************************************************************************/
+
+#ifndef _AM_TYPES_H
+#define _AM_TYPES_H
+
+#include <stdint.h>
+#include "pthread.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/*****************************************************************************
+* Global Definitions
+*****************************************************************************/
+
+/**\brief Boolean value*/
+typedef uint8_t        AM_Bool_t;
+
+
+/**\brief Error code of the function result,
+ * Low 24 bits store the error number.
+ * High 8 bits store the module's index.
+ */
+typedef int            AM_ErrorCode_t;
+
+/**\brief The module's index */
+enum AM_MOD_ID
+{
+	AM_MOD_EVT,    /**< Event module*/
+	AM_MOD_DMX,    /**< Demux module*/
+	AM_MOD_DVR,    /**< DVR module*/
+	AM_MOD_NET,    /**< Network manager module*/
+	AM_MOD_OSD,    /**< OSD module*/
+	AM_MOD_AV,     /**< AV decoder module*/
+	AM_MOD_AOUT,   /**< Audio output device module*/
+	AM_MOD_VOUT,   /**< Video output device module*/
+	AM_MOD_SMC,    /**< Smartcard module*/
+	AM_MOD_INP,    /**< Input device module*/
+	AM_MOD_FEND,   /**< DVB frontend device module*/
+	AM_MOD_DSC,    /**< Descrambler device module*/
+	AM_MOD_CFG,    /**< Configure file manager module*/
+	AM_MOD_SI,     /**< SI decoder module*/
+	AM_MOD_SCAN,   /**< Channel scanner module*/
+	AM_MOD_EPG,    /**< EPG scanner module*/
+	AM_MOD_IMG,    /**< Image loader module*/
+	AM_MOD_FONT,   /**< Font manager module*/
+	AM_MOD_DB,     /**< Database module*/
+	AM_MOD_GUI,    /**< GUI module*/
+	AM_MOD_REC,    /**< Recorder module*/
+	AM_MOD_TV,     /**< TV manager module*/
+	AM_MOD_SUB,    /**< Subtitle module*/
+	AM_MOD_SUB2,   /**< Subtitle(version 2) module*/
+	AM_MOD_TT,     /**< Teletext module*/
+	AM_MOD_TT2,    /**< Teletext(version 2) module*/
+	AM_MOD_FEND_DISEQCCMD,/**< Diseqc command module*/
+	AM_MOD_FENDCTRL, /**< DVB frontend high level control module*/
+	AM_MOD_PES,    /**< PES parser module*/
+	AM_MOD_CAMAN,  /**< CA manager module*/
+	AM_MOD_CI,     /**< DVB-CI module*/
+	AM_MOD_USERDATA, /**< MPEG user data reader device module*/
+	AM_MOD_CC,     /**< Close caption module*/
+	AM_MOD_AD,     /**< Audio description module*/
+	AM_MOD_UPD,    /**< Uploader module*/
+	AM_MOD_TFILE, /*File wrapper module*/
+	AM_MOD_SCTE27,
+	AM_MOD_MAX
+};
+
+/**\brief Get the error code base of each module
+ * \param _mod The module's index
+ */
+#define AM_ERROR_BASE(_mod)    ((_mod)<<24)
+
+#ifndef AM_SUCCESS
+/**\brief Function result: Success*/
+#define AM_SUCCESS     (0)
+#endif
+
+#ifndef AM_FAILURE
+/**\brief Function result: Unknown error*/
+#define AM_FAILURE     (-1)
+#endif
+
+#ifndef AM_TRUE
+/**\brief Boolean value: true*/
+#define AM_TRUE        (1)
+#endif
+
+#ifndef AM_FALSE
+/**\brief Boolean value: false*/
+#define AM_FALSE       (0)
+#endif
+
+#ifndef UNUSED
+#define UNUSED(x) (void)(x)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/test/am_aucpu_test/am_util.h b/test/am_aucpu_test/am_util.h
new file mode 100644
index 0000000..c80ea27
--- /dev/null
+++ b/test/am_aucpu_test/am_util.h
@@ -0,0 +1,129 @@
+/***************************************************************************
+ * Copyright (c) 2014 Amlogic, Inc. All rights reserved.
+ *
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ */
+/**\file
+ * \brief 一些常用宏和辅助函数
+ *
+ * \author Gong Ke <ke.gong@amlogic.com>
+ * \date 2010-05-12: create the document
+ ***************************************************************************/
+
+#ifndef _AM_UTIL_H
+#define _AM_UTIL_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/****************************************************************************
+ * Macro definitions
+ ***************************************************************************/
+
+/**\brief 函数inline属性*/
+#define AM_INLINE        inline
+
+/**\brief 计算数值_a和_b中的最大值*/
+#define AM_MAX(_a,_b)    ((_a)>(_b)?(_a):(_b))
+
+/**\brief 计算数值_a和_b中的最小值*/
+#define AM_MIN(_a,_b)    ((_a)<(_b)?(_a):(_b))
+
+/**\brief 计算数值_a的绝对值*/
+#define AM_ABS(_a)       ((_a)>0?(_a):-(_a))
+
+/**\brief 计算数值a与b差值的绝对值*/
+#define AM_ABSSUB(a,b) ((a>=b)?(a-b):(b-a))
+
+/**\brief 添加在命令行式宏定义的开头
+ * 一些宏需要完成一系列语句,为了使这些语句形成一个整体不被打断,需要用
+ * AM_MACRO_BEGIN和AM_MACRO_END将这些语句括起来。如:
+ * \code
+ * #define CHECK(_n)    \
+ *    AM_MACRO_BEGIN \
+ *    if ((_n)>0) printf(">0"); \
+ *    else if ((n)<0) printf("<0"); \
+ *    else printf("=0"); \
+ *    AM_MACRO_END
+ * \endcode
+ */
+#define AM_MACRO_BEGIN   do {
+
+/**\brief 添加在命令行式定义的末尾*/
+#define AM_MACRO_END     } while(0)
+
+/**\brief 计算数组常数的元素数*/
+#define AM_ARRAY_SIZE(_a)    (sizeof(_a)/sizeof((_a)[0]))
+
+/**\brief 检查如果返回值是否错误,返回错误代码给调用函数*/
+#define AM_TRY(_func) \
+	AM_MACRO_BEGIN\
+	AM_ErrorCode_t _ret;\
+	if ((_ret=(_func))!=AM_SUCCESS)\
+		return _ret;\
+	AM_MACRO_END
+
+/**\brief 检查返回值是否错误,如果错误,跳转到final标号。注意:函数中必须定义"AM_ErrorCode_t ret"和标号"final"*/
+#define AM_TRY_FINAL(_func)\
+	AM_MACRO_BEGIN\
+	if ((ret=(_func))!=AM_SUCCESS)\
+		goto final;\
+	AM_MACRO_END
+
+/**\brief 开始解析一个被指定字符隔开的字符串*/
+#define AM_TOKEN_PARSE_BEGIN(_str, _delim, _token) \
+	{\
+	char *_strb =  strdup(_str);\
+	if (_strb) {\
+		_token = strtok(_strb, _delim);\
+		while (_token != NULL) {
+
+#define AM_TOKEN_PARSE_END(_str, _delim, _token) \
+		_token = strtok(NULL, _delim);\
+		}\
+		free(_strb);\
+	}\
+	}
+
+
+/**\brief 从一个被指定字符隔开的字符串中取指定位置的值,int类型,如未找到指定位置,则使用默认值_default代替*/
+#define AM_TOKEN_VALUE_INT(_str, _delim, _index, _default) \
+	({\
+		char *token;\
+		char *_strbak = strdup(_str);\
+		int counter = 0;\
+		int val = _default;\
+		if (_strbak != NULL) {\
+			AM_TOKEN_PARSE_BEGIN(_strbak, _delim, token)\
+				if (counter == (_index)) {\
+					val = atoi(token);\
+					break;\
+				}\
+				counter++;\
+			AM_TOKEN_PARSE_END(_strbak, _delim, token)\
+			free(_strbak);\
+		}\
+		val;\
+	})
+
+/****************************************************************************
+ * Type definitions
+ ***************************************************************************/
+
+
+/****************************************************************************
+ * Function prototypes
+ ***************************************************************************/
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/test/am_aucpu_test/compile.sh b/test/am_aucpu_test/compile.sh
new file mode 100644
index 0000000..204609a
--- /dev/null
+++ b/test/am_aucpu_test/compile.sh
@@ -0,0 +1,5 @@
+export CROSS_COMPILE=/opt/gcc-linaro-6.3.1-2017.02-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
+
+$(CROSS_COMPILE)gcc -static am_sc2_dmx_test.c am_inject.c am_dmx.c linux_dvb.c -o am_sc2_dmx_test -lpthread -o am_sc2_dmx_test
+#gcc am_sc2_dmx_test.c am_inject.c am_dmx.c linux_dvb.c -o am_sc2_dmx_test 
+
diff --git a/test/am_aucpu_test/dmx.h b/test/am_aucpu_test/dmx.h
new file mode 100644
index 0000000..d722497
--- /dev/null
+++ b/test/am_aucpu_test/dmx.h
@@ -0,0 +1,320 @@
+/*
+ * dmx.h
+ *
+ * Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
+ *                  & Ralph  Metzler <ralph@convergence.de>
+ *                    for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+#ifndef _UAPI_DVBDMX_H_
+#define _UAPI_DVBDMX_H_
+
+#include <linux/types.h>
+#ifndef __KERNEL__
+#include <time.h>
+#endif
+
+#define CONFIG_AMLOGIC_DVB_COMPAT
+
+#define DMX_FILTER_SIZE 16
+
+enum dmx_output
+{
+	DMX_OUT_DECODER, /* Streaming directly to decoder. */
+	DMX_OUT_TAP,     /* Output going to a memory buffer */
+			 /* (to be retrieved via the read command).*/
+	DMX_OUT_TS_TAP,  /* Output multiplexed into a new TS  */
+			 /* (to be retrieved by reading from the */
+			 /* logical DVR device).                 */
+	DMX_OUT_TSDEMUX_TAP /* Like TS_TAP but retrieved from the DMX device */
+};
+
+typedef enum dmx_output dmx_output_t;
+
+typedef enum dmx_input
+{
+	DMX_IN_FRONTEND, /* Input from a front-end device.  */
+	DMX_IN_DVR       /* Input from the logical DVR device.  */
+} dmx_input_t;
+
+
+typedef enum dmx_ts_pes
+{
+	DMX_PES_AUDIO0,
+	DMX_PES_VIDEO0,
+	DMX_PES_TELETEXT0,
+	DMX_PES_SUBTITLE0,
+	DMX_PES_PCR0,
+
+	DMX_PES_AUDIO1,
+	DMX_PES_VIDEO1,
+	DMX_PES_TELETEXT1,
+	DMX_PES_SUBTITLE1,
+	DMX_PES_PCR1,
+
+	DMX_PES_AUDIO2,
+	DMX_PES_VIDEO2,
+	DMX_PES_TELETEXT2,
+	DMX_PES_SUBTITLE2,
+	DMX_PES_PCR2,
+
+	DMX_PES_AUDIO3,
+	DMX_PES_VIDEO3,
+	DMX_PES_TELETEXT3,
+	DMX_PES_SUBTITLE3,
+	DMX_PES_PCR3,
+
+	DMX_PES_OTHER
+} dmx_pes_type_t;
+
+#define DMX_PES_AUDIO    DMX_PES_AUDIO0
+#define DMX_PES_VIDEO    DMX_PES_VIDEO0
+#define DMX_PES_TELETEXT DMX_PES_TELETEXT0
+#define DMX_PES_SUBTITLE DMX_PES_SUBTITLE0
+#define DMX_PES_PCR      DMX_PES_PCR0
+
+
+typedef struct dmx_filter
+{
+	__u8  filter[DMX_FILTER_SIZE];
+	__u8  mask[DMX_FILTER_SIZE];
+	__u8  mode[DMX_FILTER_SIZE];
+} dmx_filter_t;
+
+
+struct dmx_sct_filter_params
+{
+	__u16          pid;
+	dmx_filter_t   filter;
+	__u32          timeout;
+	__u32          flags;
+#define DMX_CHECK_CRC       1
+#define DMX_ONESHOT         2
+#define DMX_IMMEDIATE_START 4
+#define DMX_KERNEL_CLIENT   0x8000
+#ifdef CONFIG_AMLOGIC_DVB_COMPAT
+#define DMX_USE_SWFILTER    0x100
+
+/*bit 8~15 for mem sec_level*/
+#define DMX_MEM_SEC_LEVEL1   (1 << 10)
+#define DMX_MEM_SEC_LEVEL2   (1 << 11)
+#define DMX_MEM_SEC_LEVEL3   (1 << 12)
+#endif
+};
+
+#ifdef CONFIG_AMLOGIC_DVB_COMPAT
+
+enum dmx_input_source {
+	INPUT_DEMOD,
+	INPUT_LOCAL,
+	INPUT_LOCAL_SEC
+};
+
+/**
+ * struct dmx_non_sec_es_header - non-sec Elementary Stream (ES) Header
+ *
+ * @pts_dts_flag:[1:0], 01:pts valid, 10:dts valid
+ * @pts:	pts value
+ * @dts:	dts value
+ * @len:	data len
+ */
+struct dmx_non_sec_es_header {
+	__u8 pts_dts_flag;
+	__u64 pts;
+	__u64 dts;
+	__u32 len;
+};
+
+/**
+ * struct dmx_sec_es_data - sec Elementary Stream (ES)
+ *
+ * @pts_dts_flag:[1:0], 01:pts valid, 10:dts valid
+ * @pts:	pts value
+ * @dts:	dts value
+ * @buf_start:	buf start addr
+ * @buf_end:	buf end addr
+ * @data_start: data start addr
+ * @data_end: data end addr
+ */
+struct dmx_sec_es_data {
+	__u8 pts_dts_flag;
+	__u64 pts;
+	__u64 dts;
+	__u32 buf_start;
+	__u32 buf_end;
+	__u32 data_start;
+	__u32 data_end;
+};
+
+struct dmx_sec_ts_data {
+	__u32 buf_start;
+	__u32 buf_end;
+	__u32 data_start;
+	__u32 data_end;
+};
+
+enum dmx_audio_format {
+	AUDIO_UNKNOWN = 0,	/* unknown media */
+	AUDIO_MPX = 1,		/* mpeg audio MP2/MP3 */
+	AUDIO_AC3 = 2,		/* Dolby AC3/EAC3 */
+	AUDIO_AAC_ADTS = 3,	/* AAC-ADTS */
+	AUDIO_AAC_LOAS = 4,	/* AAC-LOAS */
+	AUDIO_DTS = 5,		/* DTS */
+	AUDIO_MAX
+};
+
+struct dmx_mem_info {
+	__u32 dmx_total_size;
+	__u32 dmx_buf_phy_start;
+	__u32 dmx_free_size;
+	__u32 dvb_core_total_size;
+	__u32 dvb_core_free_size;
+	__u32 wp_offset;
+	__u64 newest_pts;
+};
+
+struct dmx_sec_mem {
+	__u32 buff;
+	__u32 size;
+};
+#endif
+
+/**
+ * struct dmx_pes_filter_params - Specifies Packetized Elementary Stream (PES)
+ *	filter parameters.
+ *
+ * @pid:	PID to be filtered.
+ * @input:	Demux input, as specified by &enum dmx_input.
+ * @output:	Demux output, as specified by &enum dmx_output.
+ * @pes_type:	Type of the pes filter, as specified by &enum dmx_pes_type.
+ * @flags:	Demux PES flags.
+ */
+struct dmx_pes_filter_params {
+	__u16           pid;
+	dmx_input_t  input;
+	dmx_output_t output;
+	dmx_pes_type_t pes_type;
+	__u32           flags;
+#ifdef CONFIG_AMLOGIC_DVB_COMPAT
+/*bit 8~15 for mem sec_level*/
+#define DMX_MEM_SEC_LEVEL1   (1 << 10)
+#define DMX_MEM_SEC_LEVEL2   (1 << 11)
+#define DMX_MEM_SEC_LEVEL3   (1 << 12)
+
+/*bit 16~23 for output */
+#define DMX_ES_OUTPUT        (1 << 16)
+/*set raw mode, it will send the struct dmx_sec_es_data, not es data*/
+#define DMX_OUTPUT_RAW_MODE	 (1 << 17)
+
+/*24~31 one byte for audio type, dmx_audio_format_t*/
+#define DMX_AUDIO_FORMAT_BIT 24
+
+#endif
+};
+
+typedef struct dmx_caps {
+	__u32 caps;
+	int num_decoders;
+} dmx_caps_t;
+
+typedef enum dmx_source {
+	DMX_SOURCE_FRONT0 = 0,
+	DMX_SOURCE_FRONT1,
+	DMX_SOURCE_FRONT2,
+	DMX_SOURCE_FRONT3,
+	DMX_SOURCE_DVR0   = 16,
+	DMX_SOURCE_DVR1,
+	DMX_SOURCE_DVR2,
+	DMX_SOURCE_DVR3,
+
+#ifdef CONFIG_AMLOGIC_DVB_COMPAT
+	DMX_SOURCE_FRONT0_OFFSET = 100,
+	DMX_SOURCE_FRONT1_OFFSET,
+	DMX_SOURCE_FRONT2_OFFSET
+#endif
+} dmx_source_t;
+
+struct dmx_stc {
+	unsigned int num;	/* input : which STC? 0..N */
+	unsigned int base;	/* output: divisor for stc to get 90 kHz clock */
+	__u64 stc;		/* output: stc in 'base'*90 kHz units */
+};
+
+#ifdef CONFIG_AMLOGIC_DVB_COMPAT
+enum {
+	DMA_0 = 0,
+	DMA_1,
+	DMA_2,
+	DMA_3,
+	DMA_4,
+	DMA_5,
+	DMA_6,
+	DMA_7,
+	FRONTEND_TS0 = 32,
+	FRONTEND_TS1,
+	FRONTEND_TS2,
+	FRONTEND_TS3,
+	FRONTEND_TS4,
+	FRONTEND_TS5,
+	FRONTEND_TS6,
+	FRONTEND_TS7,
+};
+
+/*define filter mem_info type*/
+enum {
+	DMX_VIDEO_TYPE = 0,
+	DMX_AUDIO_TYPE,
+	DMX_SUBTITLE_TYPE,
+	DMX_TELETEXT_TYPE,
+	DMX_SECTION_TYPE,
+};
+
+struct filter_mem_info {
+	__u32 type;
+	__u32 pid;
+	struct dmx_mem_info	filter_info;
+};
+
+struct dmx_filter_mem_info {
+	__u32 filter_num;
+	struct filter_mem_info info[40];
+};
+#endif
+
+#define DMX_START                _IO('o', 41)
+#define DMX_STOP                 _IO('o', 42)
+#define DMX_SET_FILTER           _IOW('o', 43, struct dmx_sct_filter_params)
+#define DMX_SET_PES_FILTER       _IOW('o', 44, struct dmx_pes_filter_params)
+#define DMX_SET_BUFFER_SIZE      _IO('o', 45)
+#define DMX_GET_PES_PIDS         _IOR('o', 47, __u16[5])
+#define DMX_GET_CAPS             _IOR('o', 48, dmx_caps_t)
+#define DMX_SET_SOURCE           _IOW('o', 49, dmx_source_t)
+#define DMX_GET_STC              _IOWR('o', 50, struct dmx_stc)
+#define DMX_ADD_PID              _IOW('o', 51, __u16)
+#define DMX_REMOVE_PID           _IOW('o', 52, __u16)
+#ifdef CONFIG_AMLOGIC_DVB_COMPAT
+#define DMX_SET_INPUT           _IO('o', 80)
+#define DMX_GET_MEM_INFO        _IOR('o', 81, struct dmx_mem_info)
+#define DMX_SET_HW_SOURCE       _IO('o', 82)
+#define DMX_GET_HW_SOURCE       _IOR('o', 83, int)
+#define DMX_GET_FILTER_MEM_INFO _IOR('o', 84, struct dmx_filter_mem_info)
+/*just for dvr sec mem, please call before DMX_SET_PES_FILTER*/
+#define DMX_SET_SEC_MEM			_IOW('o', 85, struct dmx_sec_mem)
+#endif
+
+#endif /* _UAPI_DVBDMX_H_ */
diff --git a/test/am_aucpu_test/linux_dvb.c b/test/am_aucpu_test/linux_dvb.c
new file mode 100644
index 0000000..1808d5c
--- /dev/null
+++ b/test/am_aucpu_test/linux_dvb.c
@@ -0,0 +1,367 @@
+#ifdef _FORTIFY_SOURCE
+#undef _FORTIFY_SOURCE
+#endif
+/***************************************************************************
+ * Copyright (c) 2014 Amlogic, Inc. All rights reserved.
+ *
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ */
+/**\file
+ * \brief Linux DVB demux 驱动
+ *
+ * \author Gong Ke <ke.gong@amlogic.com>
+ * \date 2010-07-21: create the document
+ ***************************************************************************/
+
+#define printf_LEVEL 5
+
+#include "am_mem.h"
+//#include <am_misc.h>
+#include <stdio.h>
+#include "am_dmx_internal.h"
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <poll.h>
+#include <stdlib.h>
+
+/*add for config define for linux dvb *.h*/
+//#include <am_config.h>
+#include "dmx.h"
+
+#define open(a...)\
+	({\
+	 int ret, times=3;\
+	 do {\
+        ret = open(a);\
+        if (ret == -1)\
+        {\
+           usleep(100*1000);\
+        }\
+	}while (ret==-1 && times--);\
+	ret;\
+	})
+
+/****************************************************************************
+ * Type definitions
+ ***************************************************************************/
+
+typedef struct
+{
+	char   dev_name[32];
+	int    fd[DMX_FILTER_COUNT];
+} DVBDmx_t;
+
+/****************************************************************************
+ * Static data definitions
+ ***************************************************************************/
+
+static AM_ErrorCode_t dvb_open(AM_DMX_Device_t *dev, const AM_DMX_OpenPara_t *para);
+static AM_ErrorCode_t dvb_close(AM_DMX_Device_t *dev);
+static AM_ErrorCode_t dvb_alloc_filter(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter);
+static AM_ErrorCode_t dvb_free_filter(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter);
+static AM_ErrorCode_t dvb_set_sec_filter(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter, const struct dmx_sct_filter_params *params);
+static AM_ErrorCode_t dvb_set_pes_filter(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter, const struct dmx_pes_filter_params *params);
+static AM_ErrorCode_t dvb_enable_filter(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter, AM_Bool_t enable);
+static AM_ErrorCode_t dvb_set_buf_size(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter, int size);
+static AM_ErrorCode_t dvb_poll(AM_DMX_Device_t *dev, AM_DMX_FilterMask_t *mask, int timeout);
+static AM_ErrorCode_t dvb_read(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter, uint8_t *buf, int *size);
+static AM_ErrorCode_t dvb_set_source(AM_DMX_Device_t *dev, AM_DMX_Source_t src);
+static AM_ErrorCode_t dvb_get_stc(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter);
+
+const AM_DMX_Driver_t linux_dvb_dmx_drv = {
+.open  = dvb_open,
+.close = dvb_close,
+.alloc_filter = dvb_alloc_filter,
+.free_filter  = dvb_free_filter,
+.set_sec_filter = dvb_set_sec_filter,
+.set_pes_filter = dvb_set_pes_filter,
+.enable_filter  = dvb_enable_filter,
+.set_buf_size   = dvb_set_buf_size,
+.poll           = dvb_poll,
+.read           = dvb_read,
+.set_source     = dvb_set_source,
+.get_stc	= dvb_get_stc
+};
+
+/****************************************************************************
+ * Static functions
+ ***************************************************************************/
+
+#ifdef LINUX
+#define DEMUX_DEVICE "/dev/dvb/adapter0/demux"
+#else
+#define DEMUX_DEVICE "/dev/dvb0.demux"
+#endif
+
+static AM_ErrorCode_t dvb_open(AM_DMX_Device_t *dev, const AM_DMX_OpenPara_t *para)
+{
+	DVBDmx_t *dmx;
+	int i;
+
+	UNUSED(para);
+
+	dmx = (DVBDmx_t*)malloc(sizeof(DVBDmx_t));
+        if (!dmx) {
+                printf("not enough memory");
+                return AM_DMX_ERR_NO_MEM;
+        }
+
+        snprintf(dmx->dev_name, sizeof(dmx->dev_name), DEMUX_DEVICE"%d", dev->dev_no);
+
+	for (i = 0; i < DMX_FILTER_COUNT; i++)
+		dmx->fd[i] = -1;
+
+	dev->drv_data = dmx;
+	return AM_SUCCESS;
+}
+
+static AM_ErrorCode_t dvb_close(AM_DMX_Device_t *dev)
+{
+	DVBDmx_t *dmx = (DVBDmx_t*)dev->drv_data;
+
+	free(dmx);
+	return AM_SUCCESS;
+}
+
+static AM_ErrorCode_t dvb_alloc_filter(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter)
+{
+	DVBDmx_t *dmx = (DVBDmx_t*)dev->drv_data;
+	int fd;
+
+	fd = open(dmx->dev_name, O_RDWR);
+        if (fd == -1) {
+                printf("cannot open \"%s\" (%s)", dmx->dev_name, strerror(errno));
+                return AM_DMX_ERR_CANNOT_OPEN_DEV;
+        }
+
+        dmx->fd[filter->id] = fd;
+
+	filter->drv_data = (void*)(long)fd;
+
+	return AM_SUCCESS;
+}
+
+static AM_ErrorCode_t dvb_free_filter(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter)
+{
+	DVBDmx_t *dmx = (DVBDmx_t*)dev->drv_data;
+	int fd = (long)filter->drv_data;
+
+	close(fd);
+	dmx->fd[filter->id] = -1;
+
+	return AM_SUCCESS;
+}
+AM_ErrorCode_t dvb_get_stc(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter)
+{
+	int fd = (long)filter->drv_data;
+	int ret;
+	struct dmx_stc stc;
+	int i = 0;
+
+	UNUSED(dev);
+
+        for (i = 0; i < 3; i++) {
+                memset(&stc, 0, sizeof(struct dmx_stc));
+                stc.num = i;
+                ret = ioctl(fd, DMX_GET_STC, &stc);
+                if (ret == 0) {
+                        printf("get stc num %d: base:0x%0x, stc:0x%lx\n", stc.num, stc.base, stc.stc);
+                } else {
+                        printf("get stc %d, fail\n", i);
+                }
+        }
+        return 0;
+}
+
+static AM_ErrorCode_t dvb_set_sec_filter(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter, const struct dmx_sct_filter_params *params)
+{
+	struct dmx_sct_filter_params p;
+	int fd = (long)filter->drv_data;
+	int ret;
+
+	UNUSED(dev);
+
+	//2. set input source
+	ret = ioctl(fd, DMX_SET_INPUT, INPUT_LOCAL);
+	if (ret != 0) {
+		printf("set pes filter failed ret = %d\n", ret);
+	}
+
+	//3. set hw source
+	ret = ioctl(fd, DMX_SET_HW_SOURCE, DMA_0);
+	if (ret != 0) {
+		printf("set pes filter failed ret = %d\n", ret);
+	}
+
+	p = *params;
+	ret = ioctl(fd, DMX_SET_FILTER, &p);
+        if (ret == -1) {
+                printf("set section filter failed (%s)", strerror(errno));
+                return AM_DMX_ERR_SYS;
+        }
+
+        return AM_SUCCESS;
+}
+
+static AM_ErrorCode_t dvb_set_pes_filter(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter, const struct dmx_pes_filter_params *params)
+{
+	int fd = (long)filter->drv_data;
+	int ret;
+
+	UNUSED(dev);
+
+	fcntl(fd,F_SETFL,O_NONBLOCK);
+
+	ret = ioctl(fd, DMX_SET_PES_FILTER, params);
+        if (ret == -1) {
+                printf("set section filter failed (%s)", strerror(errno));
+                return AM_DMX_ERR_SYS;
+        }
+        printf("%s success\n", __FUNCTION__);
+	return AM_SUCCESS;
+}
+
+static AM_ErrorCode_t dvb_enable_filter(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter, AM_Bool_t enable)
+{
+	int fd = (long)filter->drv_data;
+	int ret;
+
+	UNUSED(dev);
+
+        if (enable)
+                ret = ioctl(fd, DMX_START, 0);
+        else
+                ret = ioctl(fd, DMX_STOP, 0);
+
+        if (ret == -1) {
+                printf("start filter failed (%s)", strerror(errno));
+                return AM_DMX_ERR_SYS;
+        }
+
+        return AM_SUCCESS;
+}
+
+static AM_ErrorCode_t dvb_set_buf_size(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter, int size)
+{
+	int fd = (long)filter->drv_data;
+	int ret;
+
+	UNUSED(dev);
+
+	ret = ioctl(fd, DMX_SET_BUFFER_SIZE, size);
+        if (ret == -1) {
+                printf("set buffer size failed (%s)", strerror(errno));
+                return AM_DMX_ERR_SYS;
+        }
+
+        return AM_SUCCESS;
+}
+
+static AM_ErrorCode_t dvb_poll(AM_DMX_Device_t *dev, AM_DMX_FilterMask_t *mask, int timeout)
+{
+	DVBDmx_t *dmx = (DVBDmx_t*)dev->drv_data;
+	struct pollfd fds[DMX_FILTER_COUNT];
+	int fids[DMX_FILTER_COUNT];
+	int i, cnt = 0, ret;
+
+        for (i = 0; i < DMX_FILTER_COUNT; i++) {
+                if (dmx->fd[i] != -1) {
+                        fds[cnt].events = POLLIN | POLLERR;
+                        fds[cnt].fd = dmx->fd[i];
+                        fids[cnt] = i;
+                        cnt++;
+                }
+        }
+
+        if (!cnt)
+		return AM_DMX_ERR_TIMEOUT;
+
+        ret = poll(fds, cnt, timeout);
+        if (ret <= 0) {
+                return AM_DMX_ERR_TIMEOUT;
+        }
+
+        for (i = 0; i < cnt; i++) {
+                if (fds[i].revents & (POLLIN | POLLERR)) {
+                        AM_DMX_FILTER_MASK_SET(mask, fids[i]);
+                }
+        }
+
+        return AM_SUCCESS;
+}
+
+static AM_ErrorCode_t dvb_read(AM_DMX_Device_t *dev, AM_DMX_Filter_t *filter, uint8_t *buf, int *size)
+{
+	int fd = (long)filter->drv_data;
+	int len = *size;
+	int ret;
+	struct pollfd pfd;
+
+	UNUSED(dev);
+
+	if (fd == -1)
+		return AM_DMX_ERR_NOT_ALLOCATED;
+
+	pfd.events = POLLIN|POLLERR;
+	pfd.fd     = fd;
+
+	ret = poll(&pfd, 1, 0);
+        if (ret <= 0)
+                return AM_DMX_ERR_NO_DATA;
+
+        ret = read(fd, buf, len);
+        if (ret <= 0) {
+                if (errno == ETIMEDOUT)
+                        return AM_DMX_ERR_TIMEOUT;
+                printf("read demux failed (%s) %d", strerror(errno), errno);
+                return AM_DMX_ERR_SYS;
+        }
+
+        *size = ret;
+	return AM_SUCCESS;
+}
+
+static AM_ErrorCode_t dvb_set_source(AM_DMX_Device_t *dev, AM_DMX_Source_t src)
+{
+	char buf[32];
+	char *cmd;
+
+	snprintf(buf, sizeof(buf), "/sys/class/stb/demux%d_source", dev->dev_no);
+
+        switch (src) {
+        case AM_DMX_SRC_TS0:
+                cmd = "ts0";
+                break;
+        case AM_DMX_SRC_TS1:
+                cmd = "ts1";
+                break;
+#if defined(CHIP_8226M) || defined(CHIP_8626X)
+        case AM_DMX_SRC_TS2:
+                cmd = "ts2";
+                break;
+#endif
+        case AM_DMX_SRC_TS3:
+                cmd = "ts3";
+                break;
+        case AM_DMX_SRC_HIU:
+                cmd = "hiu";
+                break;
+        case AM_DMX_SRC_HIU1:
+                cmd = "hiu1";
+                break;
+        default:
+                printf("do not support demux source %d", src);
+                return AM_DMX_ERR_NOT_SUPPORTED;
+        }
+        return 0;
+        //	return AM_FileEcho(buf, cmd);
+}
diff --git a/test/am_aucpu_test/readme b/test/am_aucpu_test/readme
new file mode 100644
index 0000000..13331ba
--- /dev/null
+++ b/test/am_aucpu_test/readme
@@ -0,0 +1,3 @@
+command:
+am_aucpu_test src=1 dmx=0 pat=0xf m_type=6 bs0=6291456 pall=1 input=/data/birds.ts path=/data/pengcc/
+