H.264格式,iOS硬编解码 以及 iOS 11对HEVC硬编解码的支持

1,H.264格式

网络表示层NAL,如图H.264流由一帧一帧的NALU组成; 
SPS:序列参数集,作用于一系列连续的编码图像; 
PPS:图像参数集,作用于编码视频序列中一个或多个独立的图像; 
这两个帧也是独立的NALU。

I-Frame:关键帧,帧内编码后的帧,显示比较完全的一帧; 
P-Frame:参考前一帧,可能只是对比前一帧的运动估计的变化部分; 
B-Frame:会参照前后的帧,其他类似P-Frame。B和P Frame均包含了 帧间编码帧内编码。 
每个NALU以 start code 分隔:00 00 01(3 bytes) 或 00 00 00 01(4 bytes)。

2,iOS对H.264硬编解码

iOS 8以后通过VideoToolBox支持对H.264的硬编码; 
其中的CMSampleBufferRef结构很有意思,需要理解,如图


CMVideoFormatDesc中含有SPS,PPS和其他有用信息;

  • 编码时,CVPixelBuffer—>CMSampleBufferRef(其中包含已压缩的CMBlockBuffer);
  • 解码时,通过VTDecompressionSession来解码, CMSampleBufferRef(内含CMBlockBuffer)—>CVImageBufferRef(解码后的帧数据);

2.1 编码

下图参照WWDC 2014的PDF,从相机或读取视频文件输出的CVPixelBuffer—>Encoder—>CMSampleBufferRef—>NALUs。

经典的编码器 推荐直播推流的LFLiveKit,代码结构良好,数据流向非常清晰,很适合阅读; 
https://github.com/LaiFengiOS/LFLiveKit/blob/master/LFLiveKit/coder/LFHardwareVideoEncoder.m
编码步骤大致是:

  • 1,VTCompressionSessionCreate 通过宽,高,codecType(kCMVideoCodecType_H264),编码回调VTCompressionOutputCallback 等初始化VTCompressionSessionRef实例compressionSession;
  • 2,VTSessionSetProperty设置比较重要的编码属性,如 
    kVTCompressionPropertyKey_MaxKeyFrameInterval,关键帧间隔 
    kVTCompressionPropertyKey_RealTime 
    kVTCompressionPropertyKey_AverageBitRate 
    kVTCompressionPropertyKey_ProfileLevel 
    kVTCompressionPropertyKey_AllowFrameReordering等;最后VTCompressionSessionPrepareToEncodeFrames;
  • 3,往 VTCompressionSessionEncodeFrame添加原始CVPixelBuffer和pts
根据frameCount 计算出的pts
CMTime presentationTimeStamp = CMTimeMake(frameCount, (int32_t)_configuration.videoFrameRate);

和是否I-Frame:

if (frameCount % (int32_t)_configuration.videoMaxKeyframeInterval == ) {
  properties = @{(__bridge NSString *)kVTEncodeFrameOptionKey_ForceKeyFrame: @YES};
}
  • 4,VTCompressionOutputCallback回调中通过解析 CMSampleBufferRef 分别处理SPS,PPS,I-Frame和非I-Frame,添加startcode: 00 00 00 01 然后通过RTMP推出去。

2.2 解码

编码的逆过程,通常在播放器等场景应用,NALU + SPS,PPS—>CMBlockBuffer—>CMSampleBufferRef,再将CMSampleBufferRef包装的帧数据输入到 VTDecompressionSessionDecodeFrame,通过回调中CVImageBufferRef 直接上传OpenGL ES 显示)。 
我写了一个简单的iOS H.264 stream decoder: 
https://github.com/edisongz/ffmpeg_codec_demo

3,iOS 11 对HEVC的支持

iOS 11 + A9芯片开始对HEVC的支持,系统控件AVPlayer,以及Safari浏览器的支持;HEVC相对于H.264压缩效率高40%。 
硬编码需要iOS11 + A10芯片

硬解码需要iOS 11 + A9芯片

iOS 11 新API

//decoder
let hardwareDecodeSupported = VTIsHardwareDecodeSupported(kCMVideoCodecType_HEVC) //encoder
let error = VTCompressionSessionCreate(
kCFAllocatorDefault,
3840, 2160,
kCMVideoCodecType_HEVC,
encoderSpecification,
nil, nil, nil, nil, // using VTCompressionSessionEncodeFrameWithOutputHandler
&session);
if error == kVTCouldNotFindVideoEncoderErr {
// no HEVC encoder
}

具体的HEVC的VideoToolBox的硬件编解码还有待完善;后续完成会添加到这里: 
https://github.com/edisongz/ffmpeg_codec_demo

小结

H.264 iOS环境下的硬编解码都是比较老的WWDC的session了,今年的WWDC 2017,增加的硬编解码HEVC代码,还需要找一台机器测试下。

H.264格式,iOS硬编解码 以及 iOS 11对HEVC硬编解码的支持的更多相关文章

  1. 转:MediaCoder H.264格式编码参数设置及详解

    转: http://mediacoder.com.cn/node/81 由于现在大部分视频转码都选择H.264格式进行编码,同时CUDA编码的画质还达不到x264软编码的质量(如果你对画质无要求,可以 ...

  2. iOS硬解H.264:-VideoToolboxDemo源码分析[草稿]

    来源:http://www.cnblogs.com/michaellfx/p/understanding_-VideoToolboxDemo.html iOS硬解H.264:-VideoToolbox ...

  3. FFmpeg的H.264解码器源代码简单分析:宏块解码(Decode)部分-帧间宏块(Inter)

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  4. FFmpeg的H.264解码器源代码简单分析:熵解码(Entropy Decoding)部分

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  5. H.264开源解码器评测

    转自:http://wmnmtm.blog.163.com/blog/static/38245714201142883032575/ 要播放HDTV,就首先要正确地解开封装,然后进行视频音频解码.所以 ...

  6. 【图像处理】H.264开源解码器评测

    转自:http://wmnmtm.blog.163.com/blog/static/38245714201142883032575/ 要播放HDTV,就首先要正确地解开封装,然后进行视频音频解码.所以 ...

  7. h.264语法结构分析

    NAL Unit Stream Network Abstraction Layer,简称NAL. h.264把原始的yuv文件编码成码流文件,生成的码流文件就是NAL单元流(NAL unit Stre ...

  8. FFmpeg的H.264解码器源代码简单分析:解析器(Parser)部分

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  9. H.264, MPEG4之间的关系

    百度百科搜索 H.264 H.264是国际标准化组织(ISO)和国际电信联盟(ITU)共同提出的继MPEG4之后的新一代数字视频压缩格式.H.264是ITU-T以H.26x系列为名称命名的视频编解码技 ...

随机推荐

  1. 在 ubuntu 下优雅的使用 Sublime Text 3 写 Python

    此文章非技术文,就是一些对于 Sublime 俺之前经常用的 方法(快捷键 )和 工具 有一些工具俺也用过,但是效果不太好,可以说跟shi 一样,可能每个人的用处不一样,咱就不提了,免得招 来口舌之争 ...

  2. 2017TSC世界大脑与科技峰会,多角度深入探讨关于大脑意识

    TSC·世界大脑与科技峰会是全世界范围内的集会,多角度深入探讨关于大脑意识体验来源这一根本话题,我们是谁,现实的本质是什么,我们所处宇宙空间的本质为何.该峰会由亚利桑那大学意识研究中心主办. 会议时间 ...

  3. PHP 无限级分类(递归)

    网上有很多,这是我自己做测试用的$arr = array( array('id'=>1,'name'=>'电脑','pid'=>0), array('id'=>2,'name' ...

  4. 腾讯ISUX网页前端代码分析

    看了一下腾讯ISUX网页,无论是pc端还是移动端,展示都挺好看的,先对其代码进行分析如下: 1,先看前三行代码 <!DOCTYPE html> <!-- 腾讯 ISUX 是腾讯集团核 ...

  5. Docker - 从零开始到操作

    从零开始 介绍Docker的基本概念和命令,并给出简单使用示例和参考信息. Docker - 基础讲义 http://www.cnblogs.com/anliven/p/6281373.html Do ...

  6. 浅析SQL Server数据库中的伪列以及伪列的含义

    SQL Server中的伪列 下午看QQ群有人在讨论(非聚集)索引的存储,说,对于聚集索引表,非聚集索引存储的是索引键值+聚集索引键值:对于非聚集索引表,索引存储的是索引键值+RowId,这应该是一个 ...

  7. 从源码来理解slf4j的绑定,以及logback对配置文件的加载

    项目中的日志系统使用的是slf4j + logback.slf4j作为一个简单日志门面,为各种loging APIs(像java.util.logging, logback, log4j)提供一个简单 ...

  8. mysql中 date datetime time timestamp 的区别

    MySQL中关于时间的数据类型:它们分别是 date.datetime.time.timestamp.year date :"yyyy-mm-dd"  日期     1000-01 ...

  9. SAP ECC EHP7 RFC 发布成WebService

    1.说明介绍 本文将RFC发布成WebService的详细步骤,参考了百度经验http://jingyan.baidu.com/article/8275fc867c9e2946a13cf66c.htm ...

  10. liunx命令2

    查看系统和bios硬件时间 [root@localhost ~]# date '+%y- %m- %d %H:%M' 17- 05- 15 02:57[root@localhost ~]# date ...