1、在iOS11的系統之上,蘋果逐漸放開H265硬編硬解的能力,硬解碼的能力只要升級到iOS11之后,iPhone6+以上的機型就支持了(印象中);
H265硬編碼的能力對設備要求較高,不僅要求系統版本在iOS11以上,並且設備在iPhone8以上(目前驗證到),部門ipad設備在調用系統API檢測是否支持HEVC編碼的時候,
雖然返回True,但是依然編碼返回錯誤。
所以我使用了一段真實的硬編代碼進行測試機器到底是否支持硬編碼:
//嘗試創建H265硬編碼器檢測是否支持H265 bool SurpportHW265() { if (@available(iOS 11.0, *)) { if(VTIsHardwareDecodeSupported(kCMVideoCodecType_HEVC)) { VTCompressionSessionRef _encodingSession = nil; CFMutableDictionaryRef sessionAttributes = CFDictionaryCreateMutable( NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); // 創建編碼 OSStatus status = VTCompressionSessionCreate(kCFAllocatorDefault, (int32_t)640, (int32_t)1136, kCMVideoCodecType_HEVC, sessionAttributes, NULL, NULL, NULL, NULL, &_encodingSession); NSLog(@"H264: VTCompressionSessionCreate %d", (int)status); if (status == 0) { VTCompressionSessionCompleteFrames(_encodingSession, kCMTimeInvalid); // End the session VTCompressionSessionInvalidate(_encodingSession); CFRelease(_encodingSession); _encodingSession = NULL; return true; } } } return false; }
2、RTMP推流 擴展支持 H265
RTMP協議是基於TCP協議的,RTMP協議中推流中目前廣泛使用了一種類似FLV Tag的格式,FLV的格式相對非常簡單,從開始到結束一般分為
FLV FILE HEADER + FLV FILE BODY
其中 FLV FILE HEADER 一般9個字節,標記了后面的FLV數據中是否包含音頻或者視頻的一些信息;頭三個字節對應FLV的ascii碼
其中 FLV FILE BODY 又分為下面的結構
prev_tag_size + NextTagHeader + NextTagData | prev_tag_size + NextTagHeader + NextTagData | prev_tag_size + NextTagHeader + NextTagData | 。。。。
以上的結構不停循環
prev_tag_size 為4個字節,標記前面一個TagHeader + TagData 的大小, 第一個Tag因為之前沒有,所以四個字節為0,這里4個字節為大端序
NextTagHeader 一般為11個字節,里面包含 tag類型,時間戳, 數據大小等等
NextTagData 是真正的數據,也就是H264或者H265的NALU的裸數據(去掉開始碼)
3、一個完整的FLV 結構類型
一個推流完整的FLV ,在RTMP建立連接之后會:
先發一個 MetaData的包,這個包對應TagType 為 Script Tag
發一個 Video SequenceHeader 的Tag, 這個Tag 在RTMP的payload 對應的幀類型和編碼類型【是17或者27】 + 【NALU類型是00】+【000000】(三個字節無意義)+ ConfigurationRecord(二進制數據)
發一個 Video 視頻數據的Tag, 這個Tag 在RTMP的payload 對應的幀類型和編碼類型【是17或者27】 + 【NALU類型是01】+【000000】(三個字節無意義)+ 【nalu size】(四個字節)+ 【nalu data】
注意上面音視頻的格式不一樣,視頻數據的封包頭多了4個字節標記每個NALU的大小;如果視頻中payload包含多個NALU,那么每個NALU前面都需要加上 【nalu size】(四個字節)
5、推H265和H264做了哪些改變
1、音頻保持不變
2、視頻的metadata 的 script tag中有一個編碼類型,H264的時候為7 , H265的時候需要改成自定義類型
3、視頻的 Video SequenceHeader 的Tag 中的 ConfigurationRecord 需要更新為 HEVCDecoderConfigurationRecord 類型,這個結構體是公開的
4、 Video 視頻數據的Tag 中, 幀類型和編碼類型【是17或者27 后四個比特,標記編碼類型,需要自己制定類型
6、一些經驗
因為FLV目前沒有兼容H265的標准,所以建議在VideoTag中每個關鍵幀的數據之前加上 VPS NALU| PPS_NALU|SPS_NALU|VIDEO_NALU 格式;每個NALU = NALU Size(4個字節)+ NALU Raw Data
H265相比H264更省帶寬,而且編碼輸出的質量更高,相等碼率下面的流,H265明顯比H264清晰