Live555 源代码分析(五)

2020-09-23  本文已影响0人  RonZheng2010

1 主程序

1.1 基本概念与实体

下图展示主程序中涉及的主要概念与实体。

MediaServer是服务器的抽象。

ClientConnection是与客户端的数据连接的抽象。

MediaSession是媒体的抽象。

媒体中可以有多个通道,MediaSubsession是媒体通道的抽象。

ClientSession是与客户端的对话的抽象,承载在ClientConnection上。

StreamState是ClientSession用于挂接到MediaSubsession的中介。

1.2 Main()

Main()创建任务调度器,创建RTSPServer实例,将它的socket置于调度器的监听下,最后运行调度器,处理socket事件。

GenericMediaServer::setUpOurSocket()创建TCP socket。

1.3 GenericMediaServer::incomingConnectionHandler()

当有新的数据连接请求时,GenericMediaServer::incomingConnectionHandler()被调用。其中调用incomingConnectionHandlerOnSocket(),参数是成员fServerSocket。

在createNewClientConnection()中,

1.4 ClientConnection::incomingRequestHandler()

当数据连接有数据到达时,ClientConnection::incomingRequestHandler()被调用。

1.4.1.请求OPTIONS

OPTIONS的请求字符串如下:

OPTIONS rtsp://192.168.2.133:8554/jzl.mp3 
RTSP/1.0\r\n
CSeq: 2\r\n
User-Agent: LibVLC/2.2.8 (LIVE555 Streaming Media v2016.02.22)\r\n\r\n

调用handleCmd_OPTIONS()处理。

RTSP/1.0 200 OK\r\n
CSeq: 2\r\n
Date: Tue, Apr 28 2020 02:37:34 GMT\r\n
Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, GET_PARAMETER, SET_PARAMETER\r\n\r\n

1.4.2 请求DESCRIBE

DESCRIBE的请求字符串如下:

DESCRIBE rtsp://192.168.2.133:8554/jzl.mp3 
RTSP/1.0\r\n
CSeq: 3\r\n
User-Agent: LibVLC/2.2.8 (LIVE555 Streaming Media v2016.02.22)\r\n
Accept: application/sdp\r\n\r\n

调用handleCmd_DESCRIBE()处理。

如下是DESCRIBE请求的回复字符串。

RTSP/1.0 200 OK\r\n
CSeq: 3\r\n
Date: Tue, Apr 28 2020 06:31:55 GMT\r\n
Content-Base: rtsp://192.168.2.133:8554/jzl.mp3/\r\n
Content-Type: application/sdp\r\n
Content-Length: 391\r\n\r\n
v=0\r\n
o=- 1588055515931667 1 IN IP4 192.168.2.133\r\n
s=MPEG-1 or 2 Audio, streamed by the LIVE555 Media Server\r\n
i=jzl.mp3\r\n
t=0 0\r\n
a=tool:LIVE555 Streaming Media v2019.12.30\r\n
a=type:broadcast\r\n
a=control:*\r\n
a=range:npt=0-232.590\r\n
a=x-qt-text-nam:MPEG-1 or 2 Audio, streamed by the LIVE555 Media Server\r\n
a=x-qt-text-inf:jzl.mp3\r\n
m=audio 0 RTP/AVP 14\r\n
c=IN IP4 0.0.0.0\r\n
b=AS:128\r\n
a=control:track1\r\n

DynamicRTSPServer::lookupServerMediaSessin()根据key值,在GenericMediaServer的成员fSerMediaSessions中查找对应的实例。fServerMediaSessesions是一个Hash表。这里的key值是文件名“jzl.mp3”。

在全局函数createSMS()中,

OnDemandServerMediaSubsession::sdpLines()得到子session的sdp字符串。

1.4.3 请求SETUP

SETUP的请求字符串如下。它请求jzl.mp3文件的通道track1。

SETUP rtsp://192.168.2.133:8554/jzl.mp3/track1 RTSP/1.0\r\n
CSeq: 4\r\n
User-Agent: LibVLC/2.2.8 (LIVE555 Streaming Media v2016.02.22)\r\n
Transport: RTP/AVP;unicast;client_port=65512-65513\r\n\r\n

这里先调用createNewClientSessionWithId()创建ClientSession实例,再调用handleCmd_SETUP()处理。注意这里的handleCmd_SETUP()从属于RTSPClientSession(是它的成员函数),而前面的handleCmd_DESCRIBE()从属于RTSPClientConnection。

createNewClientSessionWithId()实现如下:

RTSPClientSession::handleCmd_SETUP()的实现如下。

以下是handleCmd_SETUP()的回复字符串。它的传输头部指定了收发两端的地址和端口,同时还指定了Session编号0x4F1FB7E7。

RTSP/1.0 200 OK\r\n
CSeq: 4\r\n
Date: Wed, Apr 29 2020 08:30:41 GMT\r\n
Transport: RTP/AVP;unicast;destination=192.168.2.128;source=192.168.2.133;client_port=63032-63033;server_port=6970-6971\r\n
Session: 4F1FB7E7;timeout=65\r\n\r\n

getStreamParameters()创建数据通道。

1.4.4 请求PLAY

PLAY的请求字符串如下。它请求jzl.mp3文件,ClientSession的编号是0xC47271EC。

这个session在之前处理SETUP请求时已经创建了。这里先用它查询先前创建的ClientSession实例,再调用RTSPClientSession::handleCmd_PLAY()。

PLAY rtsp://192.168.2.133:8554/jzl.mp3/ RTSP/1.0\r\n
CSeq: 5\r\n
User-Agent: LibVLC/2.2.8 (LIVE555 Streaming Media v2016.02.22)\r\n
Session: C47271EC\r\n
Range: npt=0.000-\r\n\r\n\
000port=53834-53835\r\n\r\n

RTSPClientSession::handleCmd_PLAY()的实现如下。

OnDemandServerMediaSubsession::seekStream()的工作如下:

OnDemandServrMediaSubsession::startStream()的工作如下:

以下是handleCmd_PLAY()的回复字符串。

RTSP/1.0 200 OK\r\n
CSeq: 5\r\n
Date: Wed, May 06 2020 07:59:07 GMT\r\n
Range: npt=0.000-\r\n
Session: C47271EC\r\n
RTP-Info: url=rtsp://192.168.2.151:8554/jzl.mp3/track1;seq=15637;rtptime=133202039\r\n\r\n

1.4.5 连接图

如下是最后得到的连接图。

上一篇下一篇

猜你喜欢

热点阅读