IOS硬編碼

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);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容