龙空技术网

SRS流媒体框架分析(1)

antonio 1111

前言:

而今朋友们对“srs架构”大约比较注重,兄弟们都需要剖析一些“srs架构”的相关资讯。那么小编同时在网上搜集了一些对于“srs架构””的相关知识,希望我们能喜欢,小伙伴们快快来学习一下吧!

0.引言

在前面的文章已经讲述了怎么搭建srs流媒体服务器,演示了流媒体服务器成功的运行。读者,可以参考前面的文章,自行学习。文章列表如下:

手把手搭建流媒体服务器详细步骤

简述SRS流媒体服务器相关技术

手把手配置HLS流媒体服务器

流媒体服务器架构与应用分析

1.SRS框架认识

关于SRS框架的初步认识,如下图所示。首先是通过main,到run_master,run_master主要是负责监听以及svr->cycle主要做的工作。svr->listen可以监听多种协议,如rtmp,http等。这里就以监听rtmp协议为例子,listen_rtmp通过层层调用,一直到tcp的调用,最后会启动协程,也就是一个连接,会对应一个协程。SrsTcpListener::cycle()主要的功过就是读取协程是否结束,通过srs_accept检查是否有新的连接,用on_tcp_client(stfd)处理新的连接。在fd2conn()中,绑定了fd和连接,并选定了一个协程,也就是一个协程绑定一个连接。绑定连接后,就启动连接对应的协程,协程执行的主要工作是在一个cycle里面执行,就是这个SrsRtmpConn:service_cycle,调用stream_service_cycle(),继续发布和推流不同分支查找或创建一个source,这里就分出了2个分支,就是推流和拉流的动作。更为具体的工作,下面会有源码分析。

2.源码调试

gdb 调试srs源码

gdb ./objs/srs

调试界面如下:

设置参数:

set args -c ./conf/srs.conf

在某个函数下打断点:

b SrsTcpListener::listen()

界面如下:

项目运行起来,输入命令:

r

界面如下:

对应停在源码的地方,也就是前面打的端点处。源码如下:

这个时候,就可以观察调用栈,输入命令:

bt

经过以下一些函数,调用栈界面如下:

(1)main函数,对应目录srs/main/srs_main_server.cpp:192行。源码如下:

(2)do_main函数,对应目录srs/main/srs_main_server.cpp:184行。源码如下:

(3)run函数,对应目录srs/main/srs_main_server.cpp:409行。源码如下:

(4)run_master函数,对应目录srs/main/srs_main_server.cpp:469行。源码如下:

(5)SrsServer::listen函数,对应目录srs/app/srs_app_server.cpp:872行。源码如下:

(6)SrsServer::listen_rtmp函数,对应目录srs/app/srs_app_server.cpp:1258行。源码如下:

(7)SrsBufferListener::listen函数,对应目录srs/app/srs_app_server.cpp:155行。源码如下:

(8)SrsTcpListener::listen函数,对应目录srs/app/srs_app_listener.cpp:168行。源码如下:

3.源码分析

监听完后,需要有个循环accept,等待连接。

答案是每个监听,都是对应一个协程,每个客户端也是对应一个协程。

监听类型是很重要,创建连接的时候,需要创建不同的连接。监听类型如下:

监听和创建协程。

在trd->start():启动协程,如果协程要回调,可以通过this指针找到对象。启动协程后,就好会调用SrsSTCoroutine::cycle(),然后调用handler->cycle(),再调用SrsTcpListener::cycle()。

更加细致的流程如下:

调用cycle的源码,如下所示:

fd和connection的绑定,SrsServer::fd2conn,调用的是new SrsRtmpConn(this,stfd,ip),通过server服务(还可以管理其它事情)去管理所有连接。源码如下:

把所有的连接管理起来。

连接上之后,会启动协程。每个SrsRtmpConn都有1:1对应的协程,同时该连接,一定也对应一个cycle。只要某个类有start,那基本上意味着绑定了一个协程的循坏,肯定是调用该类的cycle去实现了。

服务端,具体的循环操作,源码如下:

设置窗口大小,带宽等。

真正循环体的实现。

SrsRtmpConn::stream_service_cycle(),一个直播对应一个source,一个推流,对应0-n个拉流。source的消费者,每个拉流都会绑定一个SrsConsumer。具体工作,

SrsSource对应客户端的consumers。

在这个循环里面,如果有播放或推流,它们对应的线程是不一样。

do_playing(source,consumer,&trd)和do_publishing(source,&trd)分别对应的协程是SrsQueueRecvThread trd(consumer,rtmp,xxx)和SrsPublishThread(),

4.总结

本篇文章结合源码调试,讲解了SRS流媒体框架的基本认识,学好基本框架,为后面的学习打好基础。

欢迎关注,转发,点赞,收藏,分享,评论区讨论。

后期关于项目的知识,会在微信公众号上更新,如果想要学习项目,可以关注微信公众号“记录世界 from antonio”

标签: #srs架构