VideoToolBox硬編碼,硬解碼

VideoToolBox硬編碼(h264)

H264編碼分為兩層:

視頻編碼層(VCL:Video Coding Layer)負(fù)責(zé)高效的視頻內(nèi)容表示
網(wǎng)絡(luò)提取層(NAL:Network Abstraction Layer)負(fù)責(zé)以網(wǎng)絡(luò)所要求的恰當(dāng)?shù)姆绞綄?shù)據(jù)進(jìn)行打包和傳送(根據(jù)不同的網(wǎng)絡(luò)把數(shù)據(jù)打包成相應(yīng)的格式,將VCL產(chǎn)生的比特字符串適配到各種各樣的網(wǎng)絡(luò)和多元環(huán)境中)
NALU:NAL unit,NAL單元

I幀、P幀、B幀都是被封裝成一個或者多個NALU進(jìn)行傳輸或者存儲的
I幀開始之前也有非VCL的NAL單元,用于保存其他信息,比如:PPS、SPS

PPS(Picture Parameter Sets):圖像參數(shù)集
SPS(Sequence Parameter Set):序列參數(shù)集
在實(shí)際的H264數(shù)據(jù)幀中,往往幀前面帶有00 00 00 01 或 00 00 01分隔符,一般來說編碼器編出的首幀數(shù)據(jù)為PPS與SPS,接著為I幀,后續(xù)是B幀、P幀等數(shù)據(jù)。
GOP:Group of picture圖像組,一組中包含一個i幀多個bp幀,每個i幀都是 IDR 圖像(立即刷新圖像),當(dāng)解碼器解碼到 IDR 圖像時,立即將參考幀隊(duì)列清空,將已解碼的數(shù)據(jù)全部輸出或拋棄,重新查找參數(shù)集,開始一個新的序列。這樣,如果前一個序列出現(xiàn)重大錯誤,在這里可以獲得重新同步的機(jī)會。

H.264編碼流程:

1、通過攝像頭采集畫面,通過- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection 方法傳回sampleBuffer,sampleBuffer中存放了視頻畫面信息。
2、初始化文件寫入對象(NSFileHandle),設(shè)置文件存儲路徑.
3、初始化壓縮會話(VTCompressionSessionRef),設(shè)置視頻的壓縮轉(zhuǎn)換格式(h.264),幀率、碼率,幀間隔等轉(zhuǎn)換信息(配置轉(zhuǎn)換器)。
4、將攝像頭采集到的畫面?zhèn)魅?,按照h.264的壓縮算法進(jìn)行壓縮,轉(zhuǎn)換完成后會通過創(chuàng)建VTCompressionSessionRef是的方法中的回調(diào)方法 傳出壓縮轉(zhuǎn)換后的sampleBuffer。
5、獲取到轉(zhuǎn)換后的sampleBuffer,按照h.264的編碼格式進(jìn)行編碼寫入文件。
關(guān)鍵幀

1>判斷是否為關(guān)鍵幀(一個新的GOP),i幀前存放sps和pps(寫入sps和pps時要在前面添加‘00 00 00 01’分隔)。
2>圖像數(shù)據(jù)區(qū)域(i,b,p)是被封裝成一個個NAL Unit。但是前面通過h.264壓縮算法后傳回的sampleBuffer,每一幀錢存放的不是‘00 00 00 01’,所以需要跳過讀取,需要在每一幀前添加‘00 00 00 01’,然后寫入文件。
VideoToolBox硬解碼(h264):

1、讀取數(shù)據(jù)到buffer中,通過startCode“00 00 00 01”定位起始位置

,繼續(xù)移動指針查找到下一個startCode,來確定當(dāng)前數(shù)據(jù)集合的長度,并拷貝數(shù)據(jù)信息。

2、解析獲取的數(shù)據(jù)信息,startCode之后的第一個字節(jié)保存的是NALU的類型信息。將其轉(zhuǎn)為二進(jìn)制后:

第1位:值為1,表示語法出錯。
第2~3位:參考級別。
第4~8位:NALU類型。
NALU類型如下圖:


3、通過上一步解析出來的sps和pps的信息,創(chuàng)建視頻描述CMFormatDescriptionRef,再根據(jù)CMFormatDescriptionRef創(chuàng)建生成解碼會話VTDecompressionSessionRef。
4、讀取到視頻數(shù)據(jù)信息后,進(jìn)行解碼。創(chuàng)建CMBlockBufferRef(存放視頻圖像數(shù)據(jù)),使用解碼會話進(jìn)行解碼,獲取解碼后的信息存放到CVPixelBufferRef中,通過系統(tǒng)的AVSampleBufferDisplayLayer預(yù)覽,或者生成圖像,通過imageView顯示,或者使用OpenGL顯示。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容