LIVE555再学习 -- testRTSPClient 源码分析

现在开讲 testRTSPClient。在官网这这样一段介绍,参看:RTSP client
翻译下来就是:
testRTSPClient 是一个命令行程序,显示如何打开和接收由 RTSP URL 指定的媒体流,即以rtsp://开头的URL
在这个演示应用中,接收到的音频/视频数据什么也没有。 但是,您可以在自己的应用程序中使用和调整此代码(例如)解码和播放接收到的数据。
openRTSP 类似于“testRTSPClient”,但具有更多的功能。 这是一个命令行程序,它与“testRTSPClient”不同,旨在用作一个完整的全功能应用程序(而不是在其他应用程序中使用其代码)。 也正应为如此,openRTSP”源代码并不是最好的例子,因为它包含很多额外的选项,大多数你可能不需要。
所以,如果您正在寻找如何使用“LIVE555 Streaming Media”代码构建自己的RTSP / RTP媒体播放器客户端
应该使用“testRTSPClient”应用程序代码(也在“testProgs”目录中)作为模型。

一、源码解析

参看:庖丁解牛-----Live555源码彻底解密(根据testRTSPClient讲解)
参看:庖丁解牛-----Live555源码彻底解密(testRTSPClient流程图)
参看:live555/testProgs/testRTSPClient.cpp

推荐使用 ctags 来查看源码进行分析 
参看:日常生活小技巧 -- vim 中 ctags 的安装和使用
下面所说的跳转查看就是 ctrl+},然后看完后返回跳转前位置 ctrl+t

(1)首先从 testRTSPClient.cpp 的 main函数开始看起

LIVE555再学习 -- testRTSPClient 源码分析_第1张图片
上图可以看到,创建BasicTaskScheduler 和 BisicUsageEnvironment对象。
重点是 openURL 函数,然后 ctrl+] 跳转查看 openURL 的定义
LIVE555再学习 -- testRTSPClient 源码分析_第2张图片
首先通过 ourRTSPClient::createNew 函数最终会调用 ourRTSPClient 的构造函数,基类 RTSPClient 的指针指向派生类 ourRTSPClient 对象,并且最终会调用 RTSPClient 的构造函数;
sendDescribeCommand 函数往服务器端发送 Describe 请求;continueAfterDESCRIBE 为回调函数;在DoEventLoop 中的 SingleStep 中调用;
RTP over tcp 还是udp 由宏 #define REQUEST_STREAMING_OVER_TCP False 进行控制;

(2)然后跳转查看 sendDescribeCommand 


将continueAfterDESCRIBE 函数传递到 responseHandler,相当于 continueAfterDESCRIBE 为一个回调函数;注意 RequestRecord 这个类的作用;在 SendRequest 中调用 RequestRecord 的构造函数.

(3)然后跳转查看 RequestRecord 


可看到将回调函数保存在 RequestRecord 类的 fHandler 上;

(4)然后跳转查看 fHandler 

LIVE555再学习 -- testRTSPClient 源码分析_第3张图片
根据上图可看到 RequestRecord 类定义。所以说 在 SendRequest 中调用 RequestRecord 的构造函数.

(5)然后返回到(2),跳转查看 sendRequest

函数有点长,自行查看吧。
然后其中有一部分:
LIVE555再学习 -- testRTSPClient 源码分析_第4张图片

(6)然后跳转查看 openConnection 

LIVE555再学习 -- testRTSPClient 源码分析_第5张图片
parseRTSPURL
setupStreamSocket
connectToServer
setBackgroundHandling
incomingDataHandler
这几个函数下面需要一一看一下,根据名字也可能看出它们是什么作用的。

(7)然后跳转查看 setBackgroundHandling

LIVE555再学习 -- testRTSPClient 源码分析_第6张图片
上图为 setBackgroundHandling 函数定义,其中 HandlerSet* fHandlers 连上服务器后,调用incomingDataHandler 回调函数;

(8)然后跳转查看 assignHandler

LIVE555再学习 -- testRTSPClient 源码分析_第7张图片

(9)然后跳转查看 lookupHandler

LIVE555再学习 -- testRTSPClient 源码分析_第8张图片

回顾(6)~(9)
openConnection 函数用来连接到服务器;在该函数中首先调用 parseRTSPURL 解析客户端的 RtspURL;然后建立socket(),然后 connectToServer 连接到服务器;; incomingDataHandler 为回调函数; incomingDataHandler 函数,最终赋值给了 handler->handlerProc = handlerProc;
那么我们接下来就看看这几个函数。

(10)然后返回到(6),跳转查看 parseRTSPURL

函数有点长,自行查看吧。

(11)然后返回到(6),跳转查看 setupStreamSocket

LIVE555再学习 -- testRTSPClient 源码分析_第9张图片
建立 socket 的函数为 setupStreamSocket,该函数建立的是一个 tcp 的 socket;
setupStreamSocket 函数首先创建 socket,然后设置 SO_REUSEADDR socket 属性;并且调用 bind 函数绑定socket;最后将 socket 设置成非阻塞形式;

(12)然后返回到(6),跳转查看 connectToServer 

LIVE555再学习 -- testRTSPClient 源码分析_第10张图片
主要起作用的是这句话:
envir().taskScheduler().setBackgroundHandling(socketNum,SOCKET_WRITABLE|SOCKET_EXCEPTION,(TaskScheduler::BackgroundHandlerProc*)&connectionHandler,
然后  setBackgroundHandling 我们在 (7)里看过了。现在看一下 connectionHandler

(12)然后跳转查看 connectionHandler


(13)然后跳转查看 connectionHandler1

LIVE555再学习 -- testRTSPClient 源码分析_第11张图片

(14)然后返回到(1),跳转查看 doEventLoop 

LIVE555再学习 -- testRTSPClient 源码分析_第12张图片
这里如果想要该程序退出,在外面将 *watchVariable=1 就可以了

(15)然后跳转查看 SingleStep

函数有点长,自行查看吧

connectionHandler 在 SingleStep 函数中会调用,调用如下:
(*handler->handlerProc)(handler->clientData,resultConditionSet);

到此,将数据接收部分的源码分析完了。


你可能感兴趣的:(图像和流媒体,图像和流媒体)