├── .gitignore ├── capJPEG ├── README.md ├── capJPEG.h ├── stub.h ├── stub.c ├── Makefile ├── include ├── imp │ ├── imp_utils.h │ ├── imp_ivs_base_move.h │ ├── imp_ivs_move.h │ ├── imp_log.h │ ├── imp_decoder.h │ ├── imp_common.h │ ├── imp_system.h │ ├── imp_ivs.h │ ├── imp_dmic.h │ ├── imp_osd.h │ ├── imp_framesource.h │ ├── imp_encoder.h │ └── imp_audio.h └── sysutils │ ├── su_adc.h │ ├── su_battery.h │ ├── su_cipher.h │ ├── su_misc.h │ └── su_base.h └── capJPEG.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | -------------------------------------------------------------------------------- /capJPEG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/capjpeg/main/capJPEG -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## CAPJPEG 2 | 3 | Quick and dirty libimp (T31 - ingenic) testing for catpure still images using openipc sdk. 4 | -------------------------------------------------------------------------------- /capJPEG.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | 5 | #ifndef __CAPJPEG_H__ 6 | #ifndef __CAPJPEG_H__ 7 | 8 | 9 | 10 | #endif /* __CAPJPEG_H__ */ 11 | -------------------------------------------------------------------------------- /stub.h: -------------------------------------------------------------------------------- 1 | #ifndef __STUB_H__ 2 | #define __STUB_H__ 3 | 4 | #include 5 | #include 6 | 7 | void __ctype_b(void); 8 | void __ctype_tolower(void); 9 | 10 | void __pthread_register_cancel(void); 11 | void __pthread_unregister_cancel(void); 12 | void __assert(void); 13 | int __fgetc_unlocked(FILE *stream); 14 | 15 | void *mmap64(void *start, size_t len, int prot, int flags, int fd, off_t off); 16 | void *mmap(void *start, size_t len, int prot, int flags, int fd, uint32_t off); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /stub.c: -------------------------------------------------------------------------------- 1 | #include "stub.h" 2 | 3 | void __ctype_b(void) {} 4 | void __ctype_tolower(void) {} 5 | 6 | void __pthread_register_cancel(void) {} 7 | void __pthread_unregister_cancel(void) {} 8 | void __assert(void) {} 9 | int __fgetc_unlocked(FILE *stream) { 10 | return fgetc_unlocked(stream); 11 | } 12 | 13 | void *mmap64(void *start, size_t len, int prot, int flags, int fd, off_t off); 14 | void *mmap(void *start, size_t len, int prot, int flags, int fd, uint32_t off) { 15 | return mmap64(start, len, prot, flags, fd, off); 16 | } 17 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CROSS_COMPILE ?= mipsel-openipc-linux-musl- 2 | #CROSS_COMPILE ?= mips-linux-gnu- 3 | #CROSS_COMPILE ?= mips-buildroot-linux-musl- 4 | 5 | 6 | CC = $(CROSS_COMPILE)gcc 7 | CPLUSPLUS = $(CROSS_COMPILE)g++ 8 | LD = $(CROSS_COMPILE)ld 9 | AR = $(CROSS_COMPILE)ar cr 10 | STRIP = $(CROSS_COMPILE)strip 11 | 12 | SYSROOT := $(shell $(CC) --print-sysroot) 13 | TARGET = /home/javier/camera_t31n/firmware/output/target 14 | 15 | EXTRA_LIBS_DIR = $(TARGET)/usr/lib 16 | EXTRA_INC_DIR = $(SYSROOT)/usr/include 17 | 18 | STATIC_LIBS_PATH = -L lib/uclibc 19 | 20 | INCLUDES = -I$(EXTRA_INC_DIR) -I./include 21 | 22 | CFLAGS = $(INCLUDES) -O2 -Wall -g 23 | CFLAGS += -march=mips32r2 24 | 25 | LIBS = -L $(EXTRA_LIBS_DIR) 26 | 27 | LDFLAG += -Wl,-z,now,-gc-sections 28 | 29 | all: capJPEG 30 | 31 | capJPEG: stub.o capJPEG.o 32 | $(CC) $(LDFLAG) $(LIBS) -o $@ $^ -limp -lalog -lpthread -lm -lrt 33 | $(STRIP) $@ 34 | 35 | %.o:%.c stub.h 36 | $(CC) -c $(CFLAGS) $< -o $@ 37 | 38 | test: 39 | @echo $(SYSROOT) 40 | 41 | clean: 42 | rm -f *.o *~ capJPEG capJPEG-static 43 | 44 | distclean: clean 45 | rm -f $(SAMPLES) 46 | -------------------------------------------------------------------------------- /include/imp/imp_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * IMP utils header file. 3 | * 4 | * Copyright (C) 2014 Ingenic Semiconductor Co.,Ltd 5 | */ 6 | 7 | #ifndef __IMP_UTILS_H__ 8 | #define __IMP_UTILS_H__ 9 | 10 | #include "imp_common.h" 11 | 12 | #ifdef __cplusplus 13 | #if __cplusplus 14 | extern "C"{ 15 | #endif 16 | #endif /* __cplusplus */ 17 | 18 | /** 19 | * @file 20 | * IMP utils头文件 21 | */ 22 | 23 | #undef offsetof 24 | #ifdef __compiler_offsetof 25 | #define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER) 26 | #else 27 | #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 28 | #endif 29 | 30 | /** 31 | * container_of - cast a member of a structure out to the containing structure 32 | * Copy from kernel.h 33 | * @ptr: the pointer to the member. 34 | * @type: the type of the container struct this is embedded in. 35 | * @member: the name of the member within the struct. 36 | * 37 | */ 38 | #define container_of(ptr, type, member) ({ \ 39 | const typeof( ((type *)0)->member ) *__mptr = (ptr); \ 40 | (type *)( (char *)__mptr - offsetof(type,member) );}) 41 | 42 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) 43 | 44 | char *IMPPixfmtToString(IMPPixelFormat pixfmt); 45 | 46 | #ifdef __cplusplus 47 | #if __cplusplus 48 | } 49 | #endif 50 | #endif /* __cplusplus */ 51 | 52 | #endif /* __IMP_UTILS_H__ */ 53 | -------------------------------------------------------------------------------- /include/imp/imp_ivs_base_move.h: -------------------------------------------------------------------------------- 1 | /* 2 | * IMP IVS Move func header file. 3 | * 4 | * Copyright (C) 2016 Ingenic Semiconductor Co.,Ltd 5 | */ 6 | 7 | #ifndef __IMP_IVS_BASE_MOVE_H__ 8 | #define __IMP_IVS_BASE_MOVE_H__ 9 | 10 | #ifdef __cplusplus 11 | #if __cplusplus 12 | extern "C" 13 | { 14 | #endif 15 | #endif /* __cplusplus */ 16 | 17 | #define IMP_IVS_MOVE_MAX_ROI_CNT 52 18 | 19 | #include 20 | 21 | /** 22 | * @file 23 | * IMP IVS 移动侦测模块 24 | */ 25 | 26 | /** 27 | * @defgroup MoveDetection 28 | * @ingroup IMP_IVS 29 | * @brief 移动侦测接口 30 | * @{ 31 | */ 32 | 33 | /** 34 | * 基本移动侦测算法的输入结构体 35 | */ 36 | typedef struct { 37 | int skipFrameCnt; /*< 隔帧检测的个数 */ 38 | int referenceNum; /*<指定相对于当前帧的第-referenceNum帧为参考帧*/ 39 | int sadMode; /*< SAD模式,0表示8*8*/ 40 | int sense; /*<灵敏度,0-3,值越大灵敏度越大*/ 41 | IMPFrameInfo frameInfo; /**< 帧尺寸信息,只需要配置width和height */ 42 | 43 | } IMP_IVS_BaseMoveParam; 44 | 45 | /* 46 | * 基本移动侦测算法的输出结构体 47 | */ 48 | typedef struct { 49 | int ret; 50 | uint8_t* data; 51 | int datalen; 52 | int64_t timeStamp; /**< 帧的时间戳 */ 53 | } IMP_IVS_BaseMoveOutput; 54 | 55 | /** 56 | * 创建移动侦测接口资源 57 | * 58 | * @fn IMPIVSInterface *IMP_IVS_CreateBaseMoveInterface(IMP_IVS_BaseMoveParam *param); 59 | * 60 | * @param[in] param 移动侦测算法的输入结构体参数 61 | * 62 | * @retval 非NULL 成功,返回移动侦测算法接口指针句柄 63 | * @retval NULL 失败 64 | * 65 | * @attention 无 66 | */ 67 | IMPIVSInterface *IMP_IVS_CreateBaseMoveInterface(IMP_IVS_BaseMoveParam *param); 68 | 69 | /** 70 | * 销毁移动侦测接口资源 71 | * 72 | * @fn void IMP_IVS_DestroyBaseMoveInterface(IMPIVSInterface *moveInterface); 73 | * 74 | * @param[in] moveInterface 移动侦测算法接口指针句柄 75 | * 76 | * @retval 无返回值 77 | * 78 | * @attention 无 79 | */ 80 | void IMP_IVS_DestroyBaseMoveInterface(IMPIVSInterface *moveInterface); 81 | 82 | 83 | #ifdef __cplusplus 84 | #if __cplusplus 85 | } 86 | #endif 87 | #endif /* __cplusplus */ 88 | #endif /* __IMP_IVS_MOVE_H__ */ 89 | -------------------------------------------------------------------------------- /include/imp/imp_ivs_move.h: -------------------------------------------------------------------------------- 1 | /* 2 | * IMP IVS Move func header file. 3 | * 4 | * Copyright (C) 2016 Ingenic Semiconductor Co.,Ltd 5 | */ 6 | 7 | #ifndef __IMP_IVS_MOVE_H__ 8 | #define __IMP_IVS_MOVE_H__ 9 | 10 | #ifdef __cplusplus 11 | #if __cplusplus 12 | extern "C" 13 | { 14 | #endif 15 | #endif /* __cplusplus */ 16 | 17 | #define IMP_IVS_MOVE_MAX_ROI_CNT 52 18 | 19 | #include 20 | 21 | /** 22 | * @file 23 | * IMP IVS 移动侦测模块 24 | */ 25 | 26 | /** 27 | * @defgroup MoveDetection 28 | * @ingroup IMP_IVS 29 | * @brief 移动侦测接口 30 | * @{ 31 | */ 32 | 33 | /** 34 | * 移动侦测算法的输入结构体 35 | */ 36 | typedef struct { 37 | int sense[IMP_IVS_MOVE_MAX_ROI_CNT]; /**< 移动侦测的灵敏度, 对正常摄像机范围是0-4,对全景摄像机范围是0-8 */ 38 | int skipFrameCnt; /*< 隔帧检测的个数 */ 39 | IMPFrameInfo frameInfo; /**< 帧尺寸信息,只需要配置width和height */ 40 | IMPRect roiRect[IMP_IVS_MOVE_MAX_ROI_CNT]; /*< 需要检测的roi区域坐标信息 */ 41 | int roiRectCnt; /*< 需要检测的roi区域数量,范围为0-51,若为0:则不检测,1:检测roiRect 0 42 | 区域,2、检测roiRect 0,1区域,3、检测roiRect 0,1,2区域,依次类推 */ 43 | } IMP_IVS_MoveParam; 44 | 45 | /* 46 | * 移动侦测算法的输出结构体 47 | */ 48 | typedef struct { 49 | int retRoi[IMP_IVS_MOVE_MAX_ROI_CNT]; /*< 区域检测移动结果,与roiRect坐标信息严格对应,0:表示未检测到运动,1:表示检测到运动 */ 50 | } IMP_IVS_MoveOutput; 51 | 52 | /** 53 | * 创建移动侦测接口资源 54 | * 55 | * @fn IMPIVSInterface *IMP_IVS_CreateMoveInterface(IMP_IVS_MoveParam *param); 56 | * 57 | * @param[in] param 移动侦测算法的输入结构体参数 58 | * 59 | * @retval 非NULL 成功,返回移动侦测算法接口指针句柄 60 | * @retval NULL 失败 61 | * 62 | * @attention 无 63 | */ 64 | IMPIVSInterface *IMP_IVS_CreateMoveInterface(IMP_IVS_MoveParam *param); 65 | 66 | /** 67 | * 销毁移动侦测接口资源 68 | * 69 | * @fn void IMP_IVS_DestroyMoveInterface(IMPIVSInterface *moveInterface); 70 | * 71 | * @param[in] moveInterface 移动侦测算法接口指针句柄 72 | * 73 | * @retval 无返回值 74 | * 75 | * @attention 无 76 | */ 77 | void IMP_IVS_DestroyMoveInterface(IMPIVSInterface *moveInterface); 78 | 79 | /** 80 | * @} 81 | */ 82 | 83 | #ifdef __cplusplus 84 | #if __cplusplus 85 | } 86 | #endif 87 | #endif /* __cplusplus */ 88 | #endif /* __IMP_IVS_MOVE_H__ */ 89 | -------------------------------------------------------------------------------- /include/sysutils/su_adc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SU ADC header file. 3 | * 4 | * Copyright (C) 2015 Ingenic Semiconductor Co.,Ltd 5 | */ 6 | 7 | #ifndef __SU_ADC_H__ 8 | #define __SU_ADC_H__ 9 | 10 | #ifdef __cplusplus 11 | #if __cplusplus 12 | extern "C" 13 | { 14 | #endif 15 | #endif /* __cplusplus */ 16 | 17 | /** 18 | * @file 19 | * ADC模块头文件 20 | */ 21 | 22 | /** 23 | * @defgroup Sysutils_ADC 24 | * @ingroup sysutils 25 | * @brief 模数转化模块 26 | * 27 | * 使用方法请参考Samples 28 | * @{ 29 | */ 30 | 31 | /** 32 | * @fn int SU_ADC_Init(void); 33 | * 34 | * 初始化ADC模块 35 | * 36 | * @retval 0 成功 37 | * @retval 非0 失败,返回错误码 38 | * 39 | * @remark 使用ADC之前,一定要调用这个函数。 40 | * 41 | * @attention 无。 42 | */ 43 | int SU_ADC_Init(void); 44 | 45 | /** 46 | * @fn int SU_ADC_Exit(void); 47 | * 48 | * 去初始化ADC模块 49 | * 50 | * @retval 0 成功 51 | * @retval 非0 失败,返回错误码 52 | * 53 | * @remark 不使用ADC之后,一定要调用这个函数。 54 | * 55 | * @attention 无。 56 | */ 57 | int SU_ADC_Exit(void); 58 | 59 | /** 60 | * @fn int SU_ADC_EnableChn(uint32_t chn_num); 61 | * 62 | * 启动通道 63 | * 64 | * @param[in] chn_num 启动第几路通道 65 | * 66 | * @retval 0 成功 67 | * @retval 非0 失败,返回错误码 68 | * 69 | * @remark 无 70 | * 71 | * @attention 无. 72 | */ 73 | int SU_ADC_EnableChn(uint32_t chn_num); 74 | 75 | /** 76 | * @fn int SU_ADC_DisableChn(uint32_t chn_num); 77 | * 78 | * 关闭通道 79 | * 80 | * @param[in] chn_num 停止第几路通道 81 | * 82 | * @retval 0 成功 83 | * @retval 非0 失败,返回错误码 84 | * 85 | * @remark 无 86 | * 87 | * @attention 无 88 | */ 89 | int SU_ADC_DisableChn(uint32_t chn_num); 90 | 91 | /** 92 | * @fn int SU_ADC_GetChnValue(uint32_t chn_num, int *value); 93 | * 94 | * 得到第chn_num通道的ADC值 95 | * 96 | * @param[in] chn_num 第几路通道 97 | * 98 | * @param[out] value 得到的ADC值 99 | * 100 | * @retval 0 成功 101 | * @retval 非0 失败,返回错误码 102 | * 103 | * @remark 无 104 | * 105 | * @attention 无 106 | */ 107 | int SU_ADC_GetChnValue(uint32_t chn_num, int *value); 108 | 109 | #ifdef __cplusplus 110 | #if __cplusplus 111 | } 112 | #endif 113 | #endif /* __cplusplus */ 114 | 115 | /** 116 | * @} 117 | */ 118 | 119 | #endif /* __SU_ADC_H__ */ 120 | -------------------------------------------------------------------------------- /include/sysutils/su_battery.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Battery utils header file. 3 | * 4 | * Copyright (C) 2014 Ingenic Semiconductor Co.,Ltd 5 | */ 6 | 7 | #ifndef __SU_BATTERY_H__ 8 | #define __SU_BATTERY_H__ 9 | 10 | #ifdef __cplusplus 11 | #if __cplusplus 12 | extern "C" 13 | { 14 | #endif 15 | #endif /* __cplusplus */ 16 | 17 | /** 18 | * @file 19 | * Sysutils 电池管理头文件 20 | */ 21 | 22 | /** 23 | * @defgroup Sysutils_Battery 24 | * @ingroup sysutils 25 | * @brief 电池管理 26 | * @{ 27 | */ 28 | 29 | /** 30 | * 电池状态. 31 | */ 32 | typedef enum { 33 | Unknown = -1, /**< 未知状态或者没有电池*/ 34 | Charging, /**< 充电中 */ 35 | Discharging, /**< 未充电 */ 36 | Full, /**< 充满电 */ 37 | } SUBatStatus; 38 | 39 | /** 40 | * 电池事件. 41 | */ 42 | typedef enum { 43 | AC_ONLINE, /**< AC Adapter插入 */ 44 | AC_OFFLINE, /**< AC Adapter拔出 */ 45 | USB_ONLINE, /**< USB插入 */ 46 | USB_OFFLINE, /**< USB拔出 */ 47 | } SUBatEvent; 48 | 49 | /** 50 | * @fn int SU_Battery_GetStatus(SUBatStatus *status) 51 | * 52 | * 获取电池状态. 53 | * 54 | * @param[in] status 电池状态指针. 55 | * 56 | * @retval 0 成功. 57 | * @retval 非0 失败. 58 | * 59 | * @remarks 该函数直接返回,无阻塞. 60 | * 61 | * @attention 无. 62 | */ 63 | int SU_Battery_GetStatus(SUBatStatus *status); 64 | 65 | /** 66 | * @fn int SU_Battery_GetEvent(SUBatEvent *event) 67 | * 68 | * 获取电池事件. 69 | * 70 | * @param[out] event 电池事件指针. 71 | * 72 | * @retval 0 成功. 73 | * @retval 非0 失败. 74 | * 75 | * @remarks 该函数阻塞,直到有事件发生返回. 76 | * 77 | * @attention 无. 78 | */ 79 | int SU_Battery_GetEvent(SUBatEvent *event); 80 | 81 | /** 82 | * @fn int SU_Battery_GetCapacity(void) 83 | * 84 | * 获取电池电量百分比. 85 | * 86 | * @param 无. 87 | * 88 | * @retval >=0 电池电量百分比. 89 | * @retval 非0 失败. 90 | * 91 | * @remarks 无. 92 | * 93 | * @attention 无. 94 | */ 95 | int SU_Battery_GetCapacity(void); 96 | 97 | /** 98 | * @fn int SU_Battery_GetVoltageUV(void) 99 | * 100 | * 获取电池当前电压. 101 | * 102 | * @param 无. 103 | * 104 | * @retval >=0 电池电压,单位uV. 105 | * @retval 非0 失败. 106 | * 107 | * @remarks 无. 108 | * 109 | * @attention 无. 110 | */ 111 | int SU_Battery_GetVoltageUV(void); 112 | 113 | /** 114 | * @} 115 | */ 116 | 117 | #ifdef __cplusplus 118 | #if __cplusplus 119 | } 120 | #endif 121 | #endif /* __cplusplus */ 122 | 123 | #endif /* __SU_BATTERY_H__ */ 124 | -------------------------------------------------------------------------------- /include/imp/imp_log.h: -------------------------------------------------------------------------------- 1 | /* 2 | * IMP log func header file. 3 | * 4 | * Copyright (C) 2014 Ingenic Semiconductor Co.,Ltd 5 | */ 6 | 7 | #ifndef __IMP_LOG_H__ 8 | #define __IMP_LOG_H__ 9 | 10 | /** 11 | * @file 12 | * Log接口头文件 13 | */ 14 | 15 | #ifdef __cplusplus 16 | #if __cplusplus 17 | extern "C" 18 | { 19 | #endif 20 | #endif /* __cplusplus */ 21 | 22 | /** 23 | * define log level 24 | */ 25 | enum { 26 | IMP_LOG_LEVEL_UNKNOWN, 27 | IMP_LOG_LEVEL_RESERVED, 28 | IMP_LOG_LEVEL_VERBOSE, 29 | IMP_LOG_LEVEL_DEBUG, 30 | IMP_LOG_LEVEL_INFO, 31 | IMP_LOG_LEVEL_WARN, 32 | IMP_LOG_LEVEL_ERROR, 33 | IMP_LOG_LEVEL_FATAL, 34 | IMP_LOG_LEVEL_SILENT 35 | }; 36 | 37 | #define IMP_LOG_LEVEL_DEFAULT IMP_LOG_LEVEL_DEBUG 38 | 39 | /** 40 | * define log out 41 | */ 42 | #define IMP_LOG_OUT_STDOUT 0 43 | #define IMP_LOG_OUT_LOCAL_FILE 1 44 | #define IMP_LOG_OUT_SERVER 2 45 | //#define IMP_LOG_OUT_DEFAULT IMP_LOG_OUT_SERVER 46 | #define IMP_LOG_OUT_DEFAULT IMP_LOG_OUT_STDOUT 47 | 48 | /** 49 | * define log option 50 | */ 51 | #define IMP_LOG_OP_PID_SHIFT 0 52 | #define IMP_LOG_OP_USTIME_SHIFT 1 53 | #define IMP_LOG_OP_MODULE_SHIFT 2 54 | #define IMP_LOG_OP_FILE_SHIFT 3 55 | #define IMP_LOG_OP_FUNC_SHIFT 4 56 | #define IMP_LOG_OP_LINE_SHIFT 5 57 | 58 | 59 | #define IMP_LOG_OP_PID (1< 11 | #include 12 | 13 | #ifdef __cplusplus 14 | #if __cplusplus 15 | extern "C" 16 | { 17 | #endif 18 | #endif /* __cplusplus */ 19 | 20 | /** 21 | * @file 22 | * IMP解码器头文件 23 | */ 24 | 25 | /** 26 | * @defgroup IMP_Decoder 27 | * @ingroup imp 28 | * @brief 视频解码模块,当前只支持JPEG解码 29 | * @{ 30 | */ 31 | 32 | /** 33 | * 定义解码器属性 34 | */ 35 | typedef struct { 36 | IMPPayloadType decType; /**< 解码帧原数据协议类型 */ 37 | uint32_t maxWidth; /**< 解码帧最大的宽度 */ 38 | uint32_t maxHeight; /**< 解码帧最大的高度 */ 39 | IMPPixelFormat pixelFormat; /**< 解码帧目标数据协议类型 */ 40 | uint32_t nrKeepStream; /**< 解码器缓存帧个数 */ 41 | uint32_t frmRateNum; /**< 在一秒钟内的时间单元的数量, 以时间单元为单位。即帧率的分子 */ 42 | uint32_t frmRateDen; /**< 在一帧内的时间单元的数量, 以时间单元为单位。即帧率的分母 */ 43 | } IMPDecoderAttr; 44 | 45 | /** 46 | * 定义解码Channel属性 47 | */ 48 | typedef struct { 49 | IMPDecoderAttr decAttr; /**< 解码器属性 */ 50 | } IMPDecoderCHNAttr; 51 | 52 | /** 53 | * 定义解码帧数据属性 54 | */ 55 | typedef struct { 56 | int i_payload; /**< 解码帧的数据长度 */ 57 | uint8_t *p_payload; /**< 解码帧的数据指针 */ 58 | int64_t timeStamp; /**< 解码帧的时间戳 */ 59 | } IMPDecoderNal; 60 | 61 | /** 62 | * 定义解码器码流属性 63 | */ 64 | typedef struct { 65 | IMPDecoderNal decoderNal; /**< 解码帧数据结构体 */ 66 | } IMPDecoderStream; 67 | 68 | /** 69 | * @fn int IMP_Decoder_CreateChn(int decChn, const IMPDecoderCHNAttr *attr) 70 | * 71 | * 创建解码Channel 72 | * 73 | * @param[in] decChn 解码Channel号,取值范围: [0, @ref NR_MAX_DEC_CHN - 1] 74 | * @param[in] attr 解码Channel属性指针 75 | * 76 | * @retval 0 成功 77 | * @retval 非0 失败 78 | * 79 | * @remarks 无。 80 | * @attention 无。 81 | */ 82 | int IMP_Decoder_CreateChn(int decChn, const IMPDecoderCHNAttr *attr); 83 | 84 | /** 85 | * @fn int IMP_Decoder_DestroyChn(int decChn) 86 | * 87 | * 销毁解码Channel 88 | * 89 | * @param[in] decChn 解码Channel号,取值范围: [0, @ref NR_MAX_DEC_CHN - 1] 90 | * 91 | * @retval 0 成功 92 | * @retval 非0 失败 93 | * 94 | * @remarks 无。 95 | * @attention 无。 96 | */ 97 | int IMP_Decoder_DestroyChn(int decChn); 98 | 99 | /** 100 | * @fn int IMP_Decoder_StartRecvPic(int decChn) 101 | * 102 | * 开启解码Channel接收图像 103 | * 104 | * @param[in] decChn 解码Channel号,取值范围: [0, @ref NR_MAX_DEC_CHN - 1] 105 | * 106 | * @retval 0 成功 107 | * @retval 非0 失败 108 | * 109 | * @remarks 开启解码Channel接收图像后才能开始解码 110 | * 111 | * @attention 如果Channel未创建,则返回失败 112 | */ 113 | int IMP_Decoder_StartRecvPic(int decChn); 114 | 115 | /** 116 | * @fn int IMP_Decoder_StopRecvPic(int decChn) 117 | * 118 | * 停止解码Channel接收图像 119 | * 120 | * @param[in] decChn 解码Channel号,取值范围: [0, @ref NR_MAX_DEC_CHN - 1] 121 | * 122 | * @retval 0 成功 123 | * @retval 非0 失败 124 | * 125 | * @remarks 停止解码Channel接收图像 126 | * 127 | * @attention 如果Channel未创建,则返回失败 128 | */ 129 | int IMP_Decoder_StopRecvPic(int decChn); 130 | 131 | /** 132 | * @fn int IMP_Decoder_SendStreamTimeout(int decChn, IMPDecoderStream *stream, uint32_t timeoutMsec) 133 | * 134 | * 发送需解码数据 135 | * 136 | * @param[in] decChn 解码Channel号,取值范围: [0, @ref NR_MAX_DEC_CHN - 1] 137 | * @param[in] stream 需解码的数据流结构体指针 138 | * @param[in] timeoutMsec 解码超时时间 单位ms 139 | * 140 | * @retval 0 成功 141 | * @retval 非0 失败 142 | * 143 | * @remarks 无。 144 | * 145 | * @attention 如果Channel未创建,则返回失败 146 | */ 147 | int IMP_Decoder_SendStreamTimeout(int decChn, IMPDecoderStream *stream, uint32_t timeoutMsec); 148 | 149 | /** 150 | * @fn int IMP_Decoder_PollingFrame(int decChn, uint32_t timeoutMsec) 151 | * 152 | * Polling 解码码流缓存 153 | * 154 | * @param[in] decChn 解码Channel号,取值范围: [0, @ref NR_MAX_DEC_CHN - 1] 155 | * @param[in] timeoutMsec 超时时间 单位ms 156 | * 157 | * @retval 0 成功 158 | * @retval 非0 失败 159 | * 160 | * @remarks 无。 161 | * 162 | * @attention 如果Channel未创建,则返回失败 163 | */ 164 | int IMP_Decoder_PollingFrame(int decChn, uint32_t timeoutMsec); 165 | 166 | /** 167 | * @fn int IMP_Decoder_GetFrame(int decChn, IMPFrameInfo **frame) 168 | * 169 | * 获取解码码流 170 | * 171 | * @param[in] decChn 解码Channel号,取值范围: [0, @ref NR_MAX_DEC_CHN - 1] 172 | * @param[out] frame 解码码流结构体指针 173 | * 174 | * @retval 0 成功 175 | * @retval 非0 失败 176 | * 177 | * @remarks 无。 178 | * 179 | * @attention 解码码流buffer由解码器内部申请,该函数只需要传入结构体指针即可。 180 | */ 181 | int IMP_Decoder_GetFrame(int decChn, IMPFrameInfo **frame); 182 | 183 | /** 184 | * @fn int IMP_Decoder_ReleaseFrame(int decChn, IMPFrameInfo *frame) 185 | * 186 | * 释放码流缓存 187 | * 188 | * @param[in] decChn 解码Channel号,取值范围: [0, @ref NR_MAX_DEC_CHN - 1] 189 | * @param[in] frame 解码码流结构体指针 190 | * 191 | * @retval 0 成功 192 | * @retval 非0 失败 193 | * 194 | * @remarks 无。 195 | * 196 | * @attention 无。 197 | */ 198 | int IMP_Decoder_ReleaseFrame(int decChn, IMPFrameInfo *frame); 199 | 200 | /** 201 | * @} 202 | */ 203 | 204 | #ifdef __cplusplus 205 | #if __cplusplus 206 | } 207 | #endif 208 | #endif /* __cplusplus */ 209 | 210 | #endif /* __IMP_DECODER_H__ */ 211 | -------------------------------------------------------------------------------- /include/sysutils/su_cipher.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Cipher utils header file. 3 | * 4 | * Copyright (C) 2014 Ingenic Semiconductor Co.,Ltd 5 | */ 6 | 7 | #ifndef __SU_CIPHER_H__ 8 | #define __SU_CIPHER_H__ 9 | 10 | #ifdef __cplusplus 11 | #if __cplusplus 12 | extern "C" 13 | { 14 | #endif 15 | #endif /* __cplusplus */ 16 | 17 | /** 18 | * @file 19 | * Sysutils 加解密管理头文件 20 | */ 21 | 22 | /** 23 | * @defgroup Sysutils_Cipher 24 | * @ingroup sysutils 25 | * @brief 加解密管理 26 | * @{ 27 | */ 28 | 29 | /** 30 | * 选择加密算法. 31 | * @remarks 支持AES和DES两种加密算法. 32 | */ 33 | typedef enum IN_UNF_CIPHER_ALG_E 34 | { 35 | IN_UNF_CIPHER_ALG_AES = 0x0, 36 | IN_UNF_CIPHER_ALG_DES = 0x1 37 | } IN_UNF_CIPHER_ALG; 38 | 39 | /** 40 | * 选择加密模式. 41 | * @remarks 支持CBC和ECB两种加密模式. 42 | */ 43 | typedef enum IN_UNF_CIPHER_WORK_MODE_E 44 | { 45 | IN_UNF_CIPHER_WORK_MODE_ECB = 0x0, 46 | IN_UNF_CIPHER_WORK_MODE_CBC = 0x1, 47 | IN_UNF_CIPHER_WORK_MODE_OTHER = 0x2 48 | } IN_UNF_CIPHER_WORK_MODE; 49 | 50 | /** 51 | * 选择加密使用的密钥长度. 52 | * @remarks 受硬件的限制,现阶段只支持128bit长度的KEY. 53 | */ 54 | typedef enum IN_UNF_CIPHER_KEY_LENGTH_E 55 | { 56 | IN_UNF_CIPHER_KEY_AES_128BIT = 0x0, 57 | } IN_UNF_CIPHER_KEY_LENGTH; 58 | 59 | /** 60 | * 选择加密算法一次处理的数据长度. 61 | * @remarks 受硬件的限制,现阶段只支持一次处理128bit长度的数据. 62 | */ 63 | typedef enum IN_UNF_CIPHER_BIT_WIDTH_E 64 | { 65 | IN_UNF_CIPHER_BIT_WIDTH_128BIT = 0x0, 66 | } IN_UNF_CIPHER_BIT_WIDTH; 67 | 68 | /** 69 | * 选择加密处理控制结构体. 70 | */ 71 | typedef struct IN_UNF_CIPHER_CTRL_S 72 | { 73 | unsigned int key[4]; /**< 加密时使用的密钥 */ 74 | unsigned int IV[4]; /**< 加密时使用的IV向量 */ 75 | unsigned int enDataLen; /**< 需要处理的数据总长度*/ 76 | IN_UNF_CIPHER_ALG enAlg; /**< 处理数据使用的加密算法*/ 77 | IN_UNF_CIPHER_BIT_WIDTH enBitWidth; /**< 加密算法一次处理的数据长度*/ 78 | IN_UNF_CIPHER_WORK_MODE enWorkMode; /**< 处理数据使用的加密算法的模式*/ 79 | IN_UNF_CIPHER_KEY_LENGTH enKeyLen; /**< 加密算法使用的KEY的长度*/ 80 | } IN_UNF_CIPHER_CTRL; 81 | 82 | /** 83 | * @fn int SU_CIPHER_Init(void) 84 | * 85 | * 加密模块打开接口. 86 | * 87 | * @param 无. 88 | * 89 | * @retval 0 成功. 90 | * @retval 非0 失败. 91 | * 92 | * @remarks 无. 93 | * 94 | * @attention 无. 95 | */ 96 | int SU_CIPHER_Init(void); 97 | 98 | /** 99 | * @fn int SU_CIPHER_DES_Init(void) 100 | * 101 | * DES模块打开接口. 102 | * 103 | * @param 无. 104 | * 105 | * @retval 0 成功. 106 | * @retval 非0 失败. 107 | * 108 | * @remarks 无. 109 | * 110 | * @attention 无. 111 | */ 112 | int SU_CIPHER_DES_Init(void); 113 | 114 | /** 115 | * @fn int SU_CIPHER_Exit(void) 116 | * 117 | * 加密模块关闭接口. 118 | * 119 | * @param 无. 120 | * 121 | * @retval 0 成功. 122 | * @retval 非0 失败. 123 | * 124 | * @remarks 无. 125 | * 126 | * @attention 无. 127 | */ 128 | int SU_CIPHER_Exit(void); 129 | 130 | /** 131 | * @fn int SU_CIPHER_DES_Exit(void) 132 | * 133 | * DES模块关闭接口. 134 | * 135 | * @param 无. 136 | * 137 | * @retval 0 成功. 138 | * @retval 非0 失败. 139 | * 140 | * @remarks 无. 141 | * 142 | * @attention 无. 143 | */ 144 | int SU_CIPHER_DES_Exit(void); 145 | 146 | /** 147 | * @fn int SU_CIPHER_DES_Test(void) 148 | * 149 | * 调用DES模块接口测试. 150 | * 151 | * @param None. 152 | * 153 | * @retval 0 Success. 154 | * @retval Non-0 Failure. 155 | * 156 | * @remarks None. 157 | * 158 | * @attention None. 159 | */ 160 | int SU_CIPHER_DES_Test(void); 161 | 162 | /** 163 | * @fn int SU_CIPHER_CreateHandle(void) 164 | * 165 | * 获得加密模块句柄接口. 166 | * 167 | * @param 无. 168 | * 169 | * @retval 成功: 返回句柄. 170 | * @retval 失败: retval < 0. 171 | * 172 | * @remarks 无. 173 | * 174 | * @attention 该函数可以多次调用,每调用一次都会返回一个句柄. 175 | * 当调用的N次该函数之后,需要调用N次SU_CIPHER_DestroyHandle()才可以 176 | * 将所有的句柄销毁. 177 | * 178 | */ 179 | int SU_CIPHER_CreateHandle(void); 180 | 181 | /** 182 | * @fn int SU_CIPHER_DestroyHandle(int fd) 183 | * 184 | * 销毁加密模块句柄. 185 | * 186 | * @param[in] fd 需要销毁的句柄 187 | * 188 | * @retval 0 成功. 189 | * @retval 非0 失败. 190 | * 191 | * @remarks 无. 192 | * 193 | * @attention 该函数可以多次调用,每调用一次都会销毁一个句柄. 194 | * 195 | */ 196 | int SU_CIPHER_DestroyHandle(int fd); 197 | 198 | /** 199 | * @fn int SU_CIPHER_ConfigHandle(int hCipher, IN_UNF_CIPHER_CTRL* Ctrl) 200 | * 201 | * 对加密模块进行配置. 202 | * 203 | * @param[in] hCipher 需要进行配置的句柄. 204 | * @param[in] Ctrl 带有配置信息的结构体. 205 | * 206 | * @retval 0 成功. 207 | * @retval 非0 失败. 208 | * 209 | * @remarks 无. 210 | * 211 | * @attention 无. 212 | * 213 | */ 214 | int SU_CIPHER_ConfigHandle(int hCipher, IN_UNF_CIPHER_CTRL* Ctrl); 215 | 216 | /** 217 | * @fn int SU_CIPHER_Encrypt(int hCipher, unsigned int * srcAddr, unsigned int * dstAddr, unsigned int dataLen) 218 | * 219 | * 开始进行数据的加密. 220 | * 221 | * @param[in] hCipher 需要进行操作的句柄. 222 | * @param[in] srcAddr 需要进行加密的数据源地址. 223 | * @param[in] dstAddr 加密完成之后的数据存放地址. 224 | * @param[in] dataLen 需要处理的数据长度. 225 | * 226 | * @retval 0 成功. 227 | * @retval 非0 失败. 228 | * 229 | * @remarks 无. 230 | * 231 | * @attention 加密的数据长度dataLen最大不要超过1Mbyte (1024*1024). 232 | * 233 | */ 234 | int SU_CIPHER_Encrypt(int hCipher, unsigned int * srcAddr, unsigned int * dstAddr, unsigned int dataLen); 235 | 236 | /** 237 | * @fn int SU_CIPHER_Decrypt(int hCipher, unsigned int * srcAddr, unsigned int * dstAddr, unsigned int dataLen); 238 | * 239 | * 开始进行数据的解密. 240 | * 241 | * @param[in] hCipher 需要进行操作的句柄. 242 | * @param[in] srcAddr 需要进行解密的数据源地址. 243 | * @param[in] dstAddr 解密完成之后的数据存放地址. 244 | * @param[in] dataLen 需要处理的数据长度. 245 | * 246 | * @retval 0 成功. 247 | * @retval 非0 失败. 248 | * 249 | * @remarks 无. 250 | * 251 | * @attention 解密的数据长度dataLen最大不要超过1Mbyte (1024*1024). 252 | * 253 | */ 254 | int SU_CIPHER_Decrypt(int hCipher, unsigned int * srcAddr, unsigned int * dstAddr, unsigned int dataLen); 255 | 256 | /** 257 | * 错误码. 258 | */ 259 | #define REINIT -10 /**< 重复初始化 */ 260 | #define INIT_FAILED -11 /**< 初始化失败*/ 261 | #define FAILED_GETHANDLE -12 /**< 获取句柄失败*/ 262 | #define INVALID_PARA -13 /**< 无效的参数*/ 263 | #define SET_PARA_FAILED -14 /**< 设置参数失败*/ 264 | #define FAILURE -15 /**< 操作失败*/ 265 | #define SET_DATALEN_ERR -16 /**< 设置操作数据长度错误*/ 266 | #define EXIT_ERR -17 /**< 模块退出失败*/ 267 | #define UNINIT -18 /**< 模块未初始化*/ 268 | #define FAILED_DESHANDLE -19 /**< 销毁句柄失败*/ 269 | 270 | /** 271 | * @} 272 | */ 273 | #ifdef __cplusplus 274 | #if __cplusplus 275 | } 276 | #endif 277 | #endif /* __cplusplus */ 278 | 279 | #endif /* __SU_CIPHER_H__ */ 280 | -------------------------------------------------------------------------------- /include/sysutils/su_misc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Misc utils header file. 3 | * 4 | * Copyright (C) 2014 Ingenic Semiconductor Co.,Ltd 5 | */ 6 | 7 | #ifndef __SU_MISC_H__ 8 | #define __SU_MISC_H__ 9 | 10 | #ifdef __cplusplus 11 | #if __cplusplus 12 | extern "C" 13 | { 14 | #endif 15 | #endif /* __cplusplus */ 16 | 17 | /** 18 | * @file 19 | * Sysutils 其他功能头文件 20 | */ 21 | 22 | /** 23 | * @defgroup Sysutils_Misc 24 | * @ingroup sysutils 25 | * @brief 其他功能. 26 | * @{ 27 | */ 28 | 29 | /** 30 | * 按键事件. 31 | */ 32 | typedef enum { 33 | KEY_RELEASED, /**< 按键抬起 */ 34 | KEY_PRESSED, /**< 按键按下 */ 35 | } SUKeyEvent; 36 | 37 | /** 38 | * LED行为命令. 39 | */ 40 | typedef enum { 41 | LED_OFF, /**< LED关闭 */ 42 | LED_ON, /**< LED打开 */ 43 | } SULedCmd; 44 | 45 | /** 46 | * @fn int SU_Key_OpenEvent(void) 47 | * 48 | * 获得按键事件句柄. 49 | * 50 | * @param 无 51 | * 52 | * @retval >0 按键事件句柄. 53 | * @retval <=0 失败. 54 | * 55 | * @remarks 在成功获得一个按键事件句柄之后,即开始“记录”按键事件,直到关闭这个按键事件。 56 | * @remarks 若打开多个句柄,则每个按键事件会记录一份按键事件。 57 | * @remarks 例如,两个线程分别打开了一个按键事件,每个线程持有一个句柄,则这两个线程会读取到相同的事件序列。 58 | * 但是如果两个线程共享同一个句柄,则每个按键事件只能被读取到一次。 59 | * 60 | * @attention 无。 61 | */ 62 | int SU_Key_OpenEvent(void); 63 | 64 | /** 65 | * @fn int SU_Key_CloseEvent(int evfd) 66 | * 67 | * 关闭按键事件. 68 | * 69 | * @param[in] evfd 按键事件句柄 70 | * 71 | * @retval 0 成功. 72 | * @retval 非0 失败. 73 | * 74 | * @remarks 无 75 | * 76 | * @attention 无。 77 | */ 78 | int SU_Key_CloseEvent(int evfd); 79 | 80 | /** 81 | * @fn int SU_Key_ReadEvent(int evfd, int *keyCode, SUKeyEvent *event) 82 | * 83 | * 读取按键事件. 84 | * 85 | * @param[in] evfd 按键事件句柄 86 | * @param[in] keyCode 按键码 87 | * @param[out] event 按键事件指针. 88 | * 89 | * @retval 0 成功. 90 | * @retval 非0 失败. 91 | * 92 | * @remarks 该函数阻塞,直到有按键事件发生返回. 93 | * @remarks 按键码的定义在linux/input.h中,与GPIO的映射关系定义在kernel板级文件中。 94 | * @remarks 例如几个常用的按键: 95 | * @code 96 | #define KEY_HOME 102 //HOME键 97 | #define KEY_POWER 116 //开关机键,一般也可用来作为唤醒键 98 | #define KEY_WAKEUP 143 //唤醒键,除POWER键之外用来唤醒系统的按键 99 | #define KEY_F13 183 //当PIR作为按键使用时被定义为F13键 100 | * @endcode 101 | * 102 | * @remarks 按键键码与GPIO号的定义,是否作为唤醒源,有效电平等信息均定义在内核板级文件中,如下所示: 103 | * 104 | * @code 105 | struct gpio_keys_button __attribute__((weak)) board_buttons[] = { 106 | #ifdef GPIO_HOME 107 | { 108 | .gpio = GPIO_HOME, //定义GPIO号 109 | .code = KEY_HOME, //定义按键码 110 | .desc = "home key", 111 | .active_low = ACTIVE_LOW_HOME, //定义有效电平 112 | #ifdef WAKEUP_HOME 113 | .wakeup = WAKEUP_HOME, //定义是否可做为唤醒源,1为可唤醒suspend 114 | #endif 115 | #ifdef CAN_DISABLE_HOME 116 | .can_disable = CAN_DISABLE_HOME, //定义是否可以被Disable 117 | #endif 118 | }, 119 | #endif 120 | #ifdef GPIO_POWER 121 | { 122 | .gpio = GPIO_POWER, 123 | .code = KEY_POWER, 124 | .desc = "power key", 125 | .active_low = ACTIVE_LOW_POWER, 126 | #ifdef WAKEUP_POWER 127 | .wakeup = WAKEUP_POWER, 128 | #endif 129 | #ifdef CAN_DISABLE_POWER 130 | .can_disable = CAN_DISABLE_POWER, 131 | #endif 132 | }, 133 | #endif 134 | } 135 | * @endcode 136 | * @remarks 对于数字PIR,一种使用方式是把PIR作为一个按键定义,PIR触发相当于按键按下事件(@ref KEY_PRESSED), 137 | * PIR恢复相当于按键抬起事件(@ref KEY_RELEASED)。若需要PIR唤醒功能,则把PIR对应的按键定义为唤醒源即可。 138 | * @remarks API详细使用方法请参考sample-keyevent.c. 139 | * 140 | * @attention 无。 141 | */ 142 | int SU_Key_ReadEvent(int evfd, int *keyCode, SUKeyEvent *event); 143 | 144 | /** 145 | * @fn int SU_Key_DisableEvent(int keyCode) 146 | * 147 | * Disable按键事件. 148 | * 149 | * @param[in] keyCode 按键码 150 | * 151 | * @retval 0 成功. 152 | * @retval 非0 失败. 153 | * 154 | * @remarks 如果按键被配置为唤醒源,那么在系统suspend时,(无论该按键是否被Open)按下按键会使系统唤醒。 155 | * 在Disable按键事件后,系统会关闭按键事件的中断,该按键也就无法唤醒系统 156 | * @remarks 该API可用来Disable PIR"按键"唤醒系统。 157 | * 158 | * @attention 无。 159 | */ 160 | int SU_Key_DisableEvent(int keyCode); 161 | 162 | /** 163 | * @fn int SU_Key_EnableEvent(int keyCode) 164 | * 165 | * Enable按键事件. 166 | * 167 | * @param[in] keyCode 按键码 168 | * 169 | * @retval 0 成功. 170 | * @retval 非0 失败. 171 | * 172 | * @remarks 作为Disable按键事件的反过程。详见@ref SU_Key_DisableEvent(int keyCode) 173 | * 174 | * @attention 无。 175 | */ 176 | int SU_Key_EnableEvent(int keyCode); 177 | 178 | /** 179 | * @fn int SU_LED_Command(int ledNum, SULedCmd cmd) 180 | * 181 | * 发送LED命令. 182 | * 183 | * @param[in] ledNum LED号. 184 | * @param[in] cmd LED行为命令. 185 | * 186 | * @retval 0 成功. 187 | * @retval 非0 失败. 188 | * 189 | * @remarks LED号根据开发板的不同而不同。LED号定义在内核板级文件中,注册为Linux标 190 | * 准Fixed Regulator设备。在板级文件中需定义LED的GPIO号,有效电平,电源递归关系等 191 | * 信息。下面是定义了两个LED fixed regulator的例子: 192 | * @code 193 | FIXED_REGULATOR_DEF( //定义fixed regulator 194 | led0, 195 | "LED0", 3300000, GPIO_PA(14), 196 | HIGH_ENABLE, UN_AT_BOOT, 0, 197 | "ldo7", "vled0", NULL); 198 | 199 | FIXED_REGULATOR_DEF( 200 | led1, 201 | "LED1", 3300000, GPIO_PA(15), 202 | HIGH_ENABLE, UN_AT_BOOT, 0, 203 | "ldo7", "vled1", NULL); 204 | 205 | static struct platform_device *fixed_regulator_devices[] __initdata = { 206 | &gsensor_regulator_device, 207 | &led0_regulator_device, 208 | &led1_regulator_device, 209 | }; 210 | 211 | static int __init fix_regulator_init(void) //在subsys_initcall_sync中注册regulator 212 | { 213 | int i; 214 | 215 | for (i = 0; i < ARRAY_SIZE(fixed_regulator_devices); i++) 216 | fixed_regulator_devices[i]->id = i; 217 | 218 | return platform_add_devices(fixed_regulator_devices, 219 | ARRAY_SIZE(fixed_regulator_devices)); 220 | } 221 | subsys_initcall_sync(fix_regulator_init); 222 | * @endcode 223 | * @remarks 此API的使用示例: 224 | * @code 225 | if (SU_LED_Command(0, LED_ON) < 0) //使能LED0 226 | printf("LED0 turn on error\n"); 227 | if (SU_LED_Command(1, LED_ON) < 0) //使能LED1 228 | printf("LED0 turn on error\n"); 229 | if (SU_LED_Command(0, LED_OFF) < 0) //关闭LED0 230 | printf("LED1 turn off error\n"); 231 | if (SU_LED_Command(1, LED_OFF) < 0) //关闭LED1 232 | printf("LED1 turn off error\n"); 233 | * @endcode 234 | * @attention 无。 235 | */ 236 | int SU_LED_Command(int ledNum, SULedCmd cmd); 237 | 238 | #ifdef __cplusplus 239 | #if __cplusplus 240 | } 241 | #endif 242 | #endif /* __cplusplus */ 243 | 244 | #endif /* __SU_MISC_H__ */ 245 | -------------------------------------------------------------------------------- /include/sysutils/su_base.h: -------------------------------------------------------------------------------- 1 | /* 2 | * System utils header file. 3 | * 4 | * Copyright (C) 2014 Ingenic Semiconductor Co.,Ltd 5 | */ 6 | 7 | #ifndef __SU_BASE_H__ 8 | #define __SU_BASE_H__ 9 | 10 | #include 11 | 12 | #ifdef __cplusplus 13 | #if __cplusplus 14 | extern "C" 15 | { 16 | #endif 17 | #endif /* __cplusplus */ 18 | 19 | /** 20 | * @file 21 | * Sysutils 基础功能头文件 22 | */ 23 | 24 | /** 25 | * @defgroup sysutils System Utils 26 | */ 27 | 28 | /** 29 | * @defgroup Sysutils_Base 30 | * @ingroup sysutils 31 | * @brief 系统基础功能. 32 | * @{ 33 | */ 34 | 35 | /** 36 | * 设备ID逻辑编码 37 | */ 38 | #define DEVICE_ID_MAGIC "53ef" 39 | 40 | /** 41 | * 设备ID逻辑编码长度 42 | */ 43 | #define DEVICE_ID_MAGIC_LEN 4 44 | 45 | /** 46 | * 设备ID长度 47 | */ 48 | #define DEVICE_ID_LEN 32 49 | 50 | /** 51 | * 设备型号\设备ID\固件版本信息的最大长度 52 | */ 53 | #define MAX_INFO_LEN 64 54 | 55 | /** 56 | * 设备型号. 57 | */ 58 | typedef struct { 59 | char chr[MAX_INFO_LEN]; /**< 设备型号字符串 */ 60 | } SUModelNum; 61 | 62 | /** 63 | * 设备软件版本. 64 | */ 65 | typedef struct { 66 | char chr[MAX_INFO_LEN]; /**< 设备软件版本字符串 */ 67 | } SUVersion; 68 | 69 | /** 70 | * 设备ID.设备ID为唯一值,不同的CPU芯片间的值有差异 71 | */ 72 | typedef union { 73 | char chr[MAX_INFO_LEN]; /**< 设备ID字符串 */ 74 | uint8_t hex[MAX_INFO_LEN]; /**< 设备ID二进制 */ 75 | } SUDevID; 76 | 77 | /** 78 | * 系统时间结构体. 79 | */ 80 | typedef struct { 81 | int sec; /**< 秒数,范围:0~59 */ 82 | int min; /**< 分钟数,范围:0~59 */ 83 | int hour; /**< 小时数,范围:0~23 */ 84 | int mday; /**< 一个月中的第几天,范围:1~31 */ 85 | int mon; /**< 月份,范围:1~12 */ 86 | int year; /**< 年份,范围:>1900 */ 87 | } SUTime; 88 | 89 | /** 90 | * @fn int SU_Base_GetModelNumber(SUModelNum *modelNum) 91 | * 92 | * 获取设备型号. 93 | * 94 | * @param[out] modelNum 设备型号结构体指针. 95 | * 96 | * @retval 0 成功. 97 | * @retval 非0 失败. 98 | * 99 | * @remarks 无. 100 | * 101 | * @attention 无. 102 | */ 103 | int SU_Base_GetModelNumber(SUModelNum *modelNum); 104 | 105 | /** 106 | * @fn int SU_Base_GetVersion(SUVersion *version) 107 | * 108 | * 获取设备版本. 109 | * 110 | * @param[out] version 设备版本结构体指针. 111 | * 112 | * @retval 0 成功. 113 | * @retval 非0 失败. 114 | * 115 | * @remarks 无. 116 | * 117 | * @attention 无. 118 | */ 119 | int SU_Base_GetVersion(SUVersion *version); 120 | 121 | /** 122 | * @fn int SU_Base_GetDevID(SUDevID *devID) 123 | * 124 | * 获取设备ID. 125 | * 126 | * @param[out] devID 设备ID结构体指针. 127 | * 128 | * @retval 0 成功. 129 | * @retval 非0 失败. 130 | * 131 | * @remarks 每颗CPU芯片的设备ID是唯一的. 132 | * 133 | * @attention 无. 134 | */ 135 | int SU_Base_GetDevID(SUDevID *devID); 136 | 137 | /** 138 | * @fn int SU_Base_GetTime(SUTime *time) 139 | * 140 | * 获得系统时间. 141 | * 142 | * @param[in] time 系统时间结构体指针. 143 | * 144 | * @retval 0 成功. 145 | * @retval 非0 失败. 146 | * 147 | * @remarks 无. 148 | * 149 | * @attention 无. 150 | */ 151 | int SU_Base_GetTime(SUTime *time); 152 | 153 | /** 154 | * @fn int SU_Base_SetTime(SUTime *time) 155 | * 156 | * 设置系统时间. 157 | * 158 | * @param[out] time 系统时间结构体指针. 159 | * 160 | * @retval 0 成功. 161 | * @retval 非0 失败. 162 | * 163 | * @remarks 无. 164 | * 165 | * @attention 系统时间参数需在合理范围,否则函数调用失败. 166 | */ 167 | int SU_Base_SetTime(SUTime *time); 168 | 169 | /** 170 | * @fn int SU_Base_SUTime2Raw(SUTime *suTime, uint32_t *rawTime) 171 | * 172 | * 将SUTime类型的时间转换为以秒为单位的Raw时间. 173 | * 174 | * @param[in] suTime 系统时间结构体指针. 175 | * @param[out] rawTime Raw时间(从1970-01-01 00:00:00开始算起). 176 | * 177 | * @retval 0 成功. 178 | * @retval 非0 失败. 179 | * 180 | * @remarks 此函数可以用在设置相对秒数的Alarm. 181 | * 182 | * @attention 无. 183 | */ 184 | int SU_Base_SUTime2Raw(SUTime *suTime, uint32_t *rawTime); 185 | 186 | /** 187 | * @fn int SU_Base_Raw2SUTime(uint32_t *rawTime, SUTime *suTime) 188 | * 189 | * 将以秒为单位的Raw时间转换为SUTime类型的时间. 190 | * 191 | * @param[in] rawTime Raw时间(从1970-01-01 00:00:00开始算起). 192 | * @param[out] suTime 系统时间结构体指针. 193 | * 194 | * @retval 0 成功. 195 | * @retval 非0 失败. 196 | * 197 | * @remarks 此函数可以用在设置相对秒数的Alarm. 198 | * 199 | * @attention 无. 200 | */ 201 | int SU_Base_Raw2SUTime(uint32_t *rawTime, SUTime *suTime); 202 | 203 | /** 204 | * @fn int SU_Base_SetAlarm(SUTime *time) 205 | * 206 | * 设定闹钟时间. 207 | * 208 | * @param[in] time 系统时间结构体指针. 209 | * 210 | * @retval 0 成功. 211 | * @retval 非0 失败. 212 | * 213 | * @remarks 暂支持24小时内的闹钟设定. 214 | * 215 | * @attention 系统时间参数需在合理范围,否则函数调用失败. 216 | */ 217 | int SU_Base_SetAlarm(SUTime *time); 218 | 219 | /** 220 | * @fn int SU_Base_GetAlarm(SUTime *time) 221 | * 222 | * 获得闹钟定时时间. 223 | * 224 | * @param[out] time 系统时间结构体指针. 225 | * 226 | * @retval 0 成功. 227 | * @retval 非0 失败. 228 | * 229 | * @remarks 无. 230 | * 231 | * @attention 无. 232 | */ 233 | int SU_Base_GetAlarm(SUTime *time); 234 | 235 | /** 236 | * @fn int SU_Base_EnableAlarm() 237 | * 238 | * 使能闹钟. 239 | * 240 | * @param 无. 241 | * 242 | * @retval 0 成功. 243 | * @retval 非0 失败. 244 | * 245 | * @remarks 调用该函数之前,请调用SU_Base_GetAlarm(SUTime *time)设定闹钟时间. 246 | * 247 | * @attention 如果闹钟时间在当前系统时间之前返回失败. 248 | */ 249 | int SU_Base_EnableAlarm(void); 250 | 251 | /** 252 | * @fn int SU_Base_DisableAlarm() 253 | * 254 | * 关闭闹钟. 255 | * 256 | * @param 无. 257 | * 258 | * @retval 0 成功. 259 | * @retval 非0 失败. 260 | * 261 | * @remarks 无. 262 | * 263 | * @attention 无. 264 | */ 265 | int SU_Base_DisableAlarm(void); 266 | 267 | /** 268 | * @fn int SU_Base_PollingAlarm(uint32_t timeoutMsec) 269 | * 270 | * 等待闹钟. 271 | * 272 | * @param[in] 超时时间,单位:毫秒. 273 | * 274 | * @retval 0 成功. 275 | * @retval 非0 失败. 276 | * 277 | * @remarks 调用该函数后,程序会进入阻塞状态,一直到闹钟响应退出或超时退出. 278 | * 279 | * @attention 无. 280 | */ 281 | int SU_Base_PollingAlarm(uint32_t timeoutMsec); 282 | 283 | /** 284 | * @fn int SU_Base_Shutdown(void) 285 | * 286 | * 设备关机. 287 | * 288 | * @param 无. 289 | * 290 | * @retval 0 成功. 291 | * @retval 非0 失败. 292 | * 293 | * @remarks 调用该函数后设备会立即关机并关闭主电源. 294 | * 295 | * @attention 在调用此函数之前请确保已保存所有文件. 296 | */ 297 | int SU_Base_Shutdown(void); 298 | 299 | /** 300 | * @fn int SU_Base_Reboot(void) 301 | * 302 | * 设备重启. 303 | * 304 | * @param 无. 305 | * 306 | * @retval 0 成功. 307 | * @retval 非0 失败. 308 | * 309 | * @remarks 调用该函数后设备会立即重启. 310 | * 311 | * @attention 在调用此函数之前请确保已保存所有文件. 312 | */ 313 | int SU_Base_Reboot(void); 314 | 315 | /** 316 | * @fn int SU_Base_Suspend(void) 317 | * 318 | * 设备休眠. 319 | * 320 | * @param 无. 321 | * 322 | * @retval 0 成功. 323 | * @retval 非0 失败. 324 | * 325 | * @remarks 调用该函数后设备会立即进入休眠,函数正常退出后说明系统已经唤醒. 326 | * 327 | * @attention 无. 328 | */ 329 | int SU_Base_Suspend(); 330 | 331 | /** 332 | * @} 333 | */ 334 | 335 | #ifdef __cplusplus 336 | #if __cplusplus 337 | } 338 | #endif 339 | #endif /* __cplusplus */ 340 | 341 | #endif /* __SU_BASE_H__ */ 342 | -------------------------------------------------------------------------------- /include/imp/imp_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * IMP common data structure header file. 3 | * 4 | * Copyright (C) 2014 Ingenic Semiconductor Co.,Ltd 5 | */ 6 | 7 | #ifndef __IMP_COMMON_H__ 8 | #define __IMP_COMMON_H__ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #ifdef __cplusplus 16 | #if __cplusplus 17 | extern "C" 18 | { 19 | #endif 20 | #endif /* __cplusplus */ 21 | 22 | /** 23 | * @file 24 | * SDK-T15公共数据结构头文件 25 | */ 26 | 27 | /** 28 | * IMP 设备ID枚举定义. 29 | */ 30 | typedef enum { 31 | DEV_ID_FS, /**< 视频源 */ 32 | DEV_ID_ENC, /**< 编码器 */ 33 | DEV_ID_DEC, /**< 解码器 */ 34 | DEV_ID_IVS, /**< 算法 */ 35 | DEV_ID_OSD, /**< 图像叠加 */ 36 | DEV_ID_FG1DIRECT, /**< FB FG1Direct */ 37 | DEV_ID_RESERVED_START, 38 | DEV_ID_RESERVED_END = 23, 39 | NR_MAX_DEVICES, 40 | } IMPDeviceID; 41 | 42 | /** 43 | * IMPCell枚举定义. 44 | */ 45 | typedef struct { 46 | IMPDeviceID deviceID; /**< 设备ID */ 47 | int groupID; /**< 组ID */ 48 | int outputID; /**< 输出ID */ 49 | } IMPCell; 50 | 51 | /** 52 | * IMP帧图像信息定义. 53 | */ 54 | typedef struct { 55 | int index; /**< 帧序号 */ 56 | int pool_idx; /**< 帧所在的Pool的ID */ 57 | 58 | uint32_t width; /**< 帧宽 */ 59 | uint32_t height; /**< 帧高 */ 60 | uint32_t pixfmt; /**< 帧的图像格式 */ 61 | uint32_t size; /**< 帧所占用空间大小 */ 62 | 63 | uint32_t phyAddr; /**< 帧的物理地址 */ 64 | uint32_t virAddr; /**< 帧的虚拟地址 */ 65 | 66 | int64_t timeStamp; /**< 帧的时间戳 */ 67 | uint32_t priv[0]; /* 私有数据 */ 68 | } IMPFrameInfo; 69 | 70 | /** 71 | * IMP帧时间参数. 72 | */ 73 | typedef struct { 74 | uint64_t ts; /**< 时间 */ 75 | uint64_t minus; /**< 下限 */ 76 | uint64_t plus; /**< 上限 */ 77 | } IMPFrameTimestamp; 78 | 79 | /** 80 | * 编解码协议类型 81 | */ 82 | typedef enum { 83 | PT_JPEG, /**< JPEG图像协议类型 */ 84 | PT_H264, /**< H264视频协议类型 */ 85 | PT_H265, /**< H265视频协议类型 */ 86 | } IMPPayloadType; 87 | 88 | /** 89 | * IMP图像格式定义. 90 | */ 91 | typedef enum { 92 | PIX_FMT_YUV420P, /**< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples) */ 93 | PIX_FMT_YUYV422, /**< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr */ 94 | PIX_FMT_UYVY422, /**< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1 */ 95 | PIX_FMT_YUV422P, /**< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples) */ 96 | PIX_FMT_YUV444P, /**< planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples) */ 97 | PIX_FMT_YUV410P, /**< planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples) */ 98 | PIX_FMT_YUV411P, /**< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) */ 99 | PIX_FMT_GRAY8, /**< Y , 8bpp */ 100 | PIX_FMT_MONOWHITE, /**< Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb */ 101 | PIX_FMT_MONOBLACK, /**< Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb */ 102 | 103 | PIX_FMT_NV12, /**< planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (first byte U and the following byte V) */ 104 | PIX_FMT_NV21, /**< as above, but U and V bytes are swapped */ 105 | 106 | PIX_FMT_RGB24, /**< packed RGB 8:8:8, 24bpp, RGBRGB... */ 107 | PIX_FMT_BGR24, /**< packed RGB 8:8:8, 24bpp, BGRBGR... */ 108 | 109 | PIX_FMT_ARGB, /**< packed ARGB 8:8:8:8, 32bpp, ARGBARGB... */ 110 | PIX_FMT_RGBA, /**< packed RGBA 8:8:8:8, 32bpp, RGBARGBA... */ 111 | PIX_FMT_ABGR, /**< packed ABGR 8:8:8:8, 32bpp, ABGRABGR... */ 112 | PIX_FMT_BGRA, /**< packed BGRA 8:8:8:8, 32bpp, BGRABGRA... */ 113 | 114 | PIX_FMT_RGB565BE, /**< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian */ 115 | PIX_FMT_RGB565LE, /**< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian */ 116 | PIX_FMT_RGB555BE, /**< packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), big-endian, most significant bit to 0 */ 117 | PIX_FMT_RGB555LE, /**< packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), little-endian, most significant bit to 0 */ 118 | 119 | PIX_FMT_BGR565BE, /**< packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), big-endian */ 120 | PIX_FMT_BGR565LE, /**< packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), little-endian */ 121 | PIX_FMT_BGR555BE, /**< packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), big-endian, most significant bit to 1 */ 122 | PIX_FMT_BGR555LE, /**< packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), little-endian, most significant bit to 1 */ 123 | 124 | PIX_FMT_0RGB, /**< packed RGB 8:8:8, 32bpp, 0RGB0RGB... */ 125 | PIX_FMT_RGB0, /**< packed RGB 8:8:8, 32bpp, RGB0RGB0... */ 126 | PIX_FMT_0BGR, /**< packed BGR 8:8:8, 32bpp, 0BGR0BGR... */ 127 | PIX_FMT_BGR0, /**< packed BGR 8:8:8, 32bpp, BGR0BGR0... */ 128 | 129 | PIX_FMT_BAYER_BGGR8, /**< bayer, BGBG..(odd line), GRGR..(even line), 8-bit samples */ 130 | PIX_FMT_BAYER_RGGB8, /**< bayer, RGRG..(odd line), GBGB..(even line), 8-bit samples */ 131 | PIX_FMT_BAYER_GBRG8, /**< bayer, GBGB..(odd line), RGRG..(even line), 8-bit samples */ 132 | PIX_FMT_BAYER_GRBG8, /**< bayer, GRGR..(odd line), BGBG..(even line), 8-bit samples */ 133 | 134 | PIX_FMT_RAW, 135 | 136 | PIX_FMT_HSV, 137 | 138 | PIX_FMT_NB, /**< number of pixel formats. */ 139 | } IMPPixelFormat; 140 | 141 | /** 142 | * IMP点坐标信息. 143 | */ 144 | typedef struct { 145 | int x; /**<横坐标 */ 146 | int y; /**<纵坐标 */ 147 | } IMPPoint; 148 | 149 | /** 150 | * IMP 矩形区域信息. 151 | * 152 | * 如下图所示,当p0(100,100)作为起始点,要使width和height为100时,则p1为(199,199) 153 | * width = abs(p1.x-p0.x)+1 height = abs(p1.y-p0.y)+1 点数等于距离+1 154 | * p0(100,100) _____100______ 155 | * | | 156 | * | | 157 | * 100| | 158 | * | | 159 | * |______________| 160 | * p1(199,199) 161 | * 162 | */ 163 | typedef struct { 164 | IMPPoint p0; /**<左上角点坐标信息 */ 165 | IMPPoint p1; /**<右下角点坐标信息 */ 166 | } IMPRect; 167 | 168 | static inline int calc_pic_size(int width, int height, IMPPixelFormat imp_pixfmt) 169 | { 170 | int bpp1 = 0, bpp2 = 1,size; 171 | 172 | #define BPP(FMT, A, B) case FMT: bpp1 = A;bpp2 = B;break 173 | switch (imp_pixfmt) { 174 | BPP(PIX_FMT_NV12, 3, 2); 175 | BPP(PIX_FMT_YUYV422, 2, 1); 176 | BPP(PIX_FMT_UYVY422, 2, 1); 177 | BPP(PIX_FMT_RGB565BE, 2, 1); 178 | BPP(PIX_FMT_BGR0, 4, 1); 179 | BPP(PIX_FMT_BGR24, 3, 1); 180 | default: break; 181 | } 182 | #undef BPP 183 | size = width * height * bpp1 / bpp2; 184 | 185 | return size; 186 | } 187 | 188 | static inline const char *fmt_to_string(IMPPixelFormat imp_pixfmt) 189 | { 190 | static const char *nv12 = "nv12"; 191 | static const char *yuyv422 = "yuyv422"; 192 | 193 | switch (imp_pixfmt) { 194 | case PIX_FMT_NV12: 195 | return nv12; 196 | case PIX_FMT_YUYV422: 197 | return yuyv422; 198 | default: 199 | break; 200 | } 201 | return NULL; 202 | } 203 | 204 | #ifdef __cplusplus 205 | #if __cplusplus 206 | } 207 | #endif 208 | #endif /* __cplusplus */ 209 | 210 | #endif /* __IMP_COMMON_H__ */ 211 | -------------------------------------------------------------------------------- /include/imp/imp_system.h: -------------------------------------------------------------------------------- 1 | /* 2 | * IMP System header file. 3 | * 4 | * Copyright (C) 2014 Ingenic Semiconductor Co.,Ltd 5 | */ 6 | 7 | #ifndef __IMP_SYSTEM_H__ 8 | #define __IMP_SYSTEM_H__ 9 | 10 | #include "imp_common.h" 11 | 12 | #ifdef __cplusplus 13 | #if __cplusplus 14 | extern "C" 15 | { 16 | #endif 17 | #endif /* __cplusplus */ 18 | 19 | /** 20 | * @file 21 | * IMP系统模块头文件 22 | */ 23 | 24 | /** 25 | * @defgroup imp IMP(Ingenic Media Platform) 26 | */ 27 | 28 | /** 29 | * @defgroup IMP_System 30 | * @ingroup imp 31 | * @brief 系统控制模块,包括IMP的基础功能以及模块间绑定的相关功能 32 | * @section concept 1 相关概念 33 | * 系统控制主要实现连接各模块,定义数据流的功能。以下是一些重要概念: 34 | * 35 | * @subsection device 1.1 Device 36 | * Device是完成某一(类)功能的集合。如FrameSource完成视频源数据的输出,Encoder完成视频编码或者图像编码的功能。这里的FrameSource和Encoder就是Device的概念。\n 37 | * Device只是一个集合的概念,并不是具体的数据流节点。 38 | * 39 | * @subsection group 1.2 Group 40 | * Group是一路数据输入的最小单位。一个Device可以有多个Group,每个Group只能接收一路数据输入。Group可以有多路输出(@ref output )。\n 41 | * Group也是具体”功能“的容器,可以详见@ref channel 部分的解释。 42 | * 43 | * @subsection output 1.3 Output 44 | * Output是一个Group的一路数据输出的最小单位。一个Group可以有多个Output,每个Output只能输出一路数据。 45 | * 46 | * @subsection cell 1.4 Cell 47 | * Cell指包含了Device、Group、Output信息的集合。以@ref IMPCell的数据结构呈现。\n 48 | * Cell主要用来Bind(@ref bind)。根据Device、Group、Output的定义,Output作为数据输出的节点,而Group作为数据输入的节点。\n 49 | * 在Bind时数据输出节点的Cell索引到输出的Output,数据输入节点的Cell索引到输入的Group(因此作为数据输入的Cell,Output是一个无意义值)。 50 | * 51 | * @subsection channel 1.5 Channel 52 | * Channel通常指一个单一功能的单元,Channel在Create时(实例化)时被指定具体功能。\n 53 | * 例如:\n 54 | * * 对于Encoder,一个Channel完成一路H264编码或者JPEG编码的功能,具体的编码功能(类型,参数)在通道创建时指定 55 | * * 对于IVS,一个Channel完成一个具体的算法的功能,具体的算法类型参数在通道创建时指定 56 | * * 对于OSD,有一个同Channel类似的概念Region,一个Region是一个具体的叠加区域,可以是PIC(图像),COVER(遮挡)等 57 | * * 对于FrameSource,一个Channel输出一路原始图像,FrameSource的Channel实际上就是Group 58 | * 59 | * Channel作为功能单元,通常需要Register到Group中(FrameSource除外),才能接收到数据。Channel注册到Group中后,会得到Group输入的数据。\n 60 | * 不同Device的Group可Register的Channel数也不同。 61 | * 62 | * @section bind 2 模块绑定(Bind) 63 | * 两个Group经过Bind连接后,源Group的数据会自动发到目的Group。\n 64 | * 由于Group是数据输入的最小单元,Output是数据输出的最小单元,因此IMP_System_Bind(IMPCell *srcCell, IMPCell *dstCell)的两个参数中srcCell的deviceID, groupID, outputID是有效的 65 | * 而dstCell仅deviceID和groupID有效,outputID作为数据输入是无意义的。\n 66 | * 下图是一个简单Bind的例子。 67 | * @image html system_bind0.jpg 68 | * 在上图中,实现了FrameSource的一路输出Bind到Encoder的一个Group。 69 | * 在Encoder Group中Register了两个Channel,因此Encoder Group有H264和JPEG两路输出。 70 | * 参考代码: 71 | * @code 72 | * IMPCell fs_chn0 = {DEV_ID_FS, 0, 0}; //FrameSource deviceID:DEV_ID_FS groupID:0 outputID:0 73 | * IMPCell enc_grp0 = {DEV_ID_ENC, 0, 0}; //ENC deviceID:DEV_ID_ENC groupID:0 outputID:0, 这里enc_grp0的第三个参数无意义。 74 | * int ret = IMP_System_Bind(&fs_chn0, &enc_grp0); 75 | * if (ret < 0) 76 | * printf("Bind FrameSource Channel0 and Encoder Group0 failed\n"); 77 | * @endcode 78 | * Bind将系统的数据流串接起来,根据不同的产品功能需求,Bind的策略也可能不同。 79 | * 80 | * 以下是典型双路码流产品应用Bind的示意图: 81 | * 82 | * @image html typical_application.png 83 | * 84 | * 上图中,FrameSource有两路输出,分别是Channel0主码流(1280x720)和Channel1从码流(640x360)。\n 85 | * * 主码流:FrameSource的Channel0 Bind OSD Group.0,OSD Group.0 Bind Encoder Group.0。其中: 86 | * * OSD Group.0 注册了两个Region,分别用来显示时间戳和字符串信息 87 | * * Encoder Group.0 注册了两个Channel,分别进行H264编码和JPEG编码。其中JPEG编码通道的图像大小如果不等于输入设置(FrameSource的Channel0),那么就会进行缩放(Software at T10),达到任意分辨率抓拍的目的 88 | * * 从码流:FrameSource的Channel1 Bind IVS Group.0,IVS Group.0 Bind OSD Group.1,OSD Group.1 Bind Encoder Group.1。其中: 89 | * * IVS Group.0 注册了一个Channel,用来进行移动侦测 90 | * * OSD Group.1 注册了两个Region,分别用来显示时间戳和字符串信息 91 | * * Encoder Group.1 注册了一个Channel,进行H264编码 92 | * * 这里值得注意的一点是,IVS Bind 在 OSD之前,是因为OSD的时间戳可能造成IVS移动侦测的误判 93 | * 94 | * 参考代码:\n 95 | * 主码流数据流Bind: 96 | * @code 97 | * IMPCell fs_chn0 = {DEV_ID_FS, 0, 0}; 98 | * IMPCell osd_grp0 = {DEV_ID_OSD, 0, 0}; 99 | * IMPCell enc_grp0 = {DEV_ID_ENC, 0, 0}; 100 | * int ret = IMP_System_Bind(&fs_chn0, &osd_grp0); 101 | * if (ret < 0) 102 | * printf("Bind FrameSource Channel0 and OSD Group0 failed\n"); 103 | * 104 | * int ret = IMP_System_Bind(&osd_grp0, &enc_grp0); 105 | * if (ret < 0) 106 | * printf("Bind OSD Group0 and Encoder Group0 failed\n"); 107 | * @endcode 108 | * 从码流数据流Bind: 109 | * @code 110 | * IMPCell fs_chn1_output0 = {DEV_ID_FS, 1, 0}; 111 | * IMPCell ivs_grp0 = {DEV_ID_IVS, 0, 0}; 112 | * IMPCell osd_grp1 = {DEV_ID_OSD, 1, 0}; 113 | * IMPCell enc_grp1 = {DEV_ID_ENC, 1, 0}; 114 | * 115 | * int ret = IMP_System_Bind(&fs_chn1_output0, &ivs_grp0); 116 | * if (ret < 0) 117 | * printf("Bind FrameSource Channel1 and IVS Group0 failed\n"); 118 | * 119 | * int ret = IMP_System_Bind(&ivs_grp0, &osd_grp1); 120 | * if (ret < 0) 121 | * printf("Bind IVS Group0 and OSD Group1 failed\n"); 122 | * 123 | * int ret = IMP_System_Bind(&osd_grp1, &enc_grp1); 124 | * if (ret < 0) 125 | * printf("Bind OSD Group1 and Encoder Group1 failed\n"); 126 | * 127 | * @endcode 128 | * 129 | * @attention 建议所有的Bind的操作在系统初始化时进行。 130 | * @attention 在FrameSource使能后Bind和UnBind操作不能动态调用,需要Disable FrameSource后才可进行UnBind。 131 | * @attention DestroyGroup要在UnBind之后才能进行。 132 | * 133 | * Bind可以呈树状结构,下图是一个例子: 134 | * @image html different_output.png 135 | * 上图中,FrameSource的Channel 1(Group.1)后端分别Bind了两个Group,分别从Output.0和 Output.1输出数据。本例中这样Bind的好处是,IVS Group可以与OSD Group.1并行工作。 136 | * @attention 此例中的Bind方式可能对普通移动侦测造成影响,因此普通移动侦测不建议采用这种方式。 137 | * 138 | * @{ 139 | */ 140 | 141 | /** 142 | * IMP系统版本号定义. 143 | */ 144 | typedef struct { 145 | char aVersion[64]; /**< IMP系统版本号 */ 146 | } IMPVersion; 147 | 148 | /** 149 | * @fn int IMP_System_Init(void) 150 | * 151 | * IMP系统初始化. 152 | * 153 | * @param 无. 154 | * 155 | * @retval 0 成功. 156 | * @retval 非0 失败. 157 | * 158 | * @remarks 此API调用后会初始化基础的数据结构,但不会初始化硬件单元. 159 | * 160 | * @attention 在IMP的任何操作之前必须先调用此接口进行初始化. 161 | */ 162 | int IMP_System_Init(void); 163 | 164 | /** 165 | * @fn int IMP_System_Exit(void) 166 | * 167 | * IMP系统去初始化. 168 | * 169 | * @param 无. 170 | * 171 | * @retval 0 成功. 172 | * @retval 非0 失败. 173 | * 174 | * @remarks 此函数调用后会释放IMP所有的内存以及句柄,并关闭硬件单元. 175 | * 176 | * @attention 在调用此API后,若要再次使用IMP则需重新进行IMP系统初始化. 177 | */ 178 | int IMP_System_Exit(void); 179 | 180 | /** 181 | * @fn int64_t IMP_System_GetTimeStamp(void) 182 | * 183 | * 获得IMP系统的时间戳,单位为微秒。 184 | * 185 | * @param 无。 186 | * 187 | * @retval 时间(usec) 188 | * 189 | * @remarks 系统初始化后时间戳自动被初始化。系统去初始化后时间戳失效。 190 | * 191 | * @attention 无。 192 | */ 193 | int64_t IMP_System_GetTimeStamp(void); 194 | 195 | /** 196 | * @fn int IMP_System_RebaseTimeStamp(int64_t basets) 197 | * 198 | * 设置IMP系统的时间戳,单位为微秒。 199 | * 200 | * @param[in] basets 基础时间。 201 | * 202 | * @retval 0 成功. 203 | * @retval 非0 失败. 204 | * 205 | * @remarks 无。 206 | * 207 | * @attention 无。 208 | */ 209 | int IMP_System_RebaseTimeStamp(int64_t basets); 210 | 211 | /** 212 | * @fn uint32_t IMP_System_ReadReg32(uint32_t u32Addr) 213 | * 214 | * 读取32位寄存器的值。 215 | * 216 | * @param[in] regAddr 寄存器的物理地址。 217 | * 218 | * @retval 寄存器的值(32位) 219 | * 220 | * @remarks 无。 221 | * 222 | * @attention 无。 223 | */ 224 | uint32_t IMP_System_ReadReg32(uint32_t regAddr); 225 | 226 | /** 227 | * @fn void IMP_System_WriteReg32(uint32_t regAddr, uint32_t value) 228 | * 229 | * 向32位寄存器中写值。 230 | * 231 | * @param[in] regAddr 寄存器的物理地址。 232 | * @param[in] value 要写入的值。 233 | * 234 | * @retval 无 235 | * 236 | * @remarks 无。 237 | * 238 | * @attention 在不明确寄存器的含义之前请谨慎调用此API,否则可能会导致系统错误。 239 | */ 240 | void IMP_System_WriteReg32(uint32_t regAddr, uint32_t value); 241 | 242 | /** 243 | * @fn int IMP_System_GetVersion(IMPVersion *pstVersion) 244 | * 245 | * 获取IMP系统版本号. 246 | * 247 | * @param[out] pstVersion IMP系统版本号结构体指针. 248 | * 249 | * @retval 0 成功. 250 | * @retval 非0 失败. 251 | * 252 | * @remarks 无. 253 | * 254 | * @attention 无. 255 | */ 256 | int IMP_System_GetVersion(IMPVersion *pstVersion); 257 | 258 | /** 259 | * @fn const char* IMP_System_GetCPUInfo(void) 260 | * 261 | * 获取CPU型号信息. 262 | * 263 | * @param 无. 264 | * 265 | * @retval CPU型号字符串. 266 | * 267 | * @remarks 返回值是CPU型号类型的字符串,例如对于T10来说,有"T10"及"T10-Lite". 268 | * 269 | * @attention 无. 270 | */ 271 | const char* IMP_System_GetCPUInfo(void); 272 | 273 | /** 274 | * @fn int IMP_System_Bind(IMPCell *srcCell, IMPCell *dstCell) 275 | * 276 | * 绑定源Cell和目的Cell. 277 | * 278 | * @param[in] srcCell 源Cell指针. 279 | * @param[in] dstCell 目的Cell指针. 280 | * 281 | * @retval 0 成功. 282 | * @retval 非0 失败. 283 | * 284 | * @remarks 根据Device、Group和Output的概念,每个Device可能有多个Group,每个Group可能有多个Output, 285 | * Group作为Device的输入接口,而Output作为Device的输出接口.因此绑定实际上是将输出Device的某 286 | * 个Output连接到输入Device的某个Group上. 287 | * @remarks 绑定关系成功后,源Cell(Output)产生的数据会自动传送到目的Cell(Group). 288 | * 289 | * @attention 无。 290 | */ 291 | int IMP_System_Bind(IMPCell *srcCell, IMPCell *dstCell); 292 | 293 | /** 294 | * @fn int IMP_System_UnBind(IMPCell *srcCell, IMPCell *dstCell) 295 | * 296 | * 解除源Cell和目的Cell的绑定. 297 | * 298 | * @param[in] srcCell 源Cell指针. 299 | * @param[in] dstCell 目的Cell指针. 300 | * 301 | * 302 | * @retval 0 成功. 303 | * @retval 非0 失败. 304 | * 305 | * @remarks 无. 306 | * 307 | * @attention 无。 308 | */ 309 | int IMP_System_UnBind(IMPCell *srcCell, IMPCell *dstCell); 310 | 311 | /** 312 | * @fn int IMP_System_GetBindbyDest(IMPCell *dstCell, IMPCell *srcCell) 313 | * 314 | * 获取绑定在目的Cell的源Cell信息. 315 | * 316 | * @param[in] dstCell 目的Cell指针. 317 | * @param[out] srcCell 源Cell指针. 318 | * 319 | * 320 | * @retval 0 成功. 321 | * @retval 非0 失败. 322 | * 323 | * @remarks 无. 324 | * 325 | * @attention 无。 326 | */ 327 | int IMP_System_GetBindbyDest(IMPCell *dstCell, IMPCell *srcCell); 328 | 329 | /** 330 | * @} 331 | */ 332 | 333 | #ifdef __cplusplus 334 | #if __cplusplus 335 | } 336 | #endif 337 | #endif /* __cplusplus */ 338 | 339 | #endif /* __IMP_SYSTEM_H__ */ 340 | -------------------------------------------------------------------------------- /include/imp/imp_ivs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * IMP IVS header file. 3 | * 4 | * Copyright (C) 2015 Ingenic Semiconductor Co.,Ltd 5 | */ 6 | 7 | #ifndef __IMP_IVS_H__ 8 | #define __IMP_IVS_H__ 9 | 10 | #ifdef __cplusplus 11 | #if __cplusplus 12 | extern "C" 13 | { 14 | #endif 15 | #endif /* __cplusplus */ 16 | 17 | #include 18 | 19 | /** 20 | * @file 21 | * IMP IVS模块 22 | */ 23 | 24 | #define IMP_IVS_DEFAULT_TIMEOUTMS (-1) 25 | 26 | /** 27 | * @defgroup IMP_IVS 28 | * @ingroup imp 29 | * @brief IVS智能分析通用接口API 30 | * 31 | * @section concept 1 相关概念 32 | * IMP IVS 通过IVS通用接口API调用实例化的IMPIVSInterface以将智能分析算法嵌入到SDK中来分析SDK中的frame图像。 33 | * 34 | * @subsection IMPIVSInterface 1.1 IMPIVSInterface 35 | * IMPIVSInterface 为通用算法接口,具体算法通过实现此接口并将其传给IMP IVS达到在SDK中运行具体算法的目的。\n 36 | * 一个channel有且仅为单个算法实例的载体,必须将具体实现的通用算法接口传给具体的channel才能在SDK中运行算法。 \n 37 | * IMPIVSInterface 成员param为成员函数init的参数。 \n 38 | * IMP_IVS会在传给成员函数ProcessAsync参数的frame时对其进行外部加锁,ProcessAsync必须在使用完frame后调用IMP_IVS_ReleaseData释放frame,以免死锁。 39 | * 40 | * @section ivs_usage 2 使用方法 41 | * 以移动侦测算法为例,函数的具体实现见sample-move_c.c文件\n 42 | * step.1 初始化系统,可以直接调用范例中的sample_system_init()函数。\n 43 | * 整个应用程序只能初始化系统一次,若之前初始化了,这儿不需要再初始化。\n 44 | * step.2 初始化framesource \n 45 | * 若算法所使用的framesource通道已创建,直接使用已经创建好的通道即可。\n 46 | * 若算法所使用的framesource通道未创建,可以调用范列中的sample_framesource_init(IVS_FS_CHN, &fs_chn_attr)进行创建。\n 47 | * step.3 创建ivs具体算法通道组。\n 48 | * 多个算法可以共用一个通道组,也可以分别使用通道组,具体件sample_ivs_move_init() \n 49 | * @code 50 | * int sample_ivs_move_init(int grp_num) 51 | * { 52 | * int ret = 0; 53 | * 54 | * ret = IMP_IVS_CreateGroup(grp_num); 55 | * if (ret < 0) { 56 | * IMP_LOG_ERR(TAG, "IMP_IVS_CreateGroup(%d) failed\n", grp_num); 57 | * return -1; 58 | * } 59 | * return 0; 60 | * } 61 | * @endcode 62 | * step.4 绑定算法通道组和framesource通道组 63 | * @code 64 | * IMPCell framesource_cell = {DEV_ID_FS, IVS_FS_CHN, 0}; 65 | * IMPCell ivs_cell = {DEV_ID_IVS, 0, 0}; 66 | * ret = IMP_System_Bind(&framesource_cell, &ivs_cell); 67 | * if (ret < 0) { 68 | * IMP_LOG_ERR(TAG, "Bind FrameSource channel%d and ivs0 failed\n", IVS_FS_CHN); 69 | * return -1; 70 | * } 71 | * @endcode 72 | * step.5 启动framesource和算法。建议算法通道号和算法编号一致,以便可以直接对应当前操作哪一个算法。 73 | * @code 74 | * IMP_FrameSource_SetFrameDepth(0, 0); 75 | * ret = sample_framesource_streamon(IVS_FS_CHN); 76 | * if (ret < 0) { 77 | * IMP_LOG_ERR(TAG, "ImpStreamOn failed\n"); 78 | * return -1; 79 | * } 80 | * ret = sample_ivs_move_start(0, 0, &inteface); 81 | * if (ret < 0) { 82 | * IMP_LOG_ERR(TAG, "sample_ivs_move_start(0, 0) failed\n"); 83 | * return -1; 84 | * } 85 | * @endcode 86 | * 87 | * step.6 获取算法结果 \n 88 | * Polling结果、获取结果和释放结果必须严格对应,不能中间有中断; 89 | * 只有Polling结果正确返回,获取到的结果才会被更新,否则获取到的结果无法预知。 90 | * @code 91 | * for (i = 0; i < NR_FRAMES_TO_IVS; i++) { 92 | * ret = IMP_IVS_PollingResult(0, IMP_IVS_DEFAULT_TIMEOUTMS); 93 | * if (ret < 0) { 94 | * IMP_LOG_ERR(TAG, "IMP_IVS_PollingResult(%d, %d) failed\n", 0, IMP_IVS_DEFAULT_TIMEOUTMS); 95 | * return -1; 96 | * } 97 | * ret = IMP_IVS_GetResult(0, (void **)&result); 98 | * if (ret < 0) { 99 | * IMP_LOG_ERR(TAG, "IMP_IVS_GetResult(%d) failed\n", 0); 100 | * return -1; 101 | * } 102 | * IMP_LOG_INFO(TAG, "frame[%d], result->ret=%d\n", i, result->ret); 103 | * 104 | * ret = IMP_IVS_ReleaseResult(0, (void *)result); 105 | * if (ret < 0) { 106 | * IMP_LOG_ERR(TAG, "IMP_IVS_ReleaseResult(%d) failed\n", 0); 107 | * return -1; 108 | * } 109 | * } 110 | * @endcode 111 | * step.7 释放资源 112 | * @code 113 | * sample_ivs_move_stop(0, inteface); 114 | * sample_framesource_streamoff(1); 115 | * IMP_System_UnBind(&framesource_cell, &ivs_cell); 116 | * sample_ivs_move_exit(0); 117 | * sample_framesource_exit(IVS_FS_CHN); 118 | * sample_system_exit(); 119 | * @endcode 120 | * @{ 121 | */ 122 | 123 | /** 124 | * ivs 的通用接口 125 | */ 126 | typedef struct IMPIVSInterface IMPIVSInterface; 127 | 128 | struct IMPIVSInterface { 129 | void *param; /**< 输入参数 */ 130 | int paramSize; /**< 参数空间大小 */ 131 | IMPPixelFormat pixfmt; /**< 算法需要数据格式 */ 132 | int (*init)(IMPIVSInterface *inf); /**< 初始化函数 */ 133 | void (*exit)(IMPIVSInterface *inf); /**< 注销函数 */ 134 | int (*preProcessSync)(IMPIVSInterface *inf, IMPFrameInfo *frame);/**< 预处理函数,不对传入此函数的frame额外加锁,故无需free frame,返回值:>=0 正确,<0:错误 */ 135 | int (*processAsync)(IMPIVSInterface *inf, IMPFrameInfo *frame);/**< 处理函数, SDK IVS 模块对传入此函数的frame 额外加了锁,故此函数必须在该frame使用完毕后尽快使用free_data函数解锁; 此函数是必须实现的函数,算法结果由此函数产生;返回值:0->实际检测正常返回,1->跳帧检测正常返回,-1->错误 */ 136 | int (*getResult)(IMPIVSInterface *inf, void **result); /**< 获取结果资源 */ 137 | int (*releaseResult)(IMPIVSInterface *inf, void *result); /**< 释放结果资源 */ 138 | int (*getParam)(IMPIVSInterface *inf, void *param); /**< 获得算法参数 */ 139 | int (*setParam)(IMPIVSInterface *inf, void *param); /**< 设置算法参数 */ 140 | int (*flushFrame)(IMPIVSInterface *inf); /**< 释放由外部通过processAsync输入给算法后被缓存的所有frame */ 141 | void *priv; /**< 私有变量 */ 142 | }; 143 | 144 | /** 145 | * 创建通道组 146 | * 147 | * @fn int IMP_IVS_CreateGroup(int GrpNum); 148 | * 149 | * @param[in] GrpNum IVS功能对应的通道组号 150 | * 151 | * @retval 0 成功 152 | * @retval -1 失败 153 | * 154 | * @remark 无 155 | * 156 | * @attention 无 157 | */ 158 | int IMP_IVS_CreateGroup(int GrpNum); 159 | 160 | /** 161 | * 销毁通道组 162 | * 163 | * @fn int IMP_IVS_DestroyGroup(int GrpNum); 164 | * 165 | * @param[in] GrpNum IVS功能对应的通道组号 166 | * 167 | * @retval 0 成功 168 | * @retval -1 失败 169 | * 170 | * @remark 无 171 | * 172 | * @attention 无 173 | */ 174 | int IMP_IVS_DestroyGroup(int GrpNum); 175 | /** 176 | * 创建IVS功能对应的通道 177 | * 178 | * @fn int IMP_IVS_CreateChn(int ChnNum, IMPIVSInterface *handler); 179 | * 180 | * @param[in] ChnNum 通道号 181 | * 182 | * @param[in] handler IVS功能句柄 183 | * 184 | * @retval 0 成功 185 | * @retval -1 失败 186 | * 187 | * @remark 无. 188 | * 189 | * @attention 无 190 | */ 191 | int IMP_IVS_CreateChn(int ChnNum, IMPIVSInterface *handler); 192 | 193 | /** 194 | * 销毁IVS功能句柄对应的通道 195 | * 196 | * @fn int IMP_IVS_DestroyChn(int ChnNum); 197 | * 198 | * @param[in] ChnNum 通道号 199 | * 200 | * @retval 0 成功 201 | * @retval -1 失败 202 | * 203 | * @remark 无 204 | * 205 | * @attention 无 206 | */ 207 | int IMP_IVS_DestroyChn(int ChnNum); 208 | 209 | /** 210 | * 注册通道到通道组 211 | * 212 | * @fn int IMP_IVS_RegisterChn(int GrpNum, int ChnNum); 213 | * 214 | * @param[in] GrpNum IVS功能对应的通道组号 215 | * 216 | * @param[in] ChnNum IVS功能对应的通道号 217 | * 218 | * @retval 0 成功 219 | * @retval -1 失败 220 | * 221 | * @remark 将号为Chnnum的通道注册到号为Grpnum通道组中 222 | * 223 | * @attention 无 224 | */ 225 | int IMP_IVS_RegisterChn(int GrpNum, int ChnNum); 226 | 227 | /** 228 | * 从通道组注消通道 229 | * 230 | * @fn int IMP_IVS_UnRegisterChn(int ChnNum); 231 | * 232 | * @param[in] ChnNum IVS功能对应的通道号 233 | * 234 | * @retval 0 成功 235 | * @retval -1 失败 236 | * 237 | * @remark 从号为Grpnum的通道组中注销号为Chnnum通道 238 | * 239 | * @attention 无 240 | */ 241 | int IMP_IVS_UnRegisterChn(int ChnNum); 242 | 243 | /** 244 | * 通道开始接收图像 245 | * 246 | * @fn int IMP_IVS_StartRecvPic(int ChnNum); 247 | * 248 | * @param[in] ChnNum 通道号 249 | * 250 | * @retval 0 成功 251 | * @retval -1 失败 252 | * 253 | * @remark 通道号为Chnnum的IVS功能通道开始接收图像做智能分析 254 | * 255 | * @attention 无 256 | */ 257 | int IMP_IVS_StartRecvPic(int ChnNum); 258 | 259 | /** 260 | * 通道停止接收图像 261 | * 262 | * @fn int IMP_IVS_StopRecvPic(int ChnNum); 263 | * 264 | * @param[in] ChnNum 通道号 265 | * 266 | * @retval 0 成功 267 | * @retval -1 失败 268 | * 269 | * @remark 通道号为Chnnum的IVS功能通道停止接收图像,暂停智能分析 270 | * 271 | * @attention 无 272 | */ 273 | int IMP_IVS_StopRecvPic(int ChnNum); 274 | 275 | /** 276 | * 阻塞判断是否可以获得IVS功能已计算出的智能分析结果 277 | * 278 | * @fn int IMP_IVS_PollingResult(int ChnNum, int timeoutMs); 279 | * 280 | * @param[in] ChnNum IVS功能对应的通道号 281 | * 282 | * @param[in] timeout 最大等待时间,单位ms; IMP_IVS_DEFAULT_TIMEOUTMS:库内部默认的等待时间,0:不等待,>0:用户设定的等待时间 283 | * 284 | * @retval 0 成功 285 | * @retval -1 失败 286 | * 287 | * @remark 只有该通道创建时参数IMPIVSInterface结构体中ProcessAsync函数成员返回0时,即实际检测正常返回时,此Polling函数才返回成功 288 | * 289 | * @attention 无 290 | */ 291 | int IMP_IVS_PollingResult(int ChnNum, int timeoutMs); 292 | 293 | /** 294 | * 获得IVS功能计算出的智能分析结果 295 | * 296 | * @fn int IMP_IVS_GetResult(int ChnNum, void **result); 297 | * 298 | * @param[in] ChnNum IVS功能对应的通道号 299 | * 300 | * @param[in] result IVS功能对应的通道号输出的结果,返回此通道对应的智能分析算法的结果指针,外部客户无需分配空间。 301 | * 302 | * @retval 0 成功 303 | * @retval -1 失败 304 | * 305 | * @remark 根据不同IVS功能绑定的通道,输出其对应的结果. 306 | * 307 | * @attention 无 308 | */ 309 | int IMP_IVS_GetResult(int ChnNum, void **result); 310 | 311 | /** 312 | * 释放IVS功能计算出的结果资源 313 | * 314 | * @fn int IMP_IVS_ReleaseResult(int ChnNum, void *result); 315 | * 316 | * @param[in] GrpNum 通道组号 317 | * 318 | * @param[in] ChnNum IVS功能对应的通道号 319 | * 320 | * @param[in] result IVS功能对应的通道号输出的结果 321 | * 322 | * @retval 0 成功 323 | * @retval -1 失败 324 | * 325 | * @remark 根据不同IVS功能绑定的通道,释放其输出的结果资源. 326 | * 327 | * @attention 无 328 | */ 329 | int IMP_IVS_ReleaseResult(int ChnNum, void *result); 330 | 331 | /** 332 | * 释放传给Datacallback的参数frame 333 | * 334 | * @fn int IMP_IVS_ReleaseData(void *vaddr); 335 | * 336 | * @param[in] vaddr 释放的空间虚拟地址 337 | * 338 | * @retval 0 成功 339 | * @retval -1 失败 340 | * 341 | * @remark 必须使用此函数释放传给Datacallback的frame参数,否则肯定造成死锁。 342 | * @remark 此接口仅供算法提供商使用,算法使用客户无须关注。 343 | * 344 | * @attention 无 345 | */ 346 | int IMP_IVS_ReleaseData(void *vaddr); 347 | 348 | /** 349 | * 获取通道算法参数 350 | * 351 | * @fn int IMP_IVS_GetParam(int chnNum, void *param); 352 | * 353 | * @param[in] ChnNum IVS功能对应的通道号 354 | * @param[in] param 算法参数虚拟地址指针 355 | * 356 | * @retval 0 成功 357 | * @retval -1 失败 358 | * 359 | * @attention 无 360 | */ 361 | int IMP_IVS_GetParam(int chnNum, void *param); 362 | 363 | /** 364 | * 设置通道算法参数 365 | * 366 | * @fn int IMP_IVS_SetParam(int chnNum, void *param); 367 | * 368 | * @param[in] ChnNum IVS功能对应的通道号 369 | * @param[in] param 算法参数虚拟地址指针 370 | * 371 | * @retval 0 成功 372 | * @retval -1 失败 373 | * 374 | * @attention 无 375 | */ 376 | int IMP_IVS_SetParam(int chnNum, void *param); 377 | 378 | /** 379 | * @} 380 | */ 381 | 382 | #ifdef __cplusplus 383 | #if __cplusplus 384 | } 385 | #endif 386 | #endif /* __cplusplus */ 387 | 388 | #endif /* __IMP_IVS_H__ */ 389 | -------------------------------------------------------------------------------- /include/imp/imp_dmic.h: -------------------------------------------------------------------------------- 1 | #ifndef __IMP_DMIC_H 2 | #define __IMP_DMIC_H 3 | 4 | #include 5 | #include "imp_audio.h" 6 | 7 | #ifdef __cplusplus 8 | #if __cplusplus 9 | extern "C" 10 | { 11 | #endif 12 | #endif /* __cplusplus */ 13 | 14 | typedef enum { 15 | DMIC_SAMPLE_RATE_8000 = 8000, /**8KHz 采样率*/ 16 | DMIC_SAMPLE_RATE_16000 = 16000, /*16KHz 采样率*/ 17 | } IMPDmicSampleRate; 18 | 19 | typedef enum { 20 | DMIC_BIT_WIDTH_16 = 16, /**<16 bit 采样精度*/ 21 | } IMPDmicBitWidth; 22 | 23 | typedef enum { 24 | DMIC_SOUND_MODE_MONO = 1, /*单声道*/ 25 | DMIC_SOUND_MODE_STEREO = 2, /*立体音*/ 26 | } IMPDmicSoundMode; 27 | 28 | /*DMIC 输入设备属性*/ 29 | typedef struct { 30 | IMPDmicSampleRate samplerate; /**< DMIC采样率 */ 31 | IMPDmicBitWidth bitwidth; /** 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "stub.h" 27 | 28 | #define SENSOR_FRAME_RATE_NUM 25 29 | #define SENSOR_FRAME_RATE_DEN 1 30 | 31 | #define SENSOR_NAME "gc2083" 32 | #define SENSOR_CUBS_TYPE TX_SENSOR_CONTROL_INTERFACE_I2C 33 | #define SENSOR_I2C_ADDR 0x37 34 | #define SENSOR_WIDTH 1920 35 | #define SENSOR_HEIGHT 1080 36 | #define CHN0_EN 1 37 | #define CHN1_EN 0 38 | #define CHN2_EN 0 39 | #define CHN3_EN 1 40 | #define CROP_EN 1 41 | 42 | #define SENSOR_WIDTH_SECOND 640 43 | #define SENSOR_HEIGHT_SECOND 360 44 | 45 | #define SENSOR_WIDTH_THIRD 1280 46 | #define SENSOR_HEIGHT_THIRD 720 47 | 48 | #define BITRATE_720P_Kbs 1000 49 | 50 | #define NR_FRAMES_TO_SAVE 200 51 | #define STREAM_BUFFER_SIZE (1 * 1024 * 1024) 52 | 53 | #define ENC_VIDEO_CHANNEL 0 54 | #define ENC_JPEG_CHANNEL 1 55 | 56 | #define STREAM_FILE_PATH_PREFIX "/devel" 57 | #define SNAP_FILE_PATH_PREFIX "/devel" 58 | 59 | #define OSD_REGION_WIDTH 16 60 | #define OSD_REGION_HEIGHT 34 61 | #define OSD_REGION_WIDTH_SEC 8 62 | #define OSD_REGION_HEIGHT_SEC 18 63 | 64 | 65 | #define SLEEP_TIME 1 66 | 67 | #define FS_CHN_NUM 4 //MIN 1,MAX 3 68 | #define IVS_CHN_ID 3 69 | 70 | #define CH0_INDEX 0 71 | #define CH1_INDEX 1 72 | #define CH2_INDEX 2 73 | #define CH3_INDEX 3 74 | #define CHN_ENABLE 1 75 | #define CHN_DISABLE 0 76 | 77 | struct chn_conf{ 78 | unsigned int index;//0 for main channel ,1 for second channel 79 | unsigned int enable; 80 | IMPEncoderProfile payloadType; 81 | IMPFSChnAttr fs_chn_attr; 82 | IMPCell framesource_chn; 83 | IMPCell imp_encoder; 84 | }; 85 | 86 | #define CHN_NUM ARRAY_SIZE(chn) 87 | 88 | #define TAG "Sample-Common" 89 | 90 | struct chn_conf chn[FS_CHN_NUM] = { 91 | { 92 | .index = CH0_INDEX, 93 | .enable = CHN0_EN, 94 | .payloadType = IMP_ENC_PROFILE_HEVC_MAIN, 95 | .fs_chn_attr = { 96 | .pixFmt = PIX_FMT_NV12, 97 | .outFrmRateNum = SENSOR_FRAME_RATE_NUM, 98 | .outFrmRateDen = SENSOR_FRAME_RATE_DEN, 99 | .nrVBs = 2, 100 | .type = FS_PHY_CHANNEL, 101 | 102 | .crop.enable = CROP_EN, 103 | .crop.top = 0, 104 | .crop.left = 0, 105 | .crop.width = SENSOR_WIDTH, 106 | .crop.height = SENSOR_HEIGHT, 107 | 108 | .scaler.enable = 0, 109 | 110 | .picWidth = SENSOR_WIDTH, 111 | .picHeight = SENSOR_HEIGHT, 112 | }, 113 | .framesource_chn = { DEV_ID_FS, CH0_INDEX, 0}, 114 | .imp_encoder = { DEV_ID_ENC, CH0_INDEX, 0}, 115 | }, 116 | { 117 | .index = CH1_INDEX, 118 | .enable = CHN1_EN, 119 | .payloadType = IMP_ENC_PROFILE_HEVC_MAIN, 120 | .fs_chn_attr = { 121 | .pixFmt = PIX_FMT_NV12, 122 | .outFrmRateNum = SENSOR_FRAME_RATE_NUM, 123 | .outFrmRateDen = SENSOR_FRAME_RATE_DEN, 124 | .nrVBs = 2, 125 | .type = FS_PHY_CHANNEL, 126 | 127 | .crop.enable = 0, 128 | .crop.top = 0, 129 | .crop.left = 0, 130 | .crop.width = SENSOR_WIDTH, 131 | .crop.height = SENSOR_HEIGHT, 132 | 133 | .scaler.enable = 1, 134 | .scaler.outwidth = SENSOR_WIDTH_THIRD, 135 | .scaler.outheight = SENSOR_HEIGHT_THIRD, 136 | 137 | .picWidth = SENSOR_WIDTH_THIRD, 138 | .picHeight = SENSOR_HEIGHT_THIRD, 139 | }, 140 | .framesource_chn = { DEV_ID_FS, CH1_INDEX, 0}, 141 | .imp_encoder = { DEV_ID_ENC, CH1_INDEX, 0}, 142 | }, 143 | { 144 | .index = CH2_INDEX, 145 | .enable = CHN2_EN, 146 | .payloadType = IMP_ENC_PROFILE_HEVC_MAIN, 147 | .fs_chn_attr = { 148 | .pixFmt = PIX_FMT_NV12, 149 | .outFrmRateNum = SENSOR_FRAME_RATE_NUM, 150 | .outFrmRateDen = SENSOR_FRAME_RATE_DEN, 151 | .nrVBs = 2, 152 | .type = FS_PHY_CHANNEL, 153 | 154 | .crop.enable = 0, 155 | .crop.top = 0, 156 | .crop.left = 0, 157 | .crop.width = SENSOR_WIDTH, 158 | .crop.height = SENSOR_HEIGHT, 159 | 160 | .scaler.enable = 1, 161 | .scaler.outwidth = SENSOR_WIDTH_SECOND, 162 | .scaler.outheight = SENSOR_HEIGHT_SECOND, 163 | 164 | .picWidth = SENSOR_WIDTH_SECOND, 165 | .picHeight = SENSOR_HEIGHT_SECOND, 166 | }, 167 | .framesource_chn = { DEV_ID_FS, CH2_INDEX, 0}, 168 | .imp_encoder = { DEV_ID_ENC, CH2_INDEX, 0}, 169 | }, 170 | { 171 | .index = CH3_INDEX, 172 | .enable = CHN3_EN, 173 | .payloadType = IMP_ENC_PROFILE_HEVC_MAIN, 174 | .fs_chn_attr = { 175 | .pixFmt = PIX_FMT_NV12, 176 | .outFrmRateNum = SENSOR_FRAME_RATE_NUM, 177 | .outFrmRateDen = SENSOR_FRAME_RATE_DEN, 178 | .nrVBs = 2, 179 | .type = FS_EXT_CHANNEL, 180 | 181 | .crop.enable = 0, 182 | .crop.top = 0, 183 | .crop.left = 0, 184 | .crop.width = SENSOR_WIDTH, 185 | .crop.height = SENSOR_HEIGHT, 186 | 187 | .scaler.enable = 1, 188 | .scaler.outwidth = SENSOR_WIDTH_SECOND, 189 | .scaler.outheight = SENSOR_HEIGHT_SECOND, 190 | 191 | .picWidth = SENSOR_WIDTH_SECOND, 192 | .picHeight = SENSOR_HEIGHT_SECOND, 193 | }, 194 | .framesource_chn = { DEV_ID_FS, CH3_INDEX, 0}, 195 | .imp_encoder = { DEV_ID_ENC, CH3_INDEX, 0}, 196 | }, 197 | }; 198 | 199 | extern int IMP_OSD_SetPoolSize(int size); 200 | 201 | static IMPSensorInfo sensor_info; 202 | 203 | static int save_stream(int fd, IMPEncoderStream *stream) 204 | { 205 | int ret, i, nr_pack = stream->packCount; 206 | 207 | //IMP_LOG_DBG(TAG, "----------packCount=%d, stream->seq=%u start----------\n", stream->packCount, stream->seq); 208 | for (i = 0; i < nr_pack; i++) { 209 | //IMP_LOG_DBG(TAG, "[%d]:%10u,%10lld,%10u,%10u,%10u\n", i, stream->pack[i].length, stream->pack[i].timestamp, stream->pack[i].frameEnd, *((uint32_t *)(&stream->pack[i].nalType)), stream->pack[i].sliceType); 210 | IMPEncoderPack *pack = &stream->pack[i]; 211 | if(pack->length){ 212 | uint32_t remSize = stream->streamSize - pack->offset; 213 | if(remSize < pack->length){ 214 | ret = write(fd, (void *)(stream->virAddr + pack->offset), remSize); 215 | if (ret != remSize) { 216 | IMP_LOG_ERR(TAG, "stream write ret(%d) != pack[%d].remSize(%d) error:%s\n", ret, i, remSize, strerror(errno)); 217 | return -1; 218 | } 219 | ret = write(fd, (void *)stream->virAddr, pack->length - remSize); 220 | if (ret != (pack->length - remSize)) { 221 | IMP_LOG_ERR(TAG, "stream write ret(%d) != pack[%d].(length-remSize)(%d) error:%s\n", ret, i, (pack->length - remSize), strerror(errno)); 222 | return -1; 223 | } 224 | }else { 225 | ret = write(fd, (void *)(stream->virAddr + pack->offset), pack->length); 226 | if (ret != pack->length) { 227 | IMP_LOG_ERR(TAG, "stream write ret(%d) != pack[%d].length(%d) error:%s\n", ret, i, pack->length, strerror(errno)); 228 | return -1; 229 | } 230 | } 231 | } 232 | } 233 | //IMP_LOG_DBG(TAG, "----------packCount=%d, stream->seq=%u end----------\n", stream->packCount, stream->seq); 234 | return 0; 235 | } 236 | 237 | int sample_system_init() 238 | { 239 | int ret = 0; 240 | 241 | IMP_OSD_SetPoolSize(512*1024); 242 | 243 | memset(&sensor_info, 0, sizeof(IMPSensorInfo)); 244 | memcpy(sensor_info.name, SENSOR_NAME, sizeof(SENSOR_NAME)); 245 | sensor_info.cbus_type = SENSOR_CUBS_TYPE; 246 | memcpy(sensor_info.i2c.type, SENSOR_NAME, sizeof(SENSOR_NAME)); 247 | sensor_info.i2c.addr = SENSOR_I2C_ADDR; 248 | 249 | printf("Step 1.1\n"); 250 | 251 | IMP_LOG_DBG(TAG, "sample_system_init start\n"); 252 | 253 | ret = IMP_ISP_Open(); 254 | if(ret < 0){ 255 | IMP_LOG_ERR(TAG, "failed to open ISP\n"); 256 | return -1; 257 | } 258 | 259 | printf("Step 1.2\n"); 260 | 261 | ret = IMP_ISP_AddSensor(&sensor_info); 262 | if(ret < 0){ 263 | IMP_LOG_ERR(TAG, "failed to AddSensor\n"); 264 | printf("here\n"); 265 | return -1; 266 | } 267 | 268 | printf("Step 1.3\n"); 269 | ret = IMP_ISP_EnableSensor(); 270 | if(ret < 0){ 271 | IMP_LOG_ERR(TAG, "failed to EnableSensor\n"); 272 | return -1; 273 | } 274 | 275 | printf("Step 1.4\n"); 276 | ret = IMP_System_Init(); 277 | if(ret < 0){ 278 | IMP_LOG_ERR(TAG, "IMP_System_Init failed\n"); 279 | return -1; 280 | } 281 | 282 | printf("Step 1.5\n"); 283 | /* enable turning, to debug graphics */ 284 | ret = IMP_ISP_EnableTuning(); 285 | if(ret < 0){ 286 | IMP_LOG_ERR(TAG, "IMP_ISP_EnableTuning failed\n"); 287 | return -1; 288 | } 289 | printf("Step 1.6\n"); 290 | IMP_ISP_Tuning_SetContrast(128); 291 | IMP_ISP_Tuning_SetSharpness(128); 292 | IMP_ISP_Tuning_SetSaturation(128); 293 | IMP_ISP_Tuning_SetBrightness(128); 294 | #if 1 295 | ret = IMP_ISP_Tuning_SetISPRunningMode(IMPISP_RUNNING_MODE_DAY); 296 | if (ret < 0){ 297 | IMP_LOG_ERR(TAG, "failed to set running mode\n"); 298 | return -1; 299 | } 300 | #endif 301 | #if 0 302 | ret = IMP_ISP_Tuning_SetSensorFPS(SENSOR_FRAME_RATE_NUM, SENSOR_FRAME_RATE_DEN); 303 | if (ret < 0){ 304 | IMP_LOG_ERR(TAG, "failed to set sensor fps\n"); 305 | return -1; 306 | } 307 | #endif 308 | IMP_LOG_DBG(TAG, "ImpSystemInit success\n"); 309 | 310 | return 0; 311 | } 312 | 313 | int sample_system_exit() 314 | { 315 | int ret = 0; 316 | 317 | IMP_LOG_DBG(TAG, "sample_system_exit start\n"); 318 | 319 | 320 | IMP_System_Exit(); 321 | 322 | ret = IMP_ISP_DisableSensor(); 323 | if(ret < 0){ 324 | IMP_LOG_ERR(TAG, "failed to EnableSensor\n"); 325 | return -1; 326 | } 327 | 328 | ret = IMP_ISP_DelSensor(&sensor_info); 329 | if(ret < 0){ 330 | IMP_LOG_ERR(TAG, "failed to AddSensor\n"); 331 | return -1; 332 | } 333 | 334 | ret = IMP_ISP_DisableTuning(); 335 | if(ret < 0){ 336 | IMP_LOG_ERR(TAG, "IMP_ISP_DisableTuning failed\n"); 337 | return -1; 338 | } 339 | 340 | if(IMP_ISP_Close()){ 341 | IMP_LOG_ERR(TAG, "failed to open ISP\n"); 342 | return -1; 343 | } 344 | 345 | IMP_LOG_DBG(TAG, " sample_system_exit success\n"); 346 | 347 | return 0; 348 | } 349 | 350 | int sample_framesource_init() 351 | { 352 | int i, ret; 353 | 354 | for (i = 0; i < FS_CHN_NUM; i++) { 355 | if (chn[i].enable) { 356 | ret = IMP_FrameSource_CreateChn(chn[i].index, &chn[i].fs_chn_attr); 357 | if(ret < 0){ 358 | IMP_LOG_ERR(TAG, "IMP_FrameSource_CreateChn(chn%d) error !\n", chn[i].index); 359 | return -1; 360 | } 361 | 362 | ret = IMP_FrameSource_SetChnAttr(chn[i].index, &chn[i].fs_chn_attr); 363 | if (ret < 0) { 364 | IMP_LOG_ERR(TAG, "IMP_FrameSource_SetChnAttr(chn%d) error !\n", chn[i].index); 365 | return -1; 366 | } 367 | } 368 | } 369 | 370 | return 0; 371 | } 372 | 373 | int sample_jpeg_init() 374 | { 375 | int i, ret; 376 | IMPEncoderChnAttr channel_attr; 377 | IMPFSChnAttr *imp_chn_attr_tmp; 378 | 379 | for (i = 0; i < FS_CHN_NUM; i++) { 380 | if (chn[i].enable) { 381 | imp_chn_attr_tmp = &chn[i].fs_chn_attr; 382 | memset(&channel_attr, 0, sizeof(IMPEncoderChnAttr)); 383 | ret = IMP_Encoder_SetDefaultParam(&channel_attr, IMP_ENC_PROFILE_JPEG, IMP_ENC_RC_MODE_FIXQP, 384 | imp_chn_attr_tmp->picWidth, imp_chn_attr_tmp->picHeight, 385 | imp_chn_attr_tmp->outFrmRateNum, imp_chn_attr_tmp->outFrmRateDen, 0, 0, 25, 0); 386 | 387 | /* Create Channel */ 388 | ret = IMP_Encoder_CreateChn(4 + chn[i].index, &channel_attr); 389 | if (ret < 0) { 390 | IMP_LOG_ERR(TAG, "IMP_Encoder_CreateChn(%d) error: %d\n", 391 | chn[i].index, ret); 392 | return -1; 393 | } 394 | 395 | /* Resigter Channel */ 396 | ret = IMP_Encoder_RegisterChn(i, 4 + chn[i].index); 397 | if (ret < 0) { 398 | IMP_LOG_ERR(TAG, "IMP_Encoder_RegisterChn(0, %d) error: %d\n", 399 | chn[i].index, ret); 400 | return -1; 401 | } 402 | } 403 | } 404 | 405 | return 0; 406 | } 407 | 408 | int sample_framesource_streamon() 409 | { 410 | int ret = 0, i = 0; 411 | /* Enable channels */ 412 | for (i = 0; i < FS_CHN_NUM; i++) { 413 | if (chn[i].enable) { 414 | ret = IMP_FrameSource_EnableChn(chn[i].index); 415 | if (ret < 0) { 416 | IMP_LOG_ERR(TAG, "IMP_FrameSource_EnableChn(%d) error: %d\n", ret, chn[i].index); 417 | return -1; 418 | } 419 | } 420 | } 421 | return 0; 422 | } 423 | 424 | int sample_get_jpeg_snap() 425 | { 426 | int i, ret; 427 | char snap_path[64]; 428 | 429 | for (i = 0; i < FS_CHN_NUM; i++) { 430 | if (chn[i].enable) { 431 | ret = IMP_Encoder_StartRecvPic(4 + chn[i].index); 432 | if (ret < 0) { 433 | IMP_LOG_ERR(TAG, "IMP_Encoder_StartRecvPic(%d) failed\n", 3 + chn[i].index); 434 | return -1; 435 | } 436 | 437 | sprintf(snap_path, "%s/snap-%d.jpg", 438 | SNAP_FILE_PATH_PREFIX, chn[i].index); 439 | 440 | IMP_LOG_ERR(TAG, "Open Snap file %s ", snap_path); 441 | int snap_fd = open(snap_path, O_RDWR | O_CREAT | O_TRUNC, 0777); 442 | if (snap_fd < 0) { 443 | IMP_LOG_ERR(TAG, "failed: %s\n", strerror(errno)); 444 | return -1; 445 | } 446 | IMP_LOG_DBG(TAG, "OK\n"); 447 | 448 | /* Polling JPEG Snap, set timeout as 1000msec */ 449 | ret = IMP_Encoder_PollingStream(4 + chn[i].index, 10000); 450 | if (ret < 0) { 451 | IMP_LOG_ERR(TAG, "Polling stream timeout\n"); 452 | continue; 453 | } 454 | 455 | IMPEncoderStream stream; 456 | /* Get JPEG Snap */ 457 | ret = IMP_Encoder_GetStream(chn[i].index + 4, &stream, 1); 458 | if (ret < 0) { 459 | IMP_LOG_ERR(TAG, "IMP_Encoder_GetStream() failed\n"); 460 | return -1; 461 | } 462 | 463 | ret = save_stream(snap_fd, &stream); 464 | if (ret < 0) { 465 | close(snap_fd); 466 | return ret; 467 | } 468 | 469 | IMP_Encoder_ReleaseStream(4 + chn[i].index, &stream); 470 | 471 | close(snap_fd); 472 | 473 | ret = IMP_Encoder_StopRecvPic(4 + chn[i].index); 474 | if (ret < 0) { 475 | IMP_LOG_ERR(TAG, "IMP_Encoder_StopRecvPic() failed\n"); 476 | return -1; 477 | } 478 | } 479 | } 480 | return 0; 481 | } 482 | 483 | int sample_framesource_streamoff() 484 | { 485 | int ret = 0, i = 0; 486 | /* Enable channels */ 487 | for (i = 0; i < FS_CHN_NUM; i++) { 488 | if (chn[i].enable){ 489 | ret = IMP_FrameSource_DisableChn(chn[i].index); 490 | if (ret < 0) { 491 | IMP_LOG_ERR(TAG, "IMP_FrameSource_DisableChn(%d) error: %d\n", ret, chn[i].index); 492 | return -1; 493 | } 494 | } 495 | } 496 | return 0; 497 | } 498 | 499 | int sample_jpeg_exit(void) 500 | { 501 | int ret = 0, i = 0, chnNum = 0; 502 | IMPEncoderChnStat chn_stat; 503 | 504 | for (i = 0; i < FS_CHN_NUM; i++) { 505 | if (chn[i].enable) { 506 | chnNum = 4 + chn[i].index; 507 | memset(&chn_stat, 0, sizeof(IMPEncoderChnStat)); 508 | ret = IMP_Encoder_Query(chnNum, &chn_stat); 509 | if (ret < 0) { 510 | IMP_LOG_ERR(TAG, "IMP_Encoder_Query(%d) error: %d\n", chnNum, ret); 511 | return -1; 512 | } 513 | 514 | if (chn_stat.registered) { 515 | ret = IMP_Encoder_UnRegisterChn(chnNum); 516 | if (ret < 0) { 517 | IMP_LOG_ERR(TAG, "IMP_Encoder_UnRegisterChn(%d) error: %d\n", chnNum, ret); 518 | return -1; 519 | } 520 | 521 | ret = IMP_Encoder_DestroyChn(chnNum); 522 | if (ret < 0) { 523 | IMP_LOG_ERR(TAG, "IMP_Encoder_DestroyChn(%d) error: %d\n", chnNum, ret); 524 | return -1; 525 | } 526 | } 527 | } 528 | } 529 | 530 | return 0; 531 | } 532 | 533 | int sample_framesource_exit() 534 | { 535 | int ret,i; 536 | 537 | for (i = 0; i < FS_CHN_NUM; i++) { 538 | if (chn[i].enable) { 539 | /*Destroy channel */ 540 | ret = IMP_FrameSource_DestroyChn(chn[i].index); 541 | if (ret < 0) { 542 | IMP_LOG_ERR(TAG, "IMP_FrameSource_DestroyChn(%d) error: %d\n", chn[i].index, ret); 543 | return -1; 544 | } 545 | } 546 | } 547 | return 0; 548 | } 549 | 550 | 551 | int main(int argc, char *argv[]) 552 | { 553 | int i, ret; 554 | 555 | printf("Step.1\n"); 556 | /* Step.1 System init */ 557 | ret = sample_system_init(); 558 | if (ret < 0) { 559 | IMP_LOG_ERR(TAG, "IMP_System_Init() failed\n"); 560 | return -1; 561 | } 562 | 563 | printf("Step.2\n"); 564 | /* Step.2 FrameSource init */ 565 | ret = sample_framesource_init(); 566 | if (ret < 0) { 567 | IMP_LOG_ERR(TAG, "FrameSource init failed\n"); 568 | return -1; 569 | } 570 | 571 | for (i = 0; i < FS_CHN_NUM; i++) { 572 | if (chn[i].enable) { 573 | ret = IMP_Encoder_CreateGroup(chn[i].index); 574 | if (ret < 0) { 575 | IMP_LOG_ERR(TAG, "IMP_Encoder_CreateGroup(%d) error !\n", i); 576 | return -1; 577 | } 578 | } 579 | } 580 | 581 | printf("Step.3\n"); 582 | /* Step.3 Encoder init */ 583 | ret = sample_jpeg_init(); 584 | if (ret < 0) { 585 | IMP_LOG_ERR(TAG, "Encoder init failed\n"); 586 | return -1; 587 | } 588 | 589 | printf("Step.4\n"); 590 | /* Step.4 Bind */ 591 | for (i = 0; i < FS_CHN_NUM; i++) { 592 | if (chn[i].enable) { 593 | ret = IMP_System_Bind(&chn[i].framesource_chn, &chn[i].imp_encoder); 594 | if (ret < 0) { 595 | IMP_LOG_ERR(TAG, "Bind FrameSource channel%d and Encoder failed\n",i); 596 | return -1; 597 | } 598 | } 599 | } 600 | 601 | printf("Step.5\n"); 602 | /* Step.5 Stream On */ 603 | ret = sample_framesource_streamon(); 604 | if (ret < 0) { 605 | IMP_LOG_ERR(TAG, "ImpStreamOn failed\n"); 606 | return -1; 607 | } 608 | 609 | /* drop several pictures of invalid data */ 610 | sleep(SLEEP_TIME); 611 | 612 | printf("Step.6\n"); 613 | /* Step.6 Get Snap */ 614 | ret = sample_get_jpeg_snap(); 615 | if (ret < 0) { 616 | IMP_LOG_ERR(TAG, "Get H264 stream failed\n"); 617 | return -1; 618 | } 619 | 620 | /* Exit sequence as follow... */ 621 | /* Step.a Stream Off */ 622 | ret = sample_framesource_streamoff(); 623 | if (ret < 0) { 624 | IMP_LOG_ERR(TAG, "FrameSource StreamOff failed\n"); 625 | return -1; 626 | } 627 | 628 | /* Step.b UnBind */ 629 | for (i = 0; i < FS_CHN_NUM; i++) { 630 | if (chn[i].enable) { 631 | ret = IMP_System_UnBind(&chn[i].framesource_chn, &chn[i].imp_encoder); 632 | if (ret < 0) { 633 | IMP_LOG_ERR(TAG, "UnBind FrameSource channel%d and Encoder failed\n",i); 634 | return -1; 635 | } 636 | } 637 | } 638 | 639 | ret = sample_jpeg_exit(); 640 | if (ret < 0) { 641 | IMP_LOG_ERR(TAG, "Encoder jpeg exit failed\n"); 642 | return -1; 643 | } 644 | 645 | /* Step.d FrameSource exit */ 646 | ret = sample_framesource_exit(); 647 | if (ret < 0) { 648 | IMP_LOG_ERR(TAG, "FrameSource exit failed\n"); 649 | return -1; 650 | } 651 | 652 | /* Step.e System exit */ 653 | ret = sample_system_exit(); 654 | if (ret < 0) { 655 | IMP_LOG_ERR(TAG, "sample_system_exit() failed\n"); 656 | return -1; 657 | } 658 | 659 | return 0; 660 | } 661 | -------------------------------------------------------------------------------- /include/imp/imp_encoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * IMP Encoder func header file. 3 | * 4 | * Copyright (C) 2014 Ingenic Semiconductor Co.,Ltd 5 | */ 6 | 7 | #ifndef __IMP_ENCODER_H__ 8 | #define __IMP_ENCODER_H__ 9 | 10 | #include 11 | #include 12 | 13 | #ifdef __cplusplus 14 | #if __cplusplus 15 | extern "C" 16 | { 17 | #endif 18 | #endif /* __cplusplus */ 19 | 20 | /** 21 | * @file 22 | * IMP视频编码头文件 23 | */ 24 | 25 | /** 26 | * @defgroup IMP_Encoder 27 | * @ingroup imp 28 | * @brief 视频编码(JPEG, H264, H265)模块,包含编码通道管理,编码参数设置等功能 29 | * @section enc_struct 1 模块结构 30 | * Encoder模块内部结构如下如: 31 | * @image html encoder_struct.jpg 32 | * 如上图所示,编码模块由若干个Group组成(在T15上支持两个Group),每个Group由编码Channel组成。 33 | * 每个编码Channel附带一个输出码流缓冲区,这个缓冲区由多个buffer组成。 34 | * @section enc_channel 2 编码Channel 35 | * 一个编码Channel可以完成一种协议的编码, 每个Group可以添加2个编码channel。 36 | * @section enc_rc 3 码率控制 37 | * @subsection enc_cbr 3.1 CBR 38 | * CBR(Constent Bit Rate)恒定比特率,即在码率统计时间内编码码率恒定。 39 | * 以H.264 编码为例,用户可设置maxQp,minQp,bitrate等。 40 | * maxQp,minQp 用于控制图像的质量范围, bitrate 用于钳位码率统计时间内的平均编码码率。 41 | * 当编码码率大于恒定码率时,图像QP 会逐步向maxQp 调整,当编码码率远小于恒定码率时,图像QP 会逐步向minQp 调整。 42 | * 当图像QP 达到maxQp 时,QP 被钳位到最大值,bitrate 的钳位效果失效,编码码率有可能会超出bitrate。 43 | * 当图像QP 达到minQp 时,QP 被钳位到最小值,此时编码的码率已经达到最大值,而且图像质量最好。 44 | * @subsection enc_FixQP 3.2 FixQP 45 | * Fix Qp 固定Qp 值。在码率统计时间内,编码图像所有宏块Qp 值相同,采用用户设定的图像Qp值。 46 | * @{ 47 | */ 48 | 49 | /** 50 | * 定义H.264码流NALU类型 51 | */ 52 | typedef enum { 53 | IMP_H264_NAL_UNKNOWN = 0, /**< 未指定 */ 54 | IMP_H264_NAL_SLICE = 1, /**< 一个非IDR图像的编码条带 */ 55 | IMP_H264_NAL_SLICE_DPA = 2, /**< 编码条带数据分割块A */ 56 | IMP_H264_NAL_SLICE_DPB = 3, /**< 编码条带数据分割块B */ 57 | IMP_H264_NAL_SLICE_DPC = 4, /**< 编码条带数据分割块C */ 58 | IMP_H264_NAL_SLICE_IDR = 5, /**< IDR图像的编码条带 */ 59 | IMP_H264_NAL_SEI = 6, /**< 辅助增强信息 (SEI) */ 60 | IMP_H264_NAL_SPS = 7, /**< 序列参数集 */ 61 | IMP_H264_NAL_PPS = 8, /**< 图像参数集 */ 62 | IMP_H264_NAL_AUD = 9, /**< 访问单元分隔符 */ 63 | IMP_H264_NAL_FILLER = 12, /**< 填充数据 */ 64 | } IMPEncoderH264NaluType; 65 | 66 | /** 67 | * 定义H.265码流NALU类型 68 | */ 69 | typedef enum { 70 | IMP_H265_NAL_SLICE_TRAIL_N = 0, /**< 尾随图像, 不带参考信息 */ 71 | IMP_H265_NAL_SLICE_TRAIL_R = 1, /**< 尾随图像, 带参考信息 */ 72 | IMP_H265_NAL_SLICE_TSA_N = 2, /**< 时域子层接入点图像, 不带参考信息 */ 73 | IMP_H265_NAL_SLICE_TSA_R = 3, /**< 时域子层接入点图像, 带参考信息 */ 74 | IMP_H265_NAL_SLICE_STSA_N = 4, /**< 逐步时域子层接入点图像, 不带参考信息 */ 75 | IMP_H265_NAL_SLICE_STSA_R = 5, /**< 逐步时域子层接入点图像, 带参考信息 */ 76 | IMP_H265_NAL_SLICE_RADL_N = 6, /**< 可解码随机接入前置图像, 不带参考信息 */ 77 | IMP_H265_NAL_SLICE_RADL_R = 7, /**< 可解码随机接入前置图像, 带参考信息 */ 78 | IMP_H265_NAL_SLICE_RASL_N = 8, /**< 跳过随机接入的前置图像, 不带参考信息 */ 79 | IMP_H265_NAL_SLICE_RASL_R = 9, /**< 跳过随机接入的前置图像, 带参考信息 */ 80 | IMP_H265_NAL_SLICE_BLA_W_LP = 16, /**< 断点连接接入, 带前置图像 */ 81 | IMP_H265_NAL_SLICE_BLA_W_RADL = 17, /**< 断点连接接入, 带前置图像RADL */ 82 | IMP_H265_NAL_SLICE_BLA_N_LP = 18, /**< 断点连接接入, 不带前置图像 */ 83 | IMP_H265_NAL_SLICE_IDR_W_RADL = 19, /**< 即时解码刷新, 带前置图像RADL */ 84 | IMP_H265_NAL_SLICE_IDR_N_LP = 20, /**< 即时解码刷新, 不带前置图像 */ 85 | IMP_H265_NAL_SLICE_CRA = 21, /**< 纯随机接入, 带前置图像*/ 86 | IMP_H265_NAL_VPS = 32, /**< 视频参数集 */ 87 | IMP_H265_NAL_SPS = 33, /**< 序列参数集 */ 88 | IMP_H265_NAL_PPS = 34, /**< 图像参数集 */ 89 | IMP_H265_NAL_AUD = 35, /**< 访问单元分隔符 */ 90 | IMP_H265_NAL_EOS = 36, /**< 序列结束 */ 91 | IMP_H265_NAL_EOB = 37, /**< 比特流结束 */ 92 | IMP_H265_NAL_FILLER_DATA = 38, /**< 填充数据 */ 93 | IMP_H265_NAL_PREFIX_SEI = 39, /**< 辅助增强信息 (SEI) */ 94 | IMP_H265_NAL_SUFFIX_SEI = 40, /**< 辅助增强信息 (SEI) */ 95 | IMP_H265_NAL_INVALID = 64, /**< 无效NAL类型 */ 96 | } IMPEncoderH265NaluType; 97 | 98 | /** 99 | * 定义H.264和H.265编码Channel码流NAL类型 100 | */ 101 | typedef union { 102 | IMPEncoderH264NaluType h264NalType; /**< H264E NALU 码流包类型 */ 103 | IMPEncoderH265NaluType h265NalType; /**< H265E NALU 码流包类型 */ 104 | } IMPEncoderNalType; 105 | 106 | typedef enum { 107 | IMP_ENC_SLICE_SI = 4, /**< AVC SI Slice */ 108 | IMP_ENC_SLICE_SP = 3, /**< AVC SP Slice */ 109 | IMP_ENC_SLICE_GOLDEN = 3, /**< Golden Slice */ 110 | IMP_ENC_SLICE_I = 2, /**< I Slice (can contain I blocks) */ 111 | IMP_ENC_SLICE_P = 1, /**< P Slice (can contain I and P blocks) */ 112 | IMP_ENC_SLICE_B = 0, /**< B Slice (can contain I, P and B blocks) */ 113 | IMP_ENC_SLICE_CONCEAL = 6, /**< Conceal Slice (slice was concealed) */ 114 | IMP_ENC_SLICE_SKIP = 7, /**< Skip Slice */ 115 | IMP_ENC_SLICE_REPEAT = 8, /**< Repeat Slice (repeats the content of its reference) */ 116 | IMP_ENC_SLICE_MAX_ENUM, /**< sentinel */ 117 | } IMPEncoderSliceType; 118 | 119 | /** 120 | * 定义编码帧码流包结构体 121 | */ 122 | typedef struct { 123 | uint32_t offset; /**< 码流包地址偏移 */ 124 | uint32_t length; /**< 码流包长度 */ 125 | int64_t timestamp; /**< 时间戳,单位us */ 126 | bool frameEnd; /**< 帧结束标识 */ 127 | IMPEncoderNalType nalType; /**< H.264和H.265编码Channel码流NAL类型 */ 128 | IMPEncoderSliceType sliceType; 129 | } IMPEncoderPack; 130 | 131 | /** 132 | * 定义编码帧码流类型结构体 133 | */ 134 | typedef struct { 135 | uint32_t phyAddr; /**< 帧码流物理地址 */ 136 | uint32_t virAddr; /**< 帧码流包虚拟地址 */ 137 | uint32_t streamSize; /**< virAddr对应分配的地址空间大小 */ 138 | IMPEncoderPack *pack; /**< 帧码流包结构 */ 139 | uint32_t packCount; /**< 一帧码流的所有包的个数 */ 140 | uint32_t seq; /**< 编码帧码流序列号 */ 141 | } IMPEncoderStream; 142 | 143 | typedef enum { 144 | IMP_ENC_TYPE_AVC = 0, 145 | IMP_ENC_TYPE_HEVC = 1, 146 | IMP_ENC_TYPE_JPEG = 4, 147 | } IMPEncoderEncType; 148 | 149 | #define IMP_ENC_AVC_PROFILE_IDC_BASELINE 66 150 | #define IMP_ENC_AVC_PROFILE_IDC_MAIN 77 151 | #define IMP_ENC_AVC_PROFILE_IDC_HIGH 100 152 | #define IMP_ENC_HEVC_PROFILE_IDC_MAIN 1 153 | 154 | typedef enum { 155 | IMP_ENC_PROFILE_AVC_BASELINE = ((IMP_ENC_TYPE_AVC << 24) | (IMP_ENC_AVC_PROFILE_IDC_BASELINE)), 156 | IMP_ENC_PROFILE_AVC_MAIN = ((IMP_ENC_TYPE_AVC << 24) | (IMP_ENC_AVC_PROFILE_IDC_MAIN)), 157 | IMP_ENC_PROFILE_AVC_HIGH = ((IMP_ENC_TYPE_AVC << 24) | (IMP_ENC_AVC_PROFILE_IDC_HIGH)), 158 | IMP_ENC_PROFILE_HEVC_MAIN = ((IMP_ENC_TYPE_HEVC << 24) | (IMP_ENC_HEVC_PROFILE_IDC_MAIN)), 159 | IMP_ENC_PROFILE_JPEG = (IMP_ENC_TYPE_JPEG << 24), 160 | } IMPEncoderProfile; 161 | 162 | typedef enum { 163 | IMP_ENC_PIC_FORMAT_400_8BITS = 0x0088, 164 | IMP_ENC_PIC_FORMAT_420_8BITS = 0x0188, 165 | IMP_ENC_PIC_FORMAT_422_8BITS = 0x0288, 166 | } IMPEncoderPicFormat; 167 | 168 | typedef enum { 169 | IMP_ENC_OPT_QP_TAB_RELATIVE = 0x00000001, 170 | IMP_ENC_OPT_FIX_PREDICTOR = 0x00000002, 171 | IMP_ENC_OPT_CUSTOM_LDA = 0x00000004, 172 | IMP_ENC_OPT_ENABLE_AUTO_QP = 0x00000008, 173 | IMP_ENC_OPT_ADAPT_AUTO_QP = 0x00000010, 174 | IMP_ENC_OPT_COMPRESS = 0x00000020, 175 | IMP_ENC_OPT_FORCE_REC = 0x00000040, 176 | IMP_ENC_OPT_FORCE_MV_OUT = 0x00000080, 177 | IMP_ENC_OPT_HIGH_FREQ = 0x00002000, 178 | IMP_ENC_OPT_SRD = 0x00008000, 179 | IMP_ENC_OPT_FORCE_MV_CLIP = 0x00020000, 180 | IMP_ENC_OPT_RDO_COST_MODE = 0x00040000, 181 | } IMPEncoderEncOptions; 182 | 183 | typedef enum { 184 | IMP_ENC_TOOL_WPP = 0x00000001, 185 | IMP_ENC_TOOL_TILE = 0x00000002, 186 | IMP_ENC_TOOL_LF = 0x00000004, 187 | IMP_ENC_TOOL_LF_X_SLICE = 0x00000008, 188 | IMP_ENC_TOOL_LF_X_TILE = 0x00000010, 189 | IMP_ENC_TOOL_SCL_LST = 0x00000020, 190 | IMP_ENC_TOOL_CONST_INTRA_PRED = 0x00000040, 191 | IMP_ENC_TOOL_TRANSFO_SKIP = 0x00000080, 192 | IMP_ENC_TOOL_PCM = 0x00000800, 193 | } IMPEncoderEncTools; 194 | 195 | /** 196 | * 定义编码器裁剪属性,针对输入编码器的图像先做裁剪,与编码通道的尺寸进行比较再做缩放 197 | */ 198 | typedef struct { 199 | bool enable; /**< 是否进行裁剪,取值范围:[FALSE, TRUE],TRUE:使能裁剪,FALSE:不使能裁剪 */ 200 | uint32_t x; /**< 裁剪的区域,左上角x坐标 */ 201 | uint32_t y; /**< 裁剪的区域,左上角y坐标 */ 202 | uint32_t w; /**< 裁剪的区域,宽 */ 203 | uint32_t h; /**< 裁剪的区域,高 */ 204 | } IMPEncoderCropCfg; 205 | 206 | /** 207 | * 定义编码器属性结构体 208 | */ 209 | typedef struct { 210 | IMPEncoderProfile eProfile; 211 | uint8_t uLevel; 212 | uint8_t uTier; 213 | uint16_t uWidth; 214 | uint16_t uHeight; 215 | IMPEncoderPicFormat ePicFormat; 216 | uint32_t eEncOptions; 217 | uint32_t eEncTools; 218 | IMPEncoderCropCfg crop; /**< 编码器裁剪属性 */ 219 | } IMPEncoderEncAttr; 220 | 221 | typedef enum { 222 | IMP_ENC_GOP_CTRL_MODE_DEFAULT = 0x02, 223 | IMP_ENC_GOP_CTRL_MODE_PYRAMIDAL = 0x04, 224 | IMP_ENC_GOP_CTRL_MAX_ENUM = 0xff, 225 | } IMPEncoderGopCtrlMode; 226 | 227 | typedef struct { 228 | IMPEncoderGopCtrlMode uGopCtrlMode; 229 | uint16_t uGopLength; 230 | uint8_t uNumB; 231 | uint32_t uMaxSameSenceCnt; 232 | bool bEnableLT; 233 | uint32_t uFreqLT; 234 | bool bLTRC; 235 | } IMPEncoderGopAttr; 236 | 237 | typedef enum { 238 | IMP_ENC_RC_MODE_FIXQP = 0x0, 239 | IMP_ENC_RC_MODE_CBR = 0x1, 240 | IMP_ENC_RC_MODE_VBR = 0x2, 241 | IMP_ENC_RC_MODE_CAPPED_VBR = 0x4, 242 | IMP_ENC_RC_MODE_CAPPED_QUALITY = 0x8, 243 | IMP_ENC_RC_MODE_INVALID = 0xff, 244 | } IMPEncoderRcMode; 245 | 246 | typedef enum IMPEncoderRcOptions { 247 | IMP_ENC_RC_OPT_NONE = 0x00000000, 248 | IMP_ENC_RC_SCN_CHG_RES = 0x00000001, 249 | IMP_ENC_RC_DELAYED = 0x00000002, 250 | IMP_ENC_RC_STATIC_SCENE = 0x00000004, 251 | IMP_ENC_RC_ENABLE_SKIP = 0x00000008, 252 | IMP_ENC_RC_OPT_SC_PREVENTION = 0x00000010, 253 | IMP_ENC_RC_MAX_ENUM, 254 | } IMPEncoderRcOptions; 255 | 256 | typedef struct { 257 | int16_t iInitialQP; 258 | } IMPEncoderAttrFixQP; 259 | 260 | typedef struct { 261 | uint32_t uTargetBitRate; 262 | int16_t iInitialQP; 263 | int16_t iMinQP; 264 | int16_t iMaxQP; 265 | int16_t iIPDelta; 266 | int16_t iPBDelta; 267 | uint32_t eRcOptions; 268 | uint32_t uMaxPictureSize; 269 | } IMPEncoderAttrCbr; 270 | 271 | typedef struct { 272 | uint32_t uTargetBitRate; 273 | uint32_t uMaxBitRate; 274 | int16_t iInitialQP; 275 | int16_t iMinQP; 276 | int16_t iMaxQP; 277 | int16_t iIPDelta; 278 | int16_t iPBDelta; 279 | uint32_t eRcOptions; 280 | uint32_t uMaxPictureSize; 281 | } IMPEncoderAttrVbr; 282 | 283 | typedef struct { 284 | uint32_t uTargetBitRate; 285 | uint32_t uMaxBitRate; 286 | int16_t iInitialQP; 287 | int16_t iMinQP; 288 | int16_t iMaxQP; 289 | int16_t iIPDelta; 290 | int16_t iPBDelta; 291 | uint32_t eRcOptions; 292 | uint32_t uMaxPictureSize; 293 | uint16_t uMaxPSNR; 294 | } IMPEncoderAttrCappedVbr; 295 | 296 | typedef IMPEncoderAttrCappedVbr IMPEncoderAttrCappedQuality; 297 | 298 | typedef struct { 299 | IMPEncoderRcMode rcMode; 300 | union { 301 | IMPEncoderAttrFixQP attrFixQp; 302 | IMPEncoderAttrCbr attrCbr; 303 | IMPEncoderAttrVbr attrVbr; 304 | IMPEncoderAttrCappedVbr attrCappedVbr; 305 | IMPEncoderAttrCappedQuality attrCappedQuality; 306 | }; 307 | } IMPEncoderAttrRcMode; 308 | 309 | /** 310 | * 定义编码channel帧率结构体,frmRateNum和frmRateDen经过最大公约数整除后两者之间的最小公倍数不能超过64,最好在设置之前就被最大公约数整除 311 | */ 312 | typedef struct { 313 | uint32_t frmRateNum; /**< 在一秒钟内的时间单元的数量, 以时间单元为单位。即帧率的分子 */ 314 | uint32_t frmRateDen; /**< 在一帧内的时间单元的数量, 以时间单元为单位。即帧率的分母 */ 315 | } IMPEncoderFrmRate; 316 | 317 | 318 | typedef struct { 319 | IMPEncoderAttrRcMode attrRcMode; 320 | IMPEncoderFrmRate outFrmRate; 321 | } IMPEncoderRcAttr; 322 | 323 | /** 324 | * 定义编码Channel属性结构体 325 | */ 326 | typedef struct { 327 | IMPEncoderEncAttr encAttr; /**< 编码器属性结构体 */ 328 | IMPEncoderRcAttr rcAttr; /**< 码率控制器属性结构体,只针对H264和h265 */ 329 | IMPEncoderGopAttr gopAttr; /**< 编码器属性结构体 */ 330 | } IMPEncoderChnAttr; 331 | 332 | /** 333 | * 定义编码Channel的状态结构体 334 | */ 335 | typedef struct { 336 | bool registered; /**< 注册到Group标志,取值范围:{TRUE, FALSE},TRUE:注册,FALSE:未注册 */ 337 | uint32_t leftPics; /**< 待编码的图像数 */ 338 | uint32_t leftStreamBytes; /**< 码流buffer剩余的byte数 */ 339 | uint32_t leftStreamFrames; /**< 码流buffer剩余的帧数 */ 340 | uint32_t curPacks; /**< 当前帧的码流包个数 */ 341 | uint32_t work_done; /**< 通道程序运行状态,0:正在运行,1,未运行 */ 342 | } IMPEncoderChnStat; 343 | 344 | /** 345 | * @fn int IMP_Encoder_CreateGroup(int encGroup) 346 | * 347 | * 创建编码Group 348 | * 349 | * @param[in] encGroup Group号,取值范围:[0, @ref NR_MAX_ENC_GROUPS - 1] 350 | * 351 | * @retval 0 成功 352 | * @retval 非0 失败 353 | * 354 | * @remarks 一路Group仅支持一路分辨率,不同分辨率需启动新的Group。一路Group允许最多注册2个编码channel 355 | * 356 | * @attention 如果指定的Group已经存在,则返回失败 357 | */ 358 | int IMP_Encoder_CreateGroup(int encGroup); 359 | 360 | /** 361 | * @fn int IMP_Encoder_DestroyGroup(int encGroup) 362 | * 363 | * 销毁编码Grouop. 364 | * 365 | * @param[in] encGroup Group号,取值范围:[0, @ref NR_MAX_ENC_GROUPS - 1] 366 | * 367 | * @retval 0 成功 368 | * @retval 非0 失败 369 | * 370 | * @remarks 销毁Group时,必须保证Group为空,即没有任何Channel在Group中注册,或注册到Group中 371 | * 的Channel已经反注册,否则返回失败 372 | * 373 | * @attention 销毁并不存在的Group,则返回失败 374 | */ 375 | int IMP_Encoder_DestroyGroup(int encGroup); 376 | 377 | 378 | int IMP_Encoder_SetDefaultParam(IMPEncoderChnAttr *chnAttr, IMPEncoderProfile profile, IMPEncoderRcMode rcMode, uint16_t uWidth, uint16_t uHeight, uint32_t frmRateNum, uint32_t frmRateDen, uint32_t uGopLength, int uMaxSameSenceCnt, int iInitialQP, uint32_t uTargetBitRate); 379 | 380 | /** 381 | * @fn int IMP_Encoder_CreateChn(int encChn, const IMPEncoderChnAttr *attr) 382 | * 383 | * 创建编码Channel 384 | * 385 | * @param[in] encChn 编码Channel号,取值范围: [0, @ref NR_MAX_ENC_CHN - 1] 386 | * @param[in] attr 编码Channel属性指针 387 | * 388 | * @retval 0 成功 389 | * @retval 非0 失败 390 | * 391 | * @remarks 编码Channel属性由两部分组成,编码器属性和码率控制属性 392 | * @remarks 编码器属性首先需要选择编码协议,然后分别对各种协议对应的属性进行赋值 393 | */ 394 | int IMP_Encoder_CreateChn(int encChn, const IMPEncoderChnAttr *attr); 395 | 396 | /** 397 | * @fn int IMP_Encoder_DestroyChn(int encChn) 398 | * 399 | * 销毁编码Channel 400 | * 401 | * @param[in] encChn 编码Channel号,取值范围: [0, @ref NR_MAX_ENC_CHN - 1] 402 | * 403 | * @retval 0 成功 404 | * @retval 非0 失败 405 | * 406 | * @attention 销毁并不存在的Channel,则返回失败 407 | * @attention 销毁前必须保证Channel已经从Group反注册,否则返回失败 408 | */ 409 | int IMP_Encoder_DestroyChn(int encChn); 410 | 411 | /** 412 | * @fn int IMP_Encoder_GetChnAttr(int encChn, IMPEncoderChnAttr * const attr) 413 | * 414 | * 获取编码Channel的属性 415 | * 416 | * @param[in] encChn 编码Channel号,取值范围: [0, @ref NR_MAX_ENC_CHN - 1] 417 | * @param[in] attr 编码Channel属性 418 | * 419 | * @retval 0 成功 420 | * @retval 非0 失败 421 | */ 422 | int IMP_Encoder_GetChnAttr(int encChn, IMPEncoderChnAttr * const attr); 423 | 424 | /** 425 | * @fn int IMP_Encoder_RegisterChn(int encGroup, int encChn) 426 | * 427 | * 注册编码Channel到Group 428 | * 429 | * @param[in] encGroup 编码Group号,取值范围: [0, @ref NR_MAX_ENC_GROUPS - 1] 430 | * @param[in] encChn 编码Channel号,取值范围: [0, @ref NR_MAX_ENC_CHN - 1] 431 | * 432 | * @retval 0 成功 433 | * @retval 非0 失败 434 | * 435 | * @attention 注册并不存在的Channel,则返回失败 436 | * @attention 注册Channel到不存在的Group,否则返回失败 437 | * @attention 同一个编码Channel只能注册到一个Group,如果该Channel已经注册到某个Group,则返回失败 438 | * @attention 如果一个Group已经被注册,那么这个Group就不能再被其他的Channel注册,除非之前注册关系被解除 439 | */ 440 | 441 | int IMP_Encoder_RegisterChn(int encGroup, int encChn); 442 | /** 443 | * @fn int IMP_Encoder_UnRegisterChn(int encChn) 444 | * 445 | * 反注册编码Channel到Group 446 | * 447 | * @param[in] encChn 编码Channel号,取值范围: [0, @ref NR_MAX_ENC_CHN - 1] 448 | * 449 | * @retval 0 成功 450 | * @retval 非0 失败 451 | * 452 | * @remarks Channel注销之后,编码Channel会被复位,编码Channel里的码流buffer都会被清空,如果用户还在使用 453 | * 未及时释放的码流buffer,将不能保证buffer数据的正确性,用户可以使用IMP_Encoder_Query接口来查询编 454 | * 码Channel码流buffer状态,确认码流buffer里的码流取完之后再反注册Channel 455 | * 456 | * @attention 注销未创建的Channel,则返回失败 457 | * @attention 注销未注册的Channel,则返回失败 458 | * @attention 如果编码Channel未停止接收图像编码,则返回失败 459 | */ 460 | int IMP_Encoder_UnRegisterChn(int encChn); 461 | 462 | /** 463 | * @fn int IMP_Encoder_StartRecvPic(int encChn) 464 | * 465 | * 开启编码Channel接收图像 466 | * 467 | * @param[in] encChn 编码Channel号,取值范围: [0, @ref NR_MAX_ENC_CHN - 1] 468 | * 469 | * @retval 0 成功 470 | * @retval 非0 失败 471 | * 472 | * @remarks 开启编码Channel接收图像后才能开始编码 473 | * 474 | * @attention 如果Channel未创建,则返回失败 475 | * @attention 如果Channel没有注册到Group,则返回失败 476 | */ 477 | int IMP_Encoder_StartRecvPic(int encChn); 478 | 479 | /** 480 | * @fn int IMP_Encoder_StopRecvPic(int encChn) 481 | * 482 | * 停止编码Channel接收图像 483 | * 484 | * @param[in] encChn 编码Channel号,取值范围: [0, @ref NR_MAX_ENC_CHN - 1] 485 | * 486 | * @retval 0 成功 487 | * @retval 非0 失败 488 | * 489 | * @remarks 此接口并不判断当前是否停止接收,即允许重复停止接收不返回错误 490 | * @remarks 调用此接口仅停止接收原始数据编码,码流buffer并不会被消除 491 | * 492 | * @attention 如果Channel未创建,则返回失败 493 | * @attention 如果Channel没有注册到Group,则返回失败 494 | */ 495 | int IMP_Encoder_StopRecvPic(int encChn); 496 | 497 | /** 498 | * @fn int IMP_Encoder_Query(int encChn, IMPEncoderChnStat *stat) 499 | * 500 | * 查询编码Channel状态 501 | * 502 | * @param[in] encChn 编码Channel号,取值范围: [0, @ref NR_MAX_ENC_CHN - 1] 503 | * @param[out] stat 编码Channel状态 504 | * 505 | * @retval 0 成功 506 | * @retval 非0 失败 507 | * 508 | * @remarks 无 509 | * 510 | * @attention 无 511 | */ 512 | int IMP_Encoder_Query(int encChn, IMPEncoderChnStat *stat); 513 | 514 | /** 515 | * @fn int IMP_Encoder_GetStream(int encChn, IMPEncoderStream *stream, bool blockFlag) 516 | * 517 | * 获取编码的码流 518 | * 519 | * @param[in] encChn 编码Channel号,取值范围: [0, @ref NR_MAX_ENC_CHN - 1] 520 | * @param[in] stream 码流结构体指针 521 | * @param[in] blockFlag 是否使用阻塞方式获取,0:非阻塞,1:阻塞 522 | * 523 | * @retval 0 成功 524 | * @retval 非0 失败 525 | * 526 | * @remarks 每次获取一帧码流的数据 527 | * @remarks 如果用户长时间不获取码流,码流缓冲区就会满。一个编码Channel如果发生码流缓冲区满,就会把后 528 | * 面接收的图像丢掉,直到用户获取码流,从而有足够的码流缓冲可以用于编码时,才开始继续编码。建议用户 529 | * 获取码流接口调用与释放码流的接口调用成对出现,且尽快释放码流,防止出现由于用户态获取码流,释放不 530 | * 及时而导致的码流 buffer 满,停止编码。 531 | * @remarks 对于H264和H265类型码流,一次调用成功获取一帧的码流,这帧码流可能包含多个包。 532 | * @remarks 对于JPEG类型码流,一次调用成功获取一帧的码流,这帧码流只包含一个包,这一帧包含了JPEG图片文件的完整信息。 533 | * 534 | * 示例: 535 | * @code 536 | * int ret; 537 | * ret = IMP_Encoder_PollingStream(ENC_H264_CHANNEL, 1000); //Polling码流Buffer,等待可获取状态 538 | * if (ret < 0) { 539 | * printf("Polling stream timeout\n"); 540 | * return -1; 541 | * } 542 | * 543 | * IMPEncoderStream stream; 544 | * ret = IMP_Encoder_GetStream(ENC_H264_CHANNEL, &stream, 1); //获取一帧码流,阻塞方式 545 | * if (ret < 0) { 546 | * printf("Get Stream failed\n"); 547 | * return -1; 548 | * } 549 | * 550 | * int i, nr_pack = stream.packCount; 551 | * for (i = 0; i < nr_pack; i++) { //保存这一帧码流的每个包 552 | * ret = write(stream_fd, (void *)stream.pack[i].virAddr, 553 | * stream.pack[i].length); 554 | * if (ret != stream.pack[i].length) { 555 | * printf("stream write error:%s\n", strerror(errno)); 556 | * return -1; 557 | * } 558 | * } 559 | * @endcode 560 | * 561 | * @attention 如果pstStream为NULL,则返回失败; 562 | * @attention 如果Channel未创建,则返回失败; 563 | */ 564 | int IMP_Encoder_GetStream(int encChn, IMPEncoderStream *stream, bool blockFlag); 565 | 566 | /** 567 | * @fn int IMP_Encoder_ReleaseStream(int encChn, IMPEncoderStream *stream) 568 | * 569 | * 释放码流缓存 570 | * 571 | * @param[in] encChn 编码Channel号,取值范围: [0, @ref NR_MAX_ENC_CHN - 1] 572 | * @param[in] stream 码流结构体指针 573 | * 574 | * @retval 0 成功 575 | * @retval 非0 失败 576 | * 577 | * @remarks 此接口应当和IMP_Encoder_GetStream配对起来使用,\n 578 | * 用户获取码流后必须及时释放已经获取的码流缓存,否则可能会导致码流buffer满,影响编码器编码。\n 579 | * 并且用户必须按先获取先 580 | * 释放的顺序释放已经获取的码流缓存; 581 | * @remarks 在编码Channel反注册后,所有未释放的码流包均无效,不能再使用或者释放这部分无效的码流缓存。 582 | * 583 | * @attention 如果pstStream为NULL,则返回失败; 584 | * @attention 如果Channel未创建,则返回失败; 585 | * @attention 释放无效的码流会返回失败。 586 | */ 587 | int IMP_Encoder_ReleaseStream(int encChn, IMPEncoderStream *stream); 588 | 589 | /** 590 | * @fn int IMP_Encoder_PollingStream(int encChn, uint32_t timeoutMsec) 591 | * 592 | * Polling码流缓存 593 | * 594 | * @param[in] encChn 编码Channel号,取值范围: [0, @ref NR_MAX_ENC_CHN - 1] 595 | * @param[in] timeoutMsec 超时时间,单位:毫秒 596 | * 597 | * @retval 0 成功 598 | * @retval 非0 失败 599 | * 600 | * @remarks 在获取码流之前可以用过此API进行Polling,当码流缓存不为空时或超时时函数返回。 601 | * 602 | * @attention 无 603 | */ 604 | int IMP_Encoder_PollingStream(int encChn, uint32_t timeoutMsec); 605 | 606 | /** 607 | * @fn int IMP_Encoder_PollingModuleStream(uint32_t *encChnBitmap, uint32_t timeoutMsec) 608 | * 609 | * Polling整个编码模组各个已编码channel的码流 610 | * 611 | * @param[out] encChnBitmap 每一位的位数代表对应的channel号,若有已编码好的码流,则对应的位置1,否则置0 612 | * @param[in] timeoutMsec 超时时间,单位:毫秒 613 | * 614 | * @retval 0 成功 615 | * @retval 非0 失败 616 | * 617 | * @remarks 在获取码流之前可以用过此API进行Polling,当码流缓存不为空时或超时时函数返回。 618 | * @remarks *encChnBitmap 对应置1的位只有在调用IMP_Encoder_ReleaseStream时当检测到该位对应的channel码流缓存不为空时时才会被置零 619 | * 620 | * @attention 无 621 | */ 622 | int IMP_Encoder_PollingModuleStream(uint32_t *encChnBitmap, uint32_t timeoutMsec); 623 | 624 | /** 625 | * @fn int IMP_Encoder_GetFd(int encChn) 626 | * 627 | * 获取编码Channel对应的设备文件句柄 628 | * 629 | * @param[in] encChn 编码Channel号,取值范围: [0, @ref NR_MAX_ENC_CHN - 1] 630 | * 631 | * @retval >=0 成功, 返回设备文件描述符 632 | * @retval < 0 失败 633 | * 634 | * @remarks 在使用IMP_Encoder_PollingStream不合适的场合,比如在同一个地方Polling多个编码channel的编码完成情况时, 635 | * 可以使用此文件句柄调用select, poll等类似函数来阻塞等待编码完成事件 636 | * @remarks 调用此API需要通道已经存在 637 | * 638 | * @attention 无 639 | */ 640 | int IMP_Encoder_GetFd(int encChn); 641 | 642 | /** 643 | * @fn int IMP_Encoder_SetbufshareChn(int encChn, int shareChn) 644 | * 645 | * 设置jpeg通道共享265/264编码通道内存 646 | * 647 | * @param[in] encChn 编码Channel号,取值范围: [0, @ref NR_MAX_ENC_CHN - 1] 648 | * @param[in] sharechn 被共享内存的264/265编码Channel号,取值范围: [0, @ref NR_MAX_ENC_CHN - 1] 649 | * 650 | * @retval 0 成功 651 | * @retval 非0 失败 652 | * 653 | * @remarks 调用此API之前被共享内存编码通道已创建 654 | * @remarks 此API需要在通道创建之前调用 655 | * 656 | * @attention 无 657 | */ 658 | int IMP_Encoder_SetbufshareChn(int encChn, int shareChn); 659 | 660 | /** 661 | * @fn int IMP_Encoder_SetChnResizeMode(int encChn, int en); 662 | * 663 | * 设置编码缩放是否需要申请额外rmem内存 664 | * 665 | * @param[in] encChn 编码Channel号,取值范围: [0, @ref NR_MAX_ENC_CHN - 1] 666 | * @param[in] en 使能不需要申请rmem,1:不需要申请rmem,0:需要申请rmem 667 | * 668 | * @retval 0 成功 669 | * @retval 非0 失败 670 | * 671 | * @remarks 此API只在编码缩放的分辨率小于原始分辨率的情况下调用,编码缩放的分辨率大于原始分辨率无需调用 672 | * 673 | * @attention 无 674 | */ 675 | int IMP_Encoder_SetChnResizeMode(int encChn, int en); 676 | 677 | /** 678 | * @fn int IMP_Encoder_SetMaxStreamCnt(int encChn, int nrMaxStream) 679 | * 680 | * 设置码流缓存Buffer个数 681 | * 682 | * @param[in] encChn 编码Channel号,取值范围: [0, @ref NR_MAX_ENC_CHN - 1] 683 | * @param[in] nrMaxStream 码流Buffer数,取值范围: [1, @ref NR_MAX_ENC_CHN_STREAM] 684 | * 685 | * @retval 0 成功 686 | * @retval 非0 失败 687 | * 688 | * @remarks 由于码流缓存Buffer个数在通道创建时就已经固定,因此次API需要在通道创建之前调用。 689 | * @remarks 若通道创建之前不调用此API设置码流缓存Buffer个数,则使用SDK默认的buffer个数。 690 | * 691 | * @attention 无 692 | */ 693 | int IMP_Encoder_SetMaxStreamCnt(int encChn, int nrMaxStream); 694 | 695 | /** 696 | * @fn int IMP_Encoder_GetMaxStreamCnt(int encChn, int *nrMaxStream) 697 | * 698 | * 获取码流Buffer数 699 | * 700 | * @param[in] encChn 编码Channel号,取值范围: [0, @ref NR_MAX_ENC_CHN - 1] 701 | * @param[out] nrMaxStream 码流Buffer数变量指针 702 | * 703 | * @retval 0 成功 704 | * @retval 非0 失败 705 | * 706 | * @remarks 无 707 | * 708 | * @attention 无 709 | */ 710 | int IMP_Encoder_GetMaxStreamCnt(int encChn, int *nrMaxStream); 711 | 712 | /** 713 | * @fn int IMP_Encoder_RequestIDR(int encChn) 714 | * 715 | * 请求IDR帧 716 | * 717 | * @param[in] encChn 编码Channel号,取值范围: [0, @ref NR_MAX_ENC_CHN - 1] 718 | * 719 | * @retval 0 成功 720 | * @retval 非0 失败 721 | * 722 | * @remarks 在调用此API后,会在最近的编码帧申请IDR帧编码。 723 | * 724 | * @attention 此API只适用于H264和h265编码channel 725 | */ 726 | int IMP_Encoder_RequestIDR(int encChn); 727 | 728 | /** 729 | * @fn int IMP_Encoder_FlushStream(int encChn) 730 | * 731 | * 刷掉编码器里残留的旧码流,并以IDR帧开始编码 732 | * 733 | * @param[in] encChn 编码Channel号,取值范围: [0, @ref NR_MAX_ENC_CHN - 1] 734 | * 735 | * @retval 0 成功 736 | * @retval 非0 失败 737 | * 738 | * @remarks 在调用此API后,会在最近的编码帧申请IDR帧编码。 739 | * 740 | * @attention 无 741 | */ 742 | int IMP_Encoder_FlushStream(int encChn); 743 | 744 | /** 745 | * @fn int IMP_Encoder_GetChnFrmRate(int encChn, IMPEncoderFrmRate *pstFps) 746 | * 747 | * 获取帧率控制属性 748 | * 749 | * @param[in] encChn 编码Channel号,取值范围: [0, @ref NR_MAX_ENC_CHN - 1] 750 | * @param[out] pstFpsCfg 帧率控制属性参数 751 | * 752 | * @retval 0 成功 753 | * @retval 非0 失败 754 | * 755 | * @remarks 调用此API会获取通道的帧率控制属性,调用此API需要通道已经存在。 756 | * 757 | * @attention 此API只适用于H264和h265编码channel 758 | */ 759 | int IMP_Encoder_GetChnFrmRate(int encChn, IMPEncoderFrmRate *pstFps); 760 | 761 | /** 762 | * @fn int IMP_Encoder_SetChnFrmRate(int encChn, const IMPEncoderFrmRate *pstFps) 763 | * 764 | * 动态设置帧率控制属性 765 | * 766 | * @param[in] encChn 编码Channel号,取值范围: [0, @ref NR_MAX_ENC_CHN - 1] 767 | * @param[out] pstFpsCfg 帧率控制属性参数 768 | * 769 | * @retval 0 成功 770 | * @retval 非0 失败 771 | * 772 | * @remarks 调用此API会重新设置编码器帧率属性,帧率属性在下一个GOP生效,最大延时1秒钟生效,调用此API需要通道已经存在。 773 | * @remarks 如果调用IMP_FrameSource_SetChnFPS()函数动态改变系统帧率,那么需要调用该函数修改编码器帧率,完成正确参数配置。 774 | * 775 | * @attention 此API只适用于H264和h265编码channel 776 | */ 777 | int IMP_Encoder_SetChnFrmRate(int encChn, const IMPEncoderFrmRate *pstFps); 778 | 779 | int IMP_Encoder_SetChnBitRate(int encChn, int iTargetBitRate, int iMaxBitRate); 780 | 781 | int IMP_Encoder_SetChnGopLength(int encChn, int iGopLength); 782 | 783 | /** 784 | * @fn int IMP_Encoder_GetChnAttrRcMode(int encChn, IMPEncoderAttrRcMode *pstRcModeCfg). 785 | * 786 | * 获取码率控制模式属性 787 | * 788 | * @param[in] encChn 编码Channel号,取值范围: [0, @ref NR_MAX_ENC_CHN - 1] 789 | * @param[out] pstRcCfg 码率控制模式属性参数 790 | * 791 | * @retval 0 成功 792 | * @retval 非0 失败 793 | * 794 | * @remarks 调用此API会获取通道的码率控制模式属性,调用此API需要通道已经存在。 795 | * 796 | * @attention 此API只适用于H264和h265编码channel 797 | */ 798 | int IMP_Encoder_GetChnAttrRcMode(int encChn, IMPEncoderAttrRcMode *pstRcModeCfg); 799 | 800 | /** 801 | * @fn int IMP_Encoder_SetChnAttrRcMode(int encChn, const IMPEncoderAttrRcMode *pstRcModeCfg). 802 | * 803 | * 设置码率控制模式属性 804 | * 805 | * @param[in] encChn 编码Channel号,取值范围: [0, @ref NR_MAX_ENC_CHN - 1] 806 | * @param[in] pstRcCfg 码率控制模式属性参数 807 | * 808 | * @retval 0 成功 809 | * @retval 非0 失败 810 | * 811 | * @remarks 调用此API会设置通道的码率控制模式属性,下一个IDR生效,调用此API需要通道已经存在。 812 | * 813 | * @attention 目前,码率控制模式支持ENC_RC_MODE_FIXQP, ENC_RC_MODE_CBR, ENC_RC_MODE_VBR 与 ENC_RC_MODE_SMART 814 | * @attention 此API只适用于H264和h265编码channel 815 | */ 816 | int IMP_Encoder_SetChnAttrRcMode(int encChn, const IMPEncoderAttrRcMode *pstRcModeCfg); 817 | 818 | int IMP_Encoder_GetChnGopAttr(int encChn, IMPEncoderGopAttr *pGopAttr); 819 | int IMP_Encoder_SetChnGopAttr(int encChn, const IMPEncoderGopAttr *pGopAttr); 820 | 821 | /** 822 | * @fn int IMP_Encoder_SetFisheyeEnableStatus(int encChn, int enable) 823 | * 824 | * 设置Ingenic提供的鱼眼矫正算法的使能状态 825 | * 826 | * @param[in] encChn 编码Channel号,取值范围: [0, @ref NR_MAX_ENC_CHN - 1] 827 | * @param[in] enable 0:不使能(默认),1:使能 828 | * 829 | * @retval 0 成功 830 | * @retval 非0 失败 831 | * 832 | * @remarks 由于鱼眼矫正算法的使能状态在通道创建时就已经固定,因此次API需要在通道创建之前调用。 833 | * @remarks 若通道创建之前不调用此API设置Ingenic提供的鱼眼矫正算法的使能状态,则默认不使能,即不能使用君正提供的鱼眼矫正算法。 834 | * 835 | * @attention 此API只适用于H264和h265编码channel 836 | */ 837 | int IMP_Encoder_SetFisheyeEnableStatus(int encChn, int enable); 838 | 839 | /** 840 | * @fn int IMP_Encoder_GetFisheyeEnableStatus(int encChn, int *enable) 841 | * 842 | * 获取Ingenic提供的鱼眼矫正算法的使能状态 843 | * 844 | * @param[in] encChn 编码Channel号,取值范围: [0, @ref NR_MAX_ENC_CHN - 1] 845 | * @param[out] enable 返回设置的Ingenic提供的鱼眼矫正算法的使能状态,0:未使能,1:已使能 846 | * 847 | * @retval 0 成功 848 | * @retval 非0 失败 849 | * 850 | * @attention 此API只适用于H264和h265编码channel 851 | */ 852 | int IMP_Encoder_GetFisheyeEnableStatus(int encChn, int *enable); 853 | 854 | /** 855 | * @fn int IMP_Encoder_GetChnEncType(int encChn, IMPEncoderEncType *encType) 856 | * 857 | * 获取图像编码协议类型 858 | * 859 | * @param[in] encChn 编码Channel号, 取值范围: [0, @ref NR_MAX_ENC_CHN - 1] 860 | * @param[out] encType 返回获取图像编码协议类型 861 | * 862 | * @retval 0 成功 863 | * @retval 非0 失败 864 | * 865 | * @remarks 如果通道未创建, 则返回失败 866 | * 867 | * @attention 无 868 | */ 869 | int IMP_Encoder_GetChnEncType(int encChn, IMPEncoderEncType *encType); 870 | 871 | /** 872 | * @} 873 | */ 874 | 875 | #ifdef __cplusplus 876 | #if __cplusplus 877 | } 878 | #endif 879 | #endif /* __cplusplus */ 880 | 881 | #endif /* __IMP_ENCODER_H__ */ 882 | -------------------------------------------------------------------------------- /include/imp/imp_audio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Audio utils header file. 3 | * 4 | * Copyright (C) 2014 Ingenic Semiconductor Co.,Ltd 5 | */ 6 | 7 | #ifndef __IMP_AUDIO_H__ 8 | #define __IMP_AUDIO_H__ 9 | 10 | #include 11 | 12 | #ifdef __cplusplus 13 | #if __cplusplus 14 | extern "C" 15 | { 16 | #endif 17 | #endif /* __cplusplus */ 18 | 19 | /** 20 | * @file 21 | * IMP 音频输入输出头文件 22 | */ 23 | 24 | /** 25 | * @defgroup IMP_Audio 26 | * @ingroup imp 27 | * @brief 音频模块,包含录放音、音频编解码、音量及增益设置、回声消除、自动增益等功能 28 | * 29 | * @section audio_summary 1 概述 30 | * 音频功能包含音频输入,音频输出,回音消除,音频编码和音频解码5个模块. \n 31 | * 其中音频输入和音频输出存在设备和通道的概念.其中一个MIC我们认为是一个Device,而一个MIC可以有多路Channel输入. \n 32 | * 同样的一个SPK我们认为是一个放音Device,而一个SPK也可以有多路Channel输出. \n 33 | * 当前版本的音频API一个Device只支持一个Channel. \n 34 | * 回音消除位于音频输入接口中,具体说明在功能描述中体现. \n 35 | * 音频编码当前音频API中支持PT_G711A、PT_G711U和PT_G726格式音频编码,如需要增加新的编码方式,需要注册编码器. \n 36 | * 音频解码当前音频API中支持PT_G711A、PT_G711U和PT_G726格式音频解码,如需要增加新的解码方式,需要注册解码器. \n 37 | * @section audio_function_description 2 功能描述 38 | * 以下是对每个模块的具体说明 39 | * @subsection audio_in 2.1 音频输入 40 | * 音频输入Device ID 对应关系, 0: 对应数字MIC 1: 对应模拟MIC \n 41 | * 音频输入Channel当前API只支持1个通道. \n 42 | * 音频输入的音量设置,音量的取值范围为[-30 ~ 120]. -30代表静音,120表示将声音放大30dB,步长0.5dB.其中60是音量设置的一个临界点,\n 43 | * 在这个值上软件不对音量做增加或减小,当音量值小于60时,每下降1,音量减小0.5dB;当音量值大于60时,上增加1,音量增加0.5dB。 44 | * @subsection audio_out 2.2 音频输出 45 | * 音频输出Device ID 对应关系, 0: 对应默认SPK 1: 对应其他SPK \n 46 | * 音频输出Channel当前API只支持1个通道. \n 47 | * 音频输出的音量设置,音量的取值范围为[-30 ~ 120]. -30代表静音,120表示将声音放大30dB,步长0.5dB.其中60是音量设置的一个临界点,\n 48 | * 在这个值上软件不对音量做增加或减小,当音量值小于60时,每下降1,音量减小0.5dB;当音量值大于60时,上增加1,音量增加0.5dB. \n 49 | * @subsection audio_aec 2.3 回音消除 50 | * 回音消除属于音频输入接口中的一项功能,所以在使能回音消除时必须先使能音频输入设备和通道. \n 51 | * 回音消除当前支持音频采样率为8K和16K,一帧数据采样数为10ms音频数据的整数倍(如:8K采样率, 送入的数据为:8000 × 2 / 100 = 160byte的整数倍)。\n 52 | * 回音消除针对不同的设备,不同的封装,回音消除会有不同的效果. \n 53 | * 回音消除目前不支持自适应,所以针对不同设备有单独的回音消除参数, \n 54 | * 回音消除的参数文件位于/etc/webrtc_profile.ini 配置文件中. \n 55 | * 配置文件格式为如下(以下列出主要需要调试的三个参数): \n 56 | * [Set_Far_Frame] \n 57 | * Frame_V=0.3 \n 58 | * [Set_Near_Frame] \n 59 | * Frame_V=0.1 \n 60 | * delay_ms=150 \n 61 | * 62 | * 其中第一个标签[Set_Far_Frame]中的内容代表远端参数,即SPK端放音数据参数. \n 63 | * Fram_V 代表音频幅值比例,调节该参数可以调节放音数据的幅度(此幅度只用于回音消除). \n 64 | * 其中第一个标签[Set_Near_Frame]中的内容代表近端参数,即MIC端录音数据参数. \n 65 | * Fram_V 代表音频幅值比例,调节该参数可以调节录音数据的幅度(此幅度只用于回音消除). \n 66 | * delay_ms 由于软件和硬件具有延时性,且SPK与MIC的安放有一定距离,SPK放音数据会重新被MIC采样,所以SPK数据在MIC数据中体现会存在一定延时. \n 67 | * 该时间代表放音数据在录音数据中的时间差. \n 68 | 69 | * @subsection audio_enc 2.4 音频编码 70 | * 音频编码目前音频API支持PT_G711A、PT_G711U和PT_G726格式音频编码,如果需要增加新的编码方式,需要调用IMP_AENC_RegisterEncoder接口进行注册编码器. 71 | * @subsection audio_dec 2.5 音频解码 72 | * 音频解码目前音频API支持PT_G711A、PT_G711U和PT_G726格式音频解码,如果需要增加新的解码方式,需要调用IMP_ADEC_RegisterDecoder接口进行注册解码器. 73 | * @{ 74 | */ 75 | 76 | /** 77 | * 最大音频帧缓存数 78 | */ 79 | #define MAX_AUDIO_FRAME_NUM 50 80 | 81 | /** 82 | * 音频流阻塞类型 83 | */ 84 | typedef enum { 85 | BLOCK = 0, /**< 阻塞 */ 86 | NOBLOCK = 1, /**< 非阻塞 */ 87 | } IMPBlock; 88 | 89 | /** 90 | * 音频采样率定义. 91 | */ 92 | typedef enum { 93 | AUDIO_SAMPLE_RATE_8000 = 8000, /**< 8KHz采样率 */ 94 | AUDIO_SAMPLE_RATE_16000 = 16000, /**< 16KHz采样率 */ 95 | AUDIO_SAMPLE_RATE_24000 = 24000, /**< 24KHz采样率 */ 96 | AUDIO_SAMPLE_RATE_32000 = 32000, /**< 32KHz采样率 */ 97 | AUDIO_SAMPLE_RATE_44100 = 44100, /**< 44.1KHz采样率 */ 98 | AUDIO_SAMPLE_RATE_48000 = 48000, /**< 48KHz采样率 */ 99 | AUDIO_SAMPLE_RATE_96000 = 96000, /**< 96KHz采样率 */ 100 | } IMPAudioSampleRate; 101 | 102 | /** 103 | * 音频采样精度定义. 104 | */ 105 | typedef enum { 106 | AUDIO_BIT_WIDTH_16 = 16, /**< 16bit采样精度 */ 107 | } IMPAudioBitWidth; 108 | 109 | /** 110 | * 音频声道模式定义. 111 | */ 112 | typedef enum { 113 | AUDIO_SOUND_MODE_MONO = 1, /**< 单声道 */ 114 | AUDIO_SOUND_MODE_STEREO = 2, /**< 双声道 */ 115 | } IMPAudioSoundMode; 116 | 117 | /** 118 | * 定义音频净荷类型枚举. 119 | */ 120 | typedef enum { 121 | PT_PCM = 0, 122 | PT_G711A = 1, 123 | PT_G711U = 2, 124 | PT_G726 = 3, 125 | PT_AEC = 4, 126 | PT_ADPCM = 5, 127 | PT_MAX = 6, 128 | } IMPAudioPalyloadType; 129 | 130 | /** 131 | * 定义解码方式. 132 | */ 133 | typedef enum { 134 | ADEC_MODE_PACK = 0, /**< Pack 方式解码 */ 135 | ADEC_MODE_STREAM = 1, /**< Stream 方式解码 */ 136 | } IMPAudioDecMode; 137 | 138 | /** 139 | * 音频输入输出设备属性. 140 | */ 141 | typedef struct { 142 | IMPAudioSampleRate samplerate; /**< 音频采样率 */ 143 | IMPAudioBitWidth bitwidth; /**< 音频采样精度 */ 144 | IMPAudioSoundMode soundmode; /**< 音频声道模式 */ 145 | int frmNum; /**< 缓存帧的数目, 取值范围:[2, MAX_AUDIO_FRAME_NUM] */ 146 | int numPerFrm; /**< 每帧的采样点个数 */ 147 | int chnCnt; /**< 支持的通道数目 */ 148 | } IMPAudioIOAttr; 149 | 150 | /** 151 | * 音频帧结构体. 152 | */ 153 | typedef struct { 154 | IMPAudioBitWidth bitwidth; /**< 音频采样精度 */ 155 | IMPAudioSoundMode soundmode; /**< 音频声道模式 */ 156 | uint32_t *virAddr; /**< 音频帧数据虚拟地址 */ 157 | uint32_t phyAddr; /**< 音频帧数据物理地址 */ 158 | int64_t timeStamp; /**< 音频帧数据时间戳 */ 159 | int seq; /**< 音频帧序号 */ 160 | int len; /**< 音频帧长度 */ 161 | } IMPAudioFrame; 162 | 163 | /** 164 | * 音频通道参数结构体. 165 | */ 166 | typedef struct { 167 | int usrFrmDepth; /**< 音频帧缓存深度 */ 168 | int Rev; /**< 保留 */ 169 | } IMPAudioIChnParam; 170 | 171 | /** 172 | * 音频输出通道的数据缓存状态结构体. 173 | */ 174 | typedef struct { 175 | int chnTotalNum; /**< 输出通道总的缓存块数 */ 176 | int chnFreeNum; /**< 空闲缓存块数 */ 177 | int chnBusyNum; /**< 被占用的缓存块数 */ 178 | } IMPAudioOChnState; 179 | 180 | /** 181 | * 定义音频码流结构体. 182 | */ 183 | typedef struct { 184 | uint8_t *stream; /**< 数据流指针 */ 185 | uint32_t phyAddr; /**< 数据流物理地址 */ 186 | int len; /**< 音频码流长度 */ 187 | int64_t timeStamp; /**< 时间戳 */ 188 | int seq; /**< 音频码流序号 */ 189 | } IMPAudioStream; 190 | 191 | /** 192 | * 定义音频编码通道属性结构体. 193 | */ 194 | typedef struct { 195 | IMPAudioPalyloadType type; /**< 音频净荷数据类型 */ 196 | int bufSize; /**< buf 大小,以帧为单位,[2~MAX_AUDIO_FRAME_NUM] */ 197 | uint32_t *value; /**< 协议属性指针 */ 198 | } IMPAudioEncChnAttr; 199 | 200 | /** 201 | * 定义编码器属性结构体. 202 | */ 203 | typedef struct { 204 | IMPAudioPalyloadType type; /**< 编码协议类型 */ 205 | int maxFrmLen; /**< 最大码流长度 */ 206 | char name[16]; /**< 编码器名称 */ 207 | int (*openEncoder)(void *encoderAttr, void 208 | *encoder); 209 | int (*encoderFrm)(void *encoder, IMPAudioFrame 210 | *data, unsigned char *outbuf,int *outLen); 211 | int (*closeEncoder)(void *encoder); 212 | } IMPAudioEncEncoder; 213 | 214 | /** 215 | * 定义解码通道属性结构体. 216 | */ 217 | typedef struct { 218 | IMPAudioPalyloadType type; /**< 音频解码协议类型 */ 219 | int bufSize; /**< 音频解码缓存大小 */ 220 | IMPAudioDecMode mode; /**< 解码方式 */ 221 | void *value; /**< 具体协议属性指针 */ 222 | } IMPAudioDecChnAttr; 223 | 224 | /** 225 | * 定义解码器属性结构体. 226 | */ 227 | typedef struct { 228 | IMPAudioPalyloadType type; /**< 音频解码协议类型 */ 229 | char name[16]; /**< 音频解码器名字 */ 230 | int (*openDecoder)(void *decoderAttr, void 231 | *decoder); 232 | int (*decodeFrm)(void *decoder, unsigned char 233 | *inbuf,int inLen, unsigned short *outbuf,int 234 | *outLen,int *chns); 235 | int (*getFrmInfo)(void *decoder, void *info); 236 | int (*closeDecoder)(void *decoder); 237 | } IMPAudioDecDecoder; 238 | 239 | /** 240 | * 定义AGC增益结构体. 241 | */ 242 | typedef struct { 243 | int TargetLevelDbfs; /**< 增益级别,取值为[0, 31], 这指目标音量级别,单位为db,为负值.值越小,音量越大. */ 244 | int CompressionGaindB; /**< 设置最大的增益值,[0, 90],0代表无增益,值越大,增益越高. */ 245 | } IMPAudioAgcConfig; 246 | 247 | /** 248 | * 定义噪声抑制级别. 249 | */ 250 | enum Level_ns { 251 | NS_LOW, /**< 低等级级别噪声抑制 */ 252 | NS_MODERATE, /**< 中等级级别噪声抑制 */ 253 | NS_HIGH, /**< 高等级级别噪声抑制 */ 254 | NS_VERYHIGH /**< 最高等级级别噪声抑制 */ 255 | }; 256 | 257 | /** 258 | * @fn int IMP_AI_SetPubAttr(int audioDevId, IMPAudioIOAttr *attr) 259 | * 260 | * 设置音频输入设备属性. 261 | * 262 | * @param[in] audioDevId 音频设备号. 263 | * @param[in] attr 音频设备属性指针. 264 | * 265 | * @retval 0 成功. 266 | * @retval 非0 失败. 267 | * 268 | * @remarks 示例代码 269 | * @code 270 | * int devID = 1; 271 | * IMPAudioIOAttr attr; 272 | * attr.samplerate = AUDIO_SAMPLE_RATE_8000; 273 | * attr.bitwidth = AUDIO_BIT_WIDTH_16; 274 | * attr.soundmode = AUDIO_SOUND_MODE_MONO; 275 | * attr.frmNum = 20; 276 | * attr.numPerFrm = 400; 277 | * attr.chnCnt = 1; 278 | * ret = IMP_AI_SetPubAttr(devID, &attr); 279 | * if(ret != 0) { 280 | * IMP_LOG_ERR(TAG, "Set Audio in %d attr err: %d\n", devID, ret); 281 | * return ret; 282 | * } 283 | * @endcode 284 | * 285 | * @attention 需要在IMP_AI_Enable前调用. 286 | */ 287 | int IMP_AI_SetPubAttr(int audioDevId, IMPAudioIOAttr *attr); 288 | 289 | /** 290 | * @fn int IMP_AI_GetPubAttr(int audioDevId, IMPAudioIOAttr *attr) 291 | * 292 | * 获取音频输入设备属性. 293 | * 294 | * @param[in] audioDevId 音频设备号. 295 | * @param[out] attr 音频设备属性指针. 296 | * 297 | * @retval 0 成功. 298 | * @retval 非0 失败. 299 | * 300 | * @remarks 无. 301 | * 302 | * @attention 无. 303 | */ 304 | int IMP_AI_GetPubAttr(int audioDevId, IMPAudioIOAttr *attr); 305 | 306 | /** 307 | * @fn int IMP_AI_Enable(int audioDevId) 308 | * 309 | * 启用音频输入设备. 310 | * 311 | * @param[in] audioDevId 音频设备号. 312 | * 313 | * @retval 0 成功. 314 | * @retval 非0 失败. 315 | * 316 | * @remarks 无. 317 | * 318 | * @attention 在调用此函数前必须调用 IMP_AI_SetPubAttr(). 319 | */ 320 | int IMP_AI_Enable(int audioDevId); 321 | 322 | /** 323 | * @fn int IMP_AI_Disable(int audioDevId) 324 | * 325 | * 禁用音频输入设备. 326 | * 327 | * @param[in] audioDevId 音频设备号. 328 | * 329 | * @retval 0 成功. 330 | * @retval 非0 失败. 331 | * 332 | * @remarks 无. 333 | * 334 | * @attention 与IMP_AI_Enable配套使用,在系统休眠前必须执行IMP_AI_Disable. 335 | */ 336 | int IMP_AI_Disable(int audioDevId); 337 | 338 | /** 339 | * @fn int IMP_AI_EnableChn(int audioDevId, int aiChn) 340 | * 341 | * 启用音频输入通道. 342 | * 343 | * @param[in] audioDevId 音频设备号. 344 | * @param[in] aiChn 音频输入通道号. 345 | * 346 | * @retval 0 成功. 347 | * @retval 非0 失败. 348 | * 349 | * @remarks 无. 350 | * 351 | * @attention 必须先使能device. 352 | */ 353 | int IMP_AI_EnableChn(int audioDevId, int aiChn); 354 | 355 | /** 356 | * @fn int IMP_AI_DisableChn(int audioDevId, int aiChn) 357 | * 358 | * 禁用音频输入通道. 359 | * 360 | * @param[in] audioDevId 音频设备号. 361 | * @param[in] aiChn 音频输入通道号. 362 | * 363 | * @retval 0 成功. 364 | * @retval 非0 失败. 365 | * 366 | * @remarks 无. 367 | * 368 | * @attention 与IMP_AI_EnableChn配套使用. 369 | */ 370 | int IMP_AI_DisableChn(int audioDevId, int aiChn); 371 | 372 | /** 373 | * @fn int IMP_AI_PollingFrame(int audioDevId, int aiChn, unsigned int timeout_ms) 374 | * 375 | * Polling音频流缓存. 376 | * 377 | * @param[in] audioDevId 音频设备号. 378 | * @param[in] aiChn 音频输入通道号. 379 | * @param[in] timeout_ms Polling超时时间. 380 | * 381 | * @retval 0 成功. 382 | * @retval 非0 失败. 383 | * 384 | * @remarks 无. 385 | * 386 | * @attention 在使用IMP_AI_GetFrame之前使用该接口,当该接口调用成功之后表示音频 387 | * 数据已经准备完毕,可以使用IMP_AI_GetFrame获取音频数据. 388 | */ 389 | int IMP_AI_PollingFrame(int audioDevId, int aiChn, unsigned int timeout_ms); 390 | 391 | /** 392 | * @fn int IMP_AI_GetFrame(int audioDevId, int aiChn, IMPAudioFrame *frm, IMPBlock block) 393 | * 394 | * 获取音频帧. 395 | * 396 | * @param[in] audioDevId 音频设备号. 397 | * @param[in] aiChn 音频输入通道号. 398 | * @param[out] frm 音频帧结构体指针. 399 | * @param[in] block 阻塞/非阻塞标识. 400 | * 401 | * @retval 0 成功. 402 | * @retval 非0 失败. 403 | * 404 | * @remarks 示例代码 405 | * @code 406 | * IMPAudioFrame frm; 407 | * // 获取音频帧 408 | * ret = IMP_AI_GetFrame(devID, chnID, &frm, BLOCK); 409 | * if(ret != 0) { 410 | * IMP_LOG_ERR(TAG, "Audio Get Frame Data error\n"); 411 | * return ret; 412 | * } 413 | * 414 | * fwrite(frm.virAddr, 1, frm.len, record_file); // 使用音频帧数据 415 | * 416 | * // 释放音频帧 417 | * ret = IMP_AI_ReleaseFrame(devID, chnID, &frm); 418 | * if(ret != 0) { 419 | * IMP_LOG_ERR(TAG, "Audio release frame data error\n"); 420 | * return ret; 421 | * } 422 | * @endcode 423 | * 424 | * @attention 无. 425 | */ 426 | int IMP_AI_GetFrame(int audioDevId, int aiChn, IMPAudioFrame *frm, IMPBlock block); 427 | 428 | /** 429 | * @fn int IMP_AI_ReleaseFrame(int audioDevId, int aiChn, IMPAudioFrame *frm) 430 | * 431 | * 释放音频帧. 432 | * 433 | * @param[in] audioDevId 音频设备号. 434 | * @param[in] aiChn 音频输入通道号. 435 | * @param[in] frm 音频帧结构体指针. 436 | * 437 | * @retval 0 成功. 438 | * @retval 非0 失败. 439 | * 440 | * @remarks 无. 441 | * 442 | * @attention 与IMP_AI_GetFrame配套使用. 443 | */ 444 | int IMP_AI_ReleaseFrame(int audioDevId, int aiChn, IMPAudioFrame *frm); 445 | 446 | /** 447 | * @fn int IMP_AI_SetChnParam(int audioDevId, int aiChn, IMPAudioIChnParam *chnParam) 448 | * 449 | * 设置音频输入通道参数. 450 | * 451 | * @param[in] audioDevId 音频设备号. 452 | * @param[in] aiChn 音频输入通道号. 453 | * @param[in] chnParam 音频通道参数. 454 | * 455 | * @retval 0 成功. 456 | * @retval 非0 失败. 457 | * 458 | * @remarks 示例代码 459 | * @code 460 | * int chnID = 0; 461 | * IMPAudioIChnParam chnParam; 462 | * chnParam.usrFrmDepth = 20; // the range of valid value is [2, MAX_AUDIO_FRAME_NUM]. 463 | * ret = IMP_AI_SetChnParam(devID, chnID, &chnParam); 464 | * if(ret != 0) { 465 | * IMP_LOG_ERR(TAG, "set ai %d channel %d attr err: %d\n", devID, chnID, ret); 466 | * return ret; 467 | * } 468 | * @endcode 469 | * 470 | * @attention 在IMP_AI_EnableChn前调用. 471 | */ 472 | int IMP_AI_SetChnParam(int audioDevId, int aiChn, IMPAudioIChnParam *chnParam); 473 | 474 | /** 475 | * @fn int IMP_AI_GetChnParam(int audioDevId, int aiChn, IMPAudioIChnParam *chnParam) 476 | * 477 | * 获取音频输入通道参数. 478 | * 479 | * @param[in] audioDevId 音频设备号. 480 | * @param[in] aiChn 音频输入通道号. 481 | * @param[out] chnParam 音频通道参数. 482 | * 483 | * @retval 0 成功. 484 | * @retval 非0 失败. 485 | * 486 | * @remarks 无. 487 | * 488 | * @attention 无. 489 | */ 490 | int IMP_AI_GetChnParam(int audioDevId, int aiChn, IMPAudioIChnParam *chnParam); 491 | 492 | /** 493 | * @fn int IMP_AI_EnableAec(int aiDevId, int aiChn, int aoDevId, int aoChn) 494 | * 495 | * 启用指定音频输入和音频输出的回声抵消功能. 496 | * 497 | * @param[in] aiDevId 需要进行回声抵消的音频输入设备号. 498 | * @param[in] aiChn 需要进行回声抵消的音频输入通道号. 499 | * @param[in] aoDevId 需要进行回声抵消的音频输出设备号. 500 | * @param[in] aoChn 需要进行回声抵消的音频输出通道号. 501 | * 502 | * @retval 0 成功. 503 | * @retval 非0 失败. 504 | * 505 | * @remarks 回音消除针对不同的设备,不同的封装,回音消除会有不同的效果. 506 | * @remarks 回音消除目前不支持自适应,所以针对不同设备有单独的回音消除参数, 507 | * @remarks 仅仅只是使能该功能效果不一定会好。 508 | * @remarks 回音消除的参数文件位于/etc/webrtc_profile.ini 配置文件中. 509 | * @remarks 配置文件格式为如下(以下列出主要需要调试的三个参数): 510 | * @remarks [Set_Far_Frame] 511 | * @remarks Frame_V=0.3 512 | * @remarks [Set_Near_Frame] 513 | * @remarks Frame_V=0.1 514 | * @remarks delay_ms=150 515 | * 516 | * @remarks 其中第一个标签[Set_Far_Frame]中的内容代表远端参数,即SPK端放音数据参数. 517 | * @remarks Fram_V 代表音频幅值比例,调节该参数可以调节放音数据的幅度(此幅度只用于回音消除). 518 | * @remarks 其中第一个标签[Set_Near_Frame]中的内容代表近端参数,即MIC端录音数据参数. 519 | * @remarks Fram_V 代表音频幅值比例,调节该参数可以调节录音数据的幅度(此幅度只用于回音消除). 520 | * @remarks delay_ms 由于软件和硬件具有延时性,且SPK与MIC的安放有一定距离,SPK放音数据会重新被MIC采样,所以SPK数据在MIC数据中体现会存在一定延时. 521 | * @remarks 该时间代表放音数据在录音数据中的时间差. 522 | * 523 | * @attention 实际上接口只会检查aiDevId和aiChn.但是最好在两个通道同时使能后调用. \n 524 | * 在关闭音频输入通道的同时,回音消除功能同时关闭.如果再次使用需要再次打开. 525 | */ 526 | int IMP_AI_EnableAec(int aiDevId, int aiChn, int aoDevId, int aoChn); 527 | 528 | /** 529 | * @fn int IMP_AI_DisableAec(int aiDevId, int aiChn) 530 | * 531 | * 禁用回声抵消功能. 532 | * 533 | * @param[in] aiDevId 音频输入设备号. 534 | * @param[in] aiChn 音频输入通道号. 535 | * 536 | * @retval 0 成功. 537 | * @retval 非0 失败. 538 | * 539 | * @remarks 无. 540 | * 541 | * @attention 无. 542 | */ 543 | int IMP_AI_DisableAec(int aiDevId, int aiChn); 544 | 545 | /** 546 | * @fn int IMP_AI_EnableNs(IMPAudioIOAttr *attr, int mode) 547 | * 548 | * 启用指定音频输入的噪声抑制功能. 549 | * 550 | * @param[in] attr 需要进行噪声抑制的音频属性. 551 | * @param[in] mode 噪声抑制的级别0 ~ 3,参见 Level_ns. 552 | * 553 | * @retval 0 成功. 554 | * @retval 非0 失败. 555 | * 556 | * @remarks 噪声抑制的mode参数表示噪声抑制的级别,范围为[0 ~ 3],级别越高,噪声抑制的越干净. 557 | * @remarks 然而,噪声抑制的越干净同时也就会丢失更多的声音细节,所以这里有一个矛盾点,需要在 558 | * @remarks 使用的时候进行权衡. 559 | * 560 | * @attention 回声消除包含了噪声抑制功能,如果启用回声抵消,就不需要做噪声抑制. 561 | */ 562 | int IMP_AI_EnableNs(IMPAudioIOAttr *attr, int mode); 563 | 564 | /** 565 | * @fn int IMP_AI_DisableNs(void) 566 | * 567 | * 禁用噪声抑制功能. 568 | * 569 | * @param 无. 570 | * 571 | * @retval 0 成功. 572 | * @retval 非0 失败. 573 | * 574 | * @remarks 无. 575 | * 576 | * @attention 无. 577 | */ 578 | int IMP_AI_DisableNs(void); 579 | 580 | /** 581 | * @fn int IMP_AI_EnableAgc(IMPAudioIOAttr *attr, IMPAudioAgcConfig agcConfig) 582 | * 583 | * 启用音频输入的自动增益功能. 584 | * 585 | * @param[in] attr 需要进行自动增益的音频属性. 586 | * @param[in] agcConfig 自动增益的参数配置,配置放大倍数. 587 | * 588 | * @retval 0 成功. 589 | * @retval 非0 失败. 590 | * 591 | * @remarks 需要注意agcConfig的配置,AGC的放大倍数主要有该参数配置,具体增益见IMPAudioAgcConfig说明. 592 | * @remarks 需要注意的是,AGC可以将声音的增益放大,但是如果增益的参数不合适,就会导致破音等情况,请在具体使用时自行调整. 593 | * 594 | * @attention 回声消除包含了 AGC 功能,如果启用回声抵消,就不需要做自动增益. 595 | */ 596 | int IMP_AI_EnableAgc(IMPAudioIOAttr *attr, IMPAudioAgcConfig agcConfig); 597 | 598 | /** 599 | * @fn int IMP_AI_DisableAgc(void) 600 | * 601 | * 禁用AI自动增益功能. 602 | * 603 | * @param 无. 604 | * 605 | * @retval 0 成功. 606 | * @retval 非0 失败. 607 | * 608 | * @remarks 无. 609 | * 610 | * @attention 无. 611 | */ 612 | int IMP_AI_DisableAgc(void); 613 | 614 | /** 615 | * @fn int IMP_AO_EnableAgc(IMPAudioIOAttr *attr, IMPAudioAgcConfig agcConfig) 616 | * 617 | * 启用音频输出的自动增益功能. 618 | * 619 | * @param[in] attr 需要进行自动增益的音频属性. 620 | * @param[in] agcConfig 自动增益的参数配置,配置放大倍数. 621 | * 622 | * @retval 0 成功. 623 | * @retval 非0 失败. 624 | * 625 | * @remarks 需要注意agcConfig的配置,AGC的放大倍数主要有该参数配置,具体增益见IMPAudioAgcConfig说明. 626 | * @remarks 需要注意的是,AGC可以将声音的增益放大,但是如果增益的参数不合适,就会导致破音等情况,请在具体使用时自行调整. 627 | * 628 | * @attention 回声消除包含了 AGC 功能,如果启用回声抵消,就不需要做自动增益. 629 | */ 630 | int IMP_AO_EnableAgc(IMPAudioIOAttr *attr, IMPAudioAgcConfig agcConfig); 631 | 632 | /** 633 | * @fn int IMP_AO_DisableAgc(void) 634 | * 635 | * 禁用AO自动增益功能. 636 | * 637 | * @param 无. 638 | * 639 | * @retval 0 成功. 640 | * @retval 非0 失败. 641 | * 642 | * @remarks 无. 643 | * 644 | * @attention 无. 645 | */ 646 | int IMP_AO_DisableAgc(void); 647 | 648 | /** 649 | * @fn int IMP_AI_EnableHpf(IMPAudioIOAttr *attr) 650 | * 651 | * 启用音频输入的高通滤波. 652 | * 653 | * @param[in] attr 需要进行高通滤波的音频属性. 654 | * 655 | * @retval 0 成功. 656 | * @retval 非0 失败. 657 | * 658 | * @remarks 无. 659 | * 660 | * @attention 回声消除包含了 HPF 功能,如果启用回声抵消,就不需要做 HPF. 661 | */ 662 | int IMP_AI_EnableHpf(IMPAudioIOAttr *attr); 663 | 664 | /** 665 | * @fn int IMP_AI_DisableHpf(void) 666 | * 667 | * 禁用AI高通滤波功能. 668 | * 669 | * @param 无. 670 | * 671 | * @retval 0 成功. 672 | * @retval 非0 失败. 673 | * 674 | * @remarks 无. 675 | * 676 | * @attention 无. 677 | */ 678 | int IMP_AI_DisableHpf(void); 679 | 680 | /** 681 | * @fn int IMP_AO_EnableHpf(IMPAudioIOAttr *attr) 682 | * 683 | * 启用音频输出的高通滤波. 684 | * 685 | * @param[in] attr 需要进行高通滤波的音频属性. 686 | * 687 | * @retval 0 成功. 688 | * @retval 非0 失败. 689 | * 690 | * @remarks 无. 691 | * 692 | * @attention 回声消除包含了 HPF 功能,如果启用回声抵消,就不需要做 HPF. 693 | */ 694 | int IMP_AO_EnableHpf(IMPAudioIOAttr *attr); 695 | 696 | /** 697 | * @fn int IMP_AO_DisableHpf(void) 698 | * 699 | * 禁用AO高通滤波功能. 700 | * 701 | * @param 无. 702 | * 703 | * @retval 0 成功. 704 | * @retval 非0 失败. 705 | * 706 | * @remarks 无. 707 | * 708 | * @attention 无. 709 | */ 710 | int IMP_AO_DisableHpf(void); 711 | 712 | /** 713 | * @fn int IMP_AO_SetPubAttr(int audioDevId, IMPAudioIOAttr *attr) 714 | * 715 | * 设置音频输入输出设备属性. 716 | * 717 | * @param[in] audioDevId 音频设备号. 718 | * @param[in] attr 音频输出设备属性指针. 719 | * 720 | * @retval 0 成功. 721 | * @retval 非0 失败. 722 | * 723 | * @remarks 无. 724 | * 725 | * @attention 无. 726 | */ 727 | int IMP_AO_SetPubAttr(int audioDevId, IMPAudioIOAttr *attr); 728 | 729 | /** 730 | * @fn int IMP_AO_GetPubAttr(int audioDevId, IMPAudioIOAttr *attr) 731 | * 732 | * 获取音频输入输出设备属性. 733 | * 734 | * @param[in] audioDevId 音频设备号. 735 | * @param[out] attr 音频输出设备属性指针. 736 | * 737 | * @retval 0 成功. 738 | * @retval 非0 失败. 739 | * 740 | * @remarks 无. 741 | * 742 | * @attention 无. 743 | */ 744 | int IMP_AO_GetPubAttr(int audioDevId, IMPAudioIOAttr *attr); 745 | 746 | /** 747 | * @fn int IMP_AO_Enable(int audioDevId) 748 | * 749 | * 启用音频输出设备. 750 | * 751 | * @param[in] audioDevId 音频设备号. 752 | * 753 | * @retval 0 成功. 754 | * @retval 非0 失败. 755 | * 756 | * @remarks 无. 757 | * 758 | * @attention 在使能之前必须先调用IMP_AO_SetPubAttr. 759 | */ 760 | int IMP_AO_Enable(int audioDevId); 761 | 762 | /** 763 | * @fn int IMP_AO_Disable(int audioDevId) 764 | * 765 | * 禁用音频输出设备. 766 | * 767 | * @param[in] audioDevId 音频设备号. 768 | * 769 | * @retval 0 成功. 770 | * @retval 非0 失败. 771 | * 772 | * @remarks 无. 773 | * 774 | * @attention 无. 775 | */ 776 | int IMP_AO_Disable(int audioDevId); 777 | 778 | /** 779 | * @fn int IMP_AO_EnableChn(int audioDevId, int aoChn) 780 | * 781 | * 启用音频输出通道. 782 | * 783 | * @param[in] audioDevId 音频设备号. 784 | * @param[in] aoChn 音频输出通道号. 785 | * 786 | * @retval 0 成功. 787 | * @retval 非0 失败. 788 | * 789 | * @remarks 无. 790 | * 791 | * @attention 无. 792 | */ 793 | int IMP_AO_EnableChn(int audioDevId, int aoChn); 794 | 795 | /** 796 | * @fn int IMP_AO_DisableChn(int audioDevId, int aoChn) 797 | * 798 | * 禁用音频输出通道. 799 | * 800 | * @param[in] audioDevId 音频设备号. 801 | * @param[in] aoChn 音频输出通道号. 802 | * 803 | * @retval 0 成功. 804 | * @retval 非0 失败. 805 | * 806 | * @remarks 无. 807 | * 808 | * @attention 无. 809 | */ 810 | int IMP_AO_DisableChn(int audioDevId, int aoChn); 811 | 812 | /** 813 | * @fn int IMP_AO_SendFrame(int audioDevId, int aoChn, IMPAudioFrame *data, IMPBlock block) 814 | * 815 | * 发送音频输出帧. 816 | * 817 | * @param[in] audioDevId 音频设备号. 818 | * @param[in] aoChn 音频输出通道号. 819 | * @param[in] data 音频帧结构体指针. 820 | * @param[in] block 阻塞/非阻塞标识. 821 | * 822 | * @retval 0 成功. 823 | * @retval 非0 失败. 824 | * 825 | * @remarks 示例代码 826 | * @code 827 | * while(1) { 828 | * size = fread(buf, 1, IMP_AUDIO_BUF_SIZE, play_file); 829 | * if(size < IMP_AUDIO_BUF_SIZE) 830 | * break; 831 | * 832 | * IMPAudioFrame frm; 833 | * frm.virAddr = (uint32_t *)buf; 834 | * frm.len = size; 835 | * ret = IMP_AO_SendFrame(devID, chnID, &frm, BLOCK); 836 | * if(ret != 0) { 837 | * IMP_LOG_ERR(TAG, "send Frame Data error\n"); 838 | * return ret; 839 | * } 840 | * } 841 | * @endcode 842 | * 843 | * @attention 无. 844 | */ 845 | int IMP_AO_SendFrame(int audioDevId, int aoChn, IMPAudioFrame *data, IMPBlock block); 846 | 847 | /** 848 | * @fn int IMP_AO_PauseChn(int audioDevId, int aoChn) 849 | * 850 | * 暂停音频输出通道. 851 | * 852 | * @param[in] audioDevId 音频设备号. 853 | * @param[in] aoChn 音频输出通道号. 854 | * 855 | * @retval 0 成功. 856 | * @retval 非0 失败. 857 | * 858 | * @remarks 无. 859 | * 860 | * @attention 无. 861 | */ 862 | int IMP_AO_PauseChn(int audioDevId, int aoChn); 863 | 864 | /** 865 | * @fn int IMP_AO_ResumeChn(int audioDevId, int aoChn) 866 | * 867 | * 恢复音频输出通道. 868 | * 869 | * @param[in] audioDevId 音频设备号. 870 | * @param[in] aoChn 音频输出通道号. 871 | * 872 | * @retval 0 成功. 873 | * @retval 非0 失败. 874 | * 875 | * @remarks 无. 876 | * 877 | * @attention 无. 878 | */ 879 | int IMP_AO_ResumeChn(int audioDevId, int aoChn); 880 | 881 | /** 882 | * @fn int IMP_AO_ClearChnBuf(int audioDevId, int aoChn) 883 | * 884 | * 清除音频输出通道中当前的音频数据缓存. 885 | * 886 | * @param[in] audioDevId 音频设备号. 887 | * @param[in] aoChn 音频输出通道号. 888 | * 889 | * @retval 0 成功. 890 | * @retval 非0 失败. 891 | * 892 | * @remarks 无. 893 | * 894 | * @attention 无. 895 | */ 896 | int IMP_AO_ClearChnBuf(int audioDevId, int aoChn); 897 | 898 | /** 899 | * @fn int IMP_AO_QueryChnStat(int audioDevId, int aoChn, IMPAudioOChnState *status) 900 | * 901 | * 查询音频输出通道中当前的音频数据缓存状态. 902 | * 903 | * @param[in] audioDevId 音频设备号. 904 | * @param[in] aoChn 音频输出通道号. 905 | * @param[out] status 缓存状态结构体指针. 906 | * 907 | * @retval 0 成功. 908 | * @retval 非0 失败. 909 | * 910 | * @remarks 无. 911 | * 912 | * @attention 无. 913 | */ 914 | int IMP_AO_QueryChnStat(int audioDevId, int aoChn, IMPAudioOChnState *status); 915 | 916 | /** 917 | * @fn int IMP_AENC_CreateChn(int aeChn, IMPAudioEncChnAttr *attr) 918 | * 919 | * 创建音频编码通道. 920 | * 921 | * @param[in] aeChn 通道号. 922 | * @param[in] attr 音频编码通道属性指针. 923 | * 924 | * @retval 0 成功. 925 | * @retval 非0 失败. 926 | * 927 | * @remarks 示例代码 928 | * @code 929 | * int AeChn = 0; 930 | * IMPAudioEncChnAttr attr; 931 | * attr.type = PT_G711A; 932 | * attr.bufSize = 20; 933 | * ret = IMP_AENC_CreateChn(AeChn, &attr); 934 | * if(ret != 0) { 935 | * IMP_LOG_ERR(TAG, "Audio encode create channel failed\n"); 936 | * return ret; 937 | * } 938 | * @endcode 939 | * 940 | * @attention 目前SDK支持PT_G711A、PT_G711U和PT_G726编码. \n 941 | * 所以使用SDK中的编码,只需要attr.type = PT_G711A即可. \n 942 | * 如何需要使用自定义的编码器,则需要注册编码器,示例代码在注册接口中说明. 943 | */ 944 | int IMP_AENC_CreateChn(int aeChn, IMPAudioEncChnAttr *attr); 945 | 946 | /** 947 | * @fn int IMP_AENC_DestroyChn(int aeChn) 948 | * 949 | * 销毁音频编码通道. 950 | * 951 | * @param[in] aeChn 通道号. 952 | * 953 | * @retval 0 成功. 954 | * @retval 非0 失败. 955 | * 956 | * @remarks 无. 957 | * 958 | * @attention 与IMP_AENC_CreateChn配套使用. 959 | */ 960 | int IMP_AENC_DestroyChn(int aeChn); 961 | 962 | /** 963 | * @fn int IMP_AENC_SendFrame(int aeChn, IMPAudioFrame *frm) 964 | * 965 | * 发送音频编码音频帧. 966 | * 967 | * @param[in] aeChn 通道号. 968 | * @param[in] frm 音频帧结构体指针. 969 | * 970 | * @retval 0 成功. 971 | * @retval 非0 失败. 972 | * 973 | * @remarks 示例代码 974 | * @code 975 | * while(1) { 976 | * // 读取一帧数据 977 | * ret = fread(buf_pcm, 1, IMP_AUDIO_BUF_SIZE, file_pcm); 978 | * if(ret < IMP_AUDIO_BUF_SIZE) 979 | * break; 980 | * 981 | * // 编码 982 | * IMPAudioFrame frm; 983 | * frm.virAddr = (uint32_t *)buf_pcm; 984 | * frm.len = ret; 985 | * ret = IMP_AENC_SendFrame(AeChn, &frm); 986 | * if(ret != 0) { 987 | * IMP_LOG_ERR(TAG, "imp audio encode send frame failed\n"); 988 | * return ret; 989 | * } 990 | * 991 | * // 获取编码码流 992 | * IMPAudioStream stream; 993 | * ret = IMP_AENC_GetStream(AeChn, &stream, BLOCK); 994 | * if(ret != 0) { 995 | * IMP_LOG_ERR(TAG, "imp audio encode get stream failed\n"); 996 | * return ret; 997 | * } 998 | * 999 | * // 使用编码码流 1000 | * fwrite(stream.stream, 1, stream.len, file_g711); 1001 | * 1002 | * // 释放编码码流 1003 | * ret = IMP_AENC_ReleaseStream(AeChn, &stream); 1004 | * if(ret != 0) { 1005 | * IMP_LOG_ERR(TAG, "imp audio encode release stream failed\n"); 1006 | * return ret; 1007 | * } 1008 | * } 1009 | * @endcode 1010 | * 1011 | * @attention 无. 1012 | */ 1013 | int IMP_AENC_SendFrame(int aeChn, IMPAudioFrame *frm); 1014 | 1015 | /** 1016 | * @fn int IMP_AENC_PollingStream(int AeChn, unsigned int timeout_ms) 1017 | * 1018 | * Polling编码音频流缓存. 1019 | * 1020 | * @param[in] AeChn 音频编码输入通道号. 1021 | * @param[in] timeout_ms Polling超时时间. 1022 | * 1023 | * @retval 0 成功. 1024 | * @retval 非0 失败. 1025 | * 1026 | * @remarks 无. 1027 | * 1028 | * @attention 在使用IMP_AENC_GetStream之前使用该接口,当该接口调用成功之后表示音频 1029 | * 编码数据已经准备完毕,可以使用IMP_AENC_GetStream获取编码完毕的数据. 1030 | */ 1031 | int IMP_AENC_PollingStream(int AeChn, unsigned int timeout_ms); 1032 | 1033 | /** 1034 | * @fn int IMP_AENC_GetStream(int aeChn, IMPAudioStream *stream ,IMPBlock block) 1035 | * 1036 | * 获取编码后码流. 1037 | * 1038 | * @param[in] aeChn 通道号. 1039 | * @param[in] stream 获取音频码流. 1040 | * @param[in] block 阻塞/非阻塞标识. 1041 | * 1042 | * @retval 0 成功. 1043 | * @retval 非0 失败. 1044 | * 1045 | * @remarks 示例代码见IMP_AENC_SendFrame函数说明. 1046 | * 1047 | * @attention 无. 1048 | */ 1049 | int IMP_AENC_GetStream(int aeChn, IMPAudioStream *stream ,IMPBlock block); 1050 | 1051 | /** 1052 | * @fn int IMP_AENC_ReleaseStream(int aeChn,IMPAudioStream *stream) 1053 | * 1054 | * 释放从音频编码通道获取的码流. 1055 | * 1056 | * @param[in] aeChn 通道号. 1057 | * @param[in] stream 获取音频码流指针. 1058 | * 1059 | * @retval 0 成功. 1060 | * @retval 非0 失败. 1061 | * 1062 | * @remarks 示例代码见IMP_AENC_SendFrame函数说明. 1063 | * 1064 | * @attention 无. 1065 | */ 1066 | int IMP_AENC_ReleaseStream(int aeChn,IMPAudioStream *stream); 1067 | 1068 | /** 1069 | * @fn int IMP_AENC_RegisterEncoder(int *handle, IMPAudioEncEncoder *encoder) 1070 | * 1071 | * 注册编码器. 1072 | * 1073 | * @param[in] ps32handle 注册句柄. 1074 | * @param[in] encoder 编码器属性结构体. 1075 | * 1076 | * @retval 0 成功. 1077 | * @retval 非0 失败. 1078 | * 1079 | * @remarks 示例代码 1080 | * @code 1081 | * int handle_g711a = 0; 1082 | * IMPAudioEncEncoder my_encoder; 1083 | * my_encoder.maxFrmLen = 1024; 1084 | * sprintf(my_encoder.name, "%s", "MY_G711A"); 1085 | * my_encoder.openEncoder = NULL; // 编码器回调函数 1086 | * my_encoder.encoderFrm = MY_G711A_Encode_Frm; // 编码器回调函数 1087 | * my_encoder.closeEncoder = NULL; // 编码器回调函数 1088 | * 1089 | * ret = IMP_AENC_RegisterEncoder(&handle_g711a, &my_encoder); 1090 | * if(ret != 0) { 1091 | * IMP_LOG_ERR(TAG, "IMP_AENC_RegisterEncoder failed\n"); 1092 | * return ret; 1093 | * } 1094 | * 1095 | * // 使用编码器 1096 | * int AeChn = 0; 1097 | * IMPAudioEncChnAttr attr; 1098 | * attr.type = handle_g711a; // 编码器type等于注册成功返回的handle_g711a的值即可. 1099 | * attr.bufSize = 20; 1100 | * ret = IMP_AENC_CreateChn(AeChn, &attr); 1101 | * if(ret != 0) { 1102 | * IMP_LOG_ERR(TAG, "imp audio encode create channel failed\n"); 1103 | * return ret; 1104 | * } 1105 | * @endcode 1106 | * 1107 | * @attention 注册之后使用方法和使用SDK自带编码器一样. 1108 | */ 1109 | int IMP_AENC_RegisterEncoder(int *handle, IMPAudioEncEncoder *encoder); 1110 | 1111 | /** 1112 | * @fn int IMP_AENC_ReleaseEncoder(int *handle) 1113 | * 1114 | * 注销编码器. 1115 | * 1116 | * @param[in] ps32handle 注册句柄(注册编码器时获得的句柄). 1117 | * 1118 | * @retval 0 成功. 1119 | * @retval 非0 失败. 1120 | * 1121 | * @remarks 无. 1122 | * 1123 | * @attention 无. 1124 | */ 1125 | int IMP_AENC_ReleaseEncoder(int *handle); 1126 | 1127 | /** 1128 | * @fn int IMP_ADEC_CreateChn(int adChn, IMPAudioDecChnAttr *attr) 1129 | * 1130 | * 创建音频解码通道. 1131 | * 1132 | * @param[in] adChn 通道号. 1133 | * @param[in] attr 通道属性指针. 1134 | * 1135 | * @retval 0 成功. 1136 | * @retval 非0 失败. 1137 | * 1138 | * @remarks 示例代码 1139 | * @code 1140 | * int adChn = 0; 1141 | * IMPAudioDecChnAttr attr; 1142 | * attr.type = PT_G711A; 1143 | * attr.bufSize = 20; 1144 | * attr.mode = ADEC_MODE_PACK; 1145 | * ret = IMP_ADEC_CreateChn(adChn, &attr); 1146 | * if(ret != 0) { 1147 | * IMP_LOG_ERR(TAG, "imp audio decoder create channel failed\n"); 1148 | * return ret; 1149 | * } 1150 | * @endcode 1151 | * 1152 | * @attention 无. 1153 | */ 1154 | int IMP_ADEC_CreateChn(int adChn, IMPAudioDecChnAttr *attr); 1155 | 1156 | /** 1157 | * @fn int IMP_ADEC_DestroyChn(int adChn) 1158 | * 1159 | * 销毁音频解码通道. 1160 | * 1161 | * @param[in] adChn 通道号. 1162 | * 1163 | * @retval 0 成功. 1164 | * @retval 非0 失败. 1165 | * 1166 | * @remarks 无. 1167 | * 1168 | * @attention 无. 1169 | */ 1170 | int IMP_ADEC_DestroyChn(int adChn); 1171 | 1172 | /** 1173 | * @fn int IMP_ADEC_SendStream(int adChn, IMPAudioStream *stream, IMPBlock block) 1174 | * 1175 | * 发送音频码流到音频解码通道. 1176 | * 1177 | * @param[in] adChn 通道号. 1178 | * @param[in] stream 音频码流. 1179 | * @param[in] block 阻塞/非阻塞标识. 1180 | * 1181 | * @retval 0 成功. 1182 | * @retval 非0 失败. 1183 | * 1184 | * @remarks 示例代码 1185 | * @code 1186 | * while(1) { 1187 | * // 获取需要解码的数据 1188 | * ret = fread(buf_g711, 1, IMP_AUDIO_BUF_SIZE/2, file_g711); 1189 | * if(ret < IMP_AUDIO_BUF_SIZE/2) 1190 | * break; 1191 | * 1192 | * // 发送解码数据 1193 | * IMPAudioStream stream_in; 1194 | * stream_in.stream = (uint8_t *)buf_g711; 1195 | * stream_in.len = ret; 1196 | * ret = IMP_ADEC_SendStream(adChn, &stream_in, BLOCK); 1197 | * if(ret != 0) { 1198 | * IMP_LOG_ERR(TAG, "imp audio encode send frame failed\n"); 1199 | * return ret; 1200 | * } 1201 | * 1202 | * // 获取解码后的数据 1203 | * IMPAudioStream stream_out; 1204 | * ret = IMP_ADEC_GetStream(adChn, &stream_out, BLOCK); 1205 | * if(ret != 0) { 1206 | * IMP_LOG_ERR(TAG, "imp audio decoder get stream failed\n"); 1207 | * return ret; 1208 | * } 1209 | * 1210 | * // 使用解码后的数据 1211 | * fwrite(stream_out.stream, 1, stream_out.len, file_pcm); 1212 | * 1213 | * // 释放解码后的数据 1214 | * ret = IMP_ADEC_ReleaseStream(adChn, &stream_out); 1215 | * if(ret != 0) { 1216 | * IMP_LOG_ERR(TAG, "imp audio decoder release stream failed\n"); 1217 | * return ret; 1218 | * } 1219 | * } 1220 | * @endcode 1221 | * 1222 | * @attention 无. 1223 | */ 1224 | int IMP_ADEC_SendStream(int adChn, IMPAudioStream *stream, IMPBlock block); 1225 | 1226 | /** 1227 | * @fn int IMP_ADEC_PollingStream(int AdChn, unsigned int timeout_ms) 1228 | * 1229 | * Polling解码音频流缓存. 1230 | * 1231 | * @param[in] AdChn 音频解码输入通道号. 1232 | * @param[in] timeout_ms Polling超时时间. 1233 | * 1234 | * @retval 0 成功. 1235 | * @retval 非0 失败. 1236 | * 1237 | * @remarks 无. 1238 | * 1239 | * @attention 在使用IMP_ADEC_GetStream之前使用该接口,当该接口调用成功之后表示音频 1240 | * 解码数据已经准备完毕,可以使用IMP_ADEC_GetStream获取解码完毕的数据. 1241 | */ 1242 | int IMP_ADEC_PollingStream(int AdChn, unsigned int timeout_ms); 1243 | 1244 | /** 1245 | * @fn int IMP_ADEC_GetStream(int adChn, IMPAudioStream *stream ,IMPBlock block) 1246 | * 1247 | * 获取解码后码流. 1248 | * 1249 | * @param[in] adChn 通道号. 1250 | * @param[in] stream 获取解码码流. 1251 | * @param[in] block 阻塞/非阻塞标识. 1252 | * 1253 | * @retval 0 成功. 1254 | * @retval 非0 失败. 1255 | * 1256 | * @remarks 示例代码见IMP_ADEC_SendStream函数说明. 1257 | * 1258 | * @attention 无. 1259 | */ 1260 | int IMP_ADEC_GetStream(int adChn, IMPAudioStream *stream ,IMPBlock block); 1261 | 1262 | /** 1263 | * @fn int IMP_ADEC_ReleaseStream(int adChn,IMPAudioStream *stream) 1264 | * 1265 | * 释放从音频解码通道获取的码流. 1266 | * 1267 | * @param[in] adChn 通道号. 1268 | * @param[in] stream 音频码流指针. 1269 | * 1270 | * @retval 0 成功. 1271 | * @retval 非0 失败. 1272 | * 1273 | * @remarks 示例代码见IMP_ADEC_SendStream函数说明. 1274 | * 1275 | * @attention 无. 1276 | */ 1277 | int IMP_ADEC_ReleaseStream(int adChn,IMPAudioStream *stream); 1278 | 1279 | /** 1280 | * @fn int IMP_ADEC_ClearChnBuf(int adChn) 1281 | * 1282 | * 清除音频解码通道中当前的音频数据缓存. 1283 | * 1284 | * @param[in] adChn 通道号. 1285 | * 1286 | * @retval 0 成功. 1287 | * @retval 非0 失败. 1288 | * 1289 | * @remarks 无. 1290 | * 1291 | * @attention 无. 1292 | */ 1293 | int IMP_ADEC_ClearChnBuf(int adChn); 1294 | 1295 | /** 1296 | * @fn int IMP_ADEC_RegisterDecoder(int *handle, IMPAudioDecDecoder *decoder) 1297 | * 1298 | * 注册解码器. 1299 | * 1300 | * @param[in] ps32handle 注册句柄. 1301 | * @param[in] decoder 解码器属性结构体. 1302 | * 1303 | * @retval 0 成功. 1304 | * @retval 非0 失败. 1305 | * 1306 | * @remarks 示例代码 1307 | * @code 1308 | * int handle_g711a = 0; 1309 | * IMPAudioDecDecoder my_decoder; 1310 | * sprintf(my_decoder.name, "%s", "MY_G711A"); 1311 | * my_decoder.openDecoder = NULL; // 解码器回调函数 1312 | * my_decoder.decodeFrm = MY_G711A_Decode_Frm; // 解码器回调函数 1313 | * my_decoder.getFrmInfo = NULL; // 解码器回调函数 1314 | * my_decoder.closeDecoder = NULL; // 解码器回调函数 1315 | * 1316 | * // 注册解码器 1317 | * ret = IMP_ADEC_RegisterDecoder(&handle_g711a, &my_decoder); 1318 | * if(ret != 0) { 1319 | * IMP_LOG_ERR(TAG, "IMP_ADEC_RegisterDecoder failed\n"); 1320 | * return ret; 1321 | * } 1322 | * 1323 | * // 使用解码器 1324 | * int adChn = 0; 1325 | * IMPAudioDecChnAttr attr; 1326 | * attr.type = handle_g711a; // 解码type等于解码器注册返回的handle_g711a. 1327 | * attr.bufSize = 20; 1328 | * attr.mode = ADEC_MODE_PACK; 1329 | * // 创建解码通道 1330 | * ret = IMP_ADEC_CreateChn(adChn, &attr); 1331 | * if(ret != 0) { 1332 | * IMP_LOG_ERR(TAG, "imp audio decoder create channel failed\n"); 1333 | * return ret; 1334 | * } 1335 | * @endcode 1336 | * 1337 | * @attention 注册之后使用方法和使用SDK自带解码器一样. 1338 | */ 1339 | int IMP_ADEC_RegisterDecoder(int *handle, IMPAudioDecDecoder *decoder); 1340 | 1341 | /** 1342 | * @fn int IMP_ADEC_ReleaseDecoder(int *handle) 1343 | * 1344 | * 注销解码器. 1345 | * 1346 | * @param[in] ps32handle 注册句柄(注册解码器时获得的句柄). 1347 | * 1348 | * @retval 0 成功. 1349 | * @retval 非0 失败. 1350 | * 1351 | * @remarks 无. 1352 | * 1353 | * @attention 无. 1354 | */ 1355 | int IMP_ADEC_ReleaseDecoder(int *handle); 1356 | 1357 | /** 1358 | * ACODEC配置. 1359 | */ 1360 | /** 1361 | * @fn int IMP_AI_SetVol(int audioDevId, int aiChn, int aiVol) 1362 | * 1363 | * 设置音频输入音量. 1364 | * 1365 | * @param[in] aiDevId 音频输入设备号. 1366 | * @param[in] aiChn 音频输入通道号. 1367 | * @param[in] aiVol 音频输入音量大小. 1368 | * 1369 | * @retval 0 成功. 1370 | * @retval 非0 失败. 1371 | * 1372 | * @remarks 音量的取值范围为[-30 ~ 120]. -30代表静音,120表示将声音放大30dB,步长0.5dB. 1373 | * @remarks 其中60是音量设置的一个临界点,在这个值上软件不对音量做增加或减小,当音量值小于60时,每下降1,音量减小0.5dB;当音量值大于60时,上增加1,音量增加0.5dB。 1374 | * 1375 | * 示例代码 1376 | * @code 1377 | * int volume = 60; 1378 | * ret = IMP_AI_SetVol(devID, chnID, volume); 1379 | * if(ret != 0) { 1380 | * IMP_LOG_ERR(TAG, "Audio Record set volume failed\n"); 1381 | * return ret; 1382 | * } 1383 | * @endcode 1384 | * @attention 如果输入的aiVol超过了[-30 ~ 120]的范围,小于-30的将会取-30,大于120的取120. 1385 | */ 1386 | int IMP_AI_SetVol(int audioDevId, int aiChn, int aiVol); 1387 | 1388 | /** 1389 | * @fn int IMP_AI_GetVol(int audioDevId, int aiChn, int *vol) 1390 | * 1391 | * 获取音频输入音量. 1392 | * 1393 | * @param[in] aiDevId 音频输入设备号. 1394 | * @param[in] aiChn 音频输入通道号. 1395 | * @param[out] vol 音频输入通道音量. 1396 | * 1397 | * @retval 0 成功. 1398 | * @retval 非0 失败. 1399 | * 1400 | * @remarks 无. 1401 | * 1402 | * @attention 无. 1403 | */ 1404 | int IMP_AI_GetVol(int audioDevId, int aiChn, int *vol); 1405 | 1406 | /** 1407 | * @fn int IMP_AI_SetVolMute(int audioDevId, int aiChn, int mute) 1408 | * 1409 | * 设置音频输入静音. 1410 | * 1411 | * @param[in] aiDevId 音频输入设备号. 1412 | * @param[in] aiChn 音频输入通道号. 1413 | * @param[out] mute 音频输入静音标志, mute = 0:关闭静音, mute = 1:打开静音. 1414 | * 1415 | * @retval 0 成功. 1416 | * @retval 非0 失败. 1417 | * 1418 | * @remarks 调用该接口可立刻静音. 1419 | * 1420 | * @attention 无. 1421 | */ 1422 | int IMP_AI_SetVolMute(int audioDevId, int aiChn, int mute); 1423 | 1424 | /** 1425 | * @fn int IMP_AO_SetVol(int audioDevId, int aoChn, int aoVol) 1426 | * 1427 | * 设置音频输出通道音量. 1428 | * 1429 | * @param[in] audioDevId 音频设备号. 1430 | * @param[in] aoChn 音频输出通道号. 1431 | * @param[in] aoVol 音频输出音量. 1432 | * 1433 | * @retval 0 成功. 1434 | * @retval 非0 失败. 1435 | * 1436 | * @remarks 音量的取值范围为[-30 ~ 120]. -30代表静音,120表示将声音放大30dB,步长0.5dB. 1437 | * @remarks 其中60是音量设置的一个临界点,在这个值上软件不对音量做增加或减小,当音量值小于60时,每下降1,音量减小0.5dB;当音量值大于60时,上增加1,音量增加0.5dB。 1438 | * 1439 | * @attention 如果输入的aoVol超过了[-30 ~ 120]的范围,小于-30的将会取-30,大于120的取120. 1440 | */ 1441 | int IMP_AO_SetVol(int audioDevId, int aoChn, int aoVol); 1442 | 1443 | /** 1444 | * @fn int IMP_AO_GetVol(int audioDevId, int aoChn, int *vol) 1445 | * 1446 | * 获取音频输出通道音量. 1447 | * 1448 | * @param[in] audioDevId 音频设备号. 1449 | * @param[in] aoChn 音频输出通道号. 1450 | * @param[out] aoVol 音频输出音量. 1451 | * 1452 | * @retval 0 成功. 1453 | * @retval 非0 失败. 1454 | * 1455 | * @remarks 无. 1456 | * 1457 | * @attention 无. 1458 | */ 1459 | int IMP_AO_GetVol(int audioDevId, int aoChn, int *vol); 1460 | 1461 | /** 1462 | * @fn int IMP_AO_SetVolMute(int audioDevId, int aoChn, int mute) 1463 | * 1464 | * 设置音频输出静音. 1465 | * 1466 | * @param[in] audioDevId 音频输出设备号. 1467 | * @param[in] aoChn 音频输出通道号. 1468 | * @param[out] mute 音频输出静音标志, mute = 0:关闭静音, mute = 1:打开静音. 1469 | * 1470 | * @retval 0 成功. 1471 | * @retval 非0 失败. 1472 | * 1473 | * @remarks 调用该接口可立刻静音. 1474 | * 1475 | * @attention 无. 1476 | */ 1477 | int IMP_AO_SetVolMute(int audioDevId, int aoChn, int mute); 1478 | 1479 | /** 1480 | * @fn int IMP_AI_SetGain(int audioDevId, int aiChn, int aiGain) 1481 | * 1482 | * 设置音频输入增益. 1483 | * 1484 | * @param[in] audioDevId 音频输入设备号. 1485 | * @param[in] aiChn 音频输入通道号. 1486 | * @param[out] aiGain 音频输入增益,范围[0 ~ 31],对应[-18dB ~ 28.5dB],步长1.5dB. 1487 | * 1488 | * @retval 0 成功. 1489 | * @retval 非0 失败. 1490 | * 1491 | * @remarks 无. 1492 | * 1493 | * @attention aiGain的范围为[0 ~ 31],如果输入的值小于0,则aiGain的值将会\n 1494 | * 被设置为0.如果值大于31,aiGain的值会被设置为10. 1495 | * 1496 | */ 1497 | int IMP_AI_SetGain(int audioDevId, int aiChn, int aiGain); 1498 | 1499 | /** 1500 | * @fn int IMP_AI_GetGain(int audioDevId, int aiChn, int *aiGain) 1501 | * 1502 | * 获取AI增益值. 1503 | * 1504 | * @param[in] audioDevId 音频输入设备号. 1505 | * @param[in] aiChn 音频输入通道号. 1506 | * @param[out] aiGain 音频输入增益. 1507 | * 1508 | * @retval 0 成功. 1509 | * @retval 非0 失败. 1510 | * 1511 | * @remarks 无. 1512 | * 1513 | * @attention 无. 1514 | */ 1515 | int IMP_AI_GetGain(int audioDevId, int aiChn, int *aiGain); 1516 | 1517 | /** 1518 | * @fn int IMP_AI_SetAlcGain(int audioDevId, int aiChn, int aiPgaGain) 1519 | * 1520 | * 设置音频输入增益. 1521 | * 1522 | * @param[in] audioDevId 音频输入设备号. 1523 | * @param[in] aiChn 音频输入通道号. 1524 | * @param[out] aiPgaGain 音频输入增益,范围[0 ~ 7],对应[-13.5dB, +28.5dB].步长6dB. 1525 | * 1526 | * @retval 0 成功. 1527 | * @retval 非0 失败. 1528 | * 1529 | * @remarks 无. 1530 | * 1531 | * @attention aiPgaGain的范围为[0 ~ 7],如果输入的值小于0,则aiPgaGain的值将会\n 1532 | * 被设置为0.如果值大于7,aiGain的值会被设置为7. 1533 | * 1534 | */ 1535 | int IMP_AI_SetAlcGain(int audioDevId, int aiChn, int aiPgaGain); 1536 | 1537 | /** 1538 | * @fn int IMP_AI_GetAlcGain(int audioDevId, int aiChn, int *aiPgaGain) 1539 | * 1540 | * 获取AIPga增益值. 1541 | * 1542 | * @param[in] audioDevId 音频输入设备号. 1543 | * @param[in] aiChn 音频输入通道号. 1544 | * @param[out] aiPgaGain 音频输入增益. 1545 | * 1546 | * @retval 0 成功. 1547 | * @retval 非0 失败. 1548 | * 1549 | * @remarks 无. 1550 | * 1551 | * @attention 无. 1552 | */ 1553 | int IMP_AI_GetAlcGain(int audioDevId, int aiChn, int *aiPgaGain); 1554 | 1555 | /** 1556 | * @fn int IMP_AO_SetGain(int audioDevId, int aoChn, int aoGain) 1557 | * 1558 | * 设置音频输出增益. 1559 | * 1560 | * @param[in] audioDevId 音频输出设备号. 1561 | * @param[in] aoChn 音频输出通道号. 1562 | * @param[out] aoGain 音频输出增益,范围[0 ~ 0x1f],对应[-39dB ~ 6dB],步长1.5dB. 1563 | * 1564 | * @retval 0 成功. 1565 | * @retval 非0 失败. 1566 | * 1567 | * @remarks 无. 1568 | * 1569 | * @attention aoGain的范围为[0 ~ 31],如果输入的值小于0,则aoGain的值将会\n 1570 | * 被设置为0.如果值大于31,aoGain的值会被设置为31. 1571 | * 1572 | */ 1573 | int IMP_AO_SetGain(int audioDevId, int aoChn, int aoGain); 1574 | 1575 | /** 1576 | * @fn int IMP_AO_GetGain(int audioDevId, int aoChn, int *aoGain) 1577 | * 1578 | * 获取音频输出增益. 1579 | * 1580 | * @param[in] audioDevId 音频输出设备号. 1581 | * @param[in] aoChn 音频输出通道号. 1582 | * @param[out] aoGain 音频输出增益. 1583 | * 1584 | * @retval 0 成功. 1585 | * @retval 非0 失败. 1586 | * 1587 | * @remarks 无. 1588 | * 1589 | * @attention 无. 1590 | */ 1591 | int IMP_AO_GetGain(int audioDevId, int aoChn, int *aoGain); 1592 | 1593 | /** 1594 | * @fn int IMP_AO_Soft_Mute(int audioDevId, int aoChn) 1595 | * 1596 | * 输出软静音控制. 1597 | * 1598 | * @param[in] audioDevId 音频输出设备号. 1599 | * @param[in] aoChn 音频输出通道号. 1600 | * 1601 | * @retval 0 成功. 1602 | * @retval 非0 失败. 1603 | * 1604 | * @remarks 调用该接口不会立马静音,会从正常放音状态缓慢将音量降低,直到真正静音. 1605 | * 1606 | * @attention 无. 1607 | */ 1608 | int IMP_AO_Soft_Mute(int audioDevId, int aoChn); 1609 | 1610 | /** 1611 | * @fn int IMP_AO_Soft_UNMute(int audioDevId, int aoChn) 1612 | * 1613 | * 输出软撤销静音控制. 1614 | * 1615 | * @param[in] audioDevId 音频输出设备号. 1616 | * @param[in] aoChn 音频输出通道号. 1617 | * 1618 | * @retval 0 成功. 1619 | * @retval 非0 失败. 1620 | * 1621 | * @remarks 调用该接口不会立马恢复当前音量,会从静音状态缓慢将音量增加,直到音量达到设置好的音量. 1622 | * 1623 | * @attention 无. 1624 | */ 1625 | int IMP_AO_Soft_UNMute(int audioDevId, int aoChn); 1626 | 1627 | /** 1628 | * @fn int IMP_AI_GetFrameAndRef(int audioDevId, int aiChn, IMPAudioFrame *frm, IMPAudioFrame *ref, IMPBlock block) 1629 | * 1630 | * 获取音频帧和输出参考帧. 1631 | * 1632 | * @param[in] audioDevId 音频设备号. 1633 | * @param[in] aiChn 音频输入通道号. 1634 | * @param[out] frm 音频帧结构体指针. 1635 | * @param[out] ref 参考帧结构体指针. 1636 | * @param[in] block 阻塞/非阻塞标识. 1637 | * 1638 | * @retval 0 成功. 1639 | * @retval 非0 失败. 1640 | * 1641 | * @remarks 示例代码 1642 | * @code 1643 | * IMPAudioFrame frm; 1644 | * IMPAudioFrame ref; 1645 | * // 获取音频帧和输出参考帧 1646 | * ret = IMP_AI_GetFrameAndRef(devID, chnID, &frm, &ref, BLOCK); 1647 | * if(ret != 0) { 1648 | * IMP_LOG_ERR(TAG, "Audio Get Frame Data error\n"); 1649 | * return ret; 1650 | * } 1651 | * 1652 | * fwrite(frm.virAddr, 1, frm.len, record_file); // 使用音频帧数据 1653 | * fwrite(ref.virAddr, 1, ref.len, ref_file); // 使用音频参考帧 1654 | * 1655 | * // 释放音频帧 1656 | * ret = IMP_AI_ReleaseFrame(devID, chnID, &frm); 1657 | * if(ret != 0) { 1658 | * IMP_LOG_ERR(TAG, "Audio release frame data error\n"); 1659 | * return ret; 1660 | * } 1661 | * @endcode 1662 | * 1663 | * @attention 无. 1664 | */ 1665 | int IMP_AI_GetFrameAndRef(int audioDevId, int aiChn, IMPAudioFrame *frm, IMPAudioFrame *ref, IMPBlock block); 1666 | 1667 | /** 1668 | * @fn int IMP_AI_EnableAecRefFrame(int audioDevId, int aiChn, int audioAoDevId, int aoChn) 1669 | * 1670 | * 打开获取参考帧. 1671 | * 1672 | * @param[in] audioDevId 音频设备号. 1673 | * @param[in] aiChn 音频输入通道号. 1674 | * @param[in] audioAoDevId 音频输出设备号. 1675 | * @param[in] aoChn 音频输出通道号. 1676 | * 1677 | * @retval 0 成功. 1678 | * @retval 非0 失败. 1679 | * 1680 | * @remarks 调用IMP_AI_GetFrameAndRef之前调用此接口. 1681 | * @attention 无. 1682 | */ 1683 | int IMP_AI_EnableAecRefFrame(int audioDevId, int aiChn, int audioAoDevId, int aoChn); 1684 | 1685 | /** 1686 | * @fn int IMP_AI_DisableAecRefFrame(int audioDevId, int aiChn, int audioAoDevId, int aoChn) 1687 | * 1688 | * 关闭获取参考帧. 1689 | * 1690 | * @param[in] audioDevId 音频设备号. 1691 | * @param[in] aiChn 音频输入通道号. 1692 | * @param[in] audioAoDevId 音频输出设备号. 1693 | * @param[in] aoChn 音频输出通道号. 1694 | * 1695 | * @retval 0 成功. 1696 | * @retval 非0 失败. 1697 | * 1698 | * @remarks 无. 1699 | * @attention 无. 1700 | */ 1701 | int IMP_AI_DisableAecRefFrame(int audioDevId, int aiChn, int audioAoDevId, int aoChn); 1702 | 1703 | /** 1704 | * @fn int IMP_AO_CacheSwitch(int audioDevId, int aoChn, int cache_en) 1705 | * 关闭音频播放缓存机制 1706 | * @param[in] audioDevId 音频设备号. 1707 | * @param[in] aoChn 音频输出通道号. 1708 | * @param[in] cache_en 缓存机制开启开关 1709 | * 1710 | * @retval 0 成功. 1711 | * @retval 非0 失败. 1712 | * 1713 | * @remarks 无. 1714 | * @attention 无. 1715 | */ 1716 | int IMP_AO_CacheSwitch(int audioDevId, int aoChn, int cache_en); 1717 | 1718 | /** 1719 | * @fn int IMP_AO_FlushChnBuf(int audioDevId, int aoChn); 1720 | * 等待最后一段音频数据播完; 1721 | * @param[in] audioDevId 音频设备号. 1722 | * @param[in] aoChn 音频输出通道号. 1723 | * 1724 | * @retval 0 成功. 1725 | * @retval 非0 失败. 1726 | * 1727 | * @remarks 无. 1728 | * @attention 无. 1729 | */ 1730 | int IMP_AO_FlushChnBuf(int audioDevId, int aoChn); 1731 | 1732 | #ifdef __cplusplus 1733 | #if __cplusplus 1734 | } 1735 | #endif 1736 | #endif /* __cplusplus */ 1737 | 1738 | #endif /* __IMP_AUDIO_H__ */ 1739 | --------------------------------------------------------------------------------