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 来建立。
本文参考: