luat_rtsp_push.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. /**
  2. * @file luat_rtsp_push.h
  3. * @brief RTSP推流组件 - 基于lwip raw API实现
  4. * @author LuatOS Team
  5. *
  6. * 该组件实现了RTSP(Real Time Streaming Protocol)推流功能,
  7. * 支持将H.264视频流推送到RTSP服务器。
  8. *
  9. * 主要特性:
  10. * - 基于lwip raw socket API,适应嵌入式环境
  11. * - 支持自定义H.264帧来源,灵活的NALU帧注入
  12. * - 完整的RTSP握手和连接管理
  13. * - 支持RTP/RTCP协议实现
  14. * - 支持H.264基础配置文件
  15. * - C99语法,内存使用优化
  16. *
  17. * 调试说明:
  18. * - 在 luat_rtsp_push.c 中修改 RTSP_DEBUG_VERBOSE 宏来控制详细日志输出
  19. * - 设置为 1 开启详细调试信息,设置为 0 关闭(仅保留关键日志)
  20. */
  21. #ifndef __LUAT_RTSP_PUSH_H__
  22. #define __LUAT_RTSP_PUSH_H__
  23. #include "luat_base.h"
  24. #include "lwip/tcp.h"
  25. #include "lwip/udp.h"
  26. #include <stdint.h>
  27. #include <stddef.h>
  28. #include <stdbool.h>
  29. #ifdef __cplusplus
  30. extern "C" {
  31. #endif
  32. /* ======================== RTSP常量定义 ======================== */
  33. /** RTSP默认端口 */
  34. #define RTSP_DEFAULT_PORT 554
  35. /** RTSP缓冲区大小(字节) - 需要足够大以容纳RTSP信令 */
  36. #define RTSP_BUFFER_SIZE (64 * 1024)
  37. /** RTP缓冲区大小(字节) */
  38. #define RTP_BUFFER_SIZE (256 * 1024)
  39. /** RTP UDP缓冲区最大包大小 */
  40. #define RTP_MAX_PACKET_SIZE 1400
  41. /** 发送帧队列最大字节数上限,超出将丢弃未发送帧 */
  42. #define RTSP_MAX_QUEUE_BYTES (1024 * 1024)
  43. /** RTSP命令超时时间(毫秒) */
  44. #define RTSP_CMD_TIMEOUT 5000
  45. /* ======================== 返回值定义 ======================== */
  46. /** 操作成功 */
  47. #define RTSP_OK 0
  48. /** 通用错误 */
  49. #define RTSP_ERR_FAILED (-1)
  50. /** 参数无效 */
  51. #define RTSP_ERR_INVALID_PARAM (-2)
  52. /** 内存不足 */
  53. #define RTSP_ERR_NO_MEMORY (-3)
  54. /** 连接错误 */
  55. #define RTSP_ERR_CONNECT_FAILED (-4)
  56. /** 握手失败 */
  57. #define RTSP_ERR_HANDSHAKE_FAILED (-5)
  58. /** 网络错误 */
  59. #define RTSP_ERR_NETWORK (-6)
  60. /** 超时 */
  61. #define RTSP_ERR_TIMEOUT (-7)
  62. /** 缓冲区溢出 */
  63. #define RTSP_ERR_BUFFER_OVERFLOW (-8)
  64. /* ======================== 数据类型定义 ======================== */
  65. /**
  66. * RTSP连接状态枚举
  67. */
  68. typedef enum {
  69. RTSP_STATE_IDLE = 0, /**< 空闲状态 */
  70. RTSP_STATE_CONNECTING = 1, /**< 正在连接 */
  71. RTSP_STATE_OPTIONS = 2, /**< 发送OPTIONS请求 */
  72. RTSP_STATE_DESCRIBE = 3, /**< 发送DESCRIBE请求 */
  73. RTSP_STATE_SETUP = 4, /**< 发送SETUP请求 */
  74. RTSP_STATE_PLAY = 5, /**< 发送PLAY请求,准备推流 */
  75. RTSP_STATE_PLAYING = 6, /**< 正在推流 */
  76. RTSP_STATE_DISCONNECTING = 7, /**< 正在断开连接 */
  77. RTSP_STATE_ERROR = 8 /**< 错误状态 */
  78. } rtsp_state_t;
  79. /**
  80. * H.264 NALU类型枚举
  81. */
  82. typedef enum {
  83. NALU_TYPE_NON_IDR = 1, /**< 非IDR帧 */
  84. NALU_TYPE_IDR = 5, /**< IDR帧(关键帧) */
  85. NALU_TYPE_SEI = 6, /**< SEI(补充增强信息) */
  86. NALU_TYPE_SPS = 7, /**< SPS(序列参数集) */
  87. NALU_TYPE_PPS = 8, /**< PPS(图像参数集) */
  88. NALU_TYPE_AUD = 9 /**< AUD(访问单元分隔符) */
  89. } nalu_type_t;
  90. /**
  91. * H.264视频帧信息结构体
  92. */
  93. typedef struct {
  94. uint8_t *data; /**< 视频数据指针 */
  95. uint32_t len; /**< 视频数据长度 */
  96. uint32_t timestamp; /**< 时间戳(ms) */
  97. uint8_t nalu_type; /**< NALU类型 */
  98. uint8_t is_keyframe; /**< 是否为关键帧 */
  99. } h264_frame_t;
  100. /**
  101. * RTSP推流统计信息结构体
  102. */
  103. typedef struct {
  104. uint32_t bytes_sent; /**< 已发送的字节数 */
  105. uint32_t video_frames_sent; /**< 已发送的视频帧数 */
  106. uint32_t rtp_packets_sent; /**< 已发送的RTP包数 */
  107. uint32_t connection_time; /**< 连接持续时间(毫秒) */
  108. uint32_t last_video_timestamp; /**< 最后视频时间戳(毫秒) */
  109. } rtsp_stats_t;
  110. /**
  111. * RTSP推流上下文结构体
  112. * 管理单个RTSP连接的所有状态和缓冲区
  113. */
  114. typedef struct {
  115. /** ============ 连接信息 ============ */
  116. char *url; /**< RTSP服务器URL */
  117. char *host; /**< RTSP服务器主机名/IP地址 */
  118. char *stream; /**< 推流名 */
  119. char *auth; /**< 认证信息(用户名:密码) */
  120. uint16_t port; /**< 连接端口 */
  121. /** ============ TCP连接状态(RTSP控制通道) ============ */
  122. struct tcp_pcb *control_pcb; /**< lwip TCP控制块(RTSP信令) */
  123. rtsp_state_t state; /**< 当前连接状态 */
  124. uint32_t last_activity_time; /**< 最后活动时间戳 */
  125. /** ============ UDP连接状态(RTP媒体通道) ============ */
  126. struct udp_pcb *rtp_pcb; /**< RTP UDP控制块 */
  127. struct udp_pcb *rtcp_pcb; /**< RTCP UDP控制块 */
  128. ip_addr_t remote_ip; /**< 远端IP地址 */
  129. uint16_t remote_rtp_port; /**< 远端RTP端口 */
  130. uint16_t remote_rtcp_port; /**< 远端RTCP端口 */
  131. uint16_t local_rtp_port; /**< 本地RTP端口 */
  132. uint16_t local_rtcp_port; /**< 本地RTCP端口 */
  133. /** ============ RTSP协议状态 ============ */
  134. uint32_t cseq; /**< RTSP序列号 */
  135. char *session_id; /**< RTSP会话ID */
  136. uint32_t video_stream_id; /**< 视频流ID(SSRC) */
  137. /** ============ RTP状态 ============ */
  138. uint32_t rtp_sequence; /**< RTP序列号 */
  139. uint32_t rtp_timestamp; /**< RTP时间戳 */
  140. uint32_t rtp_ssrc; /**< RTP同步源标识符 */
  141. /** ============ 缓冲区管理 ============ */
  142. uint8_t *recv_buf; /**< 接收缓冲区 */
  143. uint32_t recv_buf_size; /**< 接收缓冲区大小 */
  144. uint32_t recv_pos; /**< 接收缓冲区写位置 */
  145. uint8_t *send_buf; /**< 发送缓冲区 */
  146. uint32_t send_buf_size; /**< 发送缓冲区大小 */
  147. uint32_t send_pos; /**< 发送缓冲区写位置 */
  148. uint8_t *rtp_buf; /**< RTP发送缓冲区 */
  149. uint32_t rtp_buf_size; /**< RTP缓冲区大小 */
  150. /** ============ 帧发送队列 ============ */
  151. struct rtsp_frame_node *frame_head; /**< 待发送帧队列头 */
  152. struct rtsp_frame_node *frame_tail; /**< 待发送帧队列尾 */
  153. uint32_t frame_queue_bytes; /**< 队列占用的总字节数 */
  154. /** ============ 时间戳管理 ============ */
  155. uint32_t video_timestamp; /**< 当前视频时间戳(ms) */
  156. uint32_t base_timestamp; /**< 基准时间戳 */
  157. uint32_t start_tick; /**< 启动时刻的系统tick */
  158. /** ============ H.264编码信息 ============ */
  159. uint8_t *sps_data; /**< SPS(序列参数集)数据 */
  160. uint32_t sps_len; /**< SPS长度 */
  161. uint8_t *pps_data; /**< PPS(图像参数集)数据 */
  162. uint32_t pps_len; /**< PPS长度 */
  163. char *sprop_parameter_sets; /**< SDP中的sprop-parameter-sets */
  164. /** ============ 统计信息 ============ */
  165. uint32_t packets_sent; /**< 已发送的包数 */
  166. uint32_t bytes_sent; /**< 已发送的字节数 */
  167. uint32_t video_frames_sent; /**< 已发送的视频帧数 */
  168. uint32_t rtp_packets_sent; /**< 已发送的RTP包数 */
  169. uint32_t last_rtcp_time; /**< 上次发送RTCP SR的时间(tick) */
  170. /** ============ 用户数据 ============ */
  171. void *user_data; /**< 用户自定义数据指针 */
  172. } rtsp_ctx_t;
  173. /**
  174. * RTSP状态变化回调函数类型
  175. *
  176. * @param ctx RTSP上下文指针
  177. * @param old_state 旧状态
  178. * @param new_state 新状态
  179. * @param error_code 错误代码(仅在STATE_ERROR时有效)
  180. */
  181. typedef void (*rtsp_state_callback_t)(rtsp_ctx_t *ctx, rtsp_state_t old_state,
  182. rtsp_state_t new_state, int error_code);
  183. /* ======================== 核心接口函数 ======================== */
  184. /**
  185. * 创建RTSP推流上下文
  186. *
  187. * @return RTSP上下文指针,失败返回NULL
  188. * @note 返回的指针需要使用rtsp_destroy()释放
  189. */
  190. rtsp_ctx_t* rtsp_create(void);
  191. /**
  192. * 销毁RTSP推流上下文,释放所有资源
  193. *
  194. * @param ctx RTSP上下文指针
  195. * @return 0=成功, 负数=失败
  196. */
  197. int rtsp_destroy(rtsp_ctx_t *ctx);
  198. /**
  199. * 设置RTSP服务器URL
  200. *
  201. * @param ctx RTSP上下文指针
  202. * @param url RTSP服务器地址,格式: rtsp://host:port/stream
  203. * @return 0=成功, 负数=失败
  204. */
  205. int rtsp_set_url(rtsp_ctx_t *ctx, const char *url);
  206. /**
  207. * 设置状态变化回调函数
  208. *
  209. * @param ctx RTSP上下文指针
  210. * @param callback 回调函数指针
  211. * @return 0=成功, 负数=失败
  212. */
  213. int rtsp_set_state_callback(rtsp_ctx_t *ctx, rtsp_state_callback_t callback);
  214. /**
  215. * 连接到RTSP服务器
  216. *
  217. * @param ctx RTSP上下文指针
  218. * @return 0=成功, 负数=失败
  219. * @note 此函数应在lwip tcpip线程中调用
  220. */
  221. int rtsp_connect(rtsp_ctx_t *ctx);
  222. /**
  223. * 断开RTSP连接
  224. *
  225. * @param ctx RTSP上下文指针
  226. * @return 0=成功, 负数=失败
  227. */
  228. int rtsp_disconnect(rtsp_ctx_t *ctx);
  229. /**
  230. * 获取当前连接状态
  231. *
  232. * @param ctx RTSP上下文指针
  233. * @return 当前状态值
  234. */
  235. rtsp_state_t rtsp_get_state(rtsp_ctx_t *ctx);
  236. /**
  237. * 设置H.264 SPS数据(序列参数集)
  238. *
  239. * @param ctx RTSP上下文指针
  240. * @param sps_data SPS数据指针
  241. * @param sps_len SPS数据长度
  242. * @return 0=成功, 负数=失败
  243. * @note 数据会被复制,调用者可以释放原数据
  244. */
  245. int rtsp_set_sps(rtsp_ctx_t *ctx, const uint8_t *sps_data, uint32_t sps_len);
  246. /**
  247. * 设置H.264 PPS数据(图像参数集)
  248. *
  249. * @param ctx RTSP上下文指针
  250. * @param pps_data PPS数据指针
  251. * @param pps_len PPS数据长度
  252. * @return 0=成功, 负数=失败
  253. * @note 数据会被复制,调用者可以释放原数据
  254. */
  255. int rtsp_set_pps(rtsp_ctx_t *ctx, const uint8_t *pps_data, uint32_t pps_len);
  256. /**
  257. * 推送H.264视频帧数据
  258. *
  259. * 该函数接收H.264编码的视频帧数据(可以是完整的访问单元或单个NALU)
  260. * 内部会自动进行RTP打包并通过UDP发送到服务器。
  261. *
  262. * @param ctx RTSP上下文指针
  263. * @param frame_data 视频帧数据指针(包含起始码或不包含均可)
  264. * @param frame_len 视频帧数据长度(字节数)
  265. * @param timestamp 时间戳(毫秒),如果为0则使用内部时间戳
  266. * @return 0=成功,正数=已入队,负数=失败
  267. *
  268. * @note
  269. * - frame_data 可以包含H.264起始码(0x00000001或0x000001)或不包含
  270. * - 支持单个NALU或多个NALU的访问单元
  271. * - 如果在PLAYING状态下调用,数据会立即发送;否则进入队列
  272. * - 返回值为正数时表示字节数已加入队列
  273. *
  274. * @example
  275. * // 推送一帧H.264视频
  276. * uint8_t *frame_data = ...; // H.264编码帧数据
  277. * uint32_t frame_len = ...; // 帧长度
  278. * uint32_t timestamp = 0; // 使用内部时间戳
  279. *
  280. * int ret = rtsp_push_h264_frame(ctx, frame_data, frame_len, timestamp);
  281. * if (ret >= 0) {
  282. * printf("成功推送%d字节\n", ret);
  283. * } else {
  284. * printf("推送失败: %d\n", ret);
  285. * }
  286. */
  287. int rtsp_push_h264_frame(rtsp_ctx_t *ctx, const uint8_t *frame_data,
  288. uint32_t frame_len, uint32_t timestamp);
  289. /**
  290. * 处理RTSP连接事件,应定期调用此函数
  291. *
  292. * @param ctx RTSP上下文指针
  293. * @return 0=成功, 负数=失败
  294. * @note 建议每10-20ms调用一次此函数
  295. */
  296. int rtsp_poll(rtsp_ctx_t *ctx);
  297. /**
  298. * 获取推流统计信息
  299. *
  300. * @param ctx RTSP上下文指针
  301. * @param stats 统计信息指针
  302. * @return 0=成功, 负数=失败
  303. */
  304. int rtsp_get_stats(rtsp_ctx_t *ctx, rtsp_stats_t *stats);
  305. #ifdef __cplusplus
  306. }
  307. #endif
  308. #endif /* __LUAT_RTSP_PUSH_H__ */