前兩篇文章提出一些視頻解碼的方法,接下來講一下視頻編碼的例子。
當(dāng)我們從相機或者其他渠道獲取到CVPixelBuffers這種原始視頻流,并且想將它壓縮寫入視頻文件中時,我們可以使用AVAssetWriter這個類來實現(xiàn)。
AVAssetWriter內(nèi)部有一個編碼器,它可以將原始視頻幀壓縮成CMSampleBuffers,并且寫入視頻文件中。

?而當(dāng)我們獲取到原始視頻流,不想將它寫入視頻文件中,而是獲取到每一幀壓縮圖像,并通過網(wǎng)絡(luò)發(fā)送出去時。我們可以使用VTCompressionSession這個類來實現(xiàn)。

創(chuàng)建VTCompressionSession時,需要以下幾個參數(shù):
1、壓縮后的長寬信息
2、壓縮后的類型
3、即將發(fā)送給VTCompressionSession的CVPixelBuffer的描述(可選)
4、實現(xiàn)一個輸出回調(diào)的代碼塊

我們可以通過VTSessionSetProperty來配置VTCompressionSession,以下列出一些常用的屬性

我們使用VTCompressionSessionEncodeFrame這個方法來編碼CVPixelBuffer,由于CVPixelBuffer沒有攜帶展示時間的數(shù)據(jù),所以我們要按照展示時間順序來提供CVPixelBuffer。
compressionSession通常需要幾條幀數(shù)據(jù)一起處理,所以回調(diào)的輸出可能會有延遲??赡苄枰欢〝?shù)量的視頻幀加入到編碼器中才會有壓縮的視頻幀輸出。最后當(dāng)我們把所有的數(shù)據(jù)都加入到compressionSession中后,我們需要調(diào)用VTCompressionSessionCompleteFrames這個方法來讓它輸出所有的壓縮數(shù)據(jù)。

?在compressionSession的輸出回調(diào)中,我們會收到CMSampleBuffers,當(dāng)編碼出現(xiàn)錯誤或丟幀時,也會收到錯誤信息。壓縮的視頻幀是按解碼順序來輸出的。

?當(dāng)我們收到CMSampleBuffers時,說明它們是MPEG-4 packaging格式的,但是我們想將它通過網(wǎng)絡(luò)發(fā)送出去,所以我們需要把它們變成Elementary Stream packaging格式的數(shù)據(jù)。

首先,我們需要將parameter sets從CMVideoFormatDescription中抽離出來,打包成NAL單元。我們可以使用CMVideoFormatDescriptionGetH264ParameterSetAtIndex這個方法來實現(xiàn)。

?接下來,我們將NAL單元從CMSampleBuffer中取出來,并將其中的length code轉(zhuǎn)換成start code。

本片文章總結(jié):
1、如何創(chuàng)建VTCompressionSession
2、通過VTSessionSetProperty來配置VTCompressionSession
3、如何將CVPixelBuffer提供給compressionSession進行壓縮
4、如何將CMSampleBuffers轉(zhuǎn)換成H.264 Elementary Stream packaging

本文翻譯自WWDC14:Direct Access to Video Encoding and Decoding