美文网首页
iOS HEVC(H.265)

iOS HEVC(H.265)

作者: Goning | 来源:发表于2018-07-23 11:33 被阅读500次

    一、HEVC(H.265)介绍

    HEVC全称High Efficiency Video Coding(高效率视频编码),是比H.264更加优秀的一种视频压缩标准(也称为H.265)。H.265的压缩性能要高于H.264一倍左右。
    苹果于北京时间2017年6月6日凌晨召开的WWDC 2017大会上推出了iOS 11系统,并推出了使用VideoToolBox对H.265的硬编硬解的支持。
    但是并不是所有的iOS设备升级到iOS 11都可以使用H.265的硬编/解功能,H.265硬解最少需要A9芯片的iPhone 6s/iPhone 6s Plus/iPhone SE,H.265硬编则最少需要A10芯片的iPhone 7/iPhone 7 Plus。


    二、VideoToolBox编码

    使用VideoToolBox进行H.264和H.265编码的流程完全相同,只在创建和配置编码器上存在少量差异,下面以VideoToolBox的编码流程为线索,说明使用两种编码格式时的区别。

    1. 创建VTCompressionSession
    VT_EXPORT OSStatus 
    VTCompressionSessionCreate(
        CM_NULLABLE CFAllocatorRef                          allocator,
        int32_t                                             width,
        int32_t                                             height,
        CMVideoCodecType                                    codecType,
        CM_NULLABLE CFDictionaryRef                         encoderSpecification,
        CM_NULLABLE CFDictionaryRef                         sourceImageBufferAttributes,
        CM_NULLABLE CFAllocatorRef                          compressedDataAllocator,
        CM_NULLABLE VTCompressionOutputCallback             outputCallback,
        void * CM_NULLABLE                                  outputCallbackRefCon,
        CM_RETURNS_RETAINED_PARAMETER CM_NULLABLE VTCompressionSessionRef * CM_NONNULL compressionSessionOut) API_AVAILABLE(macosx(10.8), ios(8.0), tvos(10.2));
    
    • 如果使用H.264编码功能,参数codecType需要设置为kCMVideoCodecType_H264
    • 如果使用H.265编码功能,参数codecType需要设置为kCMVideoCodecType_HEVC;

    其他参数在使用两种编码格式时没有区别。

    2. 设置编码相关参数
    VT_EXPORT OSStatus 
    VTSessionSetProperty(
      CM_NONNULL VTSessionRef       session,
      CM_NONNULL CFStringRef        propertyKey,
      CM_NULLABLE CFTypeRef         propertyValue ) API_AVAILABLE(macosx(10.8), ios(8.0), tvos(10.2));
    

    其中在配置kVTCompressionPropertyKey_ProfileLevel属性时,H.264和H.265有各自不同的ProfileLevel定义,与H.265相关的只有两个,如下所示:

    VT_EXPORT const CFStringRef kVTProfileLevel_HEVC_Main_AutoLevel API_AVAILABLE(macosx(10.13), ios(11.0), tvos(11.0));
    VT_EXPORT const CFStringRef kVTProfileLevel_HEVC_Main10_AutoLevel API_AVAILABLE(macosx(10.13), ios(11.0), tvos(11.0));
    
    3. 启动编码
    VT_EXPORT OSStatus
    VTCompressionSessionPrepareToEncodeFrames( CM_NONNULL VTCompressionSessionRef session ) API_AVAILABLE(macosx(10.9), ios(8.0), tvos(10.2));
    
    4. 循环输入源数据(yuv类型)
    VT_EXPORT OSStatus
    VTCompressionSessionEncodeFrame(
        CM_NONNULL VTCompressionSessionRef  session,
        CM_NONNULL CVImageBufferRef         imageBuffer,
        CMTime                              presentationTimeStamp,
        CMTime                              duration, // may be kCMTimeInvalid
        CM_NULLABLE CFDictionaryRef         frameProperties,
        void * CM_NULLABLE                  sourceFrameRefCon,
        VTEncodeInfoFlags * CM_NULLABLE     infoFlagsOut ) API_AVAILABLE(macosx(10.8), ios(8.0), tvos(10.2));
    
    5. 获取编码后的数据

    通过在创建VTCompressionSession传入回调函数,获取编码后的数据。

    typedef void (*VTCompressionOutputCallback)(
            void * CM_NULLABLE outputCallbackRefCon,
            void * CM_NULLABLE sourceFrameRefCon, 
            OSStatus status, 
            VTEncodeInfoFlags infoFlags,
            CM_NULLABLE CMSampleBufferRef sampleBuffer );
    

    至此针对使用VideoToolBox进行H.264/H.265编码的基本流程已经介绍完毕。


    三、VideoToolBox解码

    VideoToolBox的解码主要涉及以下几个函数:

    VTDecompressionSessionCreate 创建解码session
    VTDecompressionSessionDecodeFrame 解码一个frame
    VTDecompressionSessionInvalidate 销毁解码session
    

    其中VTDecompressionSessionCreate创建session时需要CMVideoFormatDescriptionRef类型的视频格式描述,而对于CMVideoFormatDescriptionRef,VideoToolBox中提供了多个方法可以创建:

    CMVideoFormatDescriptionCreate
    CMVideoFormatDescriptionCreateForImageBuffer
    CMVideoFormatDescriptionCreateFromH264ParameterSets
    CMVideoFormatDescriptionCreateFromHEVCParameterSets
    

    其中最后一个CMVideoFormatDescriptionCreateFromHEVCParameterSets是在iOS11中新增的一个方法,用以创建H.265视频格式的描述。

    对于H.264和H.265的解码,在VideoToolBox层面的操作完全一致,唯一不同的就是视频格式的描述类型不同。最常使用也最容易理解的为后两个通过ParameterSets来创建的函数,前两个函数的创建方式未作详细了解。

    至此,对使用VideoToolBox解码H.265视频的重点就放在如何获取ParameterSets(即VPS、SPS和PPS)上。


    四、H.265 NALU

    与H.264的NALU Header相比(H.264的NALU Header为一个字节),H.265的NALU Header由两个字节构成:
    0----------------1----------------
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    | F | Type | LayerId | TID |
    +------------ - +---------------- - +

    H265 nalu header

    HEVC加入了NAL所在的时间层的ID,去除了nal_ref_idc,此信息合并到了naltype中。通常情况下F为0,layerid为0, TID为1。

    类型判断方式为分隔符之后的第一个字节右移一位的值。
    所以,H.265编码格式的NALU类型判断方式如下,code为NALU Header的第一个字节:

    int type = (code & 0x7E)>>1;
    

    00 00 00 01 40 01 的nuh_unit_type的值为 32, 语义为视频参数集 VPS
    00 00 00 01 42 01 的nuh_unit_type的值为 33, 语义为序列参数集 SPS
    00 00 00 01 44 01 的nuh_unit_type的值为 34, 语义为图像参数集 PPS
    00 00 00 01 4E 01 的nuh_unit_type的值为 39, 语义为补充增强信息 SEI
    00 00 00 01 26 01 的nuh_unit_type的值为 19, 语义为可能有RADL图像的IDR图像的SS编码数据 IDR
    00 00 00 01 02 01 的nuh_unit_type的值为1, 语义为被参考的后置图像,且非TSA、非STSA的SS编码数据

    在编码过程中,从编码器获取码流的时候,1、2、3、4、5是在一帧数据当中。相当于H.264的I帧。


    本文主要参考并转载来自于作者:金山视频云
    地址:基于iOS11的HEVC(H.265)硬编码/硬解码功能开发指南

    相关文章

      网友评论

          本文标题:iOS HEVC(H.265)

          本文链接:https://www.haomeiwen.com/subject/fzlidftx.html