天天看點

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

正常來說,傳輸給接口的資料沒有問題的話,打包出來的檔案就能正常播放。