prada
易百纳技术社区
易百纳技术社区
0 访问量
0 原创专栏
0 资料
0 粉丝
个性签名:此E友还没有留下个性签名哦~
加入易百纳时间:2012-11-24

个人成就

易百纳技术社区 共获得 0 个点赞
易百纳技术社区 共获得 7 个收藏
易百纳技术社区 共获得 7 次评论/回复

个人勋章

暂无勋章
分类专栏

Ta擅长的领域

暂无
  • 如题。有能画的丢我小纸条。 QQ详聊。
    2013-08-23
    6 0 4349
  • 今天大致分析了下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. 比如:rtsp://127.0.0.1:554/tv.264,所有的264文件都有一个ServerMediaSession对应,同理,所有的aac,mp3....对会有一个对应的ServerMediaSession. ServerMediaSession自己也是一个链表(单向还是双向没分析),里面的元素为ServerMediaSubSession。 ServerMediaSubSession的子类很多,比如:H264FileMediaSubSession,AACFileMediaSubSession,光看这些个类的命名,大家也基本猜测出这部分的设计思路. 比如用户同时访问: rtsp://127.0.0.1:554/tv.264 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[i].subsession->startStream(fOurSessionId, fStreamStates[i].streamToken, (TaskFunc)noteClientLiveness, this, rtpSeqNum, rtpTimestamp, handleAlternativeRequestByte, this); const char urlSuffix = fStreamStates[i].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数据包了。
    2013-08-23
    1 7 6675
易百纳技术社区
共2条
易百纳技术社区