LIVE555再学习 -- testRTSPClient 源码分析

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

一、源码解析

参看:庖丁解牛-----Live555源码彻底解密(根据testRTSPClient讲解)

推荐使用 ctags 来查看源码进行分析 
下面所说的跳转查看就是 ctrl+},然后看完后返回跳转前位置 ctrl+t

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


上图可以看到,创建BasicTaskScheduler 和 BisicUsageEnvironment对象。
重点是 openURL 函数,然后 ctrl+] 跳转查看 openURL 的定义

首先通过 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 


根据上图可看到 RequestRecord 类定义。所以说 在 SendRequest 中调用 RequestRecord 的构造函数.

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

函数有点长,自行查看吧。
然后其中有一部分:

(6)然后跳转查看 openConnection 


parseRTSPURL
setupStreamSocket
connectToServer
setBackgroundHandling
incomingDataHandler
这几个函数下面需要一一看一下,根据名字也可能看出它们是什么作用的。

(7)然后跳转查看 setBackgroundHandling


上图为 setBackgroundHandling 函数定义,其中 HandlerSet* fHandlers 连上服务器后,调用incomingDataHandler 回调函数;

(8)然后跳转查看 assignHandler


(9)然后跳转查看 lookupHandler



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

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

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

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


建立 socket 的函数为 setupStreamSocket,该函数建立的是一个 tcp 的 socket;
setupStreamSocket 函数首先创建 socket,然后设置 SO_REUSEADDR socket 属性;并且调用 bind 函数绑定socket;最后将 socket 设置成非阻塞形式;

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


主要起作用的是这句话:
envir().taskScheduler().setBackgroundHandling(socketNum,SOCKET_WRITABLE|SOCKET_EXCEPTION,(TaskScheduler::BackgroundHandlerProc*)&connectionHandler,
然后  setBackgroundHandling 我们在 (7)里看过了。现在看一下 connectionHandler

(12)然后跳转查看 connectionHandler


(13)然后跳转查看 connectionHandler1


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


这里如果想要该程序退出,在外面将 *watchVariable=1 就可以了

(15)然后跳转查看 SingleStep

函数有点长,自行查看吧

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

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


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

聚优致成

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值