欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

FLV 视频标准格式标准

程序员文章站 2022-07-05 11:11:17
...

FLV 视频标准格式标准

FLV Header

以 FLV Header (46 4C 56 01 05 00 00 00 09)为例:

Field Type Comment
Signature 1 byte 必须为’F’(0x46)
Signature 1 byte 必须为’L’(0x4C)
Signature 1 byte 必须为’V’(0x56)
(版本)Version 1 byte 通常为0x01
TypeFlagsReserved 5 bits 必须为0
TypeFlagsAudio 1 bit 表示是否含有音频
TypeFlagsReserved 1 bit 必须为0
TypeFlagsVideo 1 bit 表示是否含有视频
DataOffset 4 bytes 文件头部的大小(从文件开始位置到body的偏移量),通常为9
1-3:文件格式标识,必须为 46 4C 56【Signature】
4-4:版本,必须为 01【Version】
5-5:媒体标识位;
    1-5bit,必须为 0;【TypeFlagsReserved】
    6-6bit,音频标识;【TypeFlagsAudio】
    7-7bit,必须为 0;【TypeFlagsReserved】
    8-8bit,视频标识;【TypeFlagsVideo】
6-9:FLV头长度,必须为 00 00 00 09【DataOffset】

  FLV Header 的前三个字节是固定的FLV的 ASCII 码的值0x46 0x4C 0x56; 接下来的一个字节表示 FLV 的版本号,例如 0x01 代表 FLV 版本号为 1。第 5 个字节中的第0位和第2位分别表示video和audio的存在情况(1表示存在,0表示不存在),其余6位必须为0.最后的4字节表示FLV Header的长度,对于version 1,此处为9.

FLV File Body

  FLV Header 之后,FLV 文件的剩余部分称为 Body,它是由tag组成,它们交替如下

Field Type Comment
PreviousTagSize0 4 bytes 总是0
Tag1 FLVTAG结构 第一个tag
PreviousTagSize0 4 bytes 上一个tag的大小,包含了tag的头部。对FLV版本1来讲,它的值等于上一个tag的数据大小+11
Tag2 FLVTAG结构 第二个tag
PreviousTagSizeN - 1 4 bytes 倒数第二个tag的大小
TagN FLVTAG结构 最后一个tag
PreviousTagSizeN 4 bytes 最后一个tag的大小

FLV tags

Field Type Comment
Tag类型(TagType) 1 bytes 8:音频、9:视频、18:script数据
数据大小(DataSize) 3 bytes 数据字段的长度
时间戳(Timestamp) 3 bytes 毫秒为单位,第一个tag时,该值总是0
时间戳扩展(TimeStampExtended) 1 bytes 时间戳扩展为4bytes,代表高8位,很少用到
流ID 3bytes 总是0
数据(Data) 音频、视频或script 数据实体
1-1:数据类型
    1-2bit,必须为 0;【Reserved】
    3-3bit,0 = 未加密,1 = 加密;【Filter】
    4-8bit,8 = 音频,9 = 视频,18 = 脚本数据;【TagType】
2-4:消息长度,从 StreamID 到 Tag 结尾,也等于 TagLen -11【DataSize】
5-7:时间戳,相对于第一个 Tag 时间戳,单位毫秒【Timestamp】
8-8:扩展时间戳,高位,单位毫秒【TimestampExtended】
9-11:流ID【StreamID】
xx-xx:Data

  以 Tag 12 00 12 A9 00 00 00 00 00 00 00 02 00 0A……为例,0x12代表该 tag 为script data,00 12 A9代表该 tag 的 DataSize 为 681 byte,00 00 00代表该 tag 的 TimeStamp 为 0,00代表该 tag 的 TimeStampExtended 为 0,StreamID 总是 0,接下来的 681 byte 为script data 的内容。

  播放过程中,FLV tag的时间信息完全依赖于 FLV 时间戳,内置的其他时间信息都被忽略掉。

Audio tags

1-1:音频头【AudioTagHeader】
    1-4bit,音频格式【SoundFormat】
            0 = Linear PCM, platform endian
            1 = ADPCM
            2 = MP3
            3 = Linear PCM, little endian
            4 = Nellymoser 16 kHz mono
            5 = Nellymoser 8 kHz mono
            6 = Nellymoser
            7 = G.711 A-law logarithmic PCM , reserved
            8 = G.711 mu-law logarithmic PCM , reserved
            9 = reserved
            10 = AAC (supported in Flash Player 9,0,115,0 and higher)
            11 = Speex (supported in Flash Player 10 and higher)
            14 = MP3 8 kHz , reserved
            15 = Device-specific sound , reserved
    5-6bit,采样率【SoundRate】
            0 = 5.5kHz
            1 = 11kHz
            2 = 22kHz
            3 = 44kHz
    7-7bit,位宽,0 = 8bit samples, 1= 16bit samples【SoundSize】
    8-8bit,通道,0 = Mono, 1 = Stereo【SoundType】
[2-2]:AAC音频类型,注,只有在 SoundFormat=AAC 时,才有此数据
    0 = AAC sequence header
    1 = AAC raw
x-x:音频数据

注:SoundFormat
  如果 SoundFormat=10 即AAC格式,官方建议使用44.1kHz采样率和双声道,即SoundType=1,SoundRate=3;Flash Player会忽略这两个参数,并从音频比特流中解析获得。
  如果 SoundFormat=11 即Speex格式,音频使用压缩的16kHz采样率的单声道,各参数取值为SoundRate=0,SoundSize=1,SoundType=0。

Audio Data

数据大小 名称 备注
bit[4] Sound Format 2(0x2)-MP3;3(0x3)-PCM;10(0xA)-AAC
bit[2] Sample Rate 0(0x0)-5500Hz;1(0x1)-11025Hz;2(0x2)-22050Hz;3(0x3)-44100Hz
bit[1] Sample Size 0(0x0)-8bit;1(0x1)-16bit
bit[1] Channel Count 0(0x0)-Mono;1(0x1)-Stereo
byte[Payload Size -1] Sound Data 音频数据,随 Sound Format 不同,格式也不同

Video tags

  1-1:视频头【VideoTagHeader】
    1-4bit,帧类型【FrameType】
            1 = key frame (for AVC, a seekable frame)
            2 = inter frame (for AVC, a non-seekable frame)
            3 = disposable inter frame (H.263 only)
            4 = generated key frame (reserved for server use only)
            5 = video info/command frame
    5-8bit,编码类型【CodecID】
            2 = Sorenson H.263
            3 = Screen video
            4 = On2 VP6
            5 = On2 VP6 with alpha channel
            6 = Screen video version 2
            7 = AVC(H.264)
  [2-5]:H.264视频类型,注,只有在 CodecID=AVC 时,才有此数据
    AVCPacketType
   CompositionTime (ISO 14496-12, 8.15.3)
  x-x:视频数据
Field type Comment
幀類型 UB4 1: keyframe (for AVC, a seekable frame)——h264的IDR,關鍵幀,可重入幀。
2: inter frame (for AVC, a non- seekable frame)——h264的普通幀
3: disposable inter frame (H.263 only)
4: generated keyframe (reserved for server use only)
5: video info/command frame
編碼ID UB4 使用哪種編碼類型:
1: JPEG (currently unused)
2: Sorenson H.263
3: Screen video
4: On2 VP6
5: On2 VP6 with alpha channel
6: Screen video version 2
7: AVC
視頻數據 UI[N] 如果是avc,則參考下面的介紹:AVCVIDEOPACKET

AVCVIDEOPACKET格式:

Field type Comment
AVC packet類型 UI8 0:AVC序列頭
1:AVC NALU單元
2:AVC序列結束。低級別avc不需要。
CTS SI24 如果AVC packet類型是1,則為cts偏移(見下面的解釋),為0則為0
數據 UI8[n] 如果AVC packet類型是0,則是解碼器配置,sps,pps。
如果是1,則是nalu單元,可以是多個,具體格式:將下面

關於CTS:這是一個比較難以理解的概念,需要和pts,dts配合一起理解。
首先,pts(presentation time stamps),dts(decoder timestamps),cts(CompositionTime)的概念:
  pts:顯示時間,也就是接收方在顯示器顯示這幀的時間。單位為1/90000 秒。
  dts:解碼時間,也就是rtp包中傳輸的時間戳,表明解碼的順序。單位單位為1/90000 秒。——根據後面的理解,pts就是標準中的CompositionTime
  cts偏移:cts = (pts - dts) / 90 。cts的單位是毫秒。
  pts和dts的時間不一樣,應該只出現在含有B幀的情況下,也就是profile main以上。baseline是沒有這個問題的,baseline的pts和dts一直想吐,所以cts一直為0。
在flv tag中的時戳就是DTS。
  研究 一下文檔, ISO/IEC 14496-12:2005(E) 8.15 Time to Sample Boxes,發現CompositionTime就是presentation time stamps,只是叫法不同。——需要再進一步確認。
在上圖中,cp就是pts,顯示時間。DT是解碼時間,rtp的時戳。
  I1是第一個幀,B2是第二個,後面的序號就是攝像頭輸出的順序。決定了顯示的順序。
  DT,是編碼的順序,特別是在有B幀的情況,P4要在第二個解,因為B2和B3依賴於P4,但是P4的顯示要在B3之後,因為他的順序靠後。這樣就存在顯示時間CT(PTS)和解碼時間DT的差,就有了CT偏移。
P4解碼時間是10,但是顯示時間是40,

AVCVIDEOPACKET中data格式:

Field type Comment
長度 UI32 nalu單元的長度,不包括長度字段。
nalu數據 UI8[N] NALU數據,沒有四個字節的nalu單元頭,直接從h264頭開始,比如:65 * * ,41 * *
長度 UI32 nalu單元的長度,不包括長度字段。
nalu數據 UI8[N] NALU數據,沒有四個字節的nalu單元頭,直接從h264頭開始,比如:65 * * ,41 * *

  AVCVIDEOPACKET的数据格式,保存控制信息。
记录sps,pps信息。一般出现在第二个tag中,紧跟在onMeta之后。

AVCVIDEOPACKET实例详解:

一个典型的序列:
       0000190: 0900 0033 0000 0000 0000 0017 0000 0000  ...3............
       00001a0: 0164 002a ffe1 001e 6764 002a acd9 4078  .d.*....gd.*aaa@qq.com
       00001b0: 0227 e5ff c389 4388 0400 0003 0028 0000  .'....C......(..
       00001c0: 0978 3c60 c658 0100 0568 ebec b22c 0000  .x<`.X...h...,..
   17:表示h264IDR data
   00:表示是AVC序列头
   00 00 00 :cts为0
   从此往下就是AVCDecoderConfigurationRecord
      01 :版本号
      64 00 2a:profile level id,sps的三个字节,64表示是h264 high profile,2a表示level。
      FF:NALU长度,为3?不知道这个长度用在哪里。
      E1:表示下面紧跟SPS有一个。
   sps[N]:sps数组。
      00 1e:    前面是两个字节的sps长度,表示后面的sps的长度是1e大小。
      6764 002a acd9 4078 0227 e5ff c389 4388 0400 0003 0028 0000 0978 3c60 c658:sps的数据。
   因为只有一个sps,跳过这些长度,然后就是pps的个数信息:
      01 :pps个数,1
   pps[n] pps 的个数
      00 05:表示pps的大小是5个字节。
      68 eb ec b2 2c:pps的数据
      00 00 …….这是下一个tag 的内容了

H264帧类型判断(图像参考帧还是I、P帧等)

FLV 视频标准格式标准

FLV 视频标准格式标准

  我们还是接着看最上面图的码流对应的数据来层层分析,以00 00 00 01分割之后的下一个字节就是NALU类型,将其转为二进制数据后,解读顺序为从左往右算,如下:
(1)第1位禁止位,值为1表示语法出错
(2)第2~3位为参考级别
(3)第4~8为是nal单元类型

例如上面00000001后有67,68以及65,41
 其中0x67的二进制码为:
     0110 0111
     4-8为00111,转为十进制7,参考第一幅图:7对应序列参数集SPS
 其中0x68的二进制码为:
     0110 1000
     4-8为01000,转为十进制8,参考第一幅图:8对应图像参数集PPS
 其中0x65的二进制码为:
     0110 0101
     4-8为00101,转为十进制5,参考第一幅图:5对应IDR图像中的片(I帧)
 其中0x41的二进制码为:
     0100 0001
     4-8为00001,转为十进制1,参考第一幅图:根据上图可知道这段码流是【不分区、非IDR图像的片】,在baseline的档次中就是P帧,因为baseline没有B帧。

所以判断是否为I帧的算法为: (NALU类型 & 0001 1111) = 5 即 NALU类型 & 31 = 5
比如0x65 & 31 = 5

需要更加详细的说明请移步:

http://nkwavelet.blog.163.com/blog/static/2277560382013101321517473/ FLV文件(H264 + AAC)格式超详细分析

参考:

https://blog.ibaoger.com/2017/06/04/flv-file-format/
http://brainychen72.blogspot.com/2017/08/flv.html
https://www.cnblogs.com/cy568searchx/p/4415495.html

相关标签: 视频流媒体