1. 程式人生 > 其它 >音視訊開發之H.264 入門知識

音視訊開發之H.264 入門知識

大家如果有做過音視訊相關的專案,那麼肯定對 H.264 相關的概念瞭解的比較通透,這裡我為什麼還要寫這樣一篇文章呢?一來是為了對知識的總結,二來是為了給剛入門音視訊的同學一個參考。

基礎概念

H.264 又稱為 MPEG-4 , 它是一種面向塊,基於運動補償的視訊編碼標準,是目前市面上最常用的一種視訊編碼格式,在 Android 中你可以通過 MediaCodec.createEncoderByType("video/avc") 的形式來建立一個編碼器,也可以通過軟編 avcodec_find_encoder(AV_CODEC_ID_H264) / avcodec_find_encoder_by_name("libx264")

的形式來建立一個編碼器。因為該篇文章的主題是分析 H.264 碼流,就不再過多介紹怎麼來進行編碼了。現在就直接來了解一些常用概念吧。

GOP

兩個 I 幀之間形成的一組圖片,就是 GOP (Group Of Picture) 的概念。

I 幀

I 幀又稱為視訊的關鍵幀,你可以理解為它是一幀畫面的完整影象,可以直接拿這個 I 幀來解碼

特點:

1、它是一個全幀壓縮編碼幀,它將全幀影象資訊進行 JPEG 壓縮編碼及傳輸

2、解碼時僅用 I 幀的資料就可以重構完整影象

3、I 幀描述了影象背景和運動主體的詳情

4、I 幀不需要參考其它畫面而生成

5、I 幀是 P/B 幀的參考幀(其質量直接影響到同組中以後個幀的質量)

6、I 幀是幀組 GOP 的第一幀,在一組中只有一個 I 幀

7、I 幀不需要考慮運動向量

8、I 幀所佔資料的資訊量比較大

B 幀

B 幀又稱為雙向差別幀,也就是本幀與前後幀的差別,大白話的意思就是要解碼 B 幀,不僅要拿到之前快取的畫面,還要解碼之後的畫面,通過前後畫面的疊加來還原最終的畫面。

特點:

1、B 幀是由前面的 I 幀或 P 幀和後面的 P 幀來進行預測的

2、B 幀傳送的是它前面的 I 幀或 P 幀和後面的 P 幀之前的預測誤差及運動向量

3、B 幀是雙向預測編碼幀

4、B 幀壓縮率最高,因為它只反映參考幀間運動主體的變化情況,預測比較準確

5、B 幀不是參考幀,不會造成解碼錯誤的擴散

P 幀

P 幀又稱為前預測編碼幀。P 幀表示的是這一幀跟之前的一個 I 或 P 幀的差別,解碼時需要用之前快取的畫面疊加上本幀定義的差別,來生成最終畫面。

特點:

1、P 幀是 I 幀後面相隔 1~2 幀的編碼幀

2、P 幀採用運動補償的方法傳送它與前面的 I 或 P 真的差值及運動向量

3、解碼時必須將 I 幀中的預測值與預測誤差求和後才能重構完整的 P 幀影象

4、P 幀屬於前向預測的幀間編碼。它只參考前面最靠近它的 I 或者 P 幀

5、P 幀可以是其後面的 P 幀的參考幀,也可以是其前後的 B 幀的參考幀

6、由於 P 幀是參考幀,所以它可能造成解碼錯誤的擴散

7、由於是差值傳送,所以 P 幀的壓縮率比較高

基本的幀概念瞭解的差不多了,下一步我們基於程式碼來分析碼流

碼流分析

H.264 又稱為裸流,是由多個 NALU 組成。如果 NALU 對應的 Slice 為一幀的開始,那麼就用 4 個 位元組表示,即 0x00 00 00 01 , 否則用 3 位元組表示,0x00 00 01。要分析 H.264 碼流首先是從碼流中搜索起始位,也就是剛剛說的 0x00 00 00 01 或者 0x00 00 01 起始位,然後在分離 NALU, 最後再解析各個欄位。下面我們先來看下 NALU Header type 代表的含義:

type 說明
0 保留
1 非 IDR 影象中不採用資料劃分的片段
2 非 IDR 影象中 A 類資料劃分的片段
3 非 IDR 影象中 B 類資料劃分的片段
4 非 IDR 影象中 C 類資料劃分的片段
5 IDR 影象的片段
6 補充增強信心 (SEI)
7 SPS (序列引數集)
8 PPS (影象引數集)
9 分割符
10 序列結束符
11 流結束符
12 填充資料
13 序列引數集擴充套件
14 帶字首的 NAL 單元
15 子序列引數集
16 - 18 保留
19 不採用資料劃分的輔助編碼影象片段
20 編碼片段擴充套件
21 - 23 保留
24 - 31 保留

在實際開發中用的最多的也就是 1 、5 、7、8 , 下面我們用程式碼來進行分析:

程式碼分析

程式碼很簡單,就是讀檔案,搜尋起始碼然後一個位元組一個位元組讀,這裡直接貼結果吧

如何進階學習

成體系的音視訊入門進階的資料少之又少,一個剛畢業小白可能很難切入理解,因為音視訊中涉及大量理論知識,而程式碼的書寫需要結合這些理論,所以搞懂音視訊,編解碼等理論知識至關重要。

本人也是從實習開始接觸音視訊專案,看過很多人的文章,無意中在GitHub上發現一個標星6.8K的開源專案,在這裡分享給大家,讓更多準備學習音視訊的同學更快入門進階。

以下是這份開發文件的部分章節:

階段一:Android多媒體

第1章 三種方式繪製圖片

第2章 AudioRecord錄製PCM音訊

第3章 AudioTrack播放PCM音訊

第4章 Camera視訊採集

第5章 MediaExtractor MediaMuxer 實現視訊的解封裝與合成

第6章 MediaCodec硬編解流程與實踐

階段二:OpenGL ES

第7章 OpenGL ES 基本概念

第8章 GLSL及Shader的渲染流程

第9章 OpenGL ES 繪製平面圖形

第10章 GLSurfaceView原始碼解析&EGL環境

第11章 OpenGL ES矩陣變換與座標系統

第12章 OpenGL ES之紋理

第13章 OpenGL ES 濾鏡 (篇一)

第14章 OpenGL ES 實時濾鏡

第15章 OpenGL ES粒子系統 - 噴泉

第16章 OpenGL ES粒子效果-煙花爆炸

階段三::JNI&NDK

第17章 JNI與NDK的學習和使用

第18章 JNI - 引用型別、異常處理、函式註冊

第19章 NDK構建方式 ndk-build與cmake

第20章 指標、記憶體模型、引用

第21章 運算子過載、繼承、多型、模版

第22章 STL 之 容器

子系列 演算法

第23章 算法系列 - 氣泡排序

第24章 算法系列-快速排序

第25章 算法系列-堆排序

第26章 算法系列-選擇、插入排序以及STL中sort的實現

第27章 演算法序列 - 二叉查詢樹

第28章 演算法序列 - 平衡二叉樹

第29章 演算法序列 - 散列表

階段四 : FFmpeg

第30章 音視訊基礎知識

第31章 FFMPEG常用命令

第32章 FFMPEG +OPENSL ES實現音訊解碼和播放

第33章 FFMPEG + OPENGLES 邊解碼邊播放視訊

有需要的朋友可以【點選此處】找我免費領取。

小結

音視訊行業已經發展很多年了,隨著近幾年移動端越來越多的音視訊APP的出現,將音視訊推向一個高潮,但是由於音視訊的學習成本很高,很多開發者望而卻步,為了跟緊時代的步伐,需要的朋友可以免費獲取一下上文的資料,給大家破除音視訊的“高門檻”,希望可以共同進步。

總之,音視訊已經強勢崛起,相信未來的十年一定是音視訊的十年。並且將音視訊技術與計算機視覺和人工智慧結合將引領未來二十年。

以後我將多多分享相關文章,關注我不要迷路!

現在正是學習音視技術的最佳時機,大家一定要把握住機會,跟上時代的步伐,讓自己可以在未來大有作為。