H.264格式,iOS硬编解码 以及 iOS 11对HEVC硬编解码的支持
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代码,还需要找一台机器测试下。
参考
LFLiveKit 中硬编码部分
WWDC 2014 Direct Access to Video Encoding and Decoding
WWDC 2017 Working with HEIF and HEVC
Github 自己写的H.264流式解码
H.264格式,iOS硬编解码 以及 iOS 11对HEVC硬编解码的支持的更多相关文章
- 转:MediaCoder H.264格式编码参数设置及详解
转: http://mediacoder.com.cn/node/81 由于现在大部分视频转码都选择H.264格式进行编码,同时CUDA编码的画质还达不到x264软编码的质量(如果你对画质无要求,可以 ...
- iOS硬解H.264:-VideoToolboxDemo源码分析[草稿]
来源:http://www.cnblogs.com/michaellfx/p/understanding_-VideoToolboxDemo.html iOS硬解H.264:-VideoToolbox ...
- FFmpeg的H.264解码器源代码简单分析:宏块解码(Decode)部分-帧间宏块(Inter)
===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...
- FFmpeg的H.264解码器源代码简单分析:熵解码(Entropy Decoding)部分
===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...
- H.264开源解码器评测
转自:http://wmnmtm.blog.163.com/blog/static/38245714201142883032575/ 要播放HDTV,就首先要正确地解开封装,然后进行视频音频解码.所以 ...
- 【图像处理】H.264开源解码器评测
转自:http://wmnmtm.blog.163.com/blog/static/38245714201142883032575/ 要播放HDTV,就首先要正确地解开封装,然后进行视频音频解码.所以 ...
- h.264语法结构分析
NAL Unit Stream Network Abstraction Layer,简称NAL. h.264把原始的yuv文件编码成码流文件,生成的码流文件就是NAL单元流(NAL unit Stre ...
- FFmpeg的H.264解码器源代码简单分析:解析器(Parser)部分
===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...
- H.264, MPEG4之间的关系
百度百科搜索 H.264 H.264是国际标准化组织(ISO)和国际电信联盟(ITU)共同提出的继MPEG4之后的新一代数字视频压缩格式.H.264是ITU-T以H.26x系列为名称命名的视频编解码技 ...
随机推荐
- Redhat 安装ftp服务
介绍: 1 安装ftp服务端及客户端 2 ftp的使用
- MongoDB大数据高并发读写性能测试报告
服务器大小: 单节点部署,磁盘1T,内存128G 并发导入规模: 1,多线程并发导入csv文件 2,csv文件分1万.10万.100万.200万行记录4种大小 3,每个csv对应一个collectio ...
- 开源库RxJava、ButterKnife学习记录
1. 简介 RxJava "RxJava is a Java VM implementation of Reactive Extensions: a library for composin ...
- PAT1028. List Sorting (25)---strcmp
题目链接为:https://www.patest.cn/contests/pat-a-practise/1028 1028. List Sorting (25) Excel can sort reco ...
- 在Caffe上运行Cifar10示例
准备数据集 在终端上运行以下指令: cd caffe/data/cifar10 ./get_cifar10.sh cd caffe/examples/cifar10 ./create_cifar10. ...
- [linux 整理] linux启动过程3
本文介绍linux启动过程的第三步 busybox--------------------> rc init busybox位置即内容 busybox/init/init.c 1.各种设置信号 ...
- nginx 日志分割(简单、全面)
Nginx 日志分割 因业务需要做了简单的Nginx 日志分割, 第1章 详细配置如下. #建议在mkdir /home/shell -p 专门写shell 脚本位置 root@localhost ...
- 【 js 基础 】【 源码学习 】 setTimeout(fn, 0) 的作用
在 zepto 源码中,$.fn 对象 有个 ready 函数,其中有这样一句 setTimeout(fn,0); $.fn = { ready: function(callback){ // don ...
- 细说C#中的系列化与反系列化的基本原理和过程
虽然我们平时都使用第三方库来进行系列化和反系列化,用起来也很方便,但至少得明白系列化与反系列化的基本原理. 注意:从.NET Framework 2.0 开始,系列化格式化器类SoapFormatte ...
- spring-线程池(1)
多线程并发处理起来通常比较麻烦,如果你使用spring容器来管理业务bean,事情就好办了多了.spring封装了java的多线程的实现,你只需要关注于并发事物的流程以及一些并发负载量等特性,具体来说 ...