转:关于H264通过RTP传输的打包方式

Q:现在小弟初次尝试H264的编码通过RTP方式传输,具体实验环境的问题如下:

环境:
服务器端,H264的帧数据(可能超过64k),分成N个1460字节的包,然后加上RTP头发送。
客户端,VLC播放器,通过RTSP协议建立连接,然后接收数据解码播放。
结果:
VLC不能解码接收到的数据,解码出错,VLC的信息中显示不能解码帧数据。
我已经阅读了一遍rfc3984的文档,对里面的如何进行打包和用rtp传输不是非常理解,希望各位大虾能够帮小弟一把,告诉小弟这些和H264的帧该如何发送,该如何分包,该如何加头信息等等。
(其中看到FUs的方式好像适合分包发送,因为小弟的数据帧可能超过64k,所以忘大虾们能够仔细解释一下对于小弟这种情况下的RTP传输)

A:我觉得所有的问题在 RFC3984 里面都已经说得很清楚了。不知道你有哪点不懂,请具体提出来。

Q:斑竹好,我这边是用VLC和服务器端进行通讯的,他们是用RTSP协议建立 开始时的连接的,服务器返回DISCRIBERS请求的SDP和下面描述的相同,我使用的packetization-mode=1,即FU-As方式打 包,因为我这边上来的数据帧可能超过64k数据。能否麻烦斑竹看看我这边的SDP写的是否正确。
SDP:
v=0
o=- 1 1 IN IP4 127.0.0.1
s=VStream Live
a=type:broadcast
t=0 0
c=IN   IP4 0.0.0.0
m=video 49170 RTP/AVP 99
a=rtpmap:99 H264/90000
a=fmtp:99 profile-level-id=42A01E; packetization-mode=1; sprop-parameter-ets=Z0IACpZTBYmI, aMljiA==
a=control:trackID=0

还有就是在RTP发送时,我打好包的数据方式如下面所示:
上来的帧数据为:NALU头+EBSP数据
因为帧数据大于1460字节,所以我把数据分为N个不大于1460字节的包,每个包前面加上RTP头发出去。
其 中NALU头的数值I帧为0x65,参数集为0x67和0x68,这个值是不是有点错误,我看RFC3984上面说的好像和我现在的有点不 同,RFC3984上面说FU-As方式打包类型值为28,我不知道这个是否十进制的,如果按照RFC3984上说的NALU头应该是多少?还是用FU- As方式的FU indicator代替原来的NALU头。
还有这个FU-As方式的头好像是有两个值,一个是FU indicator,另外一个是FU header,这两个值我应该填写什么?

按照我现在填写的内容,VLC会出现解不出码的情况,希望斑竹可以帮我回答的细致一点。谢谢了。

A:我觉得 RFC3984 上面说得非常清楚啊。
首先你把一个 NALU 的 EBSP 根据需求拆分为多个包,例如 3 个,则:

第一个 FU-A 包的 FU indicator 应该是:F = NALU 头中的 F;NRI = NALU 头中的 NRI;Type = 28。FU header 应该是:S = 1;E = 0;R = 0;Type = NALU 头中的 Type。

第二个 FU-A 包的 FU indicator 应该是:F = NALU 头中的 F;NRI = NALU 头中的 NRI;Type = 28。FU header 应该是:S = 0;E = 0;R = 0;Type = NALU 头中的 Type。

第三个 FU-A 包的 FU indicator 应该是:F = NALU 头中的 F;NRI = NALU 头中的 NRI;Type = 28。FU header 应该是:S = 0;E = 1;R = 0;Type = NALU 头中的 Type。

Q:版主,我按照你的方式分好包发送了,发现VLC不会出现不能解帧的情况了, 但是,还是出不来图像。我想可能是因为发送序列参数集和图像参数集的方法不对,他们两个的长度都很小,只要一个包就可以了,我现在将他们按照singal NALU的方式发送,就是直接在NALU包前加一个RTP的头,然后发出去。
是不是我这样发参数集存在着问题,反正我这边VLC是解不了这个参数集,因为参数集解不了,所以下面的帧肯定解不了,所以出不了图像。
麻烦版主再解释一下如何发参数集。

A:今天刚接受了流媒体的相关培训。懂得看你的   SDP 了。

对 于你的问题,不知道 SPS、PPS 打包是否有问题。按照 RFC3984,而且感觉你打单一包的方式也是错的。我希望你能通过自己学习的方式去把这个问题弄清楚,因为 RFC3984 里面说得很清楚,请你自己学习学习 RFC3984 吧。既然你在做这个工作,还是应该仔细学习一下 RFC3984。

另外, SDP 中的 sprop-parameter-ets=Z0IACpZTBYmI 实际就是 SPS 和 PPS 的 BASE64 转码,你不用在码流中再传输 SPS/PPS,直接从 SDP 就可以得到。

A2:1.SDP中已经包括SPS&PPS,码流中完全可以不用传输SPS&PPS
2. profile-level-id=42A01E,这是SPS的开头几个字节,剩下的在sprop-parameter- ets=Z0IACpZTBYmI, aMljiA==中,BASE64编码,把“Z0IACpZTBYmI, aMljiA==”反BASE64转换回去,应该刚好是SPS&PPS的内容
3. 打包注意,要求H.264码流不是byte stream格式的,即没有0x000001分隔,也没有插入0x03,具体如何生成,检查你的编码器选项。
4. packetization-mode=1模式下,要求每个RTP中只有一个NAL单元,或者一个FU,不分段的NAL不做任何修改,直接作为RTP负 载;分段的NAL注意,NAL头不传输,有效负载从NAL头之后开始,根据NAL头的信息生成FU的头两个字节(相当于NAL头拆为两部分),具体生成方 式版主已经讲得很清楚。
5. RTP的payload type要与SDP中一致,不然解的出才怪

时间: 2024-12-17 02:17:17

转:关于H264通过RTP传输的打包方式的相关文章

H264 NAL RTP打包

1. 网络抽象层单元类型 (NALU) NALU是H264用于网络传输的单元类型,一个完整的NALU单元一般是以0x000001或者0x00000001开始,其后跟的则是NALU头和NALU的数据:我们在网络传输的时候,会去掉开始的0x000001或者0x00000001的标志:一般需要将这些标志替换为RTP payload的头部(1个字节): 其中NALU数据就是RBSP数据: NALU 头由一个字节组成, 它的语法如下: +---------------+ |0|1|2|3|4|5|6|7|

(转)live555学习笔记9-h264 RTP传输详解(1)

九 h264 RTP传输详解(1) 前几章对Server端的介绍中有个比较重要的问题没有仔细探究:如何打开文件并获得其SDP信息.我们就从这里入手吧. 当RTSPServer收到对某个媒体的DESCRIBE请求时,它会找到对应的ServerMediaSession,调用ServerMediaSession::generateSDPDescription().generateSDPDescription()中会遍历调用ServerMediaSession中所有的调用ServerMediaSubse

Live555中RTP包的打包与发送过程分析

这里主要分析一下,live555中关于RTP打包发送的部分.在处理完PLAY命令之后,就开始发送RTP数据包了(其实在发送PLAY命令的response包之前,就会发送一个RTP包,这里传输就已经开始了) 先介绍下主要的流程:RTP包的发送是从MediaSink::startPlaying函数调用开始的,在StartPlaying函数的最后会调用函数continuePlaying. continuePlaying函数是定义在MediaSink类中的纯虚函数,需要到特定媒体的sink子类中实现,对

【转】对H264进行RTP封包原理

1. 引言     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 视频进行流式打包传输

maven的两种可运行jar打包方式。1、内置依赖,2、外部依赖。

maven打可运行jar包的两种方式 maven常用的普通打包方式分为pom,jar,war等,至于这些打包类型就不介绍啦. 如果不进行特殊配置,那么打包出来的jar包是不可运行的.只能当作普通依赖包使用. 下面就介绍两种maven打可运行jar包的方式: 方式一:内置打包法 <plugins> <!-- 内置打包法 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <!-- 

真有用?Snap和Flatpak 通吃所有发行版的打包方式。

导读 最近我们听到越来越多的有关于Ubuntu的Snap包和由Red Hat员工Alexander Larsson创造的 Flatpak (曾经叫做 xdg-app)的消息.这两种下一代打包方法在本质上拥有相同的目标和特点:即不依赖于第三方系统功能库的独立包装.这种 Linux 新技术方向似乎自然会让人脑海中浮现这样的问题:独立包的优点/缺点是什么?这是否让我们拥有更好的 Linux 系统?其背后的动机是什么?为了回答这些问题,让我们先深入了解一下 Snap 和 Flatpak. 动机 根据Fl

Android几种常见的多渠道(批量)打包方式介绍

多渠道打包,主要是为了统计不同的渠道上包的下载数量,渠道越多,我们需要打的包数量越多,这个时候,我们没法去使用单纯的手动打包去一个一个的生成不同的渠道包,我们需要更高效的打包方式. 声明渠道方式一: 通常我们区分渠道都是在我们manifest 文件的 application 用这样来定义渠道信息: <meta-data android:name="UMENG_CHANNEL" android:value="360"/> 然后在我们的Java 代码中,我们

Android 多渠道打包方式详解

Android 多渠道打包方式详解 面试的时候,如果面试官突然问到:你们渠道包是怎么打的?如果你说是用gradle一个一个编译的,然后他很鄙视的说这个效率太低啦,你们写过什么脚本自己打渠道包没?你肯定心里想,卧槽,这么狂炫吊炸天,自己写脚本打包?!其实这个根本也不是太难啦!!今天就来聊聊多渠道打包的原理以及如何自己DIY多渠道打包的工具! 渠道包出现 当一个产品到发版的时候,我们搞Android的就会面临一个超级尴尬的问题:国内这么多的渠道,渠道统计是必须做滴,那么十多个主要渠道再加无限量的地推

delphi文件打包方式(将多个文件编译到一个单元中)

delphi文件打包方式 在Delphi项目中,通常有一个和项目名称主文件名相同的.RES文件,该文件用于保存应用程式图标等资源,对应于此文件,在项目文件中一定含有编译指示“{$R *.res}”,告诉编译器编译时需要包含和项目主文件名相同的.RES文件.同样,如果需要在应用程式中以资源形式包含所有文件类型,也能利用.RES文件.本文将告诉你怎么利用RES文件在Delphi程式内部包含文件. 一创建.RES文件 这里以一组音频文件为例.首先用记事本等所有文本编辑器编写文件“MyMusic.RC”