转自:http://blog.csdn.net/jychen105/article/details/47012099

一、H264是如何通过rtsp发送的

简单来说,H264就是通过打包到rtp协议的数据部分发送出去的。

H264打包成rtp数据包有三种方式

  • 单一封包模式
  • 组合封包模式
  • 分片模式

    要想弄明白这三种打包方式,必须先弄清楚h264的组成结构,或者叫组成单元。

二、H264结构单元

H264数据流最基本的结构单元叫nalu单元。

H264的nalu单元组成:

[start code] + [nalu header] + [nalu paload]
  • start code: 可以为 001 或者 0001, 也就是点3个字节或者4个字节

  • nalu header: 占一个字节

  • nalu paload: 长度不定

每一帧画面拥有一个或多个nalu单元,每个nalu单元以start code进行分离

nalu header

nalu header占一个字节,它又分了三个部分:F,NRI,TYPE

7 6-5 4-0
F NRI TYPE
  • F:一般为0
  • NRI:指示nalu单元的重要性,不同编码器编出来的H264数据不同
  • TYPE:nalu类型

TYPE类型:

类型 定义
0 未定义
1-23 NAL单元
24 STAP-A 单一时间组合包
25 STAP-B 单一时间组合包
26 MTAP-16 多个时间组合包
27 MTAP-24 多个时间组合包
28 FU-A 分片
29 FU-B 分片
30-31 未定义

特别注意的是7这SPS,8为PPS,发送SDP协议包时需进行base64编码 
25,26,27,29这四种类型基本不会出现

三、H264的RTP打包

前面说过有三种打包方式:单一封包模式,组合封包模式,分片模式

打包原则

单一封包模式: nalu单元长度小于MTU长度(通常是1500,live555定义的是2400)用此种方式封包 
组合封包模式: nalu单元实在太小,多个nalu长度和都小于MTU长度 
分片模式:nalu单元长度大于MTU长度

以上封包模式是按nalu长度来分的,同时也完全符合nalu单元中TYPE类型来分。 
TYPE1-23 单一封包,24组合封包, 28分片封包

打包细则

单一封包:

[RTP header] + [nalu header] + [nalu payload]

组合封包:

[RTP header]+[STAP-A头(1字节,低5位为24)] +
[第1个nalu长度(2字节)] + [第1个nalu header] + [第1个nalu payload]+
[第2个nalu长度(2字节)] + [第2个nalu header] + [第2个nalu payload]+
[第N个nalu长度(2字节)] + [第N个nalu header] + [第N个nalu payload]

分片模式封包:

此时要切分成多个RTP包

[RTP header]+[FU Indicator(1字节)]+[FU header(1字节)]+[部分nalu payload]

FU Indicator

7 6-5 4-0
F NRI TYPE

F, NRI为nalu中的F,NRI 
TYPE:固定为28

FU header

7 6 5 4-0
S E R TYPE

S:开始标志(start)

E:结束标志(end)

R:保留(reserve)

TYPE: nalu中的TYPE

标志 S E R
分片开始 1 0 0
分片中间 0 0 0
分片结束 0 1 0

RTP包头的填充

typedef struct
{
/* byte 0 */
unsigned char csrc_len:4; /* CC expect 0 */
unsigned char extension:1; /* X expect 1, see RTP_OP below */
unsigned char padding:1; /* P expect 0 */
unsigned char version:2; /* V expect 2 */ /* byte 1 */
unsigned char payload:7; /* PT RTP_PAYLOAD_RTSP */
unsigned char marker:1; /* M expect 1 */ /* byte 2,3 */
unsigned short seq_no; /*sequence number*/ /* byte 4-7 */
unsigned long timestamp; /*time stamp*/ /* byte 8-11 */
unsigned long ssrc; /* stream number is used here. */
} RTPHeader;/*12 bytes*/

各项值填充:

符号 位数 定义 数值
V 2bit 版本号 2
P 1bit 填充位 0
X 1bit 扩展位 0
CC 4bit CSRC数目 0
M 1bit 标志位 单一封包为1; 分片封包最后一个包为1,其余为0;
PT 7bit 载荷类型 96(h264为96)
SeqNum 16bit 序列号 每发一个包加1
Timestamp 32bit 时间戳 单一封包 +采样率,h264为3600; 分片封包第一个加采样率,后续不变
SSRC 32bit 同步源标识 任意指定,标准是一个MD5算法值,未明
CSRC 0bit 贡献源列表 CC为0,所以此项没有

组合模式的M跟Timestamp未调查清楚,但是可以讨巧,打包的时候不采用组合模式,采用单一模式。

版权声明:本文为博主原创文章,转载请注明出处 http://blog.csdn.net/jychen105/article/details/47012099

从零开始写一个发送h264的rtsp服务器(下)的更多相关文章

  1. 从零开始写一个发送h264的rtsp服务器(上)

    转自:http://blog.csdn.net/jychen105/article/details/47006345 一.什么是RTSP 通常所说的rtsp协议其实包含三个协议: rtsp协议, rt ...

  2. 从零开始写一个Tomcat(贰)--建立动态服务器

    上文书说道如何通过http协议建立一个静态的服务器来访问静态网页,但我们选择tomcat最主要的原因还是因为它能动态的执行servlet,这边文章将引导你实现一个能够运行servlet的服务器,这个简 ...

  3. 从零开始写一个Tomcat(叁)--请求解析

    挖坑挖了这么长时间也该继续填坑了,上文书讲到从零开始写一个Tomcat(贰)--建立动态服务器,讲了如何让服务器解析请求,分离servlet请求和静态资源请求,读取静态资源文件输出或是通过URLCla ...

  4. 深入浅出React Native 3: 从零开始写一个Hello World

    这是深入浅出React Native的第三篇文章. 1. 环境配置 2. 我的第一个应用 将index.ios.js中的代码全部删掉,为什么要删掉呢?因为我们准备从零开始写一个应用~学习技术最好的方式 ...

  5. 用ASP.Net写一个发送ICQ信息的程序

    用ASP.Net写一个发送ICQ信息的程序 这里我给大家提供一个很实用的例子,就是在线发送ICQ信息.想一想我们在网页上直接给朋友发送ICQ信息,那是多么美妙的事情啊.呵呵,在吹牛啊,其实ICQ本来就 ...

  6. 从零开始写一个武侠冒险游戏-0-开发框架Codea简介

    从零开始写一个武侠冒险游戏-0-开发框架Codea简介 作者:FreeBlues 修订记录 2016.06.21 初稿完成. 2016.08.03 增加对 XCode 项目文件的说明. 概述 本游戏全 ...

  7. 2019-5-24-WPF-源代码-从零开始写一个-UI-框架

    title author date CreateTime categories WPF 源代码 从零开始写一个 UI 框架 lindexi 2019-05-24 15:54:36 +0800 2018 ...

  8. 从零开始写一个武侠冒险游戏-8-用GPU提升性能(3)

    从零开始写一个武侠冒险游戏-8-用GPU提升性能(3) ----解决因绘制雷达图导致的帧速下降问题 作者:FreeBlues 修订记录 2016.06.23 初稿完成. 2016.08.07 增加对 ...

  9. 从零开始写一个武侠冒险游戏-7-用GPU提升性能(2)

    从零开始写一个武侠冒险游戏-7-用GPU提升性能(2) ----把地图处理放在GPU上 作者:FreeBlues 修订记录 2016.06.21 初稿完成. 2016.08.06 增加对 XCode ...

随机推荐

  1. findHomography和perspectiveTransform

    opencv中的两个函数,之前一直不明白这俩函数到底是要干嘛的. 得到两帧图像中的特征点后,就可以用findHomography得到单应性矩阵. 得到单应性矩阵后,可以 (1)根据相应的计算方法,由前 ...

  2. Centos7下yum安装zabbix-server的部署(一)

    一.环境准备 OS:CentOS 7.2 64bit Zabbix版本:3.0.12 MySQL版本:5.6 hostname ip 主机用途zabbix-server 10.0.0.44 服务端 z ...

  3. CentOS 7命令行安装图形界面(GNOME、KDE等)

    CentOS 7 默认是没有图形化界面的,但我们很多人在习惯了 Windows 的图形化界面之后,总是希望有一个图形化界面从而方便我们使用,这里介绍一下 CentOS7安装图形化桌面系统的方法. 一. ...

  4. SpringMVC JSON数据交互

    本节内容: @RequestBody @ResponseBody 请求json,响应json实现 前端可以有很多语言来写,但是基本上后台都是java开发的,除了c++(开发周期长),PHP和#Net( ...

  5. 一份可以发布jar包到MAVEN中央仓库的POM

    [2017-01-03 更新]将基础的pom抽离成一个项目无关的parent pom,euler-framework的pom继承这个parent pom 今天在家折腾了一下怎么把Jar包发布到Mave ...

  6. 【BZOJ】4380: [POI2015]Myjnie

    题解 区间dp,先离散化所有价值 \(f[i][j][k]\)表示\([i,j]\)区间里最小值为\(k\)的价值最大是多少 只考虑\(i <= a <= b <= j\)的区间,枚 ...

  7. 【LOJ】#2075. 「JSOI2016」位运算

    题解 压的状态是一个二进制位,我们规定1到n的数字互不相同是从小到大,二进制位记录的是每一位和后一个数是否相等,第n位记录第n个数和原串是否相等,处理出50个转移矩阵然后相乘,再快速幂即可 代码 #i ...

  8. 【Java】快速排序的非递归实现

    快速排序一般采用递归方法(详见快速排序及其优化),但递归方法一般都可以用循环代替.本文实现了java版的非递归快速排序. 更多:数据结构与算法合集 思路分析 采用非递归的方法,首先要想到栈的使用,通过 ...

  9. django model 条件过滤 queryset.filter(**condtions) 用法

    1.下述代码查询model对应数据库中日期等于2018-05-22的数据: queryset = model.objects.all() condtions: {'date': '2018-05-22 ...

  10. 初识thinkphp(1)

    作为一名准备成为CTF里WEB狗的萌新,在做了3个月的CTF的web题后,发现自己php代码审计非常不过关,并且web的架构模式条理也十分的不清晰,于是抱着提高代码审计能力的态度在近期会去写一个简单的 ...