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], ¶);
+ }
+ 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(¶m, 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, ¶m));
+ }
+#endif
+
+#ifdef EIT_TEST
+ if (eit & 0xf) {
+ memset(¶m, 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, ¶m));
+
+ memset(¶m, 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, ¶m));
+ }
+#endif
+
+#ifdef NIT_TEST
+ if (nit & 0xF) {
+ memset(¶m, 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, ¶m));
+ }
+#endif
+
+#ifdef BAT_TEST
+ if (bat & 0xF) {
+ memset(¶m, 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, ¶m));
+ }
+#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(¶m, 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], ¶m));
+ }
+
+ 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(¶, 0, sizeof(para));
+ //para.use_sw_filter = AM_TRUE;
+ //para.dvr_fifo_no = 1;
+ AM_TRY(AM_DMX_Open(dmx, ¶));
+
+ 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/
+