pure sdk for main

This commit is contained in:
divadiow
2025-08-27 09:51:58 +01:00
parent f0d033f1c9
commit 0571416e7c
3283 changed files with 1577720 additions and 1 deletions
+75
View File
@@ -0,0 +1,75 @@
#include "typesdef.h"
#include "pdmFilter.h"
/** @brief 去直流函数,使用一阶切比雪夫1型高通滤波器,fpass=20
* @{
*/
#define FIXED_POINT_NUM 30
//增加IIR缓存数据的小数位数,减少噪声
#define FRAC_FIXED_NUM 12
const int NUM[2][2] = {
{ 1072963942, 0, },
{ 1073741824, -1073741824 },
};
const int DEN[2][2] = {
{ 1073741824, 0, },
{ 1073741824, -1072186059, },
};
int16_t rm_dc_filter(TYPE_FIRST_ORDER_FILTER_TYPE *p_filter, int16_t input)
{
int x = input << FRAC_FIXED_NUM;
int y;
int64_t acc;
acc = (int64_t)x * (int64_t)NUM[0][0];
if(acc < 0) {
x = (acc + (1<<FIXED_POINT_NUM) - 1) >> FIXED_POINT_NUM;
} else {
x = acc >> FIXED_POINT_NUM;
}
acc = (int64_t)x * (int64_t)NUM[1][0];
acc += (int64_t)p_filter->x * (int64_t)NUM[1][1];
acc -= (int64_t)p_filter->y * (int64_t)DEN[1][1];
if(acc < 0) {
y = (acc + (1<<FIXED_POINT_NUM) - 1) >> FIXED_POINT_NUM;
} else {
y = acc >> FIXED_POINT_NUM;
}
p_filter->x = x;
p_filter->y = y;
y >>= FRAC_FIXED_NUM;
//饱和操作
if(y > 32767) {
y = 32767;
} else if(y < -32768) {
y = -32768;
}
return y;
}
/**
* @}
*/
/** @brief 音量控制。注意gain为 bit 定点数
* @{
*/
int16_t pcm_volum_gain(int16_t input, int32_t gain)
{
int32_t temp = (input * gain) >> 8;
if(temp > 32767) {
return 32767;
} else if(temp < -32768) {
return -32768;
} else {
return temp;
}
}
+11
View File
@@ -0,0 +1,11 @@
#ifndef __PDMFILTER_H
#define __PDMFILTER_H
#include "typesdef.h"
typedef struct {
int x;
int y;
} TYPE_FIRST_ORDER_FILTER_TYPE;
int16_t rm_dc_filter(TYPE_FIRST_ORDER_FILTER_TYPE *p_filter, int16_t input);
int16_t pcm_volum_gain(int16_t input, int32_t gain);
#endif
@@ -0,0 +1,268 @@
#ifndef __STREAM_DEFINE_H
#define __STREAM_DEFINE_H
#ifndef BIT
#define BIT(a) (1UL << (a))
#endif
//yuv通用参数
struct yuv_arg_s
{
uint32_t y_size;
uint32_t y_off;
uint32_t uv_off;
uint32_t out_w;
uint32_t out_h;
//状态位,如果发现要求del,那么接收流就要尽快释放了,不要占用当前节点
uint8_t *del;
};
//解码,yuv通用参数放前面,与yuv_arg_s保持一致
struct jpg_decode_arg_s
{
struct yuv_arg_s yuv_arg;
uint32_t rotate;
uint32_t decode_w; //解码图片的size
uint32_t decode_h;
uint32_t step_w;
uint32_t step_h;
uint32_t magic;
};
//用于定义各种data的类型枚举
enum {
DATA_TYPE_ANY,
DATA_TYPE_AUDIO_PDM,
DATA_TYPE_AUDIO_I2S,
DATA_TYPE_AUDIO_ADC,
DATA_TYPE_AUDIO_DAC,
DATA_TYPE_JPEG_VGA,
DATA_TYPE_JPEG_720P,
DATA_TYPE_YUV,
};
enum
{
//这里是通用命令,定义一些通用的接口,代表所有都可以调用,获取或者设置都是一样的,需要明确各个参数
JPG_DECODE_ARG = 0x01, //opcode=0x01,arg=data_s,获取的是jpg解码相关参数,有解码后size,解码前size,以及step,参考jpg_decode_arg_s的结构
YUV_ARG, //如果是yuv图片,可以通过这个获取相关yuv的参数(仅仅包含了yuv的必要参数),有y_size,uv_off,y_off,如果后续有需要可以扩展(比如旋转多少度)
SET_LVGL_YUV_UPDATE_TIME,
GET_LVGL_YUV_UPDATE_TIME,
SET_LVGL_VIDEO_ARG,
SCALE1_RESET_DPI,
SET_MJPEG_RESOLUTION_PARM_CMD,
RESET_MJPEG_DPI,
RESET_MJPEG_FROM,
PRC_MJPEG_KICK,
PRC_REGISTER_ISR,
STREAM_STOP_CMD,
STREAM_ZBAR_FROM_SD,
NEWAVI_PLAYER_LOCATE_FORWARD_INDEX,
NEWAVI_PLAYER_LOCATE_REWIND_INDEX,
NEWAVI_PLAYER_MAGIC,
NEWAVI_PLAYER_STATUS,
//这里是自定义的命令
CUSTOM_STREAM_CMD = 0x100,
};
//定义各种流的名称,R开头代表接收的流,S开头是发送的流,SR代表既要接收又要发送的流
//名称不能相同
//没有专门发送和接收,只是流负责管理
#define MANAGE_STREAM_NAME "manage-stream"
//R
#define R_RECORD_AUDIO "record-audio" //录像的音频
#define R_RECORD_JPEG "record-jpeg" //录像的音频
#define R_RECORD_H264 "record-h264" //录像的音频
#define R_PHOTO_JPEG "photo-jpeg" //录像的音频
#define R_ALK_JPEG "alk-jpeg"
#define R_AUDIO_TEST "audio-test"
#define R_SPEAKER "speaker"
#define R_JPEG_TO_LCD "JPEG-LCD"
#define R_JPEG_DEMO "jpeg_demo"
#define R_USB_AUDIO_MIC "usb-audio-mic"
#define R_RTP_AUDIO "rtp-audio" //图传的音频
#define R_RTP_JPEG "rtp-jpeg" //图传的视频
#define R_LVGL_JPEG "lvgl-jpeg" //lvgl接收回放适配
#define R_LVGL_TAKEPHOTO "lvgl_takephoto"
#define R_LOWPOERRESUME_EVENT "LOWPOERRESUME_EVENT"
#define R_AT_SAVE_OSD "AT_OSD"
#define R_AT_SAVE_AUDIO "AT_AUDIO"
#define R_AT_SAVE_PHOTO "AT_PHOTO"
#define R_AT_AVI_AUDIO "AT_AVI_AUDIO" //录像的音频
#define R_AT_AVI_JPEG "AT_AVI_JPEG" //录像的音频
#define R_SAVE_STREAM_DATA "stream_data"
#define R_INTERMEDIATE_DATA "R_Intermediate_data"
#define R_AVI_SAVE_VIDEO "AVI_SAVE_VIDEO"
#define R_AVI_SAVE_AUDIO "AVI_SAVE_AUDIO"
#define R_INTERCOM_AUDIO "INTERCOM_SEND"
#define R_PSRAM_JPEG "PSRM-jpeg" //接收到psram的视频
#define R_USB_SPK "usb_speaker"
#define R_OSD_ENCODE "osd_encode"
#define R_OSD_SHOW "osd_show"
#define R_VIDEO_P1 "VIDEO_P1"
#define R_VIDEO_P0 "VIDEO_P0"
#define R_JPG_TO_RGB "JPG_TO_RGB"
#define R_YUV_TO_JPG "YUV_TO_JPG"
#define R_ZBAR "Zbar"
#define R_DEBUG_STREAM "debug-stream"
#define R_SONIC_PROCESS "r_sonic_process"
#define R_SPEECH_RECOGNITION "r_speech_recognition"
//S
#define S_PDM "pdm"
#define S_ADC_AUDIO "adc_audio"
#define S_MP3_AUDIO "mp3_audio"
#define S_AMRNB_AUDIO "amrnb_audio"
#define S_AMRWB_AUDIO "amrwb_audio"
#define S_JPEG "jpeg"
#define S_USB_JPEG "usb-jpeg"
#define S_USB_JPEG_PSRAM "usb-jpeg-psram"
#define S_WEBJPEG "web-jpeg"
#define S_PLAYBACK "playback-jpeg"
#define S_WEBAUDIO "web-audio"
#define S_NET_JPEG "net-jpeg"
#define S_USB_DUAL "usb-dual"
#define S_INTERCOM_AUDIO "INTERCOM_RECV"
#define S_INTERMEDIATE_DATA "S_Intermediate_data"
#define S_USB_MIC "usb_microphone"
#define S_LVGL_OSD "lvgl_osd"
#define S_JPG_DECODE "jpg_decode"
#define S_LVGL_JPG "lvgl_jpg"
#define S_PREVIEW_SCALE3 "preview_scale3"
#define S_SCALE1_STREAM "scale3_stream"
#define S_PREVIEW_ENCODE_QVGA "preview_encode_qvga"
#define S_PREVIEW_ENCODE_QQVGA "preview_encode_qqvga"
#define S_PREVIEW_ENCODE_VPP "preview_encode_vpp"
#define S_SONIC_PROCESS "s_sonic_process"
#define S_NEWPLAYER "newplayer"
#define S_NEWAVI "newavi"
#define S_ZBAR_FROM_SD "zbar_read_sd"
#define S_LVGL_PHOTO "lvgl_photo"
//SR
#define SR_OTHER_JPG "other_jpg"
#define SR_OTHER_JPG_USB1 "other_jpg_usb1"
#define SR_OTHER_JPG_USB2 "other_jpg_usb2"
#define SR_VIDEO_USB "video_usb"
#define SR_ZBAR_JPG "zbar_parse"
//高16位是大类型(统一宏),低16位是细分类型
#define SET_DATA_TYPE(type1,type2) (type1<<16 | type2)
#define GET_DATA_TYPE1(type) (type>>16)
#define GET_DATA_TYPE2(type) (type&0xffff)
enum data_type1
{
TYPE1_NONE,
JPEG = 1,
SOUND,
YUV,
H264,
};
//0保留
enum DATA_TYPE2_RECV_ALL
{
RESEVER_VALUE,
RECV_ALL = RESEVER_VALUE,
};
//定义mjpeg的类型,最好自己将不同类型归类
enum JPEG_data_type2
{
JPEG_NONE = RESEVER_VALUE,
JPEG_DVP_NODE, //采用特殊的节点方式
JPEG_FULL, //jpeg的data是完整的图片,不采用节点方式
JPEG_DVP_FULL, //采用整张图保存的方式(在空间足够下,采用正常图片形式,正常是带psram才会使用)
JPEG_USB,
JPEG_FILE,
LVGL_JPEG,
SET_JPEG_MSG,
LVGL_JPEG_TO_RGB,
JPEG_NORMAL_DATA, //正常模式的data,代表用普通方式去读取jpg就可以了
};
//定义声音的类型
enum SOUND_data_type2
{
SOUND_ALL = RECV_ALL,
SOUND_NONE,//不接收声音,源头不要产生这个声音就好了
SOUND_MIC ,
SOUND_FILE,
SOUND_INTERCOM,
SOUND_MP3,
SOUND_AMRNB,
SOUND_AMRWB,
};
enum YUV_data_type2
{
YUV_P0 = BIT(0),
YUV_P1 = BIT(1),
YUV_OTHER = BIT(2),
};
//定义lvgl的video命令的类型
enum LVGL_VIDEO_data_type2
{
CMD_LVGL_NONE = 0,
CMD_LVGL_VIDEO_DEL,
};
enum
{
CMD_VIDEO_PLAYER_NONE,
CMD_VIDEO_PLAYER_EXIT,
};
//设置发送的命令,只有type1是在这里定义,type2由各个模块去定义(这个就不再有固定,因为自定义,所以在要自己在各个STREAM_SEND_CMD里面去处理识别)
#define SET_CMD_TYPE(type1,type2) (type1<<16 | type2)
#define GET_CMD_TYPE1(type) (type>>16)
#define GET_CMD_TYPE2(type) (type&0xffff)
enum cmd_type1
{
CMD_NONE,
CMD_AUDIO_DAC,
CMD_AUDIO_DAC_MODIFY_HZ, //采样率修改cmd
CMD_JPEG_FILE,
CMD_LVGL_VIDEO, //lvgl 的video命令
CMD_VIDEO_PLAYER,
};
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,201 @@
#ifndef __STREAM_FRAME_H
#define __STREAM_FRAME_H
#include "typesdef.h"
#include "stream_define.h"
//定义流的一些函数操作的回调函数,用于不同状态的时候分别通知流
enum
{
STREAM_OPEN_ENTER, //准备打开流
STREAM_OPEN_CHECK_NAME, //创建流之前可以检查name是否符合
STREAM_OPEN_EXIT, //打开流完成退出
STREAM_OPEN_SUCCESS = STREAM_OPEN_EXIT, //打开流完成退出
STREAM_OPEN_FAIL, //打开失败
STREAM_CLOSE_ENTER, //准备关闭流
STREAM_CLOSE_EXIT, //关闭流完成退出
STREAM_CLOSE_FAIL, //打开失败
STREAM_DATA_DIS, //自定义内存分配(open的时候会调用)
STREAM_DATA_DESTORY, //自定义内存释放(close的时候调用)
STREAM_FILTER_DATA, //在发送的时候,过滤数据包
STREAM_RECV_FILTER_DATA, //接收的时候过滤不需要播放的数据包
STREAM_SEND_DATA_START, //准备发送数据
STREAM_SEND_DATA_FINISH, //发送数据包完成
STREAM_RECV_DATA_FINISH,
STREAM_SEND_TO_DEST,
STREAM_GET_DATA_PRIV,
STREAM_DATA_FREE,
STREAM_DATA_FREE_END,
STREAM_SEND_CMD, //向流发送命令,可以执行一些特殊操作(如果流不想想响应,则不去响应就行了)
STREAM_DEL,
STREAM_MARK_GC_END, //stream已经可以重新使用
STREAM_CALC_AUDIO_ENERGY,
STREAM_DEFAULT_FINISH = 0x80,//定义流默认值最大,0x81-0xff都是用户流自定义
};
enum
{
STREAM_AVAILABLE, //流可用
STREAM_ISUED, //被使用
STREAM_UNAVAILABLE,
STREAM_WAIT_GC_MARKER,
STREAM_WAIT_GC_CLEAN,
STREAM_AVAILABLE_AGAIN, //流可重复利用,这个时候可能ref不为0,但是其他资源被释放
};
struct data_structure;
struct data_list;
struct stream_list;
typedef struct stream_s stream;
typedef int (*d_free_func)(struct data_structure *d);
typedef int (*stream_priv_func)(struct stream_s *s,void *priv,int opcode);
typedef void *(*stream_get_data)(void *data);
typedef uint32_t (*stream_get_data_time)(void *data);
typedef uint32_t (*stream_get_data_len)(void *data);
typedef void (*stream_data_free)(void *data);
typedef uint32 (*stream_data_custom_func)(void *data,int opcode,void *priv);
typedef uint32 (*stream_self_cmd)(stream *s,int opcode,uint32_t arg);
typedef uint32_t (*stream_set_data_len)(void *data,uint32_t len);
typedef uint32_t (*stream_set_data_timestamp)(void *data,uint32_t timestamp);
typedef struct
{
int type;
//公用函数
stream_get_data get_data; //获取data实体(不一定是数组可能是一个结构体,看流的定义)
stream_get_data_len get_data_len; //获取data的长度
stream_set_data_len set_data_len;
stream_data_free free; //释放data
stream_get_data_time get_data_time; //获取data的time
stream_set_data_timestamp set_data_time;
//用户扩展的函数(可以从data获取到到stream,一般给终端调用)
stream_data_custom_func custom_func;
}stream_ops_func;
//数据的结构体
struct data_structure
{
void *data; //数据的空间,自己申请赋值,可以是一个结构体也可以是一个数组,流自己决定,只是接收方要明确知道该数据的格式(提前协商)
struct data_structure *next;
struct data_structure *prev;
struct stream_s *s;
//注册函数,通过参数去获取一系列参数
stream_ops_func *ops;
void *priv;//私有的结构体
int type; //类型,理论每一个stream的数据类型都不是一样的
uint32_t magic; //特殊数字,转发或者特殊的,可以继承这个值,默认都是0,有需求可以改动
d_free_func free; //释放函数
int ref; //引用数量
uint32_t timestamp;
uint32_t len; //可以保存data的长度
uint32_t audio_energy;
};
struct data_list
{
struct data_structure *data;//数据
struct data_list *next; //指针指向下一个
struct data_list *prev; //指针指向下一个
};
struct stream_list
{
struct stream_list *next;
struct stream_list *prev;
struct stream_s *s;
int enable; //独立一个开关,可以随时停止发送
};
struct stream_s
{
struct stream_list *s_list; //已经绑定的流
struct stream_s *next;
struct stream_s *prev;
void *priv; //流自己的私有结构体
stream_priv_func func; //流自己的操作函数,可以自定义操作
const char *name; //stream的名称
int used; //是否被使用
int enable; //是否使能
int ref; //引用次数,为0,代表没有人在使用
int send_ref;
int open_ref; //open成功后,会+1,close一次会-1,直到变成0后,才能实际关闭
//给stream发送命令(要保证stream没有被提前释放)
stream_self_cmd self_cmd_func;
//d_free_func free; //释放data的函数,流自己专有的,释放的时候,先调用这个,再调用默认的
int src_d_list_count; //d_list的总数量,open的时候初始化好,直到删除才能被修改
void *src_d_list_head; //记录申请的空间头,删除的时候直接free掉
void *d_list_head; //记录申请的空间头,删除的时候直接free掉
//自己data的链表结构体
struct data_structure *src_d_list_f; //当是data产生源头的时候,这里可以调用的链表数量
struct data_structure *src_d_list_u; //如果被使用,则放在这个链表中,释放的时候是释放到src_d_list_f;
//接收的data链表结构体
struct data_list *d_list_f;//可用数据链表
struct data_list *d_list_u;//已有数据链表
};
void *open_stream(const char *name,int data_count,int recv_count,stream_priv_func func,void *priv);
int close_stream(struct stream_s *s);
int streamSrc_bind_streamDest(struct stream_s *s,const char *name);
int streamSrc_unbind_streamDest(struct stream_s *s,const char *name);
int send_data_to_stream(struct data_structure *data);
int enable_stream(struct stream_s *s,int enable);
struct data_structure *get_src_data_f(struct stream_s *s);
struct data_structure *recv_real_data(struct stream_s *s);
void *get_real_data(void *data_struct);
int free_data(void *data_struct);
void stream_data_mem_dis(struct stream_s *s,uint8_t *buf_head,int uint_len,int count);
int force_del_data(struct data_structure *data);
void stream_data_dis_mem(struct stream_s *s,int count);
void *get_stream_real_data(struct data_structure* data);
uint32_t get_stream_real_data_len(struct data_structure* data);
void send_stream_cmd(struct stream_s *s,void *data);
uint32_t set_stream_real_data_len(struct data_structure* data,uint32_t len);
void stream_work_queue_start();
uint32_t stream_data_custom_cmd_func(struct data_structure* data,int opcode,void *priv);
uint32_t set_stream_data_time(struct data_structure* data,uint32_t timestamp);
uint32_t get_stream_data_timestamp(struct data_structure* data);
void *open_stream_available(const char *name,int data_count,int recv_count,stream_priv_func func,void *priv);
uint32_t register_stream_self_cmd_func(stream *s,stream_self_cmd func);
uint32_t stream_self_cmd_func(stream *s,int opcode,uint32_t arg);
int open_stream_again(stream *s);
void *get_stream_available(const char *name);
void broadcast_cmd_to_destStream(stream *s,uint32_t cmd);
void stream_data_dis_mem_custom(stream *s);
int hold_data(struct data_structure *data);
uint8_t find_stream_enable(const char *name);
#endif
+75
View File
@@ -0,0 +1,75 @@
/************************************************
* 提供一个通用队列接口
************************************************/
#include "t_queue.h"
#include "osal/string.h"
void *tqueue_init()
{
struct tqueue_base_s *tqueue_head = (struct tqueue_base_s *)os_malloc(sizeof(struct tqueue_base_s));
if(tqueue_head)
{
tqueue_head->count = 0;
INIT_LIST_HEAD((struct list_head*)tqueue_head);
}
return (void*)tqueue_head;
}
//正常需要先将列表清空才可以释放
void tqueue_deinit(void *tqueue_head_ptr)
{
if(tqueue_head_ptr)
{
os_free(tqueue_head_ptr);
}
}
//如果必要,暂时需要外部进行临界保护
//这里将data放到队列
uint8_t tqueue_push(void *tqueue_head_ptr,struct tqueue_s *data)
{
struct tqueue_base_s *tqueue_head = (struct tqueue_base_s *)tqueue_head_ptr;
struct tqueue_s *tqueue_data = data;
if(tqueue_data)
{
list_add_tail((struct list_head*)tqueue_data,(struct list_head*)tqueue_head);
tqueue_head->count++;
return 0;
}
return 1;
}
//从队列取出一个data
struct tqueue_s *tqueue_pop(void *tqueue_head_ptr)
{
struct tqueue_base_s *tqueue_head = (struct tqueue_base_s *)tqueue_head_ptr;
struct tqueue_s *tqueue_data = NULL;
if(tqueue_head->count > 0)
{
tqueue_data = (struct tqueue_s *)tqueue_head->next;
list_del((struct list_head *)tqueue_data);
INIT_LIST_HEAD((struct list_head *)tqueue_data);
tqueue_head->count--;
return tqueue_data;
}
else
{
return NULL;
}
}
struct tqueue_s *tqueue_gen_data(void *data,tqueue_malloc m)
{
struct tqueue_s *tqueue_data = (struct tqueue_s *)m(sizeof(struct tqueue_s));
if(tqueue_data)
{
tqueue_data->data = data;
INIT_LIST_HEAD((struct list_head *)tqueue_data);
}
return tqueue_data;
}
+27
View File
@@ -0,0 +1,27 @@
#ifndef __T_QUEUE_H
#define __T_QUEUE_H
#include "sys_config.h"
#include "typesdef.h"
#include "list.h"
struct tqueue_s
{
struct list_head *next, *prev;
void *data;
};
struct tqueue_base_s
{
struct list_head *next, *prev;
uint32_t count;
};
typedef void *(*tqueue_malloc)(uint32_t size);
typedef void (*tqueue_free)(void *data);
void *tqueue_init();
void tqueue_deinit(void *tqueue_head_ptr);
uint8_t tqueue_push(void *tqueue_head_ptr,struct tqueue_s *data);
struct tqueue_s *tqueue_pop(void *tqueue_head_ptr);
struct tqueue_s *tqueue_gen_data(void *data,tqueue_malloc m);
#endif