一、引言
H.264流行的包装方式有两种,一种是AnnexB,另一种是avcC。对于AnnexB包装的H.264码流,其SPS和PPS被当做普通的NALU来处理;而对于avcC包装的H.264码流,其SPS和PPS信息存贮在AVCDecoderConfigurationRecord中(FFmpeg源码中把AVCDecoderConfigurationRecord称为extradata)。
在对AVCDecoderConfigurationRecord进行简介之前,请各位先从《音视频入门基础:H.264专题(1)——H.264官方文档下载》下载ISO/IEC提供的H.264官方文档《H.264-AVC-ISO_IEC_14496-15》。该文档总共有96页。本文下面所说的“页数”是指在pdf阅读器中显示的页数:
二、AVCDecoderConfigurationRecord
avcC封装的H.264码流中,最前面的是AVCDecoderConfigurationRecord(或称为extradata)。根据《H.264-AVC-ISO_IEC_14496-15》第16页,AVCDecoderConfigurationRecord包含的属性如下:
AVCDecoderConfigurationRecord中的属性依次如下:
configurationVersion:占8位(1字节),为版本,值必须为1。
AVCProfileIndication:占8位(1字节),所存放第一个SPS的第一个字节,即第一个SPS的profile_idc。
profile_compatibility:占8位(1字节),所存放第一个SPS的第二个字节,即第一个SPS的constraint_set0_flag + constraint_set1_flag + constraint_set2_flag + constraint_set3_flag + constraint_set4_flag + constraint_set5_flag + reserved_zero_2bits。
AVCLevelIndication:占8位(1字节),所存放第一个 SPS 的第三个字节,即第一个SPS的level_idc。
reserved:占6位,每个位的值都为1,即二进制的0b111111。
lengthSizeMinusOne:占2位。这里要先讲一个概念:NALUnitLength。NALUnitLength为某个NALU的以字节为单位的长度,即该NALU的NALU Header + EBSP的总长度。
avcC跟AnnexB不一样,avcC包装的H.264码流中,每个NALU前面没有起始码。avcC通过在每个NALU前加上NALUnitLength,在读取某个NALU之前,先把该NALU前面的NALUnitLength读取出来,拿到该NALU的总长度,然后根据该长度读取相应的字节数,从而读取出整个NALU。
lengthSizeMinusOne为存贮NALUnitLength所需的空间减1,单位为字节。比如,lengthSizeMinusOne为2,那么存贮该路H.264码流的每个NALUnitLength所需的空间为3个字节。我们在读取每个NALU之前,先读3个字节,把读取到的数据转成整数,这就是该NALU的总长度了。
reserved:占3位,每个位的值都为1,即二进制的0b111。
numOfSequenceParameterSets:占5位,SPS的数目。根据该SPS的数目循环读取每个SPS对应的sequenceParameterSetLength和sequenceParameterSetNALUnit。
sequenceParameterSetLength:占16位(2字节),SPS的长度,单位为字节。
sequenceParameterSetNALUnit:包含NALU Header的该SPS的实际NALU数据。不定长,长度为sequenceParameterSetLength的值。
numOfPictureParameterSets:占8位,PPS的数目。根据该PPS的数目循环读取每个PPS对应的pictureParameterSetLength和pictureParameterSetNALUnit。
pictureParameterSetLength:占16位(2字节),PPS的长度,单位为字节。
pictureParameterSetNALUnit:包含NALU Header的该PPS实际的NALU数据,不定长,长度为pictureParameterSetLength的值。
当SPS的profile_idc为如下值时,AVCDecoderConfigurationRecord中还包含如下属性:
三、AVCDecoderConfigurationRecord实例分析
通过《音视频入门基础:H.264专题(2)——使用FFmpeg命令生成H.264裸流文件》中介绍的方法生成的H.264裸流文件是AnnexB包装的。MP4、FLV等文件格式常使用avcC封装的H.264。所以我们可以通过分析FLV文件来了解avcC和AVCDecoderConfigurationRecord。
按照《音视频入门基础:FLV专题(4)——使用flvAnalyser工具分析FLV文件》中介绍的方法,通过flvAnalyser工具打开一个视频压缩编码方式为H.264的FLV文件,分析其第一个Video Tag。下面红框中所示的就是AVCDecoderConfigurationRecord: