導航:首頁 > 源碼編譯 > h264編碼器源碼

h264編碼器源碼

發布時間:2024-11-14 12:42:35

A. iOS 視頻h264 和 h265 硬編碼-代碼

iOS 視頻h264 和 h265 硬編碼-代碼概覽


在iOS開發中,H265編碼因其優點被廣泛應用。要進行H265硬編碼,關鍵在於判斷設備支持性(iPhone 7及以上,iOS 11以上版本)和初始化編碼器設置。以下是一些關鍵編碼設置:



編碼過程中,對每一幀數據進行處理,例如構造連續的時間戳、設置H264的最大碼率(H265暫不支持)以及使用進行編碼。編碼完成後,涉及截取I幀、提取SPS/PPS等信息並寫入文件。


碼流數據結構上,H264和H265有不同,H265中vps在流數據的最前面。H264碼流由NALU單元構成,包含圖像數據和參數信息,如FormatDesc、SPS和PPS。通過CMVideoFormatDescriptionRef、CMBlockBufferRef和時間信息,可以創建CMSampleBuffer用於解碼。

B. FFmpeg-視頻編碼-YUV編碼出H264

編碼出來的h264數據可以直接使⽤ffplay播放

int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align);

函數的作⽤是通過指定像素格式、圖像寬、圖像⾼來計算所需的內存⼤⼩

重點說明⼀個參數 align :此參數是設定內存對⻬的對⻬數,也就是按多⼤的位元組進⾏內存對⻬:

av_image_alloc()是這樣定義的。此函數的功能是按照指定的寬、⾼、像素格式來 分配圖像內存

int av_image_alloc(uint8_t *pointers[4], int linesizes[4], int w, int h, enum AVPixelFormat pix_fmt, int align);

int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4], const uint8_t *src, enum AVPixelFormat pix_fmt, int width, int height, int align);

av_image_fill_arrays()函數 ⾃身不具備內存申請的功能 ,此函數類似於格式化已經申請的內存,即通過 av_malloc()函數申請的內存空間,或者av_frame_get_buffer()函數申請的內存空間。

av_image_fill_arrays()中 參數具體說明

視頻碼率是視頻數據(包含視頻⾊彩量、亮度量、像素量)每秒輸出的位數。⼀般⽤的單位是kbps。

在視頻會議應用中,視頻質量和網路帶寬佔用是矛盾的,通常情況下視頻流佔用的帶寬越高則視頻質量也越高;如要求高質量的視頻效果,那麼需要的網路帶寬也越大;解決這一矛盾的鑰匙當然是視頻編解碼技術。評判一種視頻編解碼技術的優劣,是比較在相同的帶寬條件下,哪個視頻質量更好;在相同的視頻質量條件下,哪個佔用的網路帶寬更少。
是不是視頻碼率越高,質量越好呢?理論上是這樣的,然而在我們肉眼分辨的范圍內,當碼率高到一定程度,感覺沒有什麼差別。所以碼率設置有它的最優值,H.264(也叫AVC或X.264)的文檔中,視頻的建議碼率如下:

鑒於x264的參數眾多,各種參數的配合復雜,為了使⽤者⽅便,x264建議如⽆特別需要可使 ⽤preset和tune設置。這套開發者推薦的參數較為合理,可在此基礎上在調整⼀些具體參數以符合⾃⼰需要,⼿動設定的參數會覆蓋preset和tune⾥的參數。

使⽤ ffmpeg -h encoder=libx264 命令查詢相關⽀持的參數

x264是⼀個 H.264/MPEG4 AVC 編碼器,本指南將指導新⼿如何創建⾼質量的H.264視頻。 對於普通⽤戶通常有兩種碼率控制模式:CRF(Constant Rate Factor)和Two pass ABR。碼率控制是⼀種決定為每⼀個視頻幀分配多少⽐特數的⽅法,它將決定⽂件的⼤⼩和質量的分配。

如果你在編譯和安裝libx264 ⽅⾯需要幫助,請查看ffmpeg和x264編譯指南: http://ffmpeg.org/trac/ffmpeg/wiki/CompilationGuide

量化⽐例的范圍為0~51,其中0為⽆損模式, 23 為預設值,51可能是最差的。該數字越⼩,圖像質量越 好。從主觀上講,18~28是⼀個合理的范圍。18往往被認為從視覺上看是⽆損的,它的輸出視頻質量和輸 ⼊視頻⼀模⼀樣或者說相差⽆⼏。但從技術的⻆度來講,它依然是有損壓縮。

若CRF值加6,輸出碼率⼤概減少⼀半;若CRF值減6,輸出碼率翻倍。通常是在保證可接受視頻質量的前提下選擇⼀個最⼤的CRF值,如果輸出視頻質量很好,那就嘗試⼀個更⼤的值,如果看起來很糟,那就嘗 試⼀個⼩⼀點值。

預設是⼀系列參數的集合,這個集合能夠在編碼速度和壓縮率之間做出⼀個權衡。⼀個編碼速度稍慢的預 設會提供更⾼的壓縮效率(壓縮效率是以⽂件⼤⼩來衡量的)。這就是說,假如你想得到⼀個指定⼤⼩的⽂ 件或者采⽤恆定⽐特率編碼模式,你可以采⽤⼀個較慢的預設來獲得更好的質量。同樣的,對於恆定質量編碼模式,你可以通過選擇⼀個較慢的預設輕松地節省⽐特率。

如果你很有耐⼼,通常的建議是使⽤最慢的預設。⽬前所有的預設按照編碼速度降序排列為:

tune是x264中重要性僅次於preset的選項,它是視覺優化的參數,tune可以理解為視頻偏好(或者視頻類型),tune不是⼀個單⼀的參數,⽽是由⼀組參數構成 -tune 來改變參數設置。當前的 tune包括:

如果你不確定使⽤哪個選項或者說你的輸⼊與所有的tune皆不匹配,你可以忽略--tune 選項。 你可以使⽤-tune來查看tune列表,也可以通過x264 --fullhelp來查看tune所采⽤的參數配置。

另外⼀個可選的參數是-profile:v,它可以將你的輸出限制到⼀個特定的 H.264 profile。⼀些⾮常⽼的或者 要被淘汰的設備僅⽀持有限的選項,⽐如只⽀持baseline或者main。

所有的profile 包括:

查找指定的編碼器

初始化

設置編碼器參數

將codec_ctx和codec進行綁定

分配pkt和frame

計算出每一幀的數據 像素格式 * 寬 * 高

讀取YUV數據

格式化已經申請的內存,將YUV數據,格式化放入frame中

發送YUV數據進編碼器

從編碼器中獲取encode的packet數據

encode的packet數據寫入文件

C. 手寫H264編碼器

在視頻編碼領域,H.264作為新一代標准,以其高壓縮率和高質量著稱。本文將深入探討視頻編碼中三種關鍵幀(I幀、P幀和B幀)的概念及其編碼原理。

1. **幀類型解析**

**I幀**:幀內編碼幀,表示關鍵幀,解碼時僅需本幀數據,完整保留畫面信息。

**P幀**:前向預測編碼幀。描述與前一關鍵幀(或P幀)的差異,解碼時需要前一幀的緩存。

**B幀**:雙向預測內插編碼幀。記錄與前後幀的差異,解碼時需前後兩幀數據。

2. **壓縮演算法詳解**

**幀內壓縮**:僅考慮本幀數據,類似於靜態圖像壓縮,適用於獨立解碼顯示。

**幀間壓縮**:利用相鄰幀之間的冗餘信息,通過比較數據差異進行壓縮,適用於連續視頻的高效編碼。

**運動預測編碼**:在P幀編碼中,通過搜索參考幀中與當前幀塊最相似的塊,描述差異,顯著減少數據量。

3. **手寫H264編碼器**

實現一個H264編碼器需要理解基本圖像處理知識、信號時域和頻域原理,以及傅立葉變換技術。

**第一步**:有損圖像壓縮。將RGB圖像轉換為YUV格式,對Y分量進行8x8塊的DCT變換,量化和壓縮。

**第二步**:宏塊誤差計算。定義運動預測編碼原理,通過比較宏塊差異,生成P幀。

**第三步**:運動預測編碼實現。搜索參考幀中與當前幀宏塊最相似的位置,記錄差異。

**第四步**:P幀編碼。將搜索結果進行壓縮,生成最終P幀數據。

**第五步**:實現GOP生成。通過I幀和P幀構建視頻流,確保連續播放。

**第六步**:容器組裝。將編碼後的GOP以特定格式保存,如MP4,形成完整視頻文件。

通過上述步驟,理解並實現H264編碼器的基礎原理,為視頻壓縮和流媒體傳輸提供了堅實的基礎。掌握這些技術不僅能夠優化視頻質量與存儲,還能在實時通信和網路應用中發揮關鍵作用。

D. 音視頻入門——H.264編碼(宏塊+片+幀)淺析

(1)圖像冗餘信息:空間冗餘、時間冗餘
(2)視頻編碼關鍵點:壓縮比、演算法復雜度、還原度
(3)H.264的2大組成部分:視頻編碼層VCL和網路抽象層面NAL Network Abstract Layer,

(1)宏塊 MB macroblock
(2)片 slice
(3)幀 frame
(4)I幀、B幀、P幀

(5)幀率 fps
(6)像素->宏塊->片->幀->序列->碼流

我們了解了什麼是宏快,宏快作為壓縮視頻的最小的一部分,需要被組織,然後在網路之間做相互傳輸。

H264更深層次 —》宏塊 太淺了

如果單純的用宏快來發送數據是雜亂無章的,就好像在沒有集裝箱 出現之前,貨物總是隨意被堆放到船上。

上貨(編碼),下貨是非常痛苦的。 當集裝箱出現之後,一切都發生了改變,傳輸效率大大增高。

集裝箱可以理解成H264編碼標准,他制定了相互傳輸的格式,將宏快 有組織,有結構,有順序的形成一系列的碼流。這種碼流既可 通過 InputStream 網路流的數據進行傳輸,也可以封裝成一個文件進行保存

H264: H264/AVC是廣泛採用的一種編碼方式 。 主要作用是為了傳輸

組成H264碼流的結構中 包含以下幾部分 ,從大到小排序依次是

NAL層:(Network Abstraction Layer,視頻數據網路抽象層): 它的作用是H264隻要在網路上傳輸,在傳輸的過程每個包乙太網是1500位元組,而H264的幀往往會大於1500位元組,所以要進行拆包,將一個幀拆成多個包進行傳輸,所有的拆包或者組包都是通過NAL層去處理的。
VCL層:(Video Coding Layer,視頻數據編碼層): 對視頻原始數據進行壓縮

H264是一種碼流 類似與一種不見頭,也不見尾的一條河流。如何從和流中取到自己想要的數據呢,

在H264的標磚中有這樣的一個封裝格式叫做"Annex-B"的位元組流格式。 它是H264編碼的主要位元組流格式。

幾乎市面上的編碼器是以這種格式進行輸出的。起始碼0x 00 00 00 01 或者 0x 00 00 01 作為分隔符。

兩個 0x 00 00 00 01之間的位元組數據 是表示一個NAL Unit

切片頭:包含了一組片的信息,比如片的數量,順序等等

H264中,以16x16的宏塊為編碼最小單元,一個宏塊可以被分成多個4x4或8x8的塊
同一個宏塊內,像素的相似程度會比較高,若16x16的宏塊中,像素相差較大,那麼就需要繼續細分

當然,像素塊越小,編碼的復雜度也會隨之增加,編碼效率自然就會降低。但是這樣是值得的,因為圖像的壓縮效率有了顯著提高,也就是編碼後得到的相同質量的圖像,H.264的壓縮比更大,佔用的空間及帶寬更小。

不合理的分塊會出現塊效應,即塊與塊之間色差明顯
海思在3559之後有deblock的介面可以應對塊效應,3519上用的很多

在I幀中,全部宏塊都採用幀內預測的方式,所以解碼時僅用I幀的數據就可重構完整圖像,不須要參考其餘畫面而生成。web

H.264中規定了兩種類型的I幀:普通I幀(normal Iframes)和IDR幀(InstantaneousDecoding Refresh, 即時解碼刷新)。 IDR幀實質也是I幀,使用幀內預測。IDR幀的做用是當即刷新,會致使DPB(Decoded Picture Buffer參考幀列表)清空,而I幀不會。因此IDR幀承擔了隨機訪問功能,一個新的IDR幀開始,能夠從新算一個新的Gop開始編碼,播放器永遠能夠從一個IDR幀播放,由於在它以後沒有任何幀引用以前的幀。若是一個視頻中沒有IDR幀,這個視頻是不能隨機訪問的。全部位於IDR幀後的B幀和P幀都不能參考IDR幀之前的幀,而普通I幀後的B幀和P幀仍然能夠參考I幀以前的其餘幀。IDR幀阻斷了偏差的積累,而I幀並無阻斷偏差的積累。演算法

一個GOP序列的第一個圖像叫作 IDR 圖像(當即刷新圖像),IDR 圖像都是 I 幀圖像,但I幀不必定都是IDR幀,只有GOP序列的第1個I幀是IDR幀。緩存

疑問:按照GOP、IDR幀、I幀的解釋,若是一個GOP出現除去第一個IDR幀以外的I幀,是不存在的,那這樣的話,就不存在非IDR的I幀了,但是為何還要說明非IDR的I幀呢。svg

解答:H264編碼存在多種編碼方式CBR、VBR、CVBR、ABR等等,VBR編碼模式下圖像內容變化差別很大時,會動態調整I幀的數量,所以GOP的概念須要修正:兩個IDR幀之間的間隔為一組GOP,一組GOP中能夠出現非IDR的I幀。編碼

P幀:前向預測編碼幀。P幀表示的是這一幀跟以前的一個關鍵幀(或P幀)的差異,解碼時須要用以前緩存的畫面疊加上本幀定義的差異,生成最終畫面,P幀沒有完整畫面數據,只有與前一幀的畫面差別的數據。P幀的壓縮率20code

B幀:雙向預測內插編碼幀。B幀是雙向差異幀,也就是B幀記錄的是本幀與先後幀的差異,要解碼B幀,不只要取得以前的緩存畫面,還要解碼以後的畫面,經過先後畫面的與本幀數據的疊加取得最終的畫面。B幀壓縮率高,約為50,可是解碼時CPU會比較累。orm

通常能夠輸出H264幀的USB攝像頭,使用的是BP-Baseline Profile,只有I幀與P幀。視頻

而slice呢,也是對宏塊的劃分

本文簡單敘述了;音視頻中的H264編碼中的,宏塊、幀、片。音視頻還有更深入的學習,知識范圍很廣,需要一套很詳細的學習資料與路線。我推薦上面的一套入門到精通資料輔佐。

閱讀全文

與h264編碼器源碼相關的資料

熱點內容
android圖片變灰 瀏覽:268
linuxvi下一個 瀏覽:973
安卓手機的應用鎖怎麼解 瀏覽:735
linux增加路徑 瀏覽:849
sql身份證號最後四位加密 瀏覽:533
xp系統表格加密 瀏覽:856
光遇安卓軍大衣什麼時候上線 瀏覽:840
android應用商店圖標 瀏覽:341
java計算圓的面積 瀏覽:643
應用編譯優化recovery 瀏覽:577
域控命令n 瀏覽:258
php導出文件 瀏覽:13
谷歌地圖網頁版無法連接伺服器地址 瀏覽:298
菜鳥工具在線編譯python 瀏覽:858
柵格化命令有何作用 瀏覽:823
為什麼壓縮文件不能解壓 瀏覽:311
足球app哪個軟體好 瀏覽:96
產品經理逼瘋程序員的一天 瀏覽:17
修改svn伺服器ip地址 瀏覽:584
下列關於編譯說法正確的是 瀏覽:246