0
点赞
收藏
分享

微信扫一扫

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 源码分析_构造函数

上图可以看到,创建BasicTaskScheduler 和 BisicUsageEnvironment对象。

重点是 openURL 函数,然后 ctrl+] 跳转查看 openURL 的定义

LIVE555再学习 -- testRTSPClient 源码分析_构造函数_02

首先通过 ourRTSPClient::createNew 函数最终会调用 ourRTSPClient 的构造函数,基类 RTSPClient 的指针指向派生类 ourRTSPClient 对象,并且最终会调用 RTSPClient 的构造函数;

sendDescribeCommand 函数往服务器端发送 Describe 请求;continueAfterDESCRIBE 为回调函数;在DoEventLoop 中的 SingleStep 中调用;

RTP over tcp 还是udp 由宏 #define REQUEST_STREAMING_OVER_TCP False 进行控制;

LIVE555再学习 -- testRTSPClient 源码分析_构造函数_03


(2)然后跳转查看 sendDescribeCommand 



LIVE555再学习 -- testRTSPClient 源码分析_构造函数_04


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

(3)然后跳转查看 RequestRecord 

LIVE555再学习 -- testRTSPClient 源码分析_回调函数_05

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

(4)然后跳转查看 fHandler 


LIVE555再学习 -- testRTSPClient 源码分析_应用程序_06


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

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


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


然后其中有一部分:



LIVE555再学习 -- testRTSPClient 源码分析_构造函数_07



(6)然后跳转查看 openConnection 



LIVE555再学习 -- testRTSPClient 源码分析_构造函数_08



parseRTSPURL
setupStreamSocket
connectToServer
setBackgroundHandling
incomingDataHandler


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


(7)然后跳转查看 setBackgroundHandling



LIVE555再学习 -- testRTSPClient 源码分析_回调函数_09



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


(8)然后跳转查看 assignHandler



LIVE555再学习 -- testRTSPClient 源码分析_应用程序_10



(9)然后跳转查看 lookupHandler



LIVE555再学习 -- testRTSPClient 源码分析_应用程序_11




回顾(6)~(9)


openConnection 函数用来连接到服务器;在该函数中首先调用 parseRTSPURL 解析客户端的 RtspURL;然后建立socket(),然后 connectToServer 连接到服务器;; incomingDataHandler 为回调函数; incomingDataHandler 函数,最终赋值给了 handler->handlerProc = handlerProc;


那么我们接下来就看看这几个函数。


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


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


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



LIVE555再学习 -- testRTSPClient 源码分析_应用程序_12



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


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



LIVE555再学习 -- testRTSPClient 源码分析_回调函数_13



主要起作用的是这句话:
envir().taskScheduler().setBackgroundHandling(socketNum,SOCKET_WRITABLE|SOCKET_EXCEPTION,(TaskScheduler::BackgroundHandlerProc*)&connectionHandler,


setBackgroundHandling 我们在 (7)里看过了。现在看一下 connectionHandler


(12)然后跳转查看 connectionHandler


LIVE555再学习 -- testRTSPClient 源码分析_回调函数_14


(13)然后跳转查看 connectionHandler1



LIVE555再学习 -- testRTSPClient 源码分析_应用程序_15



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



LIVE555再学习 -- testRTSPClient 源码分析_回调函数_16



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


(15)然后跳转查看 SingleStep


函数有点长,自行查看吧



LIVE555再学习 -- testRTSPClient 源码分析_应用程序_17



connectionHandler 在 SingleStep 函数中会调用,调用如下:

(*handler->handlerProc)(handler->clientData,resultConditionSet);


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




举报

相关推荐

0 条评论