【总结】FLV(AAC/AVC)学习笔记

Posted on Posted in 计算机5,334 views

一、FLV

    FLV是一种能很好适应网络流媒体的网络视频格式。相对于其它视频文件格,具有的视频质量良好、结构简单、占有率低和体积小等特点很适合网络传输。

1.1、FLV文件格式

    FLV文件格式结构比较简单,可以分为Header和Body两部分,Body又由一个个Tag和Tag Length组成。相惜结构如下图,注意Tag0 length一般取0。

1501497519534575.png

1.2、FLV Header

    FLV头部结构也很简单,如下图所示:

1501497666334345.png

                Signature:FLV

                Version:版本

                V:1 – 包含视频流, 0 – 不包含视频流

                A:1 – 包含音频流, 0 – 不包含音频流

1.3、FLV Body

    FLV Body重点是由FLV Tag组成,而FLV Tag Length只是用32bit(UI32)来记录前一个Tag的长度总体长度。FLV Tag的整体结构是统一的,其结构划分如下:

1501497809543014.png

                Type: 8- audio, 9- video, 18(0x12)- script data

                Data Size: Data字段的长度,单位是bit

                Timestamp: 时间戳,一般用于DTS

                Ext Timestamp: 溢出时间戳,当Timestamp溢出后才有意义

                StreamID: 流ID,对于一个FLV文件,总会设置为0

                Data: Tag所承载的音视频流数据

1.4、一般解封装流程

1501497900286266.png

二、AVC/AAC下的FLV Tag结构

    上面给出了FLV的基本结构,其格式比较统一。因为FLV Tag内部承载的数据有多种类型,所以在FLV 的Data字段内还可以划分不同的子结构。下面结合实际介绍AAC音频和H264视频下的FLV Tag的详细结构。

2.1、FLV Video Tag — AVC

    可将FLV Video Tag划分为Tag Header和 Video Data两部分,其中Video Data即为FLV的Data字段。而Video Data又可分为Video Header和Video Packet。AVC中叫AVC Video Packet。

1501498005555524.png

2.1.1、Video Header

    VIDEO HEADER长度为1个字节,其结构是:

| FrameType(4) | CodecID(4) |

                  FrameType(FT)  = 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 keyframe (reserved for server use only)

                                            = 5 : video info/command frame

                  CodecID(CID)    = 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 : H264/AVC

2.1.2、AVC Video Packet

    AVC Video Packet又可以分为AVC VIDEO Header和 Data两部分,其AVC VIDEO Header的结构如下:

| AVCPacketType(8)| CompostionTime(24) |

                AVC package type(AVC PT)= 00 :AVC Sequence Header,Data为AVC Decorder Configuration Record;

                                                = 01 :AVC NALU,Data为NALUs;

                                                = 02 : AVC end of sequence,Data为空。

                composition time    = 00 : 只有AVC package type =0时;

                                                = num: 为相对时间,即CTS,PTS = DTS + CTS*90。

    因为AVC PT主要涉及前两种类型,下面分别介绍关键帧中其结构。

    1、AVC Sequence Header

    在 ISO/IEC 14496-15 中定义,FLV文件中第一个VIDEOTAG的VIDEODATA的AVC VIDEO PACKET的Data总是 AVC Decoder Configuration Record。一般位于流的第一个Tag中。根据上面的表述,一个完成的Tag数据包结构如下,其中数字表示该段为确定值,红色部分为AVC Decoder Configuration Record结构。

1501498375848630.png 

                    CV:configurationVersion

                    PI:AVCProfileIndication

                    PC:profile_compatibility

                    LI:AVCLevelIndication

                    L:lengthSizeMinusOne,重要,视频中NALU的长度,计算方法1 + (L& 3)

                    NSPS:numOfSequenceParameterSets,SPS的个数,计算方法是 NSPS&0x1F

                    SPSL:sequenceParameterSetLength,SPS的长度。

                    SPSNU:sequenceParameterSetNALUnit,SPSNU的长=8bit* SPSL

                    NPPS:numOfPictureParameterSets, PPS 的个数

                    PPSL:pictureParameterSetLength,PPS 的长度

                    PPSNU:pictureParameterSetNALUnit,PPSNU的长=8bit* PPSL

    2、AVC NALU

    该类型下,Data部分承载的即为H264的NALU数据了,一个Video Tag可能包含多个NALU,为了区分和定位,FLV中采用NALU Length来确定NALU的长度。一个完整的关键帧的Tag的也可以表示如下图(对于其他非关键帧其结构类似,只是FT的值不一样),其中红色部分即为Data字段内容。

 07.png

    在H264中,每个NALU单元开头第一个byte的低5bits表示着该单元的类型(nal_unit_type)。所以每个NALU第一个byte & 0x1f 就可以得出它的类型:

                    nal_unit_type:

                                #define NALU_TYPE_SLICE 1  一个非IDR图像的编码条带

                                #define NALU_TYPE_DPA   2  编码条带数据分割块A

                                #define NALU_TYPE_DPB   3  编码条带数据分割块B

                                #define NALU_TYPE_DPC   4  编码条带数据分割块C

                                #define NALU_TYPE_IDR   5  IDR图像的编码条带

                                #define NALU_TYPE_SEI   6      辅助增强信息 (SEI)

                                #define NALU_TYPE_SPS   7  序列参数集

                                #define NALU_TYPE_PPS   8  图像参数集

                                #define NALU_TYPE_AUD   9  访问单元分隔符

                                #define NALU_TYPE_EOSEQ 10  序列结尾

                                #define NALU_TYPE_EOSTREAM  11 流结尾

                                #define NALU_TYPE_FILL      12 填充数据

                    例如:  0x67 & 0x1f = 7,则此单元是SPS

                                0x68 & 0x1f = 8,则此单元是PPS

        此处注意,在FLV中NALUs的结构是  |NALU长度|NALU| NALU长度|NALU|…

                        在H264中NALUs的结构是 |0000 0001|NALU|0000 0001|NALU|…

2.2、FLV Audio Tag — AAC

    可将FLV Audio Tag划分为Tag Header和 Audio Data两部分,其中Audio Data即为FLV的Data字段。可分为Audio Header和Audio Packet。AAC中叫AAC AudioPacket。

08.png

2.2.1、Audio Header

VIDEO HEADER的长度为1个字节,其结构是:

|SoundFormat(4) | SoundRate(2) |SoundSize(1)|SoundType(1)|

            SoundFormat(SF) = 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

                                        = 8 : G.711 mu-law logarithmic PCM

                                        = 9 : reserved

                                        = 10 : AAC

                                        = 11 : Speex

                                        = 14 : MP3 8 kHz

                                        = 15 : Device-specific sound

            SoundRate(R)      = 0 : 5.5 kHz

                                        = 1 : 11 kHz

                                        = 2 : 22 kHz

                                        = 3 : 44 kHz

            SoundSize(S)       = 0 : 8-bit samples

                                        = 1 : 16-bit samples

            SoundType(T)      = 0 : Mono sound

                                        = 1 : Stereo sound

2.2.2、AAC Audio Packet

    如果SoundFormat不是10(AAC),则Audio Packet的数据即为audio payload。但是AAC Audio Packet有两种不同的类型,标准中利用 AACPacketType来区分:

            AACPacketType(AACPType) = 0 : AAC sequence header

                                                          = 1 : AAC raw

1、AAC sequence header

    在FLV的文件中,一般情况下这种包只出现1次,而且是第一个audio tag。此时Data部分是2字节的Audio Specific Config,其结构如下:

 09.png

            AAC Profile(ACCP) = 0x01 : AAC Main

                                        = 0x02 : AAC LC

                                        = 0x03 : AAC SSR

                                        = ……

            AACS: 采样率       = 0x00:96000, 0x01:88200, 0x02:64000, 0x03:48000,

                                        = 0x04:44100, 0x05:32000, 0x06:24000, … …

            AACC: 声道数       = 0x01:单声道, 0x02:双声道, 0x03:三声道, ……

            R: 保留字段

2、AAC raw

    AAC raw数据很简单,在AACP Type后面紧跟的就是Audio Payload(音频有效载荷))数据,也就是ES流。整个结构如下:

10.png 

    数据播放时,一般的AAC解码器都需要把AAC的ES流打包成ADTS的格式,一般是在AAC ES流前添加7个字节的ADTS header。如下图所示:

11.png 

    其中ADST头部结构如下:

12.png 

            Syncword:为同步字段,其目的是用于定位帧头部在比特流中的位置。

            ID:用于区分标准,0表示MPEG-4, 1表示MPEG-2。

            Lay:即Layer,规定这两位为00。

            PA:即protection_absent,如果没有CRC则置为1,否则置为0。

            Pf:即Profile。规格对应为:0对应Main、1对应LC、2对应SSR,而3是保留的。

            SFI:即sampling frequency index。常见的采样率对应为:2对应64000Hz、3对应48000Hz、4对应44100Hz、5对应32000 Hz。

            CC:即channel conflguration。常见声道对应的为:1为单声道、2为双声道。

            PB为private bit、OC为original/copy、HO为Home、CIB为Copyright identification bit、CIS为Copyright identification start,这5个字段在当进行编码时设置为0,解码时则会被忽略。

            aac frame len:表示该数据帧的长度。其值必须包含ADTS头的长度,单位是字节。

            adts buffer fullness:通常置为0x7ff。

            N:表示ADTS中所包含的RDBs(AACframe)数目,通常情况下为一个。

            CRC:即Cyclic Redundancy Check,循环冗余校验。当protection_absent为0时才存在。

参考

1、http://blog.csdn.net/leixiaohua1020/article/details/17934487

2、http://www.itnose.net/detail/6195595.html

3、http://www.cnweblog.com/fly2700/archive/2008/04/09/281432.html

4、http://yanhaijing.com/html/2016/03/12/html5-video/

5、http://blog.sina.com.cn/s/blog_51396f890102ezbn.html

6、http://blog.csdn.net/hellofeiya/article/details/9249709

7、http://blog.csdn.net/peijiangping1989/article/details/6934312

8、http://blog.csdn.net/ly402609921/article/details/49387895

9、http://blog.csdn.net/jefry_xdz/article/details/8461343

10、http://www.rosoo.net/a/201405/16978.html

11、http://blog.csdn.net/huibailingyu/article/details/50554151

12、http://blog.csdn.net/tx3344/article/details/7414543

13、http://www.it610.com/article/4945935.htm

14、http://www.jianshu.com/p/5c770a22e8f8

15、http://blog.csdn.net/sunnylgz/article/details/7676340

16、http://jjf19850615.blog.163.com/blog/static/35688147201362453628488/

17、http://www.cnblogs.com/gaozehua/archive/2012/05/03/2479960.html


转载标明出处:https://blog.evanxia.com/2017/07/1378