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/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代碼,還需要找一台機器測試下。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM