1. IOS硬編碼步驟
編碼步驟:
? 創(chuàng)建編碼器啄踊,調(diào)用接口 VTCompressionSessionCreate
? 設(shè)置編碼器屬性:幀率忧设、碼率、GOP颠通、分辨率址晕、像素格式,調(diào)用接口 VTSessionSetProperty
? 設(shè)置完屬性準(zhǔn)備編碼顿锰,調(diào)用接口VTCompressionSessionPrepareToEncodeFrames
? 編碼谨垃,調(diào)用接口VTCompressionSessionEncodeFrame輸入采集到的視頻數(shù)據(jù)
? 獲取到編碼后的數(shù)據(jù)并進(jìn)行處理
? 停止編碼器,調(diào)用接口VTCompressionSessionCompleteFrames
? 銷毀編碼器硼控,調(diào)用接口VTCompressionSessionInvalidate
2. 關(guān)鍵接口說(shuō)明
2.1 碼率控制
??碼率直接影響到圖像的質(zhì)量及大小刘陶,故碼率的設(shè)置是至關(guān)重要的。H264有以下4種碼率控制方法:
a. CBR(Constant Bit Rate)是以恒定比特率方式進(jìn)行編碼牢撼,有Motion發(fā)生時(shí)匙隔,由于碼率恒定,只能通過(guò)增大QP來(lái)減少碼字大小熏版,圖像質(zhì)量變差纷责,當(dāng)場(chǎng)景靜止時(shí),圖像質(zhì)量又變好撼短,因此圖像質(zhì)量不穩(wěn)定再膳。這種算法優(yōu)先考慮碼率(帶寬)。
b. VBR(Variable Bit Rate)動(dòng)態(tài)比特率曲横,其碼率可以隨著圖像的復(fù)雜程度的不同而變化喂柒,因此其編碼效率比較高,Motion發(fā)生時(shí)禾嫉,馬賽克很少灾杰。碼率控制算法根據(jù)圖像內(nèi)容確定使用的比特率,圖像內(nèi)容比較簡(jiǎn)單則分配較少的碼率(似乎碼字更合適)夭织,圖像內(nèi)容復(fù)雜則分配較多的碼字吭露,這樣既保證了質(zhì)量,又兼顧帶寬限制尊惰。這種算法優(yōu)先考慮圖像質(zhì)量讲竿。
c. CVBR(Constrained VariableBit Rate),這樣翻譯成中文就比較難聽(tīng)了,它是VBR的一種改進(jìn)方法弄屡。但是Constrained又體現(xiàn)在什么地方呢题禀?這種算法對(duì)應(yīng)的Maximum bitRate恒定或者Average BitRate恒定。這種方法的兼顧了以上兩種方法的優(yōu)點(diǎn):在圖像內(nèi)容靜止時(shí)膀捷,節(jié)省帶寬迈嘹,有Motion發(fā)生時(shí),利用前期節(jié)省的帶寬來(lái)盡可能的提高圖像質(zhì)量,達(dá)到同時(shí)兼顧帶寬和圖像質(zhì)量的目的秀仲。
d. ABR (Average Bit Rate) 在一定的時(shí)間范圍內(nèi)達(dá)到設(shè)定的碼率融痛,但是局部碼率峰值可以超過(guò)設(shè)定的碼率,平均碼率恒定神僵⊙闼ⅲ可以作為VBR和CBR的一種折中選擇。
??VideoToolBox框架只支持ABR模式保礼。設(shè)置平均碼率是一個(gè)柔性的指標(biāo)沛励,實(shí)際輸出碼率允許在其上下浮動(dòng)。kVTCompressionPropertyKey_DataRateLimits 用來(lái)設(shè)置硬性碼率限制炮障,別看這段代碼很冗長(zhǎng)目派,實(shí)際做的就是設(shè)置碼率的硬性限制是每秒碼率不超過(guò)平均碼率的 1.5 倍,設(shè)置接口如下所示:
//設(shè)置平均碼率胁赢,單位為bps企蹭,碼率會(huì)上下浮動(dòng)
VTStatus status = VTSessionSetProperty_int(_encoderSession,
kVTCompressionPropertyKey_AverageBitRate,
_bitrate * 1024 * 1.0);
int bytesLimit = _bitrate * 1024 * GopValue / 8;
int secondLimit = GopValue;
CFNumberRef n1 = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &bytesLimit);
CFNumberRef n2 = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &secondLimit);
const void *values[] = {n1, n2};
CFArrayRef dataRateLimits = CFArrayCreate(kCFAllocatorDefault,
(const void**)&values,
sizeof(values)/sizeof(values[0]),
NULL);
status = VTSessionSetProperty(_encoderSession, kVTCompressionPropertyKey_DataRateLimits, dataRateLimits);
CFRelease(dataRateLimits);
CFRelease(n1);
CFRelease(n2);
2.2 設(shè)置畫(huà)質(zhì)
a. BP(Baseline Profile):基本畫(huà)質(zhì)。
??支持I/P 幀徘键,只支持無(wú)交錯(cuò)(Progressive)和CAVLC练对;主要應(yīng)用:可視電話遍蟋,會(huì)議電視吹害,和無(wú)線通訊等實(shí)時(shí)視頻通訊領(lǐng)域
b. EP(Extended profile):進(jìn)階畫(huà)質(zhì)。
??支持I/P/B/SP/SI 幀虚青,只支持無(wú)交錯(cuò)(Progressive)和CAVLC它呀;
c. 主流畫(huà)質(zhì)。
??提供I/P/B 幀棒厘,支持無(wú)交錯(cuò)(Progressive)和交錯(cuò)(Interlaced)蹄葱,也支持CAVLC 和CABAC 的支持祝峻;主要應(yīng)用:數(shù)字廣播電視和數(shù)字視頻存儲(chǔ)
d. 高級(jí)畫(huà)質(zhì)。
??在main Profile 的基礎(chǔ)上增加了8×8內(nèi)部預(yù)測(cè)、自定義量化情萤、 無(wú)損視頻編碼和更多的YUV 格式;應(yīng)用于廣電和存儲(chǔ)領(lǐng)域
//設(shè)置畫(huà)質(zhì)
status = VTSessionSetProperty(encoder->_encoderSession,
kVTCompressionPropertyKey_ProfileLevel,
kVTProfileLevel_H264_High_AutoLevel);
IOS 常用畫(huà)質(zhì)配置:
實(shí)時(shí)直播:
??低清Baseline Level 1.3
??標(biāo)清Baseline Level 3
??半高清Baseline Level 3.1
??全高清Baseline Level 4.1
存儲(chǔ)媒體:
??低清 Main Level 1.3
??標(biāo)清 Main Level 3
??半高清 Main Level 3.1
??全高清 Main Level 4.1
高清存儲(chǔ):
??半高清 High Level 3.1
??全高清 High Level 4.1
2.3 配置I幀間隔,GOP
// 設(shè)置一個(gè)GOP多少幀
VTSessionSetProperty_int(encoder->_encoderSession,
kVTCompressionPropertyKey_MaxKeyFrameInterval,
frameRate * kGOPIntervalInSeconds);
//SetVTSessionProperty(_compressionSession,
kVTCompressionPropertyKey_MaxKeyFrameInterval, 180);
// 設(shè)置3s必須有一個(gè)關(guān)鍵幀
//SetVTSessionProperty(_compressionSession,
kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration,
3);
2.4 配置工作模式
??設(shè)置編碼器的工作模式是實(shí)時(shí)還是離線饵较,實(shí)時(shí)會(huì)編得快些玲销,延遲更低,但壓縮效率會(huì)差一些支救,離線則編得慢些抢野,延遲更大,但壓縮效率會(huì)更高各墨。本地錄制視頻文件可以使用離線模式指孤,RTC 場(chǎng)景下為了降低延遲,則需要使用實(shí)時(shí)模式了。
VTSessionSetProperty(encoder->_encoderSession,
kVTCompressionPropertyKey_RealTime,
kCFBooleanTrue);
2.5 配置是否產(chǎn)生B幀
??High profile 支持 B 幀, 但是 B 幀會(huì)加大延遲恃轩。
VTSessionSetProperty(encoder->_encoderSession,
kVTCompressionPropertyKey_AllowFrameReordering,
kEnableBFrame ? kCFBooleanTrue : kCFBooleanFalse);