iOS视频硬件编解码H264

iOS视频硬件编解码H264

  • 硬件编码的环境:iOS8以前是私有API,仅提供使用不能发布上线,iOS8以后苹果开放了VideoToolbox框架支持硬件编码。
  • 硬件编码的好处:iOS8以前使用的通常是软编,软编对CPU的消耗比较严重。硬件编码的好处是能够几大的提高效率,降低CPU的消耗。
  • VideoToolbox 是一套纯C的API,可以在多个语言环境下使用。

视频编码

  1. 编码前和编码后的CMSampleBufferRef有什么不同我们用一张图来说明


    (图片来自网络,侵删)

  2. 实现方式

    • 准备编码前的CMSampleBufferRef:采用AVCaptureSession实现视频采集。
    • 编码:采用VTCompressionSessionRef实现将采集的未编码的CMSampleBufferRef编码成编码完成的CMSampleBufferRef。
    • 存储:将编码完成的CMSampleBufferRef转换成H264码流。

视频解码

  1. H264码流格式:H264码流是有startCode+NALU单元组成,NALU包含视频图像数据和参数信息,CMBlockBuffer内包含了图像数据信息,CMVideoFormatDesc内包含了参数信息(sps,pps)。下图显示H264码流结构

(图片来自网络,侵删)

  1. 实现方式
    • 采用NSInputStream 读取H264码流
    • 准备CMVideoFormatDesc:提取sps和pps利用函数CMVideoFormatDescriptionCreateFromH264ParameterSets创建CMVideoFormatDesc
    • 准备VTDecompressionSessionRef:根据CMVideoFormatDesc利用函数VTDecompressionSessionCreate创建VTDecompressionSessionRef管理器
    • 准备CMBlockBufferRef:提取视频数据利用函数CMBlockBufferCreateWithMemoryBlock创建CMBlockBufferRef
    • 准备CMSampleBuffer:CMSampleBufferCreateReady创建CMSampleBuffer
    • 展示图像
      1. 采用AVSampleBufferDisplayLayer直接解码显示。(该方法解码过程显示不出来,是该类提供好的方法)
      2. 利用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 来创建。

详情代码:https://github.com/fushengit/AudioVideo

本文参考:

原文地址:https://www.cnblogs.com/fusheng-it/p/7911000.html