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)鍵接口說明
2.1 碼率控制
??碼率直接影響到圖像的質(zhì)量及大小,故碼率的設(shè)置是至關(guān)重要的。H264有以下4種碼率控制方法:
a. CBR(Constant Bit Rate)是以恒定比特率方式進(jìn)行編碼,有Motion發(fā)生時,由于碼率恒定,只能通過增大QP來減少碼字大小,圖像質(zhì)量變差,當(dāng)場景靜止時,圖像質(zhì)量又變好,因此圖像質(zhì)量不穩(wěn)定。這種算法優(yōu)先考慮碼率(帶寬)。
b. VBR(Variable Bit Rate)動態(tài)比特率,其碼率可以隨著圖像的復(fù)雜程度的不同而變化,因此其編碼效率比較高,Motion發(fā)生時,馬賽克很少。碼率控制算法根據(jù)圖像內(nèi)容確定使用的比特率,圖像內(nèi)容比較簡單則分配較少的碼率(似乎碼字更合適),圖像內(nèi)容復(fù)雜則分配較多的碼字,這樣既保證了質(zhì)量,又兼顧帶寬限制。這種算法優(yōu)先考慮圖像質(zhì)量。
c. CVBR(Constrained VariableBit Rate),這樣翻譯成中文就比較難聽了,它是VBR的一種改進(jìn)方法。但是Constrained又體現(xiàn)在什么地方呢?這種算法對應(yīng)的Maximum bitRate恒定或者Average BitRate恒定。這種方法的兼顧了以上兩種方法的優(yōu)點(diǎn):在圖像內(nèi)容靜止時,節(jié)省帶寬,有Motion發(fā)生時,利用前期節(jié)省的帶寬來盡可能的提高圖像質(zhì)量,達(dá)到同時兼顧帶寬和圖像質(zhì)量的目的。
d. ABR (Average Bit Rate) 在一定的時間范圍內(nèi)達(dá)到設(shè)定的碼率,但是局部碼率峰值可以超過設(shè)定的碼率,平均碼率恒定??梢?strong>作為VBR和CBR的一種折中選擇。
??VideoToolBox框架只支持ABR模式。設(shè)置平均碼率是一個柔性的指標(biāo),實(shí)際輸出碼率允許在其上下浮動。kVTCompressionPropertyKey_DataRateLimits 用來設(shè)置硬性碼率限制,別看這段代碼很冗長,實(shí)際做的就是設(shè)置碼率的硬性限制是每秒碼率不超過平均碼率的 1.5 倍,設(shè)置接口如下所示:
//設(shè)置平均碼率,單位為bps,碼率會上下浮動
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è)置畫質(zhì)
a. BP(Baseline Profile):基本畫質(zhì)。
??支持I/P 幀,只支持無交錯(Progressive)和CAVLC;主要應(yīng)用:可視電話,會議電視,和無線通訊等實(shí)時視頻通訊領(lǐng)域
b. EP(Extended profile):進(jìn)階畫質(zhì)。
??支持I/P/B/SP/SI 幀,只支持無交錯(Progressive)和CAVLC;
c. 主流畫質(zhì)。
??提供I/P/B 幀,支持無交錯(Progressive)和交錯(Interlaced),也支持CAVLC 和CABAC 的支持;主要應(yīng)用:數(shù)字廣播電視和數(shù)字視頻存儲
d. 高級畫質(zhì)。
??在main Profile 的基礎(chǔ)上增加了8×8內(nèi)部預(yù)測、自定義量化、 無損視頻編碼和更多的YUV 格式;應(yīng)用于廣電和存儲領(lǐng)域
//設(shè)置畫質(zhì)
status = VTSessionSetProperty(encoder->_encoderSession,
kVTCompressionPropertyKey_ProfileLevel,
kVTProfileLevel_H264_High_AutoLevel);
IOS 常用畫質(zhì)配置:
實(shí)時直播:
??低清Baseline Level 1.3
??標(biāo)清Baseline Level 3
??半高清Baseline Level 3.1
??全高清Baseline Level 4.1
存儲媒體:
??低清 Main Level 1.3
??標(biāo)清 Main Level 3
??半高清 Main Level 3.1
??全高清 Main Level 4.1
高清存儲:
??半高清 High Level 3.1
??全高清 High Level 4.1
2.3 配置I幀間隔,GOP
// 設(shè)置一個GOP多少幀
VTSessionSetProperty_int(encoder->_encoderSession,
kVTCompressionPropertyKey_MaxKeyFrameInterval,
frameRate * kGOPIntervalInSeconds);
//SetVTSessionProperty(_compressionSession,
kVTCompressionPropertyKey_MaxKeyFrameInterval, 180);
// 設(shè)置3s必須有一個關(guān)鍵幀
//SetVTSessionProperty(_compressionSession,
kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration,
3);
2.4 配置工作模式
??設(shè)置編碼器的工作模式是實(shí)時還是離線,實(shí)時會編得快些,延遲更低,但壓縮效率會差一些,離線則編得慢些,延遲更大,但壓縮效率會更高。本地錄制視頻文件可以使用離線模式,RTC 場景下為了降低延遲,則需要使用實(shí)時模式了。
VTSessionSetProperty(encoder->_encoderSession,
kVTCompressionPropertyKey_RealTime,
kCFBooleanTrue);
2.5 配置是否產(chǎn)生B幀
??High profile 支持 B 幀, 但是 B 幀會加大延遲。
VTSessionSetProperty(encoder->_encoderSession,
kVTCompressionPropertyKey_AllowFrameReordering,
kEnableBFrame ? kCFBooleanTrue : kCFBooleanFalse);