本文采用的 SRS 版本是 4.0-b8 , 下载地址:
https://github.com/ossrs/srs/releases/tag/v4.0-b8
讲解 SRS 的入口文件。SRS 源码里 其实有 3 个 main() 函数,
分别在 srs_main_ingest_hls.cpp ,srs_main_mp4_parser.cpp,srs_main_server.cpp 3 个文件里面
不过 srs 可执行文件,是srs_main_server.cpp 生成的,所以先分析 srs_main_server.cpp
main() 函数的流程图如下:
main() 函数的内部逻辑实际上比较简单,因为所有的操作都封装在其他函数里面。特别是 srs_thread_initialize() 跟 run_directly_or_daemon() 函数。
所以 main() 函数本文只会提及一些重点,重点如下:
1,srs_thread_initialize() 里面有非常多的初始化操作,日志操作,配置文件,等。
2,srs_assert(srs_is_little_endian());,srs 只支持小端序机器,大端序机器不支持。
3,用了大量的 GPERF 来检测内存泄漏。
3,show_macro_features(),这个函数打印 srs 支持哪些功能,例如 srt,dvr 是否支持。
4,run_directly_or_daemon() ,此函数开始运行 SRS,可能在前台运行,也可能以守护进程运行。
小结如下:
1,SRS 服务器启动之后,会开启一个协程 (SrsTcpListener::cycle) 来 监听 1935 的RTMP端口,不断 accept 客户端请求。
2,始祖协程 利用 wg.wait() 等等其他的服务结束,其他服务是指 RTMP服务,SRT服务,RTC 服务。
3,有RTMP推流客户端请求来了,新开一个协程D(SrsRtmpConn::cycle) 来处理 请求,包括RTMP握手,传输音视频数据前的交互。处理完前期的交互工作之后,发现客户端是一个推流客户端,就会再开一个协程 E (SrsRecvThread::cycle)来处理推过来的音视频数据流。之前的协程D 会阻塞不断循环统计一些信息。