音視訊開發之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")
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的出現,將音視訊推向一個高潮,但是由於音視訊的學習成本很高,很多開發者望而卻步,為了跟緊時代的步伐,需要的朋友可以免費獲取一下上文的資料,給大家破除音視訊的“高門檻”,希望可以共同進步。
總之,音視訊已經強勢崛起,相信未來的十年一定是音視訊的十年。並且將音視訊技術與計算機視覺和人工智慧結合將引領未來二十年。
以後我將多多分享相關文章,關注我不要迷路!
現在正是學習音視技術的最佳時機,大家一定要把握住機會,跟上時代的步伐,讓自己可以在未來大有作為。