实现RTP协议的H.264视频传输系统

1.  引言
       随着信息产业的发展,人们对信息资源的要求已经逐渐由文字和图片过渡到音频和视频,并越来越强调获取资源的实时性和互动性。但人们又面临着另外一种不可避免的尴尬,就是在网络上看到生动清晰的媒体演示的同时,不得不为等待传输文件而花费大量时间。为了解决这个矛盾,一种新的媒体技术应运而生,这就是流媒体技术。流媒体由于具有启动时延小、节省客户端存储空间等优势,逐渐成为人们的首选,流媒体网络应用也在全球范围内得到不断的发展。其中实时流传输协议 RTP 详细说明了在互联网上传递音频和视频的标准数据包格式,它与传输控制协议 RTCP 配合使用,成为流媒体技术最普遍采用的协议之一。 
        H.264/AVC 是ITU-T 视频编码专家组(VCEG)和ISO/IEC 动态图像专家组(MPEG )联合组成的联合视频组(JVT)共同努力制订的新一代视频编码标准,它最大的优势是具有很高的数据压缩比率,在同等图像质量的条件下,H.264 的压缩比是MPEG-2 的2 倍以上,是 MPEG-4的1.5~2 倍。同时,采用视频编码层(VCL)和网络提取层(NAL )的分层设计,非常适用于流媒体技术进行实时传输。本文就是基于 RTP 协议,对 H.264 视频进行流式打包传输,实现了一个基本的流媒体服务器功能,同时利用开源播放器VLC 作为接收端,构成一个完整的H.264 视频传输系统。

2.  RTP 协议关键参数的设置
         RTP 协议是 IETF 在 1996 年提出的适合实时数据传输的新型协议。RTP 协议实际上是由实时传输协议RTP(Real-time Transport Protocol)和实时传输控制协议RTCP(Real-time Transport Control Protocol)两部分组成。RTP 协议基于多播或单播网络为用户提供连续媒体数据的实时传输服务;RTCP 协议是 RTP 协议的控制部分,用于实时监控数据传输质量,为系统提供拥塞控制和流控制。RTP 协议在RFC3550 中有详细介绍。每一个 RTP 数据包都由固定包头(Header )和载荷(Payload)两个部分组成,其中包头前12个字节的含义是固定的,而载荷则可以是音频或视频数据。RTP 固定包头的格式如图1所示: 
  


       
 其中比较关键的参数设置解释如下:
      (1)标示位(M ):1 位,该标示位的含义一般由具体的媒体应用框架(profile )定义, 目的在于标记处RTP 流中的重要事件。
     (2)载荷类型(PT):7 位,用来指出RTP负载的具体格式。在RFC3551中,对常用的音视频格式的RTP 传输载荷类型做了默认的取值规定,例如,类型2 表明该RTP数据包中承载的是用ITU G.721 算法编码的语音数据,采用频率为 8000HZ,并且采用单声道。
    (3)序号:16 位,每发送一个 RTP 数据包,序号加 1。接受者可以用它来检测分组丢失和恢复分组顺序。
   (4)时间戳:32 位,时间戳表示了 RTP 数据分组中第一个字节的采样时间,反映出各RTP 包相对于时间戳初始值的偏差。对于RTP 发送端而言,采样时间必须来源于一个线性单调递增的时钟。
       从 RTP 数据包的格式不难看出,它包含了传输媒体的类型、格式、序列号、时间戳以及是否有附加数据等信息。这些都为实时的流媒体传输提供了相应的基础。而传输控制协议RTCP为 RTP传输提供了拥塞控制和流控制,它的具体包结构和各字段的含义可参考RFC3550,此处不再赘述。
3.  H.264 基本流结构及其传输机制
3.1  H.264 基本流的结构
H.264 的基本流(elementary stream,ES)的结构分为两层,包括视频编码层(VCL)和网络适配层(NAL)。视频编码层负责高效的视频内容表示,而网络适配层负责以网络所要求的恰当的方式对数据进行打包和传送。引入NAL并使之与VCL分离带来的好处包括两方面:其一、使信号处理和网络传输分离,VCL 和NAL 可以在不同的处理平台上实现;其二、VCL 和NAL 分离设计,使得在不同的网络环境内,网关不需要因为网络环境不同而对VCL比特流进行重构和重编码。
       H.264 的基本流由一系列NALU (Network Abstraction Layer Unit )组成,不同的NALU数据量各不相同。H.264 草案指出[2],当数据流是储存在介质上时,在每个NALU 前添加起始码:0x000001,用来指示一个 NALU的起始和终止位置。在这样的机制下,*在码流中检测起始码,作为一个NALU得起始标识,当检测到下一个起始码时,当前NALU结束。每个NALU单元由一个字节的 NALU头(NALU Header)和若干个字节的载荷数据(RBSP)组成。其中NALU 头的格式如图2 所示:


        F:forbidden_zero_bit.1 位,如果有语法冲突,则为 1。当网络识别此单元存在比特错误时,可将其设为 1,以便接收方丢掉该单元。 
        NRI:nal_ref_idc.2 位,用来指示该NALU 的重要性等级。值越大,表示当前NALU越重要。具体大于0 时取何值,没有具体规定。
 Type:5 位,指出NALU 的类型。具体如表1 所示:


      需要特别指出的是,NRI 值为 7 和 8 的NALU 分别为序列参数集(sps)和图像参数集(pps)。参数集是一组很少改变的,为大量VCL NALU 提供解码信息的数据。其中序列参数集作用于一系列连续的编码图像,而图像参数集作用于编码视频序列中一个或多个独立的图像。如果*没能正确接收到这两个参数集,那么其他NALU 也是无法解码的。因此它们一般在发送其它 NALU 之前发送,并且使用不同的信道或者更加可靠的传输协议(如TCP)进行传输,也可以重复传输。
3.2  适用于 H.264 视频的传输机制
       前面分别讨论了RTP 协议及H.264基本流的结构,那么如何使用RTP协议来传输H.264视频了?一个有效的办法就是从H.264视频中剥离出每个NALU,在每个NALU前添加相应的RTP包头,然后将包含RTP 包头和NALU 的数据包发送出去。下面就从RTP包头和NALU两方面分别阐述。
      完整的 RTP 固定包头的格式在前面图 1 中已经指出,根据RFC3984[3],这里详细给出各个位的具体设置。
      V:版本号,2 位。根据RFC3984,目前使用的RTP 版本号应设为0x10。
      P:填充位,1 位。当前不使用特殊的加密算法,因此该位设为 0。
      X:扩展位,1 位。当前固定头后面不跟随头扩展,因此该位也为 0。
      CC:CSRC 计数,4 位。表示跟在 RTP 固定包头后面CSRC 的数目,对于本文所要实现的基本的流媒体服务器来说,没有用到混合器,该位也设为 0x0。
       M:标示位,1 位。如果当前 NALU为一个接入单元最后的那个NALU,那么将M位置 1;或者当前RTP 数据包为一个NALU 的最后的那个分片时(NALU 的分片在后面讲述),M位置 1。其余情况下M 位保持为 0。 
       PT:载荷类型,7 位。对于H.264 视频格式,当前并没有规定一个默认的PT 值。因此选用大于 95 的值可以。此处设为0x60(十进制96)。
      SQ:序号,16 位。序号的起始值为随机值,此处设为 0,每发送一个RTP 数据包,序号值加 1。
      TS:时间戳,32 位。同序号一样,时间戳的起始值也为随机值,此处设为0。根据RFC3984, 与时间戳相应的时钟频率必须为90000HZ。
      SSRC:同步源标示,32 位。SSRC应该被随机生成,以使在同一个RTP会话期中没有任何两个同步源具有相同的SSRC 识别符。此处仅有一个同步源,因此将其设为0x12345678。
      对于每一个NALU,根据其包含的数据量的不同,其大小也有差异。在IP网络中,当要传输的IP 报文大小超过最大传输单元MTU(Maximum Transmission Unit )时就会产生IP分片情况。在以太网环境中可传输的最大 IP 报文(MTU)的大小为 1500 字节。如果发送的IP数据包大于MTU,数据包就会被拆开来传送,这样就会产生很多数据包碎片,增加丢包率,降低网络速度。对于视频传输而言,若RTP 包大于MTU 而由底层协议任意拆包,可能会导致接收端播放器的延时播放甚至无法正常播放。因此对于大于MTU 的NALU 单元,必须进行拆包处理。
RFC3984 给出了3 中不同的RTP 打包方案:
(1)Single NALU Packet:在一个RTP 包中只封装一个NALU,在本文中对于小于 1400字节的NALU 便采用这种打包方案。
       (2)Aggregation Packet:在一个RTP 包中封装多个NALU,对于较小的NALU 可以采用这种打包方案,从而提高传输效率。
       (3)Fragmentation Unit:一个NALU 封装在多个RTP包中,在本文中,对于大于1400字节的NALU 便采用这种方案进行拆包处理。
4.  H.264 流媒体传输系统的实现
       一个完整的流媒体传输系统包含服务器端和客户端两个部分[5][6]。对于服务器端,其主要任务是读取H.264 视频,从码流中分离出每个NALU 单元,分析NALU 的类型,设置相应的 RTP 包头,封装 RTP 数据包并发送。而对于客户端来说,其主要任务则是接收 RTP数据包,从RTP 包中解析出NALU 单元,然后送至*进行解码播放。该流媒体传输系统的框架如图3 所示。


                                                                                                
5. 结论
本文所设计的流媒体传输系统服务器端运行在Windows XP 系统,用VLC 播放器作为客户端接收H.264 视频RTP 数据包。经测试,客户端在经过2 秒的缓冲过后即能流畅播放,传输速度设为 30 帧每秒的情况下,未出现丢包拖影等现象,视频主观质量良好,与本地播放该H.264 视频无明显区别。
AnyChat采用国际领先的视频编码标准H.264(MPEG-4 part 10 AVC /H.264)编码,H.264/AVC 在压缩效率方面有着特殊的表现,一般情况下达到 MPEG-2 及 MPEG-4 简化类压缩效率的大约 2 倍。H.264具有许多与旧标准不同的新功能,它们一起实现了编码效率的提高。特别是在帧内预测与编码、帧间预测与编码、可变矢量块大小、四分之一像素运动估计、多参考帧预测、自适应环路去块滤波器、整数变换、量化与变换系数扫描、熵编码、加权预测等实现上都有其独特的考虑。

 佰锐科技采用先进去马赛克技术,保障在视频通讯过程中不出现花屏、马赛克等现象。免费测试下载地址:
http://www2.bairuitech.com/downloads/bairuisoft/AnyChatCoreSDK_V3.0.rar


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/254906.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器人网首页应用实例工业自动化 EtherCAT 技术在库卡机器人控制系统上的应用

自 2010 年以来,库卡一直采用 EtherCAT 技术作为所有库卡机器人控制系统中的系统总线。最新的 KR AGILUS 机器人和 LBR iiwa 轻型机器人的紧凑型控制器也是在 EtherCAT 基础上实施的。Beckhoff 基于工业以太网的 EtherCAT因而可以作为整个当前库卡控制系统范围内的…

KVM虚拟机共享存储动态迁移与冷迁移

运行环境一、 配置nfs共享服务器二、 配置KVM虚拟化三、 创建桥接网卡四、 配置kvm服务器并实现动态迁移五、 配置冷迁移运行环境KVM虚拟机两台(linux 7.4)IP地址:192.168.80.100(KVM01)IP地址:192.168.80.…

HALCON示例程序surface_scratch.hdev提取划痕

小哥哥小姐姐觉得有用点个赞呗! HALCON示例程序surface_scratch.hdev提取划痕 示例程序源码(加注释) 关于显示类函数解释 dev_update_off () dev_close_window () read_image (Image, ‘surface_scratch’) get_image_size (Image, Width…

理解LSTM/RNN中的Attention机制

转自:http://www.jeyzhang.com/understand-attention-in-rnn.html,感谢分享! 导读 目前采用编码器-解码器 (Encode-Decode) 结构的模型非常热门,是因为它在许多领域较其他的传统模型方法都取得了更好的结果。这种结构的模型通常将…

[BZOJ2326] [HNOI2011] 数学作业 (矩阵乘法)

Description Input Output Sample Input Sample Output HINT Source Solution 递推式长这样:$f[n]f[n-1]*10^kn$ 对于每一段位数个数相同的$n$(如$10\sim99,100\sim999,23333\sim66666,1018701389\sim2147483647$),$k$是个定值 然…

HALCON示例程序texture.hdev检测树木

小哥哥小姐姐觉得有用点个赞呗! HALCON示例程序texture.hdev检测树木 示例程序源码(加注释) 关于显示类函数解释 dev_close_window () Interactive : 0 dev_close_window () read_image (MreutHill, ‘mreut_y’) get_image_size (MreutH…

1、python基础速成

基础模块 def prt(age,name):#函数定义 print("%s is %d 年龄 old"%(name,age)) if __name__"__main__":#程序入口 print("Hello World") prt(45,"gaici") 获取输入:使用input()函数 nameinput("you name &#x…

老男孩博客园杨海潮MySQL--MySQL机构逻辑2

转载于:https://blog.51cto.com/yanfeilai528/2103403

法国标致雪铁龙汽车公司采用通快碟片激光器进行焊接

发布日期:2011-10-14 来源:光电新闻网 发布人:星之球科技 摘要:3月11日消息,十一个碟片激光器(disk laser)将安装在标致雪铁龙集团的工厂,这家法国汽车制造商准备使用4千瓦的激光器…

HALCON示例程序vessel.hdev血管的分割与测量

小哥哥小姐姐觉得有用点个赞呗! HALCON示例程序vessel.hdev血管的分割与测量 示例程序源码(加注释) 关于显示类函数解释 dev_update_window (‘off’) dev_close_window () dev_open_window (0, 0, 512, 512, ‘black’, WindowID) set_d…

浙南联合训练赛20180414

这次题目的代码都不长,CF的一贯风格 A - Game CodeForces - 513A Two players play a simple game. Each player is provided with a box with balls. First players box contains exactly n1 balls and second players box contains exactly n2balls. In one move…

Gym 100090D Insomnia

从 n 变到 1&#xff0c;有多少种方案&#xff1f; 打表记忆化。 1 #include <bits/stdc.h>2 3 using namespace std;4 5 int n;6 int dp[1000005];7 int dfs(int n) {8 if(n1)9 return 1; 10 if(dp[n]>0) 11 return dp[n]; 12 int cnt0;…

IP/TCP/UDP/RTP/RTCP 包结构图

IP 包头结构: TCP 包头结构: UDP 包头结构: RTP 包头结构: RTCP 包头结构:

webservices系列(二)——JAX-WS文件上传下载

新建ImgData类&#xff0c;存放文件javabean DataHandler&#xff1a;使用这个类型存放文件 XmlRootElement(name"ImaData") XmlAccessorType(XmlAccessType.FIELD) public class ImgData {private Integer id;XmlMimeType("application/octet-stream")pri…

halcon sobel边缘检测sobel_amp

目录sobel_amp&#xff08;算子&#xff09;描述参数sobel_amp&#xff08;算子&#xff09; sobel_amp - 使用Sobel算子检测边缘&#xff08;幅度&#xff09;。 sobel_amp&#xff08;图片&#xff1a;边缘图像&#xff1a;滤波器方式&#xff0c;掩膜大小:) 描述 sobel_…

es中的一些知识点记录

1. forcemerge接口 强制段合并&#xff0c;设置为1时&#xff0c;是期望最终只有1个索引段。但实际情况是&#xff0c;合并的结果是段的总数会减少&#xff0c;但仍大于1&#xff0c;可以多次执行强制合并的命令。 设置的的目标值越小。合并消耗的时间会越久。 curl -XPOST htt…

通过border来实现各种三角符号

很长时间没有动笔了&#xff0c;最近学的东西很杂很乱&#xff01;又有点丢了西瓜捡芝麻&#xff0c;走马观花&#xff0c;瞻前顾后的感觉&#xff01; 因此&#xff0c;我决定一步步来&#xff0c;化繁为简&#xff0c;今天就从border入手。 很多时候我们都会需要一个三角形或…

MFC封装API

一、Win32Application Architecture 一个Win32 Application Architecture的代码结构如下&#xff1a; LRESULT CALLBACK WinWordsProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); //定义回调处理消息函数 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPr…

4.10下午

转载于:https://www.cnblogs.com/yanyuying/p/6690662.html

halcon sobel 边缘检测 sobel_dir

目录sobel_dir&#xff08;算子&#xff09;描述参数sobel_dir&#xff08;算子&#xff09; sobel_dir - 使用Sobel算子检测边缘&#xff08;振幅和方向&#xff09;。 sobel_dir(Image : EdgeAmplitude, EdgeDirection : FilterType, Size : ) 描述 sobel_dir计算图像的一…