天天看点

MP4V2封装h265

mp4v2一般是用来做h264到mp4的封装,后来经过总结和优化,出现了支持h264/h265的版本,链接如下:

mp4v2-h265

从以上链接中下载的MP4V2源码

相关接口如下:

MP4V2_EXPORT
MP4TrackId MP4AddH265VideoTrack(
    MP4FileHandle hFile,
    uint32_t      timeScale,
    MP4Duration   sampleDuration,
    uint16_t      width,
    uint16_t      height,
    uint8_t       AVCProfileIndication,
    uint8_t       profile_compat,
    uint8_t       AVCLevelIndication,
    uint8_t       sampleLenFieldSizeMinusOne );
    
MP4V2_EXPORT
void MP4AddH265VideoParameterSet(
	MP4FileHandle hFile,
	MP4TrackId trackId,
	const uint8_t *pSequence,
	uint16_t sequenceLen);    
	
MP4V2_EXPORT
void MP4AddH265SequenceParameterSet(
    MP4FileHandle  hFile,
    MP4TrackId     trackId,
    const uint8_t* pSequence,
    uint16_t       sequenceLen );
    
MP4V2_EXPORT
void MP4AddH265PictureParameterSet(
    MP4FileHandle  hFile,
    MP4TrackId     trackId,
    const uint8_t* pPict,
    uint16_t       pictLen );
           

我用的MP4v2-2.0.0 封装(打包)h265和aac到MP4文件能正常播放。为了兼容h264,我通过判断第一个I帧的NALU中是否有vps来做了一个同时支持h265和h264的mp4录制实现,这里需要了解h265和h264裸流的区别:

H.264码流

H264中,NALU类型1-5为视频帧,其余则为非视频帧。在解码过程中,我们只需要取出NALU头字节的后5位,即将NALU头字节和0x1F进行与计算即可得知NALU类型,即:

NALU类型 = NALU头字节 & 0x1F 
           
MP4V2封装h265

SPS:十进制 7

PPS:十进制 8

I 帧:十进制 5

P帧:十进制 1

SEI: 十进制 6

H.265码流

HEVC全称High Efficiency Video Coding(高效率视频编码,又称H.265),是比H.264更优秀的一种视频压缩标准。HEVC在低码率视频压缩上,提升视频质量、减少容量即节省带宽方面都有突出表现。 H.265标准围绕H.264编码标准,保留原有的某些技术,同时对一些技术进行改进,编码结构大致上和H.264的架构类似。这里着重讲一下两者编码格式的区别。 同H.264一样,H.265也是以NALU的形式组织起来。而在NALU header上,H.264的HALU header是一个字节,而H.265则是两个字节。

NALU类型 = (NALU头第一字节 & 0x7E) >> 1
           

如下图所示:

0                   1

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5

+ -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| F | Type | LayerId | TID |

+------------ - +---------------- - +

从图中可以看出hHEVC的nal包结构与h264有明显的不同,hevc加入了nal所在的时间层的ID,去除了nal_ref_idc,此信息合并到了naltype中,

通常情况下F为0,layerid为0,  TID为1。

VPS:十进制 32

SPS:十进制 33

PPS:十进制 34

I 帧:十进制 19

P帧:十进制 1

SEI: 十进制 39

生成文件:smarthome_20210419_104841.MP4

查看文件信息:

MP4V2封装h265

具体使用流程:

从h265视频流中分离出vps、sps、pps、IDR(i)帧、p帧等信息进行后面处理。处理流程类似封装h264流

h264 使用sps帧 添加视频流MP4AddH264VideoTrack

h265 使用vps帧 添加视频流MP4AddH265VideoTrack

对于h265其中有个问题就是视频的宽 高信息 在sps帧中,vps初始化使用的宽高参数就 先自己赋值为实际的视频宽高了,

接着 以下几个参数设置了

vps帧就 MP4AddH265VideoParameterSet

sps帧就 MP4AddH265SequenceParameterSet

pps帧就 MP4AddH265PictureParameterSet

i和p帧就写数据MP4WriteSample

正常来说,传输给接口的数据没有问题的话,打包出来的文件就能正常播放。