live555工程代码路径
live555工程在我的gitee下(doc下有思维导图、drawio图):https://gitee.com/lure_ai/live555/tree/master
学习demo
live555mediaserver.cpp
学习线索和姿势
1.学习的线索和姿势
网络编程
流媒体的地基是网络编程(socket编程)。
[网络编程学习]-0.学习路线。
绘图规则
本文的对象图和思维导图遵守的规则详见:
2.绘图规则
非阻塞服务端网络编程流程
socket创建、bind、listen、select、accept、select、recv/send-close。
rtsp协商流程
options、describe、setup、play、pause、teardown、get parameter、set parameter
本节内容和目标
(1)rtsp协议的setup请求与响应
(2)思维导图绘制
(3)wireshark抓包
(4)对象图
正式开始
DESCRIBE协商完事,VLC就下发了setup信令,开始协商。
1.SETUP请求
请求报文如下
图14-1
可以参照live555mediaserver-如何解析rtsp请求报文把这请求报文解析出来。需要注意的是解析的只局限于请求方法、CSeq、Session、Content-Length等,它下发的其他字段就过滤了。
需要关注的是,这里服务端会用来识别发送模式——UDP or TCP?——这个字段是:Transport字段:RTP/AVP/TCP是告诉服务端我要求采用TCP方式进行数据传输。如果是RTP/AVP那么就是UDP。
2.SETUP请求与响应
根据前面知道,每一个客户端链接,在服务端都绑定一个对象RTSPServer::RTSPClientConnection,每次客户端协议来了数据来了,都会调用到RTSPServer::RTSPClientConnection::handleRequestBytes里,如下图目前知道options、desicribe、set parameter、get parameter会在这个对象里处理。
图14-2
那么从setup开始,又新建一个处理对象进行处理了。怎么创建的呢?RTSPServer::RTSPClientConnection::handleRequestBytes识别到时setup信令,则调用流程如下图14-3。
图14-3
图14-3所示,此时setup处理流程会走到红箭头1,GenericMediaServer::createNewClientSessionWithId,这个是对象DynamicRTSPServer的父类的父类的成员,它主要干2件事,一个是创建对象RTSPServer::RTSPClientSession,另一个是把这个对象加入到GenericMediaServer::fClientSessions这个成员管理的hash链表了,如下图14-4,上一节describe的hash链表是下图的上面一个成员。
14-4
fClientSessions这个成员管理的hash链表的管理,具体如下图14-5。整个图太大,只能截断,可以看live555工程doc下的对象图。
图14-5
如上图14-5,和describe一样是同样类型的hash链表,就直接拷贝过来了,只是链表成员不一样的。setup把新创建的对象RTSPServer::RTSPClientSession的父类的指针加入到这个链表里了。
然后就调用新对象RTSPServer::RTSPClientSession的handleCmd_SETUP方法,它又调用GenericMediaServer::lookupServerMediaSession查找fServerMediaSessions管理的hash链表是否有这个url文件路径,因为describe已经插入了,在这里找到了,又移除它,又重新创建,具体原因,没有细看。
然后调用新对象RTSPServer::RTSPClientSession的回调静态方法SETUPLookupCompletionFunction1,接着调用新对象的handleCmd_SETUP_afterLookup1方法,最终来到了setup组响应报文的地方——handleCmd_SETUP_afterLookup2。其流程如下图14-6.
图14-6
如图14-6数字1是调用GenericMediaServer::lookupServerMediaSession的流向,太大了截图放不下,算了。数字2是又回调回来了。最终是数字4来到了handleCmd_SETUP_afterLookup2。
其主要干了啥事,如下思维导图,图14-7.
图14-7
创建对象数组 struct streamState 保存各个ServerMediaSubsession对象,这个保存的就是前面创建的ServerMediaSubsession对象。截图如下图14-8.
图14-8
接着是解析协商传输方式,如下图14-9。解析RTP_TCP和RAW_UDP,而我们的VLC下发的setup信息如图14-1中是RTP/AVP/TCP,这里自然就是RTP_TCP了。
图14-9
然后根据根据不同的传输方式组不同的setup响应报文。
图14-10
到此整个setup响应流程完毕。setup的完整处理思维导图如下图14-11.
图14-11。
其组装的setup响应报文用wireshark抓包如下图14-12.。
图14-12
小结
从setup开始,又新增了一个对象RTSPServer::RTSPClientSession,如下图14-13.
图14-13.
可以看到新增这个对象呢,setup、play、pause、teardown等都在这里处理了。
详细处理没有分析,只是说有个新的对象出现,应该是2个吧——另一个是struct streamState。
我觉得先根据业务实现,找到新增了什么类,然后再看流程。最后再详细分析。