FLV(Flash Video)
FLV封装格式
Tag Data分为Audio,Video,Script三种
TS(Transport Stream)传输流
TS文件分为三层,(倒叙更好理解)
- TS层:在PES层基础上加入了数据流识别信息和传输信息
- PES层:在ES层基础上加入了时间戳(PTS/DTS)等信息
- ES层:压缩编码之后的音视频数据
◆ ts包大小固定为188字节,ts层分为三个部分:ts header、adaptation field、payload。
◆ ts header固定4个字节;
◆ adaptation field可能存在也可能不存在,主要作用是给不足188字节的数据做填充。
◆ payload是 PES 数据,或者PAT,PMT等。
◆ ts Header + adaptation field 格式如下:
TS Header
◆ TS Header格式如下:
pid 决定了负载内容的类型,主要包括:PAT表,PMT表,视频流,音频流。常用的PID值:
调整字段
PAT表结构(指明PMT表的PID值)
bash
typedef struct TS_PAT{
unsigned table_id :8 //固定位0x00,表示该表是PAT
unsigned section_syntax_indicator :1 //段语法标志,固定为1
unsigned zero :1 //固定为0
unsigned reserved_1 :2 //第一个保留位
unsigned section_length :12 //表示这个字节之后有用的字节数,包括CRC_32
unsigned transport_stream_id :16 //传输流的ID,区别于一个网络中其他多路复用的流
unsigned reserved_2 :2 //第二个保留位
unsigned version_number :5 //表示PAT的版本号
unsigned current_next_indicator :1 //表示发送的PAT是当前有效还是下一个有效,为1时代表当前有效
unsigned section_number :8 //如果PAT分段传输,那么此值每次递增1
unsigned last_section_number :8 //最后一个分段的号码
for(int i=0;i<N;i++){
unsigned Program_number :16 //节目号
unsigned Reversed_3 :3 //保留位
if(Program_number == 0)
Network_id :13 //网络信息表(NIT)的PID
else
Program_MAP_PID :13 //节目映射表的PID,每个节目都有一个
}
unsigned CRC_32 :32 //CRC32校检码
}TS_PAT
PMT表(指明音视频流的PID值)
bash
typedef struct TS_program_map_section{
unsigned Table_id :8 //标志PSI分段的内容,对于PMT,此值为0x02
unsigned Section_syntax_indicator :1 //置为1
unsigned '0' :1
unsigned Reserved :2 //保留位
unsigned Section_length :12 //指明了自此到最后CRC_32的字节数
unsigned Program_number :16 //指出该节目的节目号,与PAT表对应
unsigned Reserved :2 //保留位
unsigned Version_number :5 //取值0-31,代表当前PMT的版本号
unsigned Current_next_indicator :1 //代表当前PMT是否有效
unsigned Section_number :8 //给出了当前所处段的数目
unsigned Last_section_number :8 //给出了最后一个分段,即分段的最大数目
unsigned Reserved :3 //保留位
unsigned PCR_PID :13 //指示TS包的PCR值,该TS包含有PCR字段
unsigned Reserved :4 //保留位
unsigned Program_info_length :12 //该字段描述跟随其后对节目信息描述的字节数
for(int i = 0; i < N; i++)
Descriptr()
for(int i = 0; i < N; i++){
unsigned Stream_type :8 //0x00:保留, 0x01:MPEG1视频,0x02:MPEG2视频,0x03:MPEG1音频,0x04:MPEG2音频,0x05:私有字段,0x06:含有私有数据的PES包 ......
unsigned Reserved :3 //保留
unsigned Elementary_PID :13 //指示TS包的PID,这些TS包含有相同的PID
unsigned Reserved :4 //保留
unsigned ES_info_length :12 //指示跟随其后描述相关节目元素的字节数
for(int j = 0; j < N2; j++)
Descriptr()
}
unsigned CRC_32 :32 //循环校检位
}
◆ 打包ts流时PAT和PMT表是没有调整字段的,不够的长度直接补0xff即可。
◆ 视频流和音频流都需要加adaptation field,通常加在一个帧的第一个ts包和最后一个ts包里,中间的ts包不加。
PES 层
◆ PES(Packetized Elementary Stream,打包的ES),在 ES 层的基础上加入了时间戳(PTS/TDS)等信息。
◆ ES数据包比较大,加入PES头时需将ES进行分割,只在第一个分割的ES上加PES头,如下图所示
◆ PES packet length --- 指示PES 包中跟随该字段最后字节的字节数。0 值指示PES 包长度既未指示也未限定并且仅在这样的PES 包中才被允许,该PES 包的有效载荷由来自传输流包中所包含的视频基本流的字节组成。
◆ PES结构如下:◆ PES 关键字段说明
ES 层
◆ ES(Elementary Stream,基本码流),就是音视频编码数据流,比如视频H.264,音频AAC。
◆ 一个 ES 流中只包含一种类型的数据(视频,或音频,或字幕)。
MP4(MPEG-4)
MP4由许多的box组成,每个box包含不同的信息,这些box以树状结构的形式组成,box中可以包含box
◆ box 由 header 和 body 组成,header 指明 box 的 size 和 type。size 是包含 box header 的整个 box 的大小。
◆ box type,通常是4个ASCII码的字符如"ftyp"、"moov"等,这些 box type都是已经预定义好的,表示固定的含义。如果是"uuid",表示该box为用户自定义扩展类型,如果 box type 是未定义的,应该将其忽略。
◆ 如果 header 中的 size 为1,则表示 box 长度需要更多的bits位来描述,在后面会有一个8字节的 largesize 用来描述 box 的长度。如果 size 为0,表示该 box 为文件的最后一个box,文件结尾(同样只存在于"mdat"类型的box中)。
◆ box 分为两种,Box 和 Fullbox。FullBox 是 Box 的扩展,Header 中增加了version 和 flags字段。
◆ box 定义如下:
bash
aligned(8) class Box (unsigned int(32) boxtype,
optional unsigned int(8)[16] extended_type) {
unsigned int(32) size;
unsigned int(32) type = boxtype;
if (size==1) {
unsigned int(64) largesize;
} else if (size==0) {
// box extends to end of file
}
if (boxtype=='uuid') {
unsigned int(8)[16] usertype = extended_type;
}
}
FullBox定义:
bash
aligned(8) class FullBox(unsigned int(32) boxtype, unsigned int(8) v, bit(24) f)
extends Box(boxtype) {
unsigned int(8) version = v;
bit(24) flags = f;
}
ISO/ICE 14496-12