iOS視頻硬件編解碼H264
- 硬件編碼的環境:iOS8之前是私有API,僅提供使用不能發佈上線,iOS8之後蘋果開放了VideoToolbox框架支持硬件編碼。
- 硬件編碼的好處:iOS8之前使用的一般是軟編,軟編對CPU的消耗比較嚴重。硬件編碼的好處是可以幾大的提升效率,下降CPU的消耗。
- VideoToolbox 是一套純C的API,能夠在多個語言環境下使用。
視頻編碼
編碼前和編碼後的CMSampleBufferRef有什麼不一樣咱們用一張圖來講明ios

(圖片來自網絡,侵刪)
- 實現方式
- 準備編碼前的CMSampleBufferRef:採用AVCaptureSession實現視頻採集。
- 編碼:採用VTCompressionSessionRef實現將採集的未編碼的CMSampleBufferRef編碼成編碼完成的CMSampleBufferRef。
- 存儲:將編碼完成的CMSampleBufferRef轉換成H264碼流。
視頻解碼
- H264碼流格式:H264碼流是有startCode+NALU單元組成,NALU包含視頻圖像數據和參數信息,CMBlockBuffer內包含了圖像數據信息,CMVideoFormatDesc內包含了參數信息(sps,pps)。下圖顯示H264碼流結構

(圖片來自網絡,侵刪)git
- 實現方式
- 採用NSInputStream 讀取H264碼流
- 準備CMVideoFormatDesc:提取sps和pps利用函數CMVideoFormatDescriptionCreateFromH264ParameterSets建立CMVideoFormatDesc
- 準備VTDecompressionSessionRef:根據CMVideoFormatDesc利用函數VTDecompressionSessionCreate建立VTDecompressionSessionRef管理器
- 準備CMBlockBufferRef:提取視頻數據利用函數CMBlockBufferCreateWithMemoryBlock建立CMBlockBufferRef
- 準備CMSampleBuffer:CMSampleBufferCreateReady建立CMSampleBuffer
- 展現圖像
- 採用AVSampleBufferDisplayLayer直接解碼顯示。(該方法解碼過程顯示不出來,是該類提供好的方法)
- 利用VTDecompressionSessionDecodeFrame方法解碼建立CVPixelBufferRef,利用並顯示出來。
視頻編解碼遇到的坑
1. 編碼成功後,使用CMBlockBufferRef經過CMBlockBufferGetDataPointer拿到的數據是一個個的:四個字節的大端length+nalu 的格式。寫入h264文件的時候須要將大端的length替換成{0x00 0x00 0x00 0x01} 這樣的數據格式。
2. 編碼成功後,經過CMVideoFormatDescriptionGetH264ParameterSetAtIndex獲取到sps和pps都須要在前面添加{0x00 0x00 0x00 0x01} 的startcode後寫入h264文件。
3. 解碼時,咱們須要建立CMBlockBufferRef來進行解碼,須要用 四個字節的大端length+nalu 去建立CMBlockBufferRef,而不是使用 {0x00 0x00 0x00 0x01}+nalu 來建立。
本文參考: