关于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中一致,不然解的出才怪

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

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

相关文章

AngualrJS之服务器端通信

译自《AngularJS》 与服务器通信 目前,我们已经接触过下面要谈的主题的主要内容,这些内容包括你的Angular应用如何规划设计、不同的angularjs部件如何装配在一起并正常工作以及AngularJS中的模板代码运行机制的一小部分内容。把它们结合在一起&#xff0…

硬盘显示容量和实际容量不符合_买移动固态硬盘纠结大半天?花2分钟看完这篇,购买时不再被坑...

如今移动硬盘已成为很多办公用户标配的物品,纵观整个移动硬盘市场,主要有移动机械硬盘和移动固态硬盘两种类型,前者容量大,价格较亲民;而后者具备了轻薄、读写速度快、耐振动不怕摔等优点。不少追求高效率的用户&#…

【Python基础入门系列】第10天:Python 类与对象

首先,我已经假定你是个萌新或已经看了无数遍的垃圾文章,然后依然搞不懂类和对象,但是呢起码知道有类和对象这么两个玩意儿,我觉得有必要找一篇生动形象的示例来讲解。 由于你可能没有编程经验, 所以无法从学过的编程…

数字电子技术课程设计之基于触发器的三位二进制同步减法计数器无效态000/110

基于触发器的三位二进制同步减法计数器无效态000/110 1 课程设计的目的与作用 掌握用multisim 的电路仿真程序 熟悉同步计数器工作原理和逻辑功能 熟悉计数器电路的分析和设计方法 掌握161 芯片集联成任意进制同步加法计数器 2 设计任务 三位二进制减法计数器(无…

SUSE11 搭建iscsi target 配置

https://www.suse.com/documentation/sles11/stor_admin/data/sec_inst_system_iscsi_target.html#sec_inst_system_iscsi_target_manual https://www.novell.com/support/kb/doc.php?id7001308 http://scst.sourceforge.net/comparison.html转载于:https://www.cnblogs.com/b…

图像、帧、片、NALU(firstime)

图像、帧、片、NALU 是学习 H.264 的人常常感到困惑的一些概念,我在这里对自己的理解做一些阐述,欢迎大家讨论:H.264 是一次概念的革新,它打破常规,完全没有 I 帧、P帧、B 帧的概念,也没有 IDR 帧的概念。对…

【Python的黑魔法】实例方法、静态方法和类方法

class Bird:# classmethod修饰的方法是类方法classmethoddef fly (cls):print(类方法fly: ,cls)# staticmethod修饰的方法是静态方法# staticmethoddef info (p):print(静态方法info: , p)if __name__ __main__:# 调用类方法,Bird类会自动绑定到第一个参数Bird.fl…

基于dreamweaver软件设计和开发一网站_基于 abp vNext 和 .NET Core 开发博客项目 Blazor 实战系列(一)...

系列文章使用 abp cli 搭建项目给项目瘦身,让它跑起来完善与美化,Swagger登场数据访问和代码优先自定义仓储之增删改查统一规范API,包装返回模型再说Swagger,分组、描述、小绿锁接入GitHub,用JWT保护你的API异常处理和…

CSS边框,背景,边距,溢出

CSS边框,背景,边距,溢出 css边框属性 border:宽度 样式 颜色; border-color; border-style; 边框样式:solid实现,dotted点状线,dashed虚线CSS3的样式 border-radius:圆角处理 box-shadow: x轴偏移 y轴偏移 模糊度 扩散成都 颜色…

LINUX 内存使用情况

# free 显示结果如下: Mem:表示物理内存统计 total 内存总数 8057964KBused 已使用的内存 7852484KBfree 空闲的内存数 205480KBshared 当前已经废弃不用,总是0buffers Buffer 缓存内存数: 290432KBcached Page 缓存内存数:5735024KB(存在关…

vagrant系列教程(四):vagrant搭建redis与redis的监控程序redis-stat(转)

阅读目录 下载redis解压redis编译安装redis配置redisredis开机自启动系统参数的调整上一篇php7环境的搭建 真是火爆,仅仅两天时间,就破了我之前swagger系列的一片文章,看来,大家对搭建环境真是情有独钟。 为了访问量,我…

sps及pps在解码器内传递过程

首先解码器中有一个全局变量seq_parameter_set_rbsp_t SeqParSet[MAXSPS];// MAXSPS32,它是一个指向序列参数集的数组。还有一个全局变量seq_parameter_set_rbsp_t *active_sps;主要为后续解码所用。解码器先将码流中的数据读入临时指针sps,之后存入全局…

【技术分享】Ubuntu下使用微信教程

做后端开发的同学用的Linux(ubuntu),肯定会因为没有适配微信版本会感觉不太舒服,很多时候因为缺少一些办公通讯软件而感到不便。现在已经有很方便的Wine WeChat方案,但是微信在Wine上配置还有许多bug,今天在github上看…

python join函数_Python join()函数

原博文 2016-08-12 10:16 − 今天写python 100例时,有个题目是大致是这样的:已知输入形式是1321,要求输出形式为1123 一开始思路是将输入的字符串用split()函数划分成数组,在对数组进行排序,再用for循环输出 代码附上&…

CSS中的盒子

盒子 盒子模型解释元素在页面中显示成一个方块,类似一个盒子,CSS盒子模型就是使用现实中盒子来做比喻,帮助我们设置元素对应的样式。盒子模型示意图如下: 把元素叫做盒子,设置对应的样式分别为:盒子的边框…

分享Kali Linux 2017年第17周镜像文件

分享Kali Linux 2017年第17周镜像文件 Kali Linux官方于4月23日发布2017年的第17周镜像。这次维持了11个镜像文件的规模。默认的Gnome桌面的4个镜像,E17、KDE、LXDE、MATE、XFCE桌面的各一个,手机版的包括ARMEL和ARMHF。有最近要安装Kali Linux系统的&am…

Djang重新整理migrations,解决:Django Table xxx already exist

在开发过程中,由于需求变更或者自我重构,需要清理migrations,以保持代码整洁和后续的可维护性。 场景一 不考虑数据库数据表,可以完全清空数据库里面的表的数据。 步骤: 删除所有migrations find . -path "/migr…

安全随笔2:对称加密应用场景

MD5或者说HASH值是一种不可逆的算法。如果需要从密文还原成明文,那么就需要对称和非对称这两类可逆算法。 首先,简单介绍下这两类算法。图9-1是对称算法的示意图: 图9-1 对称算法 在对称算法中,首先需要发送方和接收方协定一个密钥…

python安装多久_python安装与使用

1、进入官网下载python软件 python-3.4.4.amd64.msi http://www.python.org/download/ 这个软件包含三个环境,如下图:2、双击安装软件 3、设置环境变量path";C:\Python34"; 4、验证是否安装成功 进入cmd中,输入python,如果出现如下…

HADAMARD变换

for (j0;j<16;j) { for (i0;i<16;i) { M1[ i ][j]imgY_org[img->opix_yj][img->opix_xi]-img->mprr_2[k][j][ i ]; 计算当前宏块残差块 M0[i%4][i/4][j%4][j/4]M1[ i ][j]; } } current_intra_sad_20; //…