H.264格式,iOS硬编解码 以及 iOS 11对HEVC硬编解码的支持
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 == 0) { 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/VideoHardwareStreamDecoder
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/VideoHardwareStreamDecoder
小结
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硬编解码的支持的主要内容,如果未能解决你的问题,请参考以下文章
Ubuntu安装MPEG-4 AAC解码器和H.264解码器