一、SRS源代码入门
1. 环境准备
bash
git clone https://github.com/ossrs/srs.git
cd srs/trunk
./configure --debug=on --with-gdb=on
make
https://github.com/ossrs/srs.git无法访问时,替换为https://gitee.com/ossrs/srs.git
2. 代码结构
text
src/
├── main/ # 程序入口
├── utest/ # 测试工具
├── core/ # 核心基础设施(协程/网络)
├── app/ # 业务逻辑(推流/播放/转码)
├── protocol/ # 协议实现(RTMP/HTTP-FLV/HLS)
└── kernel/ # 基础工具(内存/日志)
3.主入口函数 (srs_main_server.cpp
)
mian目录包含了srs_main_ingest_hls.cpp、srs_main_mp4_parser.cpp、srs_main_server.cpp
三者区别
文件 | 主要功能 | main() 用途 | 生产环境 | 测试环境 |
---|---|---|---|---|
srs_main_server.cpp | SRS 主服务器 | 主进程入口 | ✅ 生成 srs | ❌ 不单独测试 |
srs_main_ingest_hls.cpp | HLS 拉流 | 独立测试工具 | ❌ 被主进程调用 | ✅ 可生成 srs_hls_test |
srs_main_mp4_parser.cpp | MP4 解析 | 独立测试工具 | ❌ 被主进程调用 | ✅ 可生成 srs_mp4_test |
int main(int argc, char** argv) {
srs_error_t err = do_main(argc, argv);
if (err != srs_success) {
srs_error("Failed, %s", srs_error_desc(err).c_str());
}
return srs_error_code(err);
}
函数调用顺序:
do_main ->do_main ->run_directly_or_daemon ->run_in_thread_pool ->run_hybrid_server
#include <srs_app_tencentcloud.hpp>
srs_error_t run_hybrid_server(void* /*arg*/)
{
srs_error_t err = srs_success;
// Create servers and register them.
_srs_hybrid->register_server(new SrsServerAdapter());
#ifdef SRS_SRT
_srs_hybrid->register_server(new SrsSrtServerAdapter());
#endif
#ifdef SRS_RTC
_srs_hybrid->register_server(new RtcServerAdapter());
#endif
// Do some system initialize.
if ((err = _srs_hybrid->initialize()) != srs_success) {
return srs_error_wrap(err, "hybrid initialize");
}
// Circuit breaker to protect server, which depends on hybrid.
if ((err = _srs_circuit_breaker->initialize()) != srs_success) {
return srs_error_wrap(err, "init circuit breaker");
}
#ifdef SRS_APM
// When startup, create a span for server information.
ISrsApmSpan* span = _srs_apm->span("main")->set_kind(SrsApmKindServer);
srs_freep(span);
#endif
// Should run util hybrid servers all done.
if ((err = _srs_hybrid->run()) != srs_success) {
return srs_error_wrap(err, "hybrid run");
}
// After all done, stop and cleanup.
_srs_hybrid->stop();
// Dispose all global objects, note that we should do this in the hybrid thread, because it may
// depend on the ST when disposing.
srs_global_dispose();
return err;
}
src\app\srs_app_server.hpp文件包含了SrsServer和SrsServerAdapter类。
SrsServerAdapter::SrsServerAdapter()
{
srs = new SrsServer();
}
-
解析命令行参数和配置文件
-
初始化日志系统 (
srs_log->initialize()
) -
创建
SrsServer
对象并运行
4. 调试方法
bash
# GDB调试RTMP握手
gdb -ex "b SrsHandshake::do_handshake" -ex "r" ./objs/srs
# 关键日志过滤
tail -f objs/srs.log | grep "RTMP publish"
二、SRS关键数据结构
1. 消息头 (srs_kernel_codec.hpp
)
struct SrsMessageHeader {
int32_t timestamp; // 时间戳(毫秒)
int32_t length; // 负载长度
uint8_t type_id; // 类型(8=音频,9=视频)
uint32_t stream_id; // 流ID
};
2. 媒体包 (srs_kernel_codec.hpp
)
class SrsCommonMessage {
SrsMessageHeader header;
char* payload; // 媒体数据指针
int size; // 实际数据大小
};
3. 请求信息 (srs_app_source.hpp
)
class SrsRequest {
std::string app; // 应用名
std::string stream; // 流名称
double duration; // 播放时长
};
三、SRS 关键类解析
核心服务器类
1. SrsServer - 服务器主控类
-
文件路径:
src/app/srs_app_server.hpp
-
核心职责:
-
服务器生命周期管理(初始化、启动、停止)
-
监听端口管理(RTMP/HTTP/WebRTC)
-
信号处理(SIGTERM/SIGINT)
-
模块协调(日志、配置、连接管理)
-
-
关键方法:
cpp
virtual int initialize(); // 初始化服务器 virtual int listen(); // 监听端口 virtual int run(); // 运行主循环 virtual int cycle(); // 主事件循环
连接管理类
2. SrsConnection - 连接基类
-
文件路径:
src/app/srs_app_conn.hpp
-
核心职责:
-
管理客户端连接的生命周期
-
处理基础网络I/O
-
协程调度管理
-
-
关键成员:
cpp
SrsStSocket* skt; // 套接字对象 SrsRequest* req; // 请求信息 SrsCoroutine* coroutine; // 关联的协程
3. SrsRtmpConn - RTMP连接处理
-
文件路径:
src/app/srs_app_rtmp_conn.hpp
-
核心职责:
-
RTMP握手过程实现
-
处理connect/createStream命令
-
管理推流(publish)/播放(play)会话
-
-
工作流程:
cpp
virtual int do_cycle() { handshake(); // RTMP握手 connect_app(); // 连接应用 service_cycle(); // 服务周期(推流/播放) }
协议处理类
4. SrsProtocol - 协议栈基类
-
文件路径:
src/protocol/srs_protocol_rtmp_stack.hpp
-
核心职责:
-
基础消息读写接口
-
协议状态管理
-
数据包解析与封装
-
-
关键方法:
cpp
virtual int recv_message(SrsCommonMessage* pmsg); // 接收消息 virtual int send_message(SrsCommonMessage* msg); // 发送消息
5. SrsRtmpServer - RTMP协议实现
-
文件路径:
src/protocol/srs_protocol_rtmp_stack.hpp
-
核心职责:
-
RTMP命令消息处理
-
窗口大小控制
-
消息分块(chunking)
-
媒体处理类
6. SrsLiveSource - 直播源管理
-
文件路径:
src/app/srs_app_source.hpp
-
核心职责:
-
管理推流发布者
-
维护播放消费者列表
-
GOP缓存管理
-
-
关键成员:
cpp
std::map<std::string, SrsConsumer*> consumers; // 消费者列表 SrsRtmpCache* cache; // GOP缓存
7. SrsConsumer - 消费者基类
-
文件路径:
src/app/srs_app_consumer.hpp
-
核心职责:
-
媒体数据分发
-
播放速度控制
-
客户端状态跟踪
-
基础架构类
8. SrsStSocket - 协程化Socket
-
文件路径:
src/kernel/srs_kernel_st.hpp
-
核心职责:
-
封装协程友好的Socket API
-
非阻塞I/O处理
-
超时管理
-
9. SrsBuffer - 缓冲区管理
-
文件路径:
src/kernel/srs_kernel_buffer.hpp
-
核心职责:
-
高效内存管理
-
零拷贝数据访问
-
数据序列化/反序列化
-
配置与日志
10. SrsConfig - 配置管理
-
文件路径:
src/app/srs_app_config.hpp
-
核心职责:
-
配置文件解析
-
运行时配置管理
-
配置热更新
-
11. SrsLog - 日志系统
-
文件路径:
src/app/srs_app_log.hpp
-
核心职责:
-
日志级别管理
-
日志文件轮转
-
线程安全日志输出
-
类协作关系
关键类生命周期
-
服务器启动:
text
SrsConfig::parse() → SrsServer::initialize() → SrsServer::listen()
-
客户端连接:
text
SrsListener::accept() → SrsServer::accept_client() → SrsRtmpConn::create()
-
推流流程:
text
SrsRtmpConn::handshake() → SrsLiveSource::on_publish() → SrsRtmpCache::cache()
-
播放流程:
text
SrsRtmpConn::handshake() → SrsLiveSource::on_play() → SrsConsumer::enqueue()
调试关键类
-
连接跟踪:
bash
gdb -ex "b SrsConnection::cycle" -ex "r" ./objs/srs
-
协议分析:
bash
gdb -ex "b SrsProtocol::recv_message" -ex "r" ./objs/srs
-
媒体流跟踪:
bash
gdb -ex "b SrsLiveSource::on_audio" -ex "b SrsLiveSource::on_video" -ex "r" ./objs/srs