fmp4打包H265视频流

1 fmp4打包H265视频流

文章目录

  • 1 fmp4打包H265视频流
    • 1.1 码流存储和传输格式介绍
      • 1.1.1 Annex B封装格式
      • 1.1.2 AVCC封装格式
      • 1.1.2 HVCC封装格式
    • 1.2 fmp4封装H265
      • 1.2.1 ftyp box
      • 1.2.2 stsd box

本文只介绍H265/HEVC的fmp4封包与fmp4封包H264不通的地方,其他有关mp4基础知识及fmp4封装和264视频流相关内容参照:
fmp4打包H264详解

1.1 码流存储和传输格式介绍

这里主要介绍下H264和H265存储和传输格式的基本知识介绍,如果知识想了解如何fmp4封装,本节可以跳过。

H265和H265标准中指定了视频如何编码成独立的包,但如何存储和传输这些包却未作规范,虽然标准中包含了一个Annex附件,里面描述了一种可能的格式Annex B,但这并不是一个必须要求的格式,为了针对不同的存储传输需求,出现了两种打包方法:一种即Annex B格式,另一种称为AVCC/HVCC格式。

1.1.1 Annex B封装格式

Annex B格式及我们厂家的HECVC或者H264码流封装格式,其格式如下:
[StartCode][NALU Header][NALU PAYLOAD]
起始码一般为00000001或者000001开头,通过定位起始码,解码器就可以识别NALU的边界,为了防止编码数据中存在与起始码相同的数据,在构建NALU时,需要将数据中的0x000000,0x000001,0x000002,0x000003中插入防竞争字节(Emulation Prevention Bytes)0x03,使其变为:

0x000000 = 0x0000 03 00
0x000001 = 0x0000 03 01
0x000002 = 0x0000 03 02
0x000003 = 0x0000 03 03

因此,解码器在检测到0x000003时,将0x03抛弃,恢复原始数据。

1.1.2 AVCC封装格式

AVCC格式不使用StartCode作为NALU的分界,而是在每个NALU前都加上一个指定NALU长度的大端格式表示的前缀,这个前缀可以是1、2或4个字节,所以在解析AVCC格式的时候需要将指定的前缀字节数的值保存在一个头部对象中,通常称为extradata或者sequence header,其中SPS和PPS数据也需要保存在extradata中。这里需要注意SPS和PPS都是去掉起始头的
H.264 extradata语法如下:
fmp4打包H265视频流_第1张图片

其中第5字节的后2位NALULengthSizeMinusOne表示的就是NALU size的字节数,NALU前缀长度减1,假设前缀长度为4,那么这个值应该为3。如果此之为3表示此码流所有nalu前需要加上四字节size,去掉起始码。

在fmp4打包H264详解文章中我们已经使用过此种封装方式来打包程avcc的box,详见此文章中的avcC box解释:moov->trak->media->minf->stbl->stsd->avc1->avcC,需要trak带有此box表示mp4封装的H264码流,此trackID的流中mdat的box中封装的是去除起00000001始码的码流,解码时需要注意这里虽然去掉了起始码,但是但防竞争字节还是有的,需要转换一下。

1.1.2 HVCC封装格式

与H.264类似,H.265(HEVC)码流也有两种封装格式,一种是用起始码作为分界的Annex B格式,另一种则是在NALU头添加NALU长度前缀的格式称为HVCC,与AVCC类似,需要通过extradata来保存视频流的编解码参数,其格式定义如下:
fmp4打包H265视频流_第2张图片

表示extradata后半段是一段格式重复的数组数据,其中numOfArrays表示数组的个数,一般为0x03,表示包含VPS/SPS/PPS,
封装方式示意如下(《ISO-14496-15 AVC file format》中有详细说明):

// The CodecPrivate syntax shall follow the
// syntax of HEVCDecoderConfigurationRecord
// defined in ISO/IEC 14496-15.
//
// The number zero (0) shall be written to
// the configurationVersion variable until
// official finalization of 14496-15, 3rd ed.
//
// After its finalization, this field and the
// following CodecPrivate structure shall
// follow the definition of the
// HEVCDecoderConfigurationRecord in 14496-15.

unsigned int(8)  configurationVersion;
unsigned int(2)  general_profile_space;
unsigned int(1)  general_tier_flag;
unsigned int(5)  general_profile_idc;
unsigned int(32) general_profile_compatibility_flags;
unsigned int(48) general_constraint_indicator_flags;
unsigned int(8)  general_level_idc;
bit(4) reserved = ‘1111’b;
unsigned int(12) min_spatial_segmentation_idc;
bit(6) reserved = ‘111111’b;
unsigned int(2)  parallelismType;
bit(6) reserved = ‘111111’b;
unsigned int(2)  chromaFormat;
bit(5) reserved = ‘11111’b;
unsigned int(3)  bitDepthLumaMinus8;
bit(5) reserved = ‘11111’b;
unsigned int(3)  bitDepthChromaMinus8;
bit(16) avgFrameRate;
bit(2)  constantFrameRate;
bit(3)  numTemporalLayers;
bit(1)  temporalIdNested;
unsigned int(2) lengthSizeMinusOne;
unsigned int(8) numOfArrays;
for (j=0; j < numOfArrays; j++) {
  bit(1) array_completeness;
  unsigned int(1)  reserved = 0;
  unsigned int(6)  NAL_unit_type;
  unsigned int(16) numNalus;
  for (i=0; i< numNalus; i++) {
    unsigned int(16) nalUnitLength;
    bit(8*nalUnitLength) nalUnit;
  }
}
bits 描述 备注
1 array_completeness 默认0
1 reserved 默认0
6 NAL_unit_type 帧类型
16 numNalus 此种类型的帧个数,一般为1,如果大于1,下面进入循环
16 nalUnitLength 2字节表示附加帧的长度
N NALU data 附加帧的数据

一般在fmp4封装时,hvcC box的box负载采用此种方式封装,其中相关的编码参数获取是从HEVC的SPS帧中分析出来的,附加帧数据VPS/SPS/PPS。

1.2 fmp4封装H265

fmp4封装H265,仅有两个box需要修改ftyp box和stsd box

1.2.1 ftyp box

ftyp box格式与H264封装一样,其中compatible brands赋值为isom、iso2、mp41,HEVC ftype示例如下:

0x00,0x00,0x00,0x1C,//box size
0x66,0x74,0x79,0x70,//ftyp的ascii 
0x69, 0x73, 0x6f, 0x6d, // major_brand: isom
0x0, 0x0, 0x02, 0x0, // minor_version: 0x01
0x69, 0x73, 0x6F, 0x6D, // isom
0x69, 0x73, 0x6F, 0x32, // iso2
0x6d, 0x70, 0x34, 0x31, // mp41

经过验证,这里直接用isom也能够正常播放,所以此box可与H264保持一致。

1.2.2 stsd box

有关H265的fmp4打包,此box需要把avc1 box替换成hvc1 box,hvc1 box的封装格式与avc1类似,只是把avcC子box替换程hvcC,其格式如下:
[4字节size][4字节type][6字节预留][2字节data_reference_index][2字节pre_defined][2字节预留][12字节pre_defined][2字节宽][2字节高][4字节horizresolution][四字节 vertresolution][4字节预留][2字节视频帧数量][Compression name长度][Compression name][Compression name预留位(32-Compression name长度-1)][2字节深度][2字节pre_defined][hvcC box][btrt box]

这里主要对与H264不同的hvcC box进行说明,其结构如下:
[4字节size][4字节type][hevc extradata]

其中hevc extradata格式见1.1.2 HVCC封装格式,其后半段附加了VPS、SPS、PPS帧数据,HVCC附加的解码信息字段可从SPS中解析得到,具体解析方式参照文章:
https://www.cnblogs.com/sddai/p/14366110.html

fmp4打包H265视频流_第3张图片
fmp4打包H265视频流_第4张图片
fmp4打包H265视频流_第5张图片

示例及详解如下:

00 00 00 6E 68 76 63 43 01 01 60 00 00 00 B0 00 00 00 00 00 7B F0 00 FC FD F8 F8 00 00 03 03 20 00 01 00 17 40 01 0C 01 FF FF 01 60 00 00 03 00 B0 00 00 03 00 00 03 00 7B AC 09 21 00 01 00 22 42 01 01 01 60 00 00 03 00 B0 00 00 03 00 00 03 00 7B A0 03 C0 80 10 E5 8D AE 49 32 F4 DC 04 04 04 02 22 00 01 00 07 44 01 C0 F2 F0 3C 90 
  • 00 00 00 6E:box长度为110
  • 68 76 63 43: boxtype=hvcC
  • 后续为hevc extradata,具体解释按照上文方式解析

以下是用mp4reader解析的结果,有关fmp4示例文件及mp4reader安装包获取,请关注微信公众号壹零仓,发送fmp4,获取:
fmp4打包H265视频流_第6张图片

你可能感兴趣的:(流媒体,fmp4,HEVC,H265,HVCC,hvc1)