Live555源码学习02 ---- 框架

0. 简介
这里的分析都是基于源码的testRTSPClient为入口。
主要分为4个库:
1.UsageEnvironment:抽象了两个类UsageEnvironment和TaskScheduler,
  a)UsageEnvironment:表示整个运行环境,同时提供错误记录和输出的功能。
  b)TaskScheduler:表示任务调度中心,用于异步事件的读取和处理。
2.groupsock:网络接口的封装
3.liveMedia:基于基类Medium,实现各种流媒体和编解码类型结构,定义了source(生产者)和sink(消费者)操作。
4.BasicUsageEnvironment:UsageEnvironment和TaskScheduler的具体实现类。

1. RTSP Client的流程

流程图如下:

这里抓包分析一下,如下:

a)   sendDescribeCommand:DESCRIBE消息,用来获取sdp信息

req:                                                
DESCRIBE rtsp://10.151.3.77:8554/test.264 RTSP/1.0
CSeq: 2
User-Agent: 1 (LIVE555 Streaming Media v2020.03.06)
Accept: application/sdp
rsp:
RTSP/1.0 200 OK
CSeq: 2
Date: Wed, Sep 08 2021 09:25:55 GMT
Content-Base: rtsp://10.151.3.77:8554/test.264/
Content-Type: application/sdp
Content-Length: 501

v=0 
// <version> 协议版本 
o=- 1631093155092004 1 IN IP4 10.151.3.77 
// <username> <session id> <version> <network type> <address type> <address> 所有者/创建者和会话标识符
s=H.264 Video, streamed by the LIVE555 Media Server
// <session name> 会话名称
i=test.264
// <session description> 会话信息
t=0 0
// <start time> <stop time> 会话活动时间
a=tool:LIVE555 Streaming Media v2021.08.24
a=type:broadcast
a=control:*
a=range:npt=now-
a=x-qt-text-nam:H.264 Video, streamed by the LIVE555 Media Server
a=x-qt-text-inf:test.264
// <attribute>:<value> 会话属性
m=video 0 RTP/AVP 96
// <media> <port> <transport> <fmt list> 媒体名称和传输地址
c=IN IP4 0.0.0.0
// <network type> <address type> <connection address> 连接信息— 如果包含在会话层则该字段可选
b=AS:500
// <modifier>:<bandwidth-value> 带宽信息
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1;profile-level-id=640028;sprop-parameter-sets=Z2QAKKzMYCgPZA==,aOlKOLA=
a=control:track1

b)   sendSetupCommand:SETUP请求,建立会话和确定传输模式

req:
SETUP rtsp://10.151.3.77:8554/test.264/track1 RTSP/1.0
CSeq: 3
User-Agent: 1 (LIVE555 Streaming Media v2020.03.06)
Transport: RTP/AVP;unicast;client_port=54346-54347
rsp:
RTSP/1.0 200 OK
CSeq: 3
Date: Wed, Sep 08 2021 09:25:55 GMT
Transport: RTP/AVP;unicast;destination=10.151.144.69;source=10.151.3.77;client_port=54346-54347;server_port=6970-6971
Session: 9F44F18F;timeout=65

c)   sendPlayCommand:播放请求,服务器开始播放

req:
PLAY rtsp://10.151.3.77:8554/test.264/ RTSP/1.0
CSeq: 4
User-Agent: 1 (LIVE555 Streaming Media v2020.03.06)
Session: 9F44F18F
Range: npt=0.000-
rsp:
RTSP/1.0 200 OK
CSeq: 4
Date: Wed, Sep 08 2021 09:25:55 GMT
Range: npt=0.000-
Session: 9F44F18F
RTP-Info: url=rtsp://10.151.3.77:8554/test.264/track1;seq=17205;rtptime=3614453685

2. RTSPClient客户端

可以看到,RTSPClient继承liveMedia,实现了RTSP协议,主要有两个部分:

1. 创建tcp连接

a)      setupStreamSocket:创建tcp socket

b)      connectToServer:连接服务器

c)      注册回调:连接成功以后,会向调度中心注册回调,用来接收TCP数据

2. 发送RTSP报文

a)      sendRequest:主要是通过这个函数,发送RTSP报文

b)      注册响应回调:回调会缓存到fRequestsAwaitingResponse链表中,incomingDataHandler收到数据,最终调用 RTSPClient::handleResponseBytes(),在这里会调用注册的回调。

3. TaskScheduler调度中心

1. 在RTSP客户端最后,会调用任务调度,如下:

看一下实现,就是while循环,这里通过select循环读取socket事件,并调用注册的回调。

2. 注册回调函数:

fHandlers保存了回调函数和socket等相关信息,它也是基于链表保存的。

4.   MediaSession

MediaSession主要用来创建RTP和RTCP客户端,以及相关数据处理。看上面的流程,发送DESCRIBE报文,收到200 OK响应,我们拿到SDP信息,就会创建相关Socket。

这些在MediaSubsession::initiate(int useSpecialRTPoffset)中实现,主要创建三个对象:

  1. fRTPSocket:RTP客户端
  2. fRTCPSocket:RTCP客户端
  3. fReadSource(H264VideoRTPSource):用来获取RTP数据,它会向调度中心注册回调

5.   MediaSink消费者

MediaSink主要是用来获取RTP数据的,需要继承实现continuePlaying();SETUP成功以后,就可以创建MediaSink,并且调用startPlaying()。

最后会调用continuePlaying(),实现如下

我们看看getNextFrame()

到这里看到,doGetNextFrame会到TaskScheduler调度中心注册回调,异步读取RTP数据。

 

posted @ 2021-09-13 10:32  Vzf  阅读(266)  评论(0编辑  收藏  举报