Initial commit: TXW82x FPV v2.7.0.7-42229 SDK + project sources

This commit is contained in:
2026-07-06 11:30:13 +08:00
commit e76462eeb7
3451 changed files with 1415300 additions and 0 deletions

View File

@@ -0,0 +1,217 @@
#ifndef _TXSEMI_FRAMEBUFF_H_
#define _TXSEMI_FRAMEBUFF_H_
#include "media_types.h"
#ifdef __cplusplus
extern "C" {
#endif
#define FB_ALLOC(size) os_malloc(size)
#define FB_FREE(fb) os_free(fb)
enum FRAMEBUFF_MTYPE {
F_NONE = 0, //无类型
F_YUV, //YUV数据
F_JPG_NODE, //jpeg
F_JPG, //jpeg
F_JPG_DECODE_MSG, //jpeg
F_THUMB_JPG, //jpeg
F_H264, //h264
F_AUDIO, //音频
F_RGB, //未压缩的rgb
F_ERGB, //压缩后的rgb
F_FILE_T, //文件类型(一般用于文件保存,仅仅支持普通模式:fb->data+fb->len)
};
//设定framebuff的子类型,用uint16_t去定义吧
enum FRAMEBUFF_STYPE
{
FSTYPE_NONE = 0, //无类型
FSTYPE_NORMAL_THUMB_JPG,
FSTYPE_NORMAL_THUMB_JPG_USB,
FSTYPE_OVER_DPI_THUMB_JPG,
FSTYPE_OVER_DPI_JPG,
FSTYPE_VIDEO_VPP_DATA0,
FSTYPE_VIDEO_VPP_DATA1,
FSTYPE_VIDEO_PRC_DATA,
FSTYPE_VIDEO_SCALER_DATA,
FSTYPE_VIDEO_GEN420_DATA,
FSTYPE_VIDEO_SOFT_DATA,
FSTYPE_YUV_P0,
FSTYPE_YUV_P1,
FSTYPE_YUV_P2,
FSTYPE_YUV_SIM_P0,
FSTYPE_YUV_SIM_P1,
FSTYPE_YUV_OTHER,
FSTYPE_YUV_TAKEPHOTO,
FSTYPE_JPG_CAMERA0,
FSTYPE_JPG_CAMERA1,
FSTYPE_JPG_CAMERA2,
FSTYPE_JPG_FILE,
FSTYPE_JPG_GEN420_0,
FSTYPE_JPG_GEN420_REJPG,
FSTYPE_USB_CAM0,
FSTYPE_USB_CAM1,
FSTYPE_AUDIO_ADC,
FSTYPE_AUDIO_AAC,
FSTYPE_AUDIO_MP3,
FSTYPE_AUDIO_OPUS,
FSTYPE_AUDIO_ALAW,
FSTYPE_AUDIO_ULAW,
FSTYPE_AUDIO_AMRNB,
FSTYPE_AUDIO_AMRWB,
FSTYPE_AUDIO_PCM,
FSTYPE_AUDIO_USB_MIC,
//h264,硬件产生
FSTYPE_H264_VPP_DATA0,
FSTYPE_H264_VPP_DATA1,
FSTYPE_H264_PRC_DATA,
FSTYPE_H264_SCALER_DATA,
FSTYPE_H264_GEN420_DATA,
FSTYPE_H264_SOFT_DATA,
FSTYPE_SCALE1_DATA,//scale1自行添加类型,这里添加一个demo去实现大分辨率拍照
//h264软件(比如读取文件)
FSTYPE_H264_FILE,
FSYPTE_INVALID = 0x80, //无效的stype,用于特殊值,由应用去特殊使用
FSTYPE_GEN420_720P,
};
enum FRAMEBUFF_SOURCE{
FRAMEBUFF_SOURCE_NONE,
FRAMEBUFF_SOURCE_JPG_GEN420, //特殊,标记从gen420编码
FRAMEBUFF_SOURCE_JPG_SCALER, //特殊,标记从scaler编码
FRAMEBUFF_SOURCE_FILE,
FRAMEBUFF_SOURCE_USB,
FRAMEBUFF_SOURCE_CAMERA0,
FRAMEBUFF_SOURCE_CAMERA1,
FRAMEBUFF_SOURCE_CAMERA2,
FRAMEBUFF_SOURCE_OSD_ENC,
FRAMEBUFF_SOURCE_CSC,
};
struct msi;
/*结构体Size控制在32Byte以内满足DMA 16 对齐的要求*/
struct framebuff {
// framebuff片段链表用于多个framebuff组成一个完整的帧
struct framebuff *next;
uint8 *data; //数据地址: 可以是外部地址也可以是framebuff自己分配的地址
uint32 len; //数据长度
uint32 time; //数据时间戳:存差值
void *priv; //私有数据
uint8 mtype, stype; //数据类型main_type + sub_type
uint8 srcID; //来源ID : enum FRAMEBUFF_SOURCE
uint8 datatag; //数据标签,应用自定义
atomic8_t users; //引用计数
uint8 index; //fbpool使用
uint8 used: 1, pool: 1, clone:1, keyfrm:1, rev: 4; //flags
struct msi *msi; //产生此fb的MSI组件
};
/* framebuff 队列 */
struct fbqueue {
struct os_semaphore sema;
uint16 reader_max;
uint16 init: 1, alloc: 1, rev: 14;
uint32 *readers;
RBUFFER_DEF_R(rbQ, struct framebuff *);
};
/* framebuff 预分配池
预分配的framebuff必须处理 MSI_CMD_FREE_FB
在MSI_CMD_FREE_FB处理后需要调用 fbpool_put API而且返回值为 1.
*/
struct fbpool {
uint8 size, rev1;
uint16 inited: 1, rev: 15;
struct framebuff *pool;
};
//创建framebuff
//data != NULL: 表示framebuff关联外部数据自己不分配数据空间
//data == NULL && size > 0: 表示framebuff需要自己分配数据空间
//data == NULL && size = 0: 表示framebuff不需要数据空间
extern struct framebuff *fb_alloc(uint8 *data, int32 size, uint16 type, struct msi *msi);
//MSI组件接收framebuff后需要执行fb_get操作fb计数加1
extern void fb_get(struct framebuff *fb);
//使用新的framebuff引用关联另1个framebuff组成framebuff链表fb_old引用计数会加1
extern void fb_ref(struct framebuff *fb_new, struct framebuff *fb_old);
//获取framebuff链表中指定type的数据的第1个节点
extern struct framebuff *fb_find(struct framebuff *fb, uint8 mtype, uint8 stype);
//获取framebuff链表中指定type的数据的总长度
extern uint32 fb_len(struct framebuff *fb, uint8 mtype, uint8 stype);
//framebuff put操作引用计数减至0时会释放framebuff资源
extern void fb_put(struct framebuff *fb);
//framebuff 队列初始化需要指定队列的buffer和大小
extern int32 fbq_init(struct fbqueue *q, uint8 *qbuff, int32 qsize);
//销毁framebuff队列并释放队列中存放的framebuff
extern int32 fbq_destory(struct fbqueue *q);
//向framebuff队列存入1个framebuff返回值表示存入是否成功
extern int32 fbq_enqueue(struct fbqueue *q, struct framebuff *fb);
//在framebuff队列中查找或丢弃指定的framebuff
extern int32 fbq_trace(struct fbqueue *q, struct framebuff *fb, int8 discard);
//从framebuff队列中取出1个framebuff
extern struct framebuff *fbq_dequeue(struct fbqueue *q, uint32 tmo_ms);
extern struct framebuff *fbq_dequeue_r(struct fbqueue *q, uint8 reader);
//framebuff预分配池初始化需要指定预分配池的大小
extern int32 fbpool_init(struct fbpool *pool, uint8 size);
//从预分配池中取出一个framebuff
extern struct framebuff *fbpool_get(struct fbpool *pool, uint16 type, struct msi *msi);
//向预分配池释放一个framebuff
extern int32 fbpool_put(struct fbpool *pool, struct framebuff *fb);
//销毁framebuff预分配池同时通知各个模块丢弃指定的framebuff
extern int32 fbpool_destroy(struct fbpool *pool);
//framebuff克隆操作克隆的framebuff会关联原framebuff的大部分信息(但是type会重新修改)
extern struct framebuff *fb_clone(struct framebuff *fb, uint16 type, struct msi *msi);
//根据fb->mtype 识别fb携带的数据为 视频,音频,图片,字幕
extern MEDIA_DATA_CATEGORY fb_category(struct framebuff *fb);
//初始化预分配的framebuff信息仅在初始化时调用。
// fbpool : framebuff 预分配池struct fbpool* 类型
// index : framebuffer的索引不能超过pool的size
// buff_addr: framebuffer 预分配的buffer地址
// buff_size: framebuffer 预分配的buffer大小
// priv_data: framebuffer 的私有数据
#define FBPOOL_SET_INFO(fbpool, index, buff_addr, buff_size, priv_data) do { \
(fbpool)->pool[index].data = buff_addr; \
(fbpool)->pool[index].len = buff_size; \
(fbpool)->pool[index].priv = priv_data; \
}while(0)
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,98 @@
#ifndef _TXSEMI_MEDIATYPES_H_
#define _TXSEMI_MEDIATYPES_H_
#ifdef __cplusplus
extern "C" {
#endif
//媒体数据类别: 根据fb主类型 识别数据类别
typedef enum {
MEDIA_DATA_VIDEO, //视频数据
MEDIA_DATA_AUDIO, //音频数据
MEDIA_DATA_PICTURE, //图片数据
MEDIA_DATA_TEXT, //字幕数据
MEDIA_DATA_MAX,
} MEDIA_DATA_CATEGORY;
//媒体数据的编码类型用于查找decoder
typedef enum {
//视频编码
MEDIA_CODEC_H264,
MEDIA_CODEC_H265,
//音频编码
MEDIA_CODEC_MP3 = 32,
MEDIA_CODEC_AAC,
MEDIA_CODEC_OPUS,
MEDIA_CODEC_FLAC,
MEDIA_CODEC_WAV,
//图片编码
MEDIA_CODEC_JPEG = 64,
MEDIA_CODEC_PNG,
MEDIA_CODEC_GIF,
MEDIA_CODEC_WebP,
MEDIA_CODEC_HEIF,
//字幕,起始 96
//自定义类型: 起始 128
} MEDIA_CODECID;
//媒体数据的封装类型: 用于查找container
typedef enum {
MEDIA_DTYPE_PIC_JPG,
MEDIA_DTYPE_PIC_PNG,
MEDIA_DTYPE_PIC_BMP,
MEDIA_DTYPE_PIC_GIF,
MEDIA_DTYPE_PIC_WEBP,
MEDIA_DTYPE_PIC_TIFF,
MEDIA_DTYPE_PIC_HEIF,
MEDIA_DTYPE_PIC_SVG,
MEDIA_DTYPE_AUDIO_MP3,
MEDIA_DTYPE_AUDIO_AAC,
MEDIA_DTYPE_AUDIO_WAV,
MEDIA_DTYPE_AUDIO_FLAC,
MEDIA_DTYPE_AUDIO_OGG,
MEDIA_DTYPE_AUDIO_WMA,
MEDIA_DTYPE_AUDIO_APE,
MEDIA_DTYPE_AUDIO_M4A,
MEDIA_DTYPE_VIDEO_MP4,
MEDIA_DTYPE_VIDEO_MKV,
MEDIA_DTYPE_VIDEO_AVI,
MEDIA_DTYPE_VIDEO_TS,
MEDIA_DTYPE_VIDEO_FLV,
MEDIA_DTYPE_VIDEO_MOV,
MEDIA_DTYPE_VIDEO_WEBM,
MEDIA_DTYPE_VIDEO_WMV,
MEDIA_DTYPE_VIDEO_M2TS,
//自定义:裸视频编码帧类型
MEDIA_DTYPE_RAW_H264,
MEDIA_DTYPE_RAW_H265,
MEDIA_DTYPE_RAW_AV1,
MEDIA_DTYPE_RAW_VP9,
MEDIA_DTYPE_RAW_VP8,
MEDIA_DTYPE_RAW_MPEG2,
MEDIA_DTYPE_RAW_MPEG4,
MEDIA_DTYPE_MAX,
} MEDIA_DATA_TYPE;
typedef enum {
MEDIA_PLAY_FORWARD_SPEED_1X = 1, //向前播放1倍速
MEDIA_PLAY_FORWARD_SPEED_2X = 2, //向前播放2倍速
MEDIA_PLAY_FORWARD_SPEED_4X = 4, //向前播放4倍速
MEDIA_PLAY_BACKWARD_SPEED_1X = -1, //向后播放1倍速
MEDIA_PLAY_BACKWARD_SPEED_2X = -2, //向后播放2倍速
MEDIA_PLAY_BACKWARD_SPEED_4X = -4, //向后播放4倍速
} MEDIA_PLAY_SPEED;
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,179 @@
#include "framebuff.h"
#ifndef _TXSEMI_MSI_H_
#define _TXSEMI_MSI_H_
#ifdef __cplusplus
extern "C" {
#endif
//最多支持4个输出接口
#ifndef MSI_OUTIF_MAX
#define MSI_OUTIF_MAX 4
#endif
//媒体流组件的命令列表
enum MSI_CMDs {
MSI_CMD_PRE_DESTROY, //通知组件MSI接口即将开始销毁
MSI_CMD_POST_DESTROY, //通知组件MSI接口即将完成销毁组件需要释放自己的资源
MSI_CMD_FREE_FB, //通知组件即将释放framebuff组件可以对framebuff进行特殊处理
MSI_CMD_SET_DATATAG,
MSI_CMD_GET_RUNNING,
MSI_CMD_SET_SPEED, //设置播放倍速
MSI_CMD_TRANS_FB,
MSI_CMD_TRANS_FB_END,
MSI_CMD_OSD_ENCODE,
MSI_CMD_SCALE1,
MSI_CMD_SCALE2,
MSI_CMD_SCALE3,
MSI_CMD_TAKEPHOTO_SCALE3,
MSI_CMD_SCALE3_NORMAL,
MSI_CMD_JPEG,
MSI_CMD_DECODE_JPEG_MSG,
MSI_CMD_JPEG_CONCAT,
MSI_CMD_HARDWARE_JPEG,
MSI_CMD_AUTO_JPG,
MSI_CMD_AUTO_H264,
MSI_CMD_JPG_RECODE,
MSI_CMD_JPG_THUMB,
MSI_CMD_LCD_VIDEO,
MSI_CMD_DECODE,
MSI_CMD_PLAYER,
MSI_CMD_VIDEO_DEMUX_CTRL,
MSI_CMD_MEDIA_PLAYER,
MSI_CMD_MEDIA_CTRL,
MSI_CMD_AUDAC,
MSI_CMD_AUTPC,
MSI_CMD_AUCODER,
MSI_CMD_CSC,
MSI_CMD_LCD_OSD,
};
enum MSI_AUDIO_CTRL_CMD
{
// audac使用
MSI_AUDAC_SET_FILTER_TRACK,
MSI_AUDAC_GET_FILTER_TRACK,
MSI_AUDAC_SET_CALL_VOLUME,
MSI_AUDAC_GET_CALL_VOLUME,
MSI_AUDAC_SET_MEDIA_VOLUME,
MSI_AUDAC_GET_MEDIA_VOLUME,
MSI_AUDAC_SET_BELL_VOLUME,
MSI_AUDAC_GET_BELL_VOLUME,
MSI_AUDAC_CLEAR_STREAM,
MSI_AUDAC_END_STREAM,
MSI_AUDAC_DELETE_MODE,
MSI_AUDAC_GET_EMPTY,
MSI_AUDAC_HOLD_EMPTY,
MSI_AUDAC_TEST_MODE,
// 音频变速变调组件使用
MSI_AUTPC_SET_SPEED,
MSI_AUTPC_GET_SPEED,
MSI_AUTPC_SET_PITCH,
MSI_AUTPC_GET_PITCH,
MSI_AUTPC_END_STREAM,
MSI_AUCODER_PAUSE,
MSI_AUCODER_CONTINUE,
MSI_AUCODER_GET_STATUS,
MSI_AUCODER_SET_SPEED,
MSI_AUCODER_GET_SPEED,
MSI_AUCODER_SET_PITCH,
MSI_AUCODER_GET_PITCH,
MSI_AUCODER_SET_BITRATE,
MSI_AUCODER_CLEAR_STREAM,
MSI_AUCODER_SET_SRCMSI,
MSI_AUCODER_SET_CODER,
MSI_AUCODER_CODER_NUM,
MSI_AUCODER_DIRECT_TO_DAC,
MSI_AUCODER_DEINIT,
};
struct msi;
typedef int (*msi_action)(struct msi *msi, uint32 cmd_id, uint32 param1, uint32 param2);
//媒体流组件接口
//media stream interface
struct msi {
struct msi *next; //单链表
const char *name; //组件ID唯一
msi_action action; //组件接口的执行函数
struct msi *output_list[MSI_OUTIF_MAX]; //输出组件列表
void *priv; //私有数据,用于关联组件的另一半数据
uint8 enable: 1, deleted: 1, rev: 6; //状态标识
atomic_t users; //组件引用计数
atomic_t bound; //组件绑定计数
atomic_t inited; //组件init计数msi_new 和 msi_destroy 需要匹配调用
struct fbqueue fbQ; //组件接收framebuff的队列
};
////////////////////////////////////////////////////////////////////////
//以下API 适合应用代码直接使用
//媒流体组件库初始化
extern int32 msi_core_init(void);
//设置该组件的输出组件:为 参数msi 或 参数lname 指定的组件设置输出 组件oname。
extern int32 msi_add_output(struct msi *msi, const char *lname, const char *oname);
//删除该组件的输出组件:删除 参数msi 或 参数lname 指定组件 的输出 组件oname。
extern int32 msi_del_output(struct msi *msi, const char *lname, const char *oname);
//指定从某个组件开始执行cmd
extern void msi_cmd(const char *name, uint32 cmd, uint32 param1, uint32 param2);
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// 以下 API 只在MSI组件内部代码中使用不适合应用代码使用。
//创建媒流体组件,创建时自动加入组件列表。和 msi_destroy 成对使用
extern struct msi *msi_new(const char *name, uint32 qsize, uint8 *isnew);
//销毁媒流体组件,销毁时自动从组件列表中删除
extern void msi_destroy(struct msi *msi);
extern void msi_put(struct msi *msi);
extern void msi_get(struct msi *msi);
//根据name查找该组件计数为加1。需要和 msi_put 成对使用
// inited: 用于表示只查找已经被初始化的模块
extern struct msi *msi_find(const char *name, uint8 inited);
//组件输出cmd: 遍历自己的输出组件列表
extern int32 msi_output_cmd(struct msi *msi, uint32 cmd, uint32 param1, uint32 param2);
//组件输出framebuff: 遍历自己的输出组件列表
//注意fb参数只能是 framebuff链表的第1个节点不能是中间节点
extern int32 msi_output_fb(struct msi *msi, struct framebuff *fb);
//组件判断不输出framebuff时需要删除framebuff
//注意fb参数只能是 framebuff链表的第1个节点不能是中间节点
extern int32 msi_delete_fb(struct msi *msi, struct framebuff *fb);
//MSI组件从队列中读取framebuff
extern struct framebuff *msi_get_fb(struct msi *msi, uint32 tmo_ms);
//MSI组件从队列中读取framebuff: 队列支持多个reader需要指定reader ID
extern struct framebuff *msi_get_fb_r(struct msi *msi, uint32 reader);
//通知通路中的各个模块丢弃指定的framebuff
extern int32 msi_discard_fb(struct msi *msi, struct framebuff *fb);
//追踪framebuff查看指定的framebuff当前在被哪些模块处理
extern int32 msi_trace_fb(struct msi *msi, struct framebuff *fb);
//组件notify可以 向上/向下 执行cmd
extern void msi_notify(struct msi *msi, uint32 cmd, uint32 param1, uint32 param2);
//组件执行自己的action不会向下输出cmd
extern int32 msi_do_cmd(struct msi *msi, uint32 cmd, uint32 param1, uint32 param2);
#ifdef __cplusplus
}
#endif
#endif