1.PS封装介绍
MPEG2-PS是一种多路复用数字音频,视频等的封装容器。PS是Program Stream(程序流或节目流)的简称。程序流
将一个或多个分组但有共同的时间基准的基本数据流(PES)合并成一个整体流。它是为可靠稳定的储存媒介如光盘
而设计的。
一般来说,采用MPEG2-HD格式的高清数码摄像机一般以"MPEG2-PS"来保存文件;而采用AVCHD格式的高清摄像机则
通常以".M2TS"或".MTS"保存文件。

此处介绍的PS封装方式需要支持MPEG2/MPEG4/H.264等视频和MPEG系列音频,可以被大部分支持ps和相应元素流解码
的播放器正常播放,支持在多个层次加入私有数据,方便解码,拖动和减少延时。
具体可参考《ISO.IEC-13818-1》
1).名词解释
PES:Packetized Elementary Stream,封装元素流,PS数据的基本单位。
GOP:Group Of Picture,图像组,一般指I帧及其后面依靠该I帧编码的其他帧。
PSH:Program Stream pack Header ,是PS包的包头,主要包含系统时间信息。
//PSM:program stream map,节目流映射提供了关于节目流中原始流以及它们之间相互关系的描述。作为一个PES分组出现。

2).PS流的基本结构:
PS GOP|PS GOP|PS GOP
其中PS GOP包含:
Video I Frame|Audio Frames|Private Data|...|Video P/B Frame|...
其中Video I Frame包含:
PSH|PSM|Video PES|Video PES|...
其中Video P/B Frame包含:
PSH|Video PES|Video PES|...
其中Video PES包含:
PES Header|PES Payload
其中Audio Frames包含:
Audio PES|Audio PES|...

3).PS 封装
PS 封装按照ISO.IEC-13818-1标准
针对H264 做如下PS 封装:每个IDR NALU 前一般都会包含SPS、PPS 等NALU,因此将SPS、PPS、IDR 的NALU 封装为一个PS 包,包括ps 头,然后加上PS system header,PS system map,PES header+h264 raw data。
所以一个IDR NALU PS 包由外到内顺序是:PSheader| PS system header | PS system Map | PES header | h264 raw data。对于其它非关键帧的PS 包,就简单多了,直接加上PS头和PES 头就可以了。
顺序为:PS header | PES header | h264raw data。以上是对只有视频video 的情况,如果要把音频Audio也打包进PS 封装,也可以。
当有音频数据时,将数据加上PES header 放到视频PES 后就可以了。顺序如下:PS 包=PS头|PES(video)|PES(audio),再用RTP 封装发送就可以了。

GB28181 对RTP 传输的数据负载类型有规定(参考GB28181 附录B),负载类型中96-127,RFC2250 建议96 表示PS 封装,建议97 为MPEG-4,建议98 为H264
即我们接收到的RTP 包首先需要判断负载类型,若负载类型为96,则采用PS 解复用,将音视频分开解码。若负载类型为98,直接按照H264 的解码类型解码。
注:此方法不一定准确,取决于打包格式是否标准

PS 包中的流类型(stream type)的取值如下:
a、 MPEG-4 视频流: 0x10;
b、 H.264 视频流: 0x1B;
c、 SVAC 视频流: 0x80;
d、 G.711 音频流: 0x90;
e、 G.722.1 音频流: 0x92;
f、 G.723.1 音频流: 0x93;
g、 G.729 音频流: 0x99;
h、 SVAC音频流: 0x9B。

2.PS 封装各个部分详细介绍
1).PSH PSheader
PSheader是一个PS包的包头,主要包含系统同步时间。
I、 Pack start code:包起始码字段,值为0x000001BA的位串,用来标志一个包的开始。
II、 System clock reference base,system clock reference extenstion:系统时钟参考字段。
III、 Pack stuffing length :包填充长度字段,3 位整数,规定该字段后填充字节的个数
如下图1:

80 60 53 1f 00 94 89 00 00 0000 00 00 00 01 ba €`S..??........?
7e ff 3e fb 44 01 00 5f 6b f8 00 00 01 e0 14 53 ~.>?D.._k?...?.S
80 80 05 2f bf cf bed1 1c 42 56 7b 13 58 0a 1e €€./????.BV{.X..
08 b1 4f 33 69 35 0453 6d 33 a8 04 15 58 d9 21 .?O3i5.Sm3?..X?!
9741 b9 f1 75 3d 94 2b 1f bc 0b b2 b4 97 bf 93 ?A??u=?+.?.?????

前12位是RTP Header,这里不再赘述;
000001ba是包头起始码;
接下来的9位包括了SCR,SCRE,MUXRate,具体看上图
最后一位是保留位(0xf8),定义了是否有扩展,二进制如下
1111 1000
前5位跳过,后3位指示了扩展长度,这里是0.

海康定义的PS流子集中,stuffing_byte为6字节,其后4字节存放当前帧的帧号。
00 00 01 BA 46 9B 4E 47 C4 01 01 47 B3 FE FF FF
00 03 23 EA(帧的帧号)

2).PS system header 系统标题
如下图2:

Systemheader当且仅当pack是第一个数据包时才存在,即PS包头之后就是系统标题。取值0x000001BB的位串,指出系统标题的开始,暂时不需要处理,读取Header Length直接跳过即可。

3).PS system Map 节目映射流(PSM)
Systemheader当且仅当pack是第一个数据包时才存在,即系统标题之后就是节目流映射。取值0x000001BC的位串,指出节目流映射的开始,暂时不需要处理,读取Header Length直接跳过即可。前5字节的结构同系统标题,见上图。

取一段码流分析系统标题和节目映射流
00 00 01 ba 45 a9 d4 5c 34 0100 5f 6b f8 00 00 ...?E??\4.._k?..
01 bb 00 0c 80 cc f5 04 e1 7f e0 e0 e8 c0 c0 20 .?..€??.?.?????
00 00 01 bc 00 1e e1 ff00 00 00 18 1b e0 00 0c ...?..?......?..
2a 0a 7f ff 00 00 0708 1f fe a0 5a 90 c0 00 00 *........??Z??..
00 00 00 00 00 00 01 e0 7f e0 80 80 0521 6a 75 .......?.?€€.!ju

前14个字节是PS包头(注意,没有扩展);
接下来的00 00 01 bb是系统标题起始码;
接下来的00 0c说明了系统标题的长度(不包括起始码和长度字节本身);
接下来的12个字节是系统标题的具体内容,这里不做解析;
继续看到00 00 01 bc,这是节目映射流起始码;
紧接着的00 1e同样代表长度;
跳过e1 ff,基本没用;
接下来是00 00,自定义的复合流描述的长度,为0表示后面没有否则
后面跟着就是自定义的描述内容(海康在这里放入了复合流的私有描述:
两字节复合流描述字(40 0E)+内容(用于放置全局时间,编码设备型号等相关信息)+
两字节复合流描述字(41 12)(可选)+内容(用于描述设备与通道号),
所以长度就不是00 00)

接下来是00 18,代表基本流长度,说明了后面还有24个字节
接下来的1b,stream type 意思是H264编码格式;
下一个字节e0,意思是视频流(stream id e0到ef表示视频);
接下里00 0c,同样代表接下的长度12个字节,表示的是元素流的自定义描述的长度,接下来
是对应长度的描述内容,这里一般是视频流的描述,以海康的为例,这里是;
两字节长度(00 10)+两字节视频描述字(42 0E)+内容(用于描述视频编码分辨率、帧率、是否场编码,B帧个数等信息)

跳过这12个字节,看到90,stream type 这是G.711音频格式;
下一个字节是c0,代表音频流(stream id c0到df表示音频);
接下来的00 00同样代表长度,这里是0,表示元素流的自定义(私有)描述长度,如果不为0后面跟着一般是音频流描述,;
不为0的情况以海康的为例:
两字节长度(00 0c)+两字节音频描述字(43 0A)+内容(用于描述音频编码的采样率,码率,帧长度,声道数等信息)

接下来4个字节是CRC,循环冗余校验。
到这里节目映射流解析完毕。

PSM节目流映射提供了关于节目流中原始流以及它们之间相互关系的描述:
I、复合流级私有描述(HIK PS私有),用于放置全局时间,编码设备型号等相关信息
II、元素流级私有描述(HIK PS私有,一般包含视频描述和音频描述两种),用于视频编码的分辨率、帧率、
是否场编码、B帧个数,帧间间隔、以及
音频编码的采样率、码率、帧长度、声道数等相关信息。

4).PES header PES分组头部
PES
Packetised Elementary Stream ,原始流分组。Elementary Stream,原始流,指的是视频或音频压缩编码后产生的比特数据,
而视频或音频原始流分别打包生成视频PES和音频PES。一个PES分组只包含一种原始流的编码数据。
如下图3:

别被这么长的图吓到,其实原理相同,但是,你必须处理其中的每一位。
1)Packet start code prefix:值为0x000001的位串,它和后面的stream id 构成了标识分组开始的分组起始码,用来标志一个包的开始。
2)Stream id:在节目流中,它规定了基本流的号码和类型。0x(C0~DF)指音频,0x(E0~EF)为视频,bf 私有,be 填充
3)PES packet length:16 位字段,指出了PES 分组中跟在该字段后的字节数目。值为0 表示PES 分组长度要么没有规定要么没有限制。这种情况只允许出现在有效负载包含来源于传输流分组中某个视频基本流的字节的PES 分组中。
4)PTS_DTS:2 位字段。当值为'10'时,PTS 字段应出现在PES 分组标题中;当值为'11'时,PTS 字段和DTS 字段都应出现在PES 分组标题中;当值为'00'时,PTS 字段和DTS 字段都不出现在PES分组标题中。值'01'是不允许的。
5)ESCR:1位。置'1'时表示ESCR 基础和扩展字段出现在PES 分组标题中;值为'0'表示没有ESCR 字段。
6)ESrate:1 位。置'1'时表示ES rate 字段出现在PES 分组标题中;值为'0'表示没有ES rate 字段。
7)DSMtrick mode:1 位。置'1'时表示有8 位特技方式字段;值为'0'表示没有该字段。
8)Additionalinfo:1 位。附加版权信息标志字段。置'1'时表示有附加拷贝信息字段;值为'0'表示没有该字段。
9)CRC:1 位。置'1'时表示CRC 字段出现在PES 分组标题中;值为'0'表示没有该字段。
10)Extensionflag:1 位标志。置'1'时表示PES 分组标题中有扩展字段;值为'0'表示没有该字段。
PES header data length: 8 位。PES 标题数据长度字段。指出包含在PES 分组标题中的可选字段和任何填充字节所占用的总字节数。该字段之前的字节指出了有无可选字段。

老规矩,上码流:
00 00 01 e0 21 33 80 80 05 2b 5f df 5c 95 71 84 ...?!3€€.+_?\?q?
aa e4 e9 e9 ec 40 cc17 e0 68 7b 23 f6 89 df 90 ?????@?.?h{#????
a9d4 be 74 b9 67 ad 34 6d f0 92 0d 5a 48 dd 13 ???t?g?4m??.ZH?.

00 00 01是起始码;
e0是视频流;
21 33 是帧长度;
接下来的两个80 80见下面的二进制解析;
下一个字节05指出了可选字段的长度,前一字节指出了有无可选字段;
接下来的5字节是PTS;
第7、8字节的二进制如下:
1000 0000 1000 0000

按顺序解析:
第7个字节:
10 是标志位,必须是10;
00 是加扰控制字段,‘00’表示没有加密,剩下的01,10,11由用户自定义;
0 是优先级,1为高,0为低;
0 是数据对齐指示字段;
0 是版权字段;
0 是原始或拷贝字段。置'1'时表示相关PES分组有效负载的内容是原始的;'0'表示内容是一份拷贝;
第8个字节:
10 是PTS_DTS字段,这里是10,表示有PTS,没有DTS;
0 是ESCR标志字段,这里为0,表示没有该段;
0 是ES速率标志字段,,这里为0,表示没有该段;
0 是DSM特技方式标志字段,,这里为0,表示没有该段;
0 是附加版权信息标志字段,,这里为0,表示没有该段;
0 是PESCRC标志字段,,这里为0,表示没有该段;
0 是PES扩展标志字段,,这里为0,表示没有该段;

3.私有信息扩展-IVS举例
PES Header|Private Data Header|Private data
其中,
Private Data Header包括:Private Data Type|Private Data Length
Private data以IVS Info举例:IVS Info Header|IVS Data

Private data type的定义如下:
0x0000 Reserved
0x0001 Basic Stream Info
0x0002 Codec Info
0x0003 IVS Info

IVS Info Header长度8byte,定义如下:
0x0000 Reserved
0x0001 MetaData
0x0002 EventData
0x0003 RuleData
0x0100 Face Identification
0x0101 Face Identification ATM

音视频处理之PS封装的介绍与使用20180928的更多相关文章

  1. 音视频处理之FFmpeg封装格式20180510

    一.FFMPEG的封装格式转换器(无编解码) 1.封装格式转换 所谓的封装格式转换,就是在AVI,FLV,MKV,MP4这些格式之间转换(对应.avi,.flv,.mkv,.mp4文件). 需要注意的 ...

  2. 音视频RTP数据包封装

    对于语音通信而言,语音码率较低,添加适当冗余是对抗网络丢包的常见方式.冗余方式有多种,包括RED,FEC等都是冗余的一种,如果冗余份数较多,可以采取交织的方式实现.RFC 3350是RTP的基础标准协 ...

  3. moviepy音视频开发:音频合成类CompositeAudioClip介绍

    ☞ ░ 前往老猿Python博文目录 ░ CompositeAudioClip是AudioClip的直接子类,用于将几个音频剪辑合成为一个音频剪辑.CompositeAudioClip类只有一个构造方 ...

  4. 音视频处理之FFmpeg程序的介绍与使用20180302

    一.FFMPEG程序介绍与使用 主要介绍一下ffmpeg工程包含的三个exe的使用方法. 1. FFMPEG程序介绍 1.1.下载 ffmpeg的官方网站是:http://ffmpeg.org/ 下载 ...

  5. moviepy音视频开发:音频合成类AudioArrayClip介绍

    ☞ ░ 前往老猿Python博文目录 ░ AudioArrayClip类是AudioClip的直接子类,用于从一个numpy音频数组构建音频剪辑.AudioArrayClip类只有一个构造方法,在构造 ...

  6. javaCV入门指南:调用FFmpeg原生API和JavaCV是如何封装了FFmpeg的音视频操作?

    通过"javaCV入门指南:序章 "大家知道了处理音视频流媒体的前置基本知识,基本知识包含了像素格式.编解码格式.封装格式.网络协议以及一些音视频专业名词,专业名词不会赘述,自行搜 ...

  7. FFmpeg命令行工具和批处理脚本进行简单的音视频文件编辑

    FFmpeg_Tutorial FFmpeg工具和sdk库的使用demo 一.使用FFmpeg命令行工具和批处理脚本进行简单的音视频文件编辑 1.基本介绍 对于每一个从事音视频技术开发的工程师,想必没 ...

  8. 融云携新版实时音视频亮相 LiveVideoStack 2019

    4 月 19 日,LiveVideoStack 2019 音视频大会在上海隆重开幕,全球多媒体创新专家.音视频技术工程师.产品负责人.高端行业用户等共襄盛会,聚焦音频.视频.图像.AI 等技术的最新探 ...

  9. Python音视频剪辑库MoviePy1.0.3中文教程导览及可执行工具下载

    ☞ ░ 前往老猿Python博文目录 ░ 一.简介 MoviePy是一个用于视频编辑的Python模块,可用于进行视频的基本操作(如剪切.拼接.标题插入).视频合成(也称非线性编辑).视频处理或创建高 ...

随机推荐

  1. 2017-2018-2 20155230《网络对抗技术》实验9:Web安全基础

    实践过程记录 下载wegot并配置好java环境后 输入java -jar webgoat-container-7.0-SNAPSHOT-war-exec.jar 在浏览器输入localhost:80 ...

  2. 使用Gzip压缩数据,加快页面访问速度

                 在返回的json数据量大时,启用Gzip压缩,可以提高传输效率.下面为Gzip压缩对json字符串压缩并输出到页面的代码. 一.代码 /** 向浏览器输出字符串响应数据,启用 ...

  3. CF434D Nanami's Power Plant

    就是切糕那道题,首先对每个函数连一串,然后\(x_u\leq x_v+d\)这个条件就是\(u\)函数\(i\)取值连向\(v\)函数\(i-d\)取值边权为inf,然后答案就是最小割了. #incl ...

  4. Java 多线程(二)之 Thread 优先级

    目录 Thread 中线程优先级相关属性 相关函数 优先级初始化 设置优先级 获取优先级 默认优先级 指定优先级 注意事项 优先级继承 @ Thread 中线程优先级相关属性 每个线程均有优先级,在 ...

  5. 3dmax2020下载安装3dmax2020破解中文版下载安装

    3dmax在室内设计.建筑设计领域是最专业的效果图制作软件,也是在游戏动画等领域中在场景方面最专业的软件,目前最新3dmax2020版本已出,我分享亲测好用的软件包,拿走不谢! 3dmax2020安装 ...

  6. Category Theory: 01 One Structured Family of Structures

    Category Theory: 01 One Structured Family of Structures 这次看来要放弃了.看了大概三分之一.似乎不能够让注意力集中了.先更新吧. 群的定义 \( ...

  7. CMake与MSVC工程化实践

    CMake与MSVC工程化实践 CMake基础 cmake无疑是最流行的c++跨平台构建工具之一,关于cmake入门指南这里不再赘述,官方文档是最好的参考,这里通过一个例子简述构建一个工程常用的函数和 ...

  8. POJ 2431 (优先队列)

    题目链接:https://vjudge.net/problem/POJ-2431 思路: “ 在卡车行驶途中, 只有经过加油站才能加油.” 我们不妨转变思路, 理解成“当卡车驶过加油站时就获得了加油的 ...

  9. React Router学习

    React Router教程 本教程引用马伦老师的的教程 React项目的可用的路由库是React-Router,当然这也是官方支持的.它也分为: react-router 核心组件 react-ro ...

  10. PAT甲题题解-1060. Are They Equal (25)-字符串处理(科学计数法)

    又是一道字符串处理的题目... 题意:给出两个浮点数,询问它们保留n位小数的科学计数法(0.xxx*10^x)是否相等.根据是和否输出相应答案. 思路:先分别将两个浮点数转换成相应的科学计数法的格式1 ...