Files
AC707N/SDK/interface/media/framework/include/jlstream.h
T
2025-12-03 11:12:34 +08:00

735 lines
20 KiB
C

#ifndef JLSTREAM_H
#define JLSTREAM_H
#include "generic/typedef.h"
#include "generic/list.h"
#include "node_uuid.h"
#include "media/audio_base.h"
#include "media/audio_def.h"
#include "media/media_config.h"
#include "system/task.h"
#include "system/spinlock.h"
#include "fs/resfile.h"
#define __STREAM_CACHE_CODE __attribute__((section(".stream.text.cache.L2")))
#define STREAM_NODE_RUN_TIMER_DEBUG_EN 0
typedef void *jlstream_breaker_t;
struct stream_oport;
struct stream_node;
struct stream_snode;
struct stream_note;
struct jlstream;
#ifndef SEEK_SET
#define SEEK_SET 0 /* Seek from beginning of file. */
#define SEEK_CUR 1 /* Seek from current position. */
#define SEEK_END 2 /* Seek from end of file. */
#endif
#define NODE_IOC_OPEN_IPORT 0x00010000
#define NODE_IOC_CLOSE_IPORT 0x00010001
#define NODE_IOC_OPEN_OPORT 0x00010002
#define NODE_IOC_CLOSE_OPORT 0x00010003
#define NODE_IOC_SET_FILE 0x00020000
#define NODE_IOC_OPEN_FILE 0x00020001
#define NODE_IOC_GET_FMT 0x00020002
#define NODE_IOC_SET_FMT 0x00020003
#define NODE_IOC_CLR_FMT 0x00020004
#define NODE_IOC_GET_DELAY 0x00020005 // 获取缓存数据的延时
#define NODE_IOC_SET_SCENE 0x00020006 // 设置数据流的场景
#define NODE_IOC_SET_CHANNEL 0x00020007
#define NODE_IOC_NEGOTIATE 0x00020008 // 各个节点参数协商
#define NODE_IOC_FLUSH_OUT 0x00020009
#define NODE_IOC_SET_TIME_STAMP 0x0002000a
#define NODE_IOC_SYNCTS 0x0002000b
#define NODE_IOC_NODE_CONFIG 0x0002000c
#define NODE_IOC_SET_PRIV_FMT 0x0002000d //设置节点私有参数
#define NODE_IOC_NAME_MATCH 0x0002000e
#define NODE_IOC_SET_PARAM 0x0002000f
#define NODE_IOC_GET_PARAM 0x00020010
#define NODE_IOC_DECODER_PP 0x00020011 //解码暂停再重开
#define NODE_IOC_DECODER_FF 0x00020012 //快进
#define NODE_IOC_DECODER_FR 0x00020013 //快退
#define NODE_IOC_DECODER_REPEAT 0x00020014 //无缝循环播放
#define NODE_IOC_DECODER_DEST_PLAY 0x00020015 //跳到指定位置播放
#define NODE_IOC_GET_CUR_TIME 0x00020016 //获取音乐播放当前时间
#define NODE_IOC_GET_TOTAL_TIME 0x00020017 //获取音乐播放总时间
#define NODE_IOC_GET_BP 0x00020018 //获取解码断点信息
#define NODE_IOC_SET_BP 0x00020019 //设置解码断点信息
#define NODE_IOC_SET_FILE_LEN 0x0002001a //设置解码文件长度信息
#define NODE_IOC_SET_BP_A 0x0002001b //设置复读A点
#define NODE_IOC_SET_BP_B 0x0002001c //设置复读B点
#define NODE_IOC_SET_AB_REPEAT 0x0002001d //设置AB点复读模式
#define NODE_IOC_GET_ODEV_CACHE 0x0002001e //获取输出设备的缓存采样数
#define NODE_IOC_SET_BTADDR 0x0002001f
#define NODE_IOC_SET_ENC_FMT 0x00020020
#define NODE_IOC_GET_ENC_FMT 0x00020021
#define NODE_IOC_GET_HEAD_INFO 0x00020022 //获取编码的头文件信息
#define NODE_IOC_SET_TASK 0x00020023
#define NODE_IOC_FSEEK 0x00020024
#define NODE_IOC_SET_BIT_WIDE 0x00020025
#define NODE_IOC_FLOW_CTRL_ENABLE 0x00020026
#define NODE_IOC_GET_BTADDR 0x00020027
#define NODE_IOC_GET_FRAME_SIZE 0x00020028
#define NODE_IOC_SET_FRAME_SIZE 0x00020029
#define NODE_IOC_SET_TS_PARM 0x0002002a
#define NODE_IOC_SET_SLEEP 0x0002002b
#define NODE_IOC_SET_SEAMLESS 0x0002002c
#define NODE_IOC_ENC_RESET 0x0002002d
#define NODE_IOC_FORCE_DUMP_PACKET 0x0002002e
#define NODE_IOC_GET_MIXER_INFO 0x0002002f
#define NODE_IOC_TWS_TX_SWITCH 0x00020030
#define NODE_IOC_GET_ID3 0x00020031
#define NODE_IOC_GET_ENC_TIME 0x00020032 //获取编码时间
#define NODE_IOC_SET_SYNC_NETWORK 0x0002003b
#define NODE_IOC_GET_PRIV_FMT 0x0002003c
#define NODE_IOC_START (0x00040000 | NODE_STA_RUN)
#define NODE_IOC_PAUSE (0x00040000 | NODE_STA_PAUSE)
#define NODE_IOC_STOP (0x00040000 | NODE_STA_STOP)
#define NODE_IOC_SUSPEND (0x00040000 | NODE_STA_SUSPEND)
#define TIMESTAMP_US_DENOMINATOR 32
enum stream_event {
STREAM_EVENT_NONE,
STREAM_EVENT_INIT,
STREAM_EVENT_LOAD_DECODER,
STREAM_EVENT_LOAD_ENCODER,
STREAM_EVENT_UNLOAD_DECODER,
STREAM_EVENT_UNLOAD_ENCODER,
STREAM_EVENT_SUSPEND,
STREAM_EVENT_READY,
STREAM_EVENT_START,
STREAM_EVENT_PAUSE,
STREAM_EVENT_STOP,
STREAM_EVENT_CLOSE_PLAYER,
STREAM_EVENT_CLOSE_RECODER,
STREAM_EVENT_PREEMPTED,
STREAM_EVENT_NEGOTIATE_FAILD,
STREAM_EVENT_GET_PIPELINE_UUID,
STREAM_EVENT_GET_COEXIST_POLICY,
STREAM_EVENT_INC_SYS_CLOCK,
STREAM_EVENT_GET_NODE_PARM,
STREAM_EVENT_GET_EFF_ONLINE_PARM,
STREAM_EVENT_A2DP_ENERGY,
STREAM_EVENT_GET_SWITCH_CALLBACK,
STREAM_EVENT_GET_CVP_MODE,
};
enum stream_scene : u8 {
STREAM_SCENE_A2DP,
STREAM_SCENE_ESCO,
STREAM_SCENE_TWS_MUSIC, // TWS转发本地音频文件
STREAM_SCENE_AI_VOICE,
STREAM_SCENE_LINEIN, //linein 模式
STREAM_SCENE_FM, //FM 模式
STREAM_SCENE_TDM, //TDM 模式
STREAM_SCENE_MUSIC, //本地音乐
STREAM_SCENE_RECODER, //录音
STREAM_SCENE_SPDIF,
STREAM_SCENE_PC_SPK,
STREAM_SCENE_PC_MIC,
STREAM_SCENE_IIS,
STREAM_SCENE_MUTI_CH_IIS,
STREAM_SCENE_MIC, //mic 模式
STREAM_SCENE_MIC_EFFECT,
STREAM_SCENE_MIC_EFFECT2,
STREAM_SCENE_HEARING_AID,
STREAM_SCENE_DEV_FLOW,
STREAM_SCENE_LE_AUDIO,//LE Audio Media
STREAM_SCENE_LEA_CALL,//LE Audio CALL
STREAM_SCENE_ADDA_LOOP,
STREAM_SCENE_OPUS,
STREAM_SCENE_WIRELESS_MIC, //16 wireless mic
STREAM_SCENE_LOCAL_TWS,
STREAM_SCENE_MIDI, //MIDI 琴解码
STREAM_SCENE_LOUDSPEAKER_IIS, //扩音器IIS
STREAM_SCENE_LOUDSPEAKER_MIC, //扩音器MIC
//最大32个场景,如果大于32个场景,需要把tone、ring、ket_tone场景号往后挪
STREAM_SCENE_TONE = 0x20,
STREAM_SCENE_RING = 0x60,
STREAM_SCENE_KEY_TONE = 0xa0,
STREAM_SCENE_NONE = 0xff,
};
enum stream_coexist : u8 {
STREAM_COEXIST_AUTO,
STREAM_COEXIST_DISABLE,
};
enum stream_state : u8 {
STREAM_STA_INIT,
STREAM_STA_NEGOTIATE,
STREAM_STA_READY,
STREAM_STA_START,
STREAM_STA_STOP,
STREAM_STA_PLAY,
STREAM_STA_PAUSE = 0x10,
STREAM_STA_PREEMPTED = 0x20,
STREAM_STA_SUSPEND = 0x30,
};
enum stream_node_state : u16 {
NODE_STA_RUN = 0x0001,
NODE_STA_PAUSE = 0x0002,
NODE_STA_SUSPEND = 0x0004,
NODE_STA_STOP = 0x0008,
NODE_STA_PEND = 0x0010,
NODE_STA_DEC_NO_DATA = 0x0020,
NODE_STA_DEC_END = 0x0040,
NODE_STA_DEC_PAUSE = 0x0080,
NODE_STA_DEC_ERR = 0x00c0,
NODE_STA_SOURCE_NO_DATA = 0x0100,
NODE_STA_DEV_ERR = 0x0200,
NODE_STA_ENC_END = 0x0400,
NODE_STA_OUTPUT_TO_FAST = 0x0800, //解码输出太多主动挂起
NODE_STA_OUTPUT_BLOCKED = 0x1000, //终端节点缓存满,数据写不进去
NODE_STA_OUTPUT_SPLIT = 0x2000,
};
enum stream_node_type : u8 {
NODE_TYPE_SYNC = 0x01,
NODE_TYPE_BYPASS = 0x03,
NODE_TYPE_FLOW_CTRL = 0x04,
NODE_TYPE_ASYNC = 0x10,
NODE_TYPE_IRQ = 0x20,
NODE_TYPE_SWITCH = 0x40,
};
enum negotiation_state : u8 {
NEGO_STA_CONTINUE = 0x01,
NEGO_STA_ACCPTED = 0x02,
NEGO_STA_SUSPEND = 0x04,
NEGO_STA_DELAY = 0x08,
NEGO_STA_ABORT = 0x10,
NEGO_STA_SAMPLE_RATE_LOCK = 0x20,
};
enum pcm_24bit_data_type : u8 {
PCM_24BIT_DATA_4BYTE = 0,
PCM_24BIT_DATA_3BYTE,
};
struct stream_fmt {
u8 Qval;
u8 bit_wide; //数据流中数据的位宽。
u8 dec_bit_wide; //解码需要配置的位宽。
u8 pcm_24bit_type; //用于判断3byte_24bit数据或4byte_24bit数据
u8 channel_mode;
u8 chconfig_id; //声道Id, LDAC解码需要配置的参数,通过这个解析出声道类型。
u16 frame_dms; //帧长时间,单位 deci-ms (ms/10)
u16 codec_version; //数据编码类型的版本,同一种coding_type,可能存在不同的版本,LHDC 解码需要配置的参数。
u32 bit_rate;
u32 sample_rate;
u32 coding_type;
};
struct stream_enc_fmt {
u8 channel;
u8 bit_width;
u16 frame_dms; //帧长时间,单位 deci-ms (ms/10)
u32 sample_rate;
u32 bit_rate;
u32 coding_type;
};
struct stream_file_ops {
int (*read)(void *file, u8 *buf, int len);
int (*seek)(void *file, int offset, int fromwhere);
int (*write)(void *file, u8 *data, int len);
int (*close)(void *file);
int (*get_fmt)(void *file, struct stream_fmt *fmt);
int (*get_name)(void *file, u8 *name, int len);
};
struct stream_file_info {
void *file;
const char *fname;
const struct stream_file_ops *ops;
struct audio_dec_breakpoint *dbp;
enum stream_scene scene;
u32 coding_type;
};
struct stream_dec_file {
void *file;
int (*fread)(void *file, u8 *buf, u32 fpos, int len, OS_SEM *sem);
};
struct stream_get_fmt {
struct stream_file_info *file_info;
struct stream_fmt *fmt;
};
struct stream_decoder_info {
enum stream_scene scene;
u8 frame_time;
u32 coding_type;
const char *task_name;
};
struct stream_encoder_info {
enum stream_scene scene;
u32 coding_type;
const char *task_name;
};
/*
* scene_a和scene_b指定的格式有冲突,scene_a抢占scene_b
*/
struct stream_coexist_policy {
enum stream_scene scene_a;
enum stream_scene scene_b;
u32 coding_a;
u32 coding_b;
};
enum frame_flags : u16 {
FRAME_FLAG_FLUSH_OUT = 0x01,
FRAME_FLAG_FILL_ZERO = 0x03, //补0包
FRAME_FLAG_FILL_PACKET = 0x05, //补数据包
FRAME_FLAG_TIMESTAMP_ENABLE = 0x08, //时间戳有效
FRAME_FLAG_RESET_TIMESTAMP_BIT = 0x10,
FRAME_FLAG_RESET_TIMESTAMP = 0x11, //重设各节点的时间戳
FRAME_FLAG_SET_DRIFT_BIT = 0x20,
FRAME_FLAG_SET_D_SAMPLE_RATE = 0x21, //设置sampte_rate的delta
FRAME_FLAG_UPDATE_TIMESTAMP = 0x40, //更新时间戳,驱动节点重设
FRAME_FLAG_UPDATE_DRIFT_SAMPLE_RATE = 0x80,
FRAME_FLAG_SYS_TIMESTAMP_ENABLE = 0x100, //数据帧使用系统时间戳
FRAME_FLAG_PERIOD_SAMPLE = 0x200,
FRAME_FLAG_UPDATE_INFO = FRAME_FLAG_UPDATE_TIMESTAMP | FRAME_FLAG_UPDATE_DRIFT_SAMPLE_RATE,
FRAME_FLAG_PULL_AGAIN = 0x1000 //frame被pull过之后被重新加回iport->frame
};
enum audio_Qval : u8 {
AUDIO_QVAL_16BIT = 15,
AUDIO_QVAL_24BIT = 23,
};
struct node_port_data_wide {
u8 iport_data_wide;//DATA_BIT_WIDE_16BIT,DATA_BIT_WIDE_24BIT
u8 oport_data_wide;//DATA_BIT_WIDE_16BIT,DATA_BIT_WIDE_24BIT
} __attribute__((packed));
struct stream_bit_width {
u8 bit_width;
} __attribute__((packed));
struct stream_frame {
struct list_head entry;
u8 bit_wide;
u16 delay;
u16 offset;
u16 len;
u16 size;
s16 d_sample_rate;
enum frame_flags flags;
u32 timestamp;
u32 fpos;
u8 data[0];
};
struct stream_thread {
u8 id;
u8 debug;
u8 start;
u8 runing;
u32 start_usec;
char name[16];
OS_SEM sem;
OS_MUTEX mutex;
struct jlstream *stream;
struct stream_thread *next;
};
struct stream_iport {
struct list_head frames;
u8 id;
u16 max_len;
enum stream_node_state state;
#if STREAM_NODE_RUN_TIMER_DEBUG_EN
u32 run_time; //usec
#endif
void *private_data;
struct stream_node *node;
struct stream_oport *prev;
struct stream_iport *sibling;
void (*handle_frame)(struct stream_iport *, struct stream_note *note);
};
struct stream_oport {
s16 d_sample_rate;
enum frame_flags flags;
u8 id;
u16 buffered_pcms;
struct stream_fmt fmt;
u32 offset;
u32 timestamp;
struct stream_node *node;
struct stream_iport *next;
struct stream_oport *sibling;
};
struct stream_node_adapter {
const char *name;
u16 uuid;
u8 ability_channel_in;
u8 ability_channel_out;
u8 ability_channel_convert;
u8 ability_resample;
u8 ability_bit_wide;
int (*bind)(struct stream_node *, u16 uuid);
int (*ioctl)(struct stream_iport *iport, int cmd, int arg);
void (*release)(struct stream_node *node);
};
struct stream_node {
u8 subid;
u16 uuid;
u16 pipeline;
enum stream_node_type type;
enum stream_node_state state;
void *private_data;
struct stream_iport *iport;
struct stream_oport *oport;
OS_MUTEX mutex;
const struct stream_node_adapter *adapter;
};
struct stream_snode {
struct stream_node node;
struct jlstream *stream;
};
enum {
THREAD_TYPE_SOURCE = 0x01,
THREAD_TYPE_DEC = 0x02,
THREAD_TYPE_ENC = 0x04,
THREAD_TYPE_OUTPUT = 0x08,
};
struct stream_note {
u8 output_time;
u8 output_start;
enum stream_node_state state;
int delay;
int sleep;
u32 jiffies;
struct jlstream *stream;
struct stream_thread *thread;
};
struct stream_ctrl {
enum stream_state state;
u16 fade_msec;
u32 fade_timeout;
OS_SEM sem;
};
struct jlstream {
struct list_head entry;
u8 id;
u8 ref;
u8 run_cnt;
u8 delay;
u8 incr_sys_clk;
u8 thread_num;
u8 output_time;
u8 thread_policy_step;
enum stream_state state;
enum stream_state pp_state;
enum stream_coexist coexist;
u16 max_delay;
u16 dest_delay; // 目标缓存大小
u16 timer;
u16 thread_timer;
enum stream_scene scene;
u32 end_jiffies;
u32 coding_type;
#if STREAM_NODE_RUN_TIMER_DEBUG_EN
u32 run_usec;
#endif
struct stream_snode *snode;
struct stream_ctrl ctrl;
struct stream_thread *thread;
struct stream_thread *last_thread;
jlstream_breaker_t breaker;
void *callback_arg;
const char *callback_task;
void (*callback_func)(void *, int);
};
#define REGISTER_STREAM_NODE_ADAPTER(adapter) \
const struct stream_node_adapter adapter sec(.stream_node_adapter)
#define PCM_SAMPLE_ONE_SECOND (1000000 * TIMESTAMP_US_DENOMINATOR)
#define PCM_SAMPLE_TO_TIMESTAMP(frames, sample_rate) \
((u64)(frames) * PCM_SAMPLE_ONE_SECOND / ((u32)sample_rate))
#define TIME_TO_PCM_SAMPLES(time, sample_rate) \
(((u64)time * sample_rate / PCM_SAMPLE_ONE_SECOND) + (((u64)time * sample_rate) % PCM_SAMPLE_ONE_SECOND == 0 ? 0 : 1))
void jlstream_lock();
void jlstream_unlock();
int jlstream_event_notify(enum stream_event, int arg);
/*
* 申请一个指定长度的frame
*/
struct stream_frame *jlstream_get_frame(struct stream_oport *, u16 len);
/*
* 将frame推送给后级节点
*/
void jlstream_push_frame(struct stream_oport *, struct stream_frame *);
/*
* 获取一个前级推送的frame
*/
struct stream_frame *jlstream_pull_frame(struct stream_iport *, struct stream_note *);
/*
* 从前级推送的frame中读取指定长度数据
*/
int jlstream_pull_data(struct stream_iport *iport, u32 fpos, u8 *buf, int len);
/*
* 释放已经处理完数据的frame
*/
void jlstream_free_frame(struct stream_frame *frame);
/*
* 释放所有缓存的frame
*/
void jlstream_free_iport_frames(struct stream_iport *iport);
void jlstream_frame_bypass(struct stream_iport *iport, struct stream_note *note);
int jlstream_get_iport_data_len(struct stream_iport *iport);
int jlstream_get_iport_delay(struct stream_iport *iport);
int jlstream_get_iport_frame_num(struct stream_iport *iport);
void jlstream_wakeup_thread(struct jlstream *stream, struct stream_node *node, struct stream_thread *thread);
int stream_node_ioctl(struct stream_node *node, u16 uuid, int cmd, int arg);
int jlstream_node_ioctl(struct jlstream *stream, u16 uuid, int cmd, int arg);
int jlstream_ioctl(struct jlstream *jlstream, int cmd, int arg);
int jlstream_iport_ioctl(struct stream_iport *iport, int cmd, int arg);
struct jlstream *jlstream_for_node(struct stream_node *node);
int jlstream_read_node_data(u16 uuid, u8 subid, u8 *buf);
int jlstream_read_node_port_data_wide(u16 uuid, u8 subid, u8 *buf);
int jlstream_read_stream_crc();
int jlstream_get_delay(struct jlstream *stream);
/*
* 数据流创建和控制接口
*/
struct jlstream *jlstream_pipeline_parse(u16 pipeline, u16 source_uuid);
struct jlstream *jlstream_pipeline_parse_by_node_name(u16 pipeline, const char *node_name);
void jlstream_set_scene(struct jlstream *stream, enum stream_scene scene);
void jlstream_set_coexist(struct jlstream *stream, enum stream_coexist coexist);
void jlstream_set_callback(struct jlstream *stream, void *arg,
void (*callback)(void *, int));
/*
* 设置文件句柄和文件操作接口
*/
int jlstream_set_dec_file(struct jlstream *stream, void *file_hdl,
const struct stream_file_ops *ops);
int jlstream_set_enc_file(struct jlstream *stream, void *file_hdl,
const struct stream_file_ops *ops);
int jlstream_add_thread(struct jlstream *stream, const char *thread_name);
/*
* 启动数据流
*/
int jlstream_start(struct jlstream *stream);
/*
* 播放/暂停切换接口,fade_msec 为淡入/淡出时间
*/
int jlstream_pp_toggle(struct jlstream *stream, u16 fade_msec);
/*
*停止数据流,fade_msec 为淡出时间
*/
void jlstream_stop(struct jlstream *stream, u16 fade_msec);
/*
*释放数据流
*/
void jlstream_release(struct jlstream *stream);
int jlstream_fade_out_32bit(int value, s16 step, s32 *data, int len, u8 channel);
int jlstream_fade_out(int value, s16 step, s16 *data, int len, u8 channel);
int jlstream_fade_in(int value, s16 step, s16 *data, int len, u8 channel);
int jlstream_fade_in_32bit(int value, s16 step, s32 *data, int len, u8 channel);
/*
* 获取节点和设置节点参数接口
*/
void *jlstream_get_node(u16 node_uuid, const char *name);
int jlstream_set_node_param_s(void *node, void *param, u16 param_len);
int jlstream_get_node_param_s(void *node, void *param, u16 param_len);
void jlstream_put_node(void *);
int jlstream_set_node_param(u16 node_uuid, const char *name, void *param, u16 param_len);
int jlstream_get_node_param(u16 node_uuid, const char *name, void *param, u16 param_len);
int jlstream_read_bit_width(u16 uuid, u8 *buf);
int jlstream_is_contains_node_from(struct stream_node *node, u16 node_uuid);
/*
* 数据淡入淡出接口
*
*/
struct jlstream_fade {
u8 in;
u8 out;
u8 channel;
u8 bit_wide;
s16 step;
s16 value;
};
/*
* dir 0:淡出, 1:淡入
*/
void jlstream_fade_init(struct jlstream_fade *fade, int dir, u32 sample_rate,
u8 channel, u16 msec);
enum stream_fade_result {
STREAM_FADE_IN,
STREAM_FADE_OUT,
STREAM_FADE_IN_END,
STREAM_FADE_OUT_END,
STREAM_FADE_END,
};
enum stream_fade_result jlstream_fade_data(struct jlstream_fade *fade, u8 *data, int len);
void jlstream_del_node_from_thread(struct stream_node *node);
int jlstream_add_node_2_thread(struct stream_node *node, const char *task_name);
void jlstream_global_lock();
void jlstream_global_unlock();
bool jlstream_global_locked();
int jlstream_global_pause();
int jlstream_global_resume();
jlstream_breaker_t jlstream_insert_breaker(struct jlstream *stream,
u16 uuid_a, const char *name_a,
u16 uuid_b, const char *name_b);
int jlstream_delete_breaker(jlstream_breaker_t breaker, bool restore);
#endif