4725
- 收藏
- 点赞
- 分享
- 举报
RTSP Live555源码分析(转)
今天大致分析了下live555的流程,以H264为例子进行的分析.
从连接到发送RTP/RTCP数据包。
首先分析呢,不能太关注细节,先整体再局部。
在分析的过程中,设计到live555自己封装的一个高级类:比如迭代器,哈希表,而且这2个类在live555中运用的范围还非常的广,但是无不例外都是用链表进行实现的。
后面我们会专门花时间来分析live555是如何实现迭代器和哈希表的.
接着二的分析,这个时候客户端会发送Options,Descriptur,Setup等命令过来,还会发送,快进,暂停,停止等信息过来,完成后,服务器就开始发送RTP/RTCP数据包.
阐述下RTP包和RTCP包得关系.
RTP/RTCP数据包的传输是基于UDP,这是一种无连接的传输方式,也就是说服务器无法判断出客户端和服务器是否依然还在保持联系中,rtcp包就是专门解决这个问题的. rtcp包含了双边发送rtp数据包的信息,包括发送了多少数据包等信息。
那么客户端和服务器就可以通过对RTCP包得分析来统计传输过程中丢了多少包,还有如果超过一定时间没有接收到RTCP数据包,那么客户端和服务器就会终止双边的连接。
说了这么多,分析下live555处理的业务流程.
客户端发送Descripture命令过来后,服务器会创建一个ServerMediaSession,SeerverMediaSession本身会放到一张哈希表中,这张哈希表的作用其实就是绑定后缀名和具体的MediaSession.
比如:[url]rtsp://127.0.0.1:554/tv.264[/url] ,所有的264文件都有一个ServerMediaSession对应,同理,所有的aac,mp3....对会有一个对应的ServerMediaSession.
ServerMediaSession自己也是一个链表(单向还是双向没分析),里面的元素为ServerMediaSubSession。
ServerMediaSubSession的子类很多,比如:H264FileMediaSubSession,AACFileMediaSubSession,光看这些个类的命名,大家也基本猜测出这部分的设计思路.
比如用户同时访问:
[url]rtsp://127.0.0.1:554/tv.264[/url]
[url]rtsp://127.0.0.1[/url]"554/tv2.264
那么live555,就会分配一个ServerMediaSession,然后再ServerMediaSession中包含2个H264FileMediaSubSession,这2个H264FileMediaSubSession一个对应tv.264,另一个对应tv2.264.
H264FileMediaSubSession的功能猜测应该是解析文件,并从中提取H264 NALU单元,并封装为RTP包.(这个类的设计也很复杂,主要是细节多.)
Descriptur完成后,客户端就知道了服务器传递过来的数据的很多信息呢,比如SPS,PPS,这个时候客户端会进行解码器的初始化等操作。
然后完成相关操作后,便会发送Setup,告诉服务器RTP/RTCP的传递端口,让服务器知道数据包具体传到哪个端口.
然后客户端发送PLAY,服务器边开始发送数据包:
fStreamStates.subsession->startStream(fOurSessionId,
fStreamStates.streamToken,
(TaskFunc*)noteClientLiveness, this,
rtpSeqNum, rtpTimestamp,
handleAlternativeRequestByte, this);
const char *urlSuffix = fStreamStates.subsession->trackId();
if (!fAreCurrentlyPlaying && fMediaSource != NULL) {
if (fRTPSink != NULL) {
fRTPSink->startPlaying(*fMediaSource, afterPlayingStreamState, this);
fAreCurrentlyPlaying = True;
} else if (fUDPSink != NULL) {
fUDPSink->startPlaying(*fMediaSource, afterPlayingStreamState, this);
fAreCurrentlyPlaying = True;
}
}
因为里面的设计的类过多,截取一下一些比较重要的代码.
简单说就是接收到PLAY命令后,就开始发送RTP数据包和定时接受/发送RTCP数据包了。
从连接到发送RTP/RTCP数据包。
首先分析呢,不能太关注细节,先整体再局部。
在分析的过程中,设计到live555自己封装的一个高级类:比如迭代器,哈希表,而且这2个类在live555中运用的范围还非常的广,但是无不例外都是用链表进行实现的。
后面我们会专门花时间来分析live555是如何实现迭代器和哈希表的.
接着二的分析,这个时候客户端会发送Options,Descriptur,Setup等命令过来,还会发送,快进,暂停,停止等信息过来,完成后,服务器就开始发送RTP/RTCP数据包.
阐述下RTP包和RTCP包得关系.
RTP/RTCP数据包的传输是基于UDP,这是一种无连接的传输方式,也就是说服务器无法判断出客户端和服务器是否依然还在保持联系中,rtcp包就是专门解决这个问题的. rtcp包含了双边发送rtp数据包的信息,包括发送了多少数据包等信息。
那么客户端和服务器就可以通过对RTCP包得分析来统计传输过程中丢了多少包,还有如果超过一定时间没有接收到RTCP数据包,那么客户端和服务器就会终止双边的连接。
说了这么多,分析下live555处理的业务流程.
客户端发送Descripture命令过来后,服务器会创建一个ServerMediaSession,SeerverMediaSession本身会放到一张哈希表中,这张哈希表的作用其实就是绑定后缀名和具体的MediaSession.
比如:[url]rtsp://127.0.0.1:554/tv.264[/url] ,所有的264文件都有一个ServerMediaSession对应,同理,所有的aac,mp3....对会有一个对应的ServerMediaSession.
ServerMediaSession自己也是一个链表(单向还是双向没分析),里面的元素为ServerMediaSubSession。
ServerMediaSubSession的子类很多,比如:H264FileMediaSubSession,AACFileMediaSubSession,光看这些个类的命名,大家也基本猜测出这部分的设计思路.
比如用户同时访问:
[url]rtsp://127.0.0.1:554/tv.264[/url]
[url]rtsp://127.0.0.1[/url]"554/tv2.264
那么live555,就会分配一个ServerMediaSession,然后再ServerMediaSession中包含2个H264FileMediaSubSession,这2个H264FileMediaSubSession一个对应tv.264,另一个对应tv2.264.
H264FileMediaSubSession的功能猜测应该是解析文件,并从中提取H264 NALU单元,并封装为RTP包.(这个类的设计也很复杂,主要是细节多.)
Descriptur完成后,客户端就知道了服务器传递过来的数据的很多信息呢,比如SPS,PPS,这个时候客户端会进行解码器的初始化等操作。
然后完成相关操作后,便会发送Setup,告诉服务器RTP/RTCP的传递端口,让服务器知道数据包具体传到哪个端口.
然后客户端发送PLAY,服务器边开始发送数据包:
fStreamStates.subsession->startStream(fOurSessionId,
fStreamStates.streamToken,
(TaskFunc*)noteClientLiveness, this,
rtpSeqNum, rtpTimestamp,
handleAlternativeRequestByte, this);
const char *urlSuffix = fStreamStates.subsession->trackId();
if (!fAreCurrentlyPlaying && fMediaSource != NULL) {
if (fRTPSink != NULL) {
fRTPSink->startPlaying(*fMediaSource, afterPlayingStreamState, this);
fAreCurrentlyPlaying = True;
} else if (fUDPSink != NULL) {
fUDPSink->startPlaying(*fMediaSource, afterPlayingStreamState, this);
fAreCurrentlyPlaying = True;
}
}
因为里面的设计的类过多,截取一下一些比较重要的代码.
简单说就是接收到PLAY命令后,就开始发送RTP数据包和定时接受/发送RTCP数据包了。
我来回答
回答1个
时间排序
认可量排序
认可0
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币
Markdown 语法
- 加粗**内容**
- 斜体*内容*
- 删除线~~内容~~
- 引用> 引用内容
- 代码`代码`
- 代码块```编程语言↵代码```
- 链接[链接标题](url)
- 无序列表- 内容
- 有序列表1. 内容
- 缩进内容
- 图片
相关问答
-
2013-01-30 00:14:56
-
2018-11-25 11:08:57
-
2017-01-21 15:59:16
-
2017-02-20 16:56:28
-
2013-01-07 08:59:41
-
2020-07-16 16:28:29
-
2015-04-30 17:17:11
-
2013-06-26 13:05:05
-
2014-12-15 09:29:44
-
2017-08-29 11:12:48
-
2018-08-23 16:21:26
-
2013-08-20 11:49:37
-
2017-11-28 11:46:30
-
2014-08-09 15:15:11
-
2016-04-14 15:20:31
-
2013-01-07 09:15:13
-
2018-08-24 17:02:23
-
2016-04-07 09:56:44
-
2015-02-11 08:56:21
无更多相似问答 去提问

点击登录
-- 积分
-- E币
提问
—
收益
—
被采纳
—
我要提问
切换马甲
上一页
下一页
举报反馈
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明
提醒
你的问题还没有最佳答案,是否结题,结题后将扣除20%的悬赏金
取消
确认
提醒
你的问题还没有最佳答案,是否结题,结题后将根据回答情况扣除相应悬赏金(1回答=1E币)
取消
确认