Live555中RTP包的打包与发送过程分析
这里主要分析一下,live555中关于RTP打包发送的部分。在处理完PLAY命令之后,就开始发送RTP数据包了(其实在发送PLAY命令的response包之前,就会发送一个RTP包,这里传输就已经开始了)
先介绍下主要的流程:RTP包的发送是从MediaSink::startPlaying函数调用开始的,在StartPlaying函数的最后会调用函数continuePlaying。
continuePlaying函数是定义在MediaSink类中的纯虚函数,需要到特定媒体的sink子类中实现,对于H264来讲是在H264VideoRTPSink中实现的。H264VideoRTPSink:continuePlaying中会创建一个辅助类H264FUAFragmenter,用于H264的RTP打包。因为H264的RTP包,有些特殊需要进一步处理。接着调用其父类MultiFramedRTPSink::continuePlaying实现。
在函数MultiFramedRTPSink::continuePlaying中主要是调MultiFramedRTPSink::buildAndSendPacket函数。
看名字就知道MultiFramedRTPSink::buildAndSendPacket()函数将完成打包并发送工作。传递了一个True参数,表示这是第一个packet。在该函数的最后调用了MultiFramedRTPSink::packFrame() ,进一步的工作,在packFrame函数中进行,
MultiFramedRTPSink::packFrame() 将为RTP包填充数据。packFrame函数需要处理两种情况:
1).buffer中存在未发送的数据(overflow data),这时可以将调用afterGettingFrame1函数进行后续处理工作。2).buffer不存在数据,这时需要调用source上的getNextFrame函数获取数据。getNextFrame调用时,参数中有两个回调用函数:afterGettingFrame函数将在获取到数据后调用,其中只是简单的调用了afterGettingFrame1函数而已;ourHandleClosure函数将在数据已经处理完毕时调用,如文件结束。可以看出,两种情况下最后都是要调用afterGettingFrame1函数,
afterGettingFrame1函数的复杂之处在于处理frame的分片,若一个frame大于TCP/UDP有效载荷(程序中定义为1448个字节),就必需分片了。最简单的情况就是一个packet(RTP包)中最多只充许一个frame,即一个RTP包中存在一个frame或者frame的一个分片,H264就是这样处理的:方法是将剩余的数据记录为buffer的溢出部分。下次调用packFrame函数时,直接从溢出部分复制到packet中。不过应该注意,一个frame的大小不能超过buffer的大小(默认为60000),否则会真的溢出, 那就应该考虑增加buffer大小了。
处理完相关分片信息,将会调用函数MultiFramedRTPSink::sendPacketIfNecessary()来发送数据包。sendPacketIfNecessary()中函数处理一些发送的细节,如packet中含有Frame则调用RTPInterface::sendPacket函数发送packet。并将下一次RTP的发送操作加入到任务调度器中:nextTask() = envir().taskScheduler().
scheduleDelayedTask。函数参数中传递了sendNext函数指针。sendNext函数又调用了buildAndSendPacket函数,轮回了。。。!
最后来看下RTPInterface::sendPacket函数。若是使用UDP方式发送,将调用Groupsock::output函数,可以实现组播功能。groupsock只实现了UDP发送功能,当用TCP方式传送时调用sendRTPOverTcP函数,这个函数中直接调用socket的send函数。至此关于RTP打包发送的主要流程分析就差不多了,具体细节实现,可参考源代码。
Live555中RTP包的打包与发送过程分析的更多相关文章
- Maven项目中War包的打包及依赖方式
两个web项目之间的依赖引用方式.Web项目之间,通过war包的方式进行引用的.例如,有两个项目,puzzle-web和puzzle-web-demo,两个均是web项目,puzzle-web-dem ...
- (转)live555学习笔记7-RTP打包与发送
七 RTP打包与发送 rtp传送开始于函数:MediaSink::startPlaying().想想也有道理,应是sink跟source要数据,所以从sink上调用startplaying(嘿嘿,相当 ...
- RTP包中timestamp的间隔问题
概述 近期在和同事调试G729的编解码库时碰到一个语音质量的问题,问题产生的原因和RTP包中的时间戳设置有关,特此记录下来. 问题现象,1001和1002账号注册在fs,媒体设置为G729并通过fs中 ...
- 得到RTP包中的timestamp
NTP------网络时间协议 PTP------精确时间协议 PTS,DTS的关系: http://www.cnblogs.com/qingquan/archive/2011/07/27/21189 ...
- maven中把依赖的JAR包一起打包
<buizld> <plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId ...
- H264 RTP包解析
1. 预备 视频: 由一副副连续的图像构成,由于数据量比较大,因此为了节省带宽以及存储,就需要进行必要的压缩与解压缩,也就是编解码. h264裸码流: 对一个图像或者一个视频序列进行压缩,即产生码流 ...
- Android IOS WebRTC 音视频开发总结(八十六)-- WebRTC中RTP/RTCP协议实现分析
本文主要介绍WebRTC中的RTP/RTCP协议,作者:weizhenwei ,文章最早发表在编风网,微信ID:befoio 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID ...
- RTP 包格式 详细解析
H.264 视频 RTP 负载格式 1. 网络抽象层单元类型 (NALU) NALU 头由一个字节组成, 它的语法如下: +---------------+ |0|1|2|3|4|5|6|7 ...
- NALU数据打RTP包流程详解
最近在看RTP发送H264数据的文章,感觉很乱,没有比较清晰易懂的教程,自己整理了一下各种资料,备忘! --------Part A ---- 先说说H264数据,H264在网络传输的是NALU(N ...
随机推荐
- 浅析白盒审计中的字符编码及SQL注入
尽管现在呼吁所有的程序都使用unicode编码,所有的网站都使用utf-8编码,来一个统一的国际规范.但仍然有很多,包括国内及国外(特别是非英语国家)的一些cms,仍然使用着自己国家的一套编码,比如g ...
- 【WCF--初入江湖】11 安全
11 安全 前言 [1]传输安全 传输安全模式 传输安全与绑定协议 [2]身份验证 身份验证分类 证书 示例:传输安全匿名客户端证书的使用 1. 传输安全 保证信息在传输过程中的 ...
- POJ 1731
#include<iostream> #include<string> #include<algorithm> using namespace std; int m ...
- 在IDEA上用python来连接集群上的hive
1.在使用Python连接hive之前需要将hive中的文件拷贝到自己创建python项目中 cp -r apache-hive--bin/lib/py /home/jia/Desktop 2.把h ...
- JavaScript执行上下文
变量声明.函数声明为何会提升?js执行时是如何查找变量的?JavaScript中最基本的部分——执行上下文(execution context) 什么是执行上下文? 当JavaScript代码运行,执 ...
- C# 构造函数的使用方法
C#构造函数是一个特殊的类方法.在很多方面,包括访问修饰符.重载以及参数列表的语法等方面,构造函数与普通的方法是类似的.然而,在使用方面以及行为方面,构造函数也具有许多特殊的语法和语义规则. 下面列出 ...
- java使用正则表达式——实例
Java代码 import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @author Der * ...
- emms指令在MMX指令中的作用
emms指令在MMX指令中的作用 转自:http://blog.csdn.net/psusong/archive/2009/01/08/3737047.aspx MMX和SSE都是INTEL开发的基于 ...
- python os.stat() 和 stat模块详解
stat 系统调用时用来返回相关文件的系统状态信息的. 首先我们看一下stat中有哪些属性: >>> import os >>> print os.stat(&qu ...
- ADO.NET基础02(语句参数化,配置文件,DataSet与DataTable)
ADO.NET连接池 ado.net默认启用了连接池 *如何清空连接池?Connection的静态方法ClearAllPools(). ClearPool() Ado.net连接池使用总结: 1.第一 ...