視頻流的解碼分為軟解和硬解非驮。軟解:利用CPU做視頻的編碼和解碼壕鹉,俗稱軟編軟解。這個(gè)方法比較通用琴许,但是占用CPU資源税肪,編解碼的效率不高。硬解:一般系統(tǒng)都會(huì)提供GPU或者專(zhuān)用處理器來(lái)對(duì)視頻流進(jìn)行編解碼榜田,也就是硬件編碼和解碼益兄。簡(jiǎn)稱硬編解碼,調(diào)用VideoToolbox的框架進(jìn)行基本數(shù)據(jù)結(jié)構(gòu)箭券。編解碼前后的視頻圖像均封裝在CMSampleBuffer中净捅,如果是編碼后的圖像,以CMBlockBuffe方式存儲(chǔ)邦鲫;解碼后的圖像灸叼,以CVPixelBuffer存儲(chǔ)。CMSampleBuffer里面還有另外的時(shí)間信息CMTime和視頻描述信息CMVideoFormatDesc庆捺。
--
蘋(píng)果自帶的框架只有在ios8.0才能支持硬編解碼 (VideoToolbox.Framework),
解碼主要需要以下三個(gè)函數(shù)
VTDecompressionSessionCreate 創(chuàng)建解碼session
VTDecompressionSessionDecodeFrame 解碼一個(gè)frame
VTDecompressionSessionInvalidate 銷(xiāo)毀解碼 session
- 編解碼前后的視頻圖像均封裝在CMSampleBuffer中古今,如果是編碼后的圖像,以CMBlockBuffe方式存儲(chǔ)滔以;解碼后的圖像捉腥,以CVPixelBuffer存儲(chǔ)。CMSampleBuffer里面還有另外的時(shí)間信息CMTime和視頻描述信息CMVideoFormatDesc你画。
硬解碼使用方法抵碟。
將H264碼流轉(zhuǎn)換成解碼前的CMSampleBuffer:解碼前的CMSampleBuffer = CMTime + FormatDesc + CMBlockBuffer桃漾。需要從H264的碼流里面提取出以上的三個(gè)信息。最后組合成CMSampleBuffer拟逮,提供給硬解碼接口來(lái)進(jìn)行解碼工作撬统。H264的碼流由NALU單元組成,NALU單元包含視頻圖像數(shù)據(jù)和H264的參數(shù)信息敦迄。其中視頻圖像數(shù)據(jù)就是CMBlockBuffer恋追,而H264的參數(shù)信息則可以組合成FormatDesc。具體來(lái)說(shuō)參數(shù)信息包含SPS(Sequence Parameter Set)和PPS(Picture Parameter Set)罚屋。
-
碼流結(jié)構(gòu):提取sps和pps生成format description苦囱。
a,每個(gè)NALU的開(kāi)始碼是0x00 00 01脾猛,按照開(kāi)始碼定位NALU撕彤。
b,通過(guò)類(lèi)型信息找到sps和pps并提取猛拴,開(kāi)始碼后第一個(gè)byte的后5 位羹铅,7代表sps,8代表pps漆弄。
c睦裳,CMVideoFormatDescriptionCreateFromH264ParameterSets函 數(shù)來(lái)構(gòu)建CMVideoFormatDescriptionRef造锅。具體代碼可以見(jiàn)demo撼唾。
-
提取視頻圖像數(shù)據(jù)生成CMBlockBuffer。
a哥蔚,通過(guò)開(kāi)始碼倒谷,定位到NALU。
b糙箍,確定類(lèi)型為數(shù)據(jù)后渤愁,將開(kāi)始碼替換成NALU的長(zhǎng)度信息(4 Bytes)。
c深夯,CMBlockBufferCreateWithMemoryBlock接口構(gòu)造CMBlockBufferRef抖格。具體代碼可以見(jiàn)demo。
根據(jù)需要咕晋,生成CMTime信息雹拄。(實(shí)際測(cè)試時(shí),加入time信息后掌呜,有不穩(wěn)定的圖像滓玖,不加入time信息反而沒(méi)有,需要進(jìn)一步研究质蕉,這里建議不加入time信息)
根據(jù)上述得到CMVideoFormatDescriptionRef势篡、CMBlockBufferRef和可選的時(shí)間信息翩肌,使用CMSampleBufferCreate接口得到CMSampleBuffer數(shù)據(jù)這個(gè)待解碼的原始的數(shù)據(jù)。
具體方式參考demo禁悠。