FFMPEG NOTE

H.264 / MPEG-4 AVC 是優秀的視訊編碼格式 就目前已成熟的視訊編碼格式而言,H.264的壓縮率是最佳的。 壓縮率極高,可以只用很低 bitrate 提供堪用畫質。

而 x264 為免費開放原始碼的 H.264 / MPEG-4 AVC 編碼器, 是目前編碼效率最高的開放原始碼 H.264 編碼器。

此文只是基礎知識,說明只是大略而已。

H.264: Wiki x264: 官網、Wiki

索引: #1F: 下載、基本參數設定 #2F: GUI - 圖形介面 工具介面介紹 #3F: CLI - 命令列介面 使用教學 #4F: CLI - FFmpeg with libx264 #5F: 其他 x264 (CLI) 編譯版 #6F: 常見設備的相容編碼參數

H.264 Profiles Baseline Profile (BP) 主要用於低成本應用,對播放設備的性能要求不高,此 profile 常見用於早期性能較低的行動設備 (如 Apple iPod)。現今行動設備性能比起以前強大許多,此 profile 已經沒有什麼必要性了。

Main Profile (MP) 此 profile 原本是用於 SD 解析度數位電視廣播,雖然沒有實行,然而被用於 HD 解析度的電視廣播。在 2004 年 High Profile 被開發之後,此 profile 已經沒有什麼必要性了。 早期的高性能行動播放設備(如 Sony PSP),也是使用此 profile。

High Profile (HiP) 目前使用最廣泛的 profile,由其是 HD 解析度電視應用 (如 Blu-ray / AVCHD 光碟儲存、遊戲機等電視多媒體播放器、HDTV DVB 廣播服務)。 現今的行動播放設備都可以流暢播放用此 profile 的 SD 解析度影片,中階等級可以上 720p 解析度,高階甚至可上 FullHD (軟解可能會有點吃力,硬解完全沒問題)。

High 10 Profile (Hi10P) 超越目前主流的消費型產品能力,此 profile 建立在 High Profile 之上,多了支援 10 bit 的精度,色彩更精準。 以影片壓製而言,將 High Profile (8 bit) 影片重新編碼輸出為 H.264 High 10 Profile ,雖然色彩精度不會變,但至少壓縮率比輸出 High Profile (8 bit) 還要高。

High 4:2:2 Profile (Hi422P) 針對專業領域應用,此 profile 建立在 High 10 Profile 之上,多了支援 4:2:2 色彩取樣,位元深度達 10 bit。

High 4:4:4 Predictive Profile (Hi444PP) 此 profile 建立在 High 4:2:2 Profile 之上,多了支援 4:4:4 色彩取樣,位元深度達 14 bit,並且支援高效率無損重新編碼,且每張畫面編碼為三個獨立的色彩平面。

ps. 目前 x264 的 H.264 Hi444P 僅支援 8-10 bit

詳細資料(Wiki)

H.264 Frame 影片是由許多連續的 Frames 所組成,但並不是所有 Frames 都是完整的畫面,那些 Frames 需要參考其他 Frames 才能解碼出一張完整的畫面。

H.264 的 Frame types 有 I、B、P 三種。

I-frame: 不需要參考其他 Frames,是一張完整的畫面。

I-frame (IDR): 不需要參考其他 Frames,是一張完整的畫面。 IDR frame 為真正的 關鍵畫格 (keyframes), P-frame & B-frame 不會越過 IDR frame 去參考其他 Frames, 所以可以隨意跳轉到任意 IDR frame 開始播放/解碼,而不會發生問題。

P-frame: 只紀錄了與之前的 Frames 相異的區塊,最多可以參考 “16 張” 之前的 Frames 播放/解碼時需要參用到之前的 Frames 的部分資料,才能解碼出完整畫面。 在 x264 中,你不能控制 P-frame 數量,但你可以控制一個 P-frame 所能參考的 Frame 數量, 也就是 Reference frame (ref) 的數值。

B-frame: 只紀錄了與前一張與後一張的 Frames 相異的區塊,壓縮率高(由其是在低動態/低變化的影片), 播放/解碼時需要用到前後兩張的 Frames 的部分資料,才能解碼出完整畫面。

從此圖你可以發見 B-Frame 有用到前一張與後一張 Frame 的資料。

播放 Farme 的順序是依照 Frame 的時間點,但解碼順序則不一定, 當 B-Frame 有用到後一張 Frame 的資料時,就必須預先解碼後一張 Frame。 以上圖為例 解碼(處理)順序: 1-2-4-3 顯示(播放)順序: 1-2-3-4

由於 P-/B-frame 不是完整的畫面,解碼時必須參考其他 Frames, 所以你不能隨意跳轉到 P-/B-frame 上播放/解碼。 也就是說你如果播放 MPEG 視訊格式,當你跳播放時間點時, 正常而言,並不會跳到你所選的時間點上,而是最近的 IDR / I-frame。

就壓縮率而言… 由於 P-/B-frame 並不是完整的畫面,所以占用的資料量較少, 提高這類 Frame 使用量可以有效提升壓縮率,但對畫質幾乎不會降低, 這代表可以使用較少的 bitrate (位元率)達到維持一定畫質。

由以上得知,在 bitrate 充足的情況下,則不需要使用較多 B-frame、Reference frame (ref) , 多少 bitrate 為充足依影片內容為定,高動態影片需要較多 bitrate,低動則較少。

至於使用時機… 提高 B-frame/ref 使用量可以降低 bitrate 的需求,使用較少 bitrate 達到目標品質。 低動態的影片可以使用較多的 B-frame,高動態或是純靜態則是 P-frame 效果較好。

對於相容性與硬體負擔… 提高 B-frame/ref 使用量的副作用是降相容性以及提高硬體負擔,請先保證相容性再來追求壓縮率。 而 ref 的副作用要比 B-frame 強,例如 ref=16 這代表解碼一個 P-frame 必須要連跳回 1~16 張之前的 Frames 取用資料。

x264 參數設定

Maximun B-frame: 當設定 B-frame 時,重複部分比較多/變化較少的 Frames 會被編碼為 B-frame 此值限制 B-frame 的最大連續數量。

Reference frame (ref): 設定一個 P-frame 所能參考的 Frames 數量。 ref 會影響播放相容性,請參考下文 H.264 Level 部分

推薦設定 ‧Reference frame (ref): 3 - 5 ‧Maximun B-frame: 3 - 6

GOP 長度: 一個 keyframe (IDR frame) 到下一個 keyframe 的範圍。 所以將 GOP 設為無限大雖然可以大幅增加壓縮率,但這樣就不能隨意跳轉到其他時間點播放/解碼。 建議維持 default 即可。

H.264 Profile (x264) Profile 越高 壓縮率 也越高,但編碼複雜度也越高,對播放硬體性能要求較高

x264 支援輸出的 H.264 Profile: baseline, main, high, high10, high422, high444

沒有特殊需求使用 High Profile 即可。

無法直接指定輸出 Profile 的話,可以手動設定參數值。

H.264 Profile 對應的參數

ps. 空欄位代表無限制 完整表格(Wiki,下拉至 Profiles 底部)

參數說明:

bframes (Number of B-frames): 設定 I-frame P-frame 之間連續 B-frames 的最大數量。

cqm (custom quantization matrices): 設定所有自訂量化矩陣(custom quantization matrices)為內建的預設之一。內建預設有 flat 和 JVT。

weightp (explicit weighted prediction): 使 x264 能夠使用明確加權預測(explicit weighted prediction)來改善 P-frame 的壓縮率。亦改善淡入/淡出的品質。模式越高越慢。

8x8dct (Adaptive 8x8 DCT): 彈性 8x8 離散餘弦轉換(DCT)使x264能夠彈性使用 I-frame 的 8x8 轉換。

cabac (CABAC: Context Adaptive Binary Arithmetic Coder): 彈性內容的二進位算數編碼資料流壓縮,禁用 CABAC 會切換回效率較低的彈性內容的可變長度編碼(CAVLC:Context Adaptive Variable Length Coder)系統。大幅降低壓縮效率(通常10~20%)和解碼的硬體需求。

interlaced: 支援編碼輸出 interlaced 的視訊。

x264 preset Preset 是一個選項集合,這設定一編碼速度來決定壓縮比。速度越慢則會得到更好的壓縮編碼效率 (畫質-位元率比 或 畫質-檔案大小比)。也就是說,若你設定一個目標位元率或是檔案大小,則越慢的 Preset 將會得到更好的輸出品質。而對於設定一個恆定品質 (CRF) 或是恆定量化值 (QP),你可以透過選擇更慢的 Preset 來簡單的節省位元率 (也就是得到更小的檔案大小)。

一般而言是使用你所能忍受的最慢 Preset。目前 Presets 依速度遞減排序是: ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow, placebo。該預設 Preset 是 medium。忽略 placebo 因為它會比 veryslow 浪費更多時間而且效果差異太小。

而越慢的 Preset 其 Reference frame (ref) 值也越高,例如 veryslow preset 的 ref 為 16。由於通常不需這麼高的 ref,你可以透過指定一個 Level 來限制 ref,或是手動指定一個合理的 ref 值 (1 ~ 6)。

x264 tune 針對特定類型的影片微調參數設定值,以獲得更好的品質或壓縮率。

Film (電影): 膠片電影。 Animation (動畫): 例如卡通/日本動畫。 Grain (膠片顆粒): 顆粒感很重的影片。 Still Image (靜止影像): 例如幻燈片效果的影片。 PSNR: 優化 PSNR 值。 Wiki SSIM: 優化 SSIM 值。 Wiki Fast Decode (快速解碼): 用於低性能播放設備。 (※ 壓縮率極低) Zero Latency (零延遲): 處裡時間低延遲。主要用於直播等。 (※ 壓縮率極低)

H.264 Level Level 、 MaxDpbMbs 直接表示了對播放設備的解碼性能要求 值越高,代表播放設備解碼性能要求越高,相對的輸出影片的壓縮率也越越高

MaxDpbMbs 對應的 Level

舉例說明: Level 3.2: MaxDpbMbs 20480 以下 Level 4.1: MaxDpbMbs 32768 以下

關係方程式:

強制指定 Level (限制 MaxDpbMbs),則 ref = Min(Floor(MaxDpbMbs / (PicWidthInMbs * FrameHeightInMbs)), 16)

ps. 1. Floor(x): 取整數,小數位直接捨去。 ex. Floor(1.9) = 1 ps. 2. Min(x, y): 取比較小的數值。 ex. Min(2, 5) = 2

強制指定 ref,則 MaxDpbMbs = PicWidthInMbs * FrameHeightInMbs * ref

PicWidthInMbs = Width / 16 FrameHeightInMbs = Height / 16 (小數直接進位)

舉例 1: 當我設定輸出為 ‧Resolution: 1280x1720 ‧Level: 不指定(自動) ‧Reference frame (ref): 4

則 MaxDpbMbs = 80 * 45 * 4 = 14400 對照上表,得 Level = 3.1

舉例 2: 當設定輸出為 ‧Resolution: 1280x1720 ‧Level: 3.1 ‧Reference frame (ref): 不指定(自動)

ref = Min(Floor(18000 / (80 * 45)), 16) = Min(Floor(5.0), 16) = Min(5, 16) = 5

則輸出 H.264 的 ref 可能為 4 或 5

同上,如果要同時強制指定 ref 與 level 則 ref 設定值不能大於 5 (強制指定 ref 不能大於 Level 的限制)

詳細說明(Wiki)

x264 Bitrate Control 指定輸出品質: QP (VBR) 、 CRF (VBR) 指定輸出 Bitrate / 檔案大小: Single pass (ABR) 、 2-pass (VBR)

通常只會使用兩種速率控制: Constant Rate Factor (CRF) 或 2-Pass Bitrate。速率控制是指決定多少位元將被用於每個畫格的方法。這將決定檔案大小且品質如何分布。而 CRF 的位元率分配效果是最佳的,若無控制輸出大小的需求則使用 CRF 即可。

Constant Quantizer (QP)

設定x264以恆定量化值(Constant Quantizer)模式來編碼視訊。此方法可以讓每一個畫格獲得相同品質 (設定值)。 設定值範圍為 0–69,0 為最無損,預設值為 23。比較低的數值會得到比較高的品質,合理的範圍 21 - 28。

Constant Ratefactor (CRF)

此方法允許編碼器自動分配位元速率來試著達到一定輸出品質。讓每個畫格得到它需要的位元數來保持所需的品質等級。CRF 會得到最佳的位元速率分配結果,缺點是你不能直接指定一個目標位元率或是檔案大小。 設定值範圍為 0–51.0,0 為最高品質,預設值為 23。比較低的數值會得到比較高的品質,合理的範圍 18 - 28。考慮 18 為視覺無損 (或接近),所以它看起來應該與輸入相同 (或接近) 但它技術上不是無損。

Bitrate

自訂 Bitrate 控制輸出 Size,直接編碼輸出視訊。由於沒有先掃描過一次,x264 無法得知影片各時間點的複雜程度。所以 x264 只能在編碼中不斷猜後之後的複雜程度,這樣將不能精準依各時間點的複雜程度等比例分配位元率,因為如果之前分配了過多流量,那麼之後就必下修流量來使輸出位元率平均值等於使用者設定值。

Bitrate, 2-Pass

此方法令編碼器 1st-Pass 將會得知影片各個畫格的複雜程度,2nd-Pass 時依照輸入視訊各個畫格的複雜程度等比例分配位元數輸出,並且最終平均位元速率會等於設定值。2-Pass 位元速率分配結果會接近 CRF,缺點是耗費大量時間。

1st-Pass CRF + 2-Pass Bitrate

此方法令編碼器在 1st-Pass 時將會得知影片各個畫格所需要的位元數,2nd-Pass 時依照各個畫格所需要的位元數等比例分配使最終位元速率總平均值會等於設定值。2-Pass 位元速率分配結果會接近 CRF,缺點是耗費大量時間。

x264 設定優先順序 preset -> tune -> 使用者設定選項 -> fast first pass -> profile -> level

當參數衝突時,後者會取代前者或是影響前者

preset slower 的參數為: –b-adapt 2 –direct auto –me umh –partitions all –rc-lookahead 60 –ref 8 –subme 9 –trellis 2

當我設定: ‧ x264 Preset: Slower ‧ Reference frame (ref): 4

等同於: –b-adapt 2 –direct auto –me umh –partitions all –rc-lookahead 60 –ref 4 –subme 9 –trellis 2

輸出 H.264 的 Reference frame (ref) 為 4

當我設定 ‧x264 Preset: Slower ‧Level: 3.2

輸出 H.264 的 Reference frame (ref) 為 5 (請參考上文 “H.264 Level” 部分)

CLI (命令列介面) 使用教學

使用 CLI 介面必須要會用基本的 CMD

CLI 使用說明: 這裡 CMD 入門教學: 這裡


基本用法

基本語法:

x264 [設定選項] -o <輸出> <輸入>

可以用 raw 輸入, 或 YUV4MPEG (.y4m) 或 Avisynth (.avs, 需要有支援的編碼版) 或 lavf / ffms 支援的輸入格式

依指定附檔名選擇輸出檔案格式: .264 -> Raw bytestream .mkv -> Matroska .flv -> Flash Video .mp4 -> MP4 (需要有 GPAC 的編譯版)

ex. 1.

x264 –crf 20 -o output.mkv input.m2ts

ex. 2.

x264 –profile high –preset veryslow –crf 18 –ref 4 –bframes 5 -o output.mp4 input.m2ts


Bitrate Control

指定 bitrate: –bitrate, -B 指定 quality (crf): –crf 指定 quality (qp): –qp

Custom Bitrate (ABR):

x264 [設定選項] -B 1000 -o <輸出> <輸入>

Custom Bitrate, 2-Pass (VBR):

x264 [設定選項] -p 1 -B 1000 -o <輸出> <輸入>

x264 [設定選項] -p 2 -B 1000 -o <輸出> <輸入>

Constant Quantizer (QP):

x264 [設定選項] –qp 20 -o <輸出> <輸入>

Constant Ratefactor (CRF):

x264 [設定選項] –crf 20 -o <輸出> <輸入>

1st pass crf + 2nd pass bitrate:

x264 -p1 –stat “XXX.stat” –crf 20 –slow-firstpass [設定選項] -o <輸出> <輸入>

x264 -p2 –stat “XXX.stat” -B 1000 [設定選項] -o <輸出> <輸入>

如果不滿意輸出檔案大小,再用 2-pass bitrate 修正 檔案大小符合需求的話,則不須進行 2-pass bitrate

※ 1-pass 必需要用 –slow-firstpass


Filtering

–vf, –video-filter //…

Filter options may be specified in := format.

目前官方版只有以下三種 filters

crop:left,top,right,bottom resize:[width,height][,sar][,fittobox][,csp][,method] select_every:step,offset1[,…]

其他編譯版常見 filters

hqdn3d:ls,cs,lt,ct pad:[left][,top][,right][,bottom][,width][,height][,red][,green][,blue] yadif:[mode][,order]

詳細請參考

x264 – fullhelp

語法1:

–vf crop:0,140,0,140/resize:width=1280,fittobox=width,method=lanczos

語法2:

–vf crop:0,140,0,140/resize:1280,,,width,,lanczos

Resize 範例:

ex. 1280x720 (PAR 1:1, DAR 16:9)

–vf resize:width=720,height=480,sar=1:1

ex. 1280xH (mod 2)

–vf resize:width=720,fittobox=width

ex. Letterbox, 720x480, PAR 40:33

–vf resize:width=720,height=480,sar=40:33,fittobox=both/pad:width=720,height=480


Frame Rate

x264 改變 fps 並不會捨棄或填補 Frames 維持 時間長度與影音同步 需要此功能的話可以使用 AviSynth 輸入 or FFmpeg

範例:

如果確定輸入是 CFR,強制輸出 CFR

x264 [設定選項] –force-cfr -o <輸出> <輸入>

強制指定 fps (CFR: 23.976 fps)

x264 [設定選項] –fps 23.976 -o <輸出> <輸入>

強制指定 fps (CFR: 24000/1001 fps)

x264 [設定選項] –fps 24000/1001 -o <輸出> <輸入>

承上,強制指定 timebase

x264 [設定選項] –timebase 1001/24000 -o <輸出> <輸入>

使用 timecode 控制輸出 fps

x264 [設定選項] –tcfile-in timecode.txt -o <輸出> <輸入>

承上,指定 timecode 的 timebase

x264 [設定選項] –timebase 1001 –tcfile-in timecode.txt -o <輸出> <輸入>

如果輸入為 VFR,輸出視訊為 Raw bytestream 時 可以匯出輸入影片的 timecode 給 Muxer / Remuxer 使用

輸出 timecode

x264 [設定選項] –tcfile-out timecode.txt -o <輸出> <輸入>


Piping

pipe A to B

A程式 [參數] | B程式 [參數]

A 的輸出參數 與 B 的的輸入參數 的 “值” 寫 “-” ※ 要注意邊解碼工具是否支援 piping

如果需要使用 ffmpeg 的 Decoder / Filters

pipe ffmpeg to x264

ffmpeg -i input.mkv [設定選項] -f yuv4mpegpipe - | x264 [設定選項] –demuxer y4m -o <輸出> -

FFmpeg 有含 x264 的編譯版,瑞無特殊需求直接使用單一 FFmpeg 即可

x264 64bit 版無法使用 AviSynth (32bit) 改用 AviSynth 64bit 或是嘗試以下方法

pipe ffmpeg(32bit) to x264

ffmpeg -i <輸入AVS檔> -f yuv4mpegpipe - | x264 [設定選項] –demuxer y4m -o <輸出> -

pipe avs2yuv to x264

avs2yuv <輸入AVS檔> - | x264 [設定選項] –demuxer y4m -o <輸出> -

x264 範例參數: profile high, preset veryslow, crf 18, ref 4, bframes 5

ex1. 內建 x264 編碼

ffmpeg -i input.mkv -an -c:v libx264 -profile:v high -preset:v veryslow -crf 18 -x264opts ref=4:bframes=5 output.mp4

ex2. 內建 x264 編碼 + copy audio

ffmpeg -i input.mkv -c:v libx264 -profile:v high -preset:v veryslow -crf 18 -x264opts ref=4:bframes=5 -c:a copy output.mp4

ex3. pipe ffmpeg to x264 (用在需要x264_10bit時,否則多此一舉)

ffmpeg -i input.mkv -f yuv4mpegpipe - | x264 –profile:v high –preset:v veryslow –crf 18 –ref 4 –bframes 5 –demuxer y4m - -o output.mp4

x264 無損壓縮

ex4. 內建 x264 無損壓縮 RGB24

ffmpeg -i rgb24.mkv -pix_fmt bgr24 -c:v libx264rgb -qp 0 output.mp4


Libx264 位元率控制

推薦 crf,如果需要控制輸出大小則用 1-pass crf + 2-pass bitrate

  1. Constant Ratefactor (CRF):

ffmpeg -i blu_ray.m2ts -c:v libx264 -crf 20 -c:a copy output.mkv

關鍵參數: -c:v libx264 -crf xx

  1. Custom Bitrate (ABR):

ffmpeg -i blu_ray.m2ts -c:v libx264 -b:v 1000k -c:a copy output.mkv

關鍵參數: -c:v libx264 -b:v xxxk

  1. Custom Bitrate, 2-Pass (VBR):

:1st-pass ffmpeg -i blu_ray.m2ts -an -pass 1 -passlogfile text.log -fastfirstpass 0 -c:v libx264 -b:v 1000k -f null - :2rd-pass ffmpeg -i blu_ray.m2ts -pass 2 -passlogfile text.log -c:v libx264 -b:v 1000k -c:a copy output.mkv

關鍵參數: -pass n -passlogfile xxx.log -c:v libx264 -b:v xxxk

  1. 1st pass crf + 2nd pass bitrate:

因為 crf 的 bitrate 分配方式是最佳的 這麼做為了讓 2-pass 參考 crf 的 bitrate 分配方式 效果與 crf 相同,多了 2-pass 可修正輸出大小

步驟 1: 1-pass crf

ffmpeg -i blu_ray.m2ts -an -pass 1 -passlogfile text.log -fastfirstpass 0 -c:v libx264 -crf 20 -f null -

步驟 2: 2-pass bitrate

ffmpeg -i blu_ray.m2ts -pass 2 -passlogfile text.log -c:v libx264 -b:v 1000k -c:a copy output.mkv

關鍵參數(1): -pass 1 -passlogfile xxx.log -c:v libx264 -crf xx 關鍵參數(2): -pass 2 -passlogfile xxx.log -c:v libx264 -b:v xxxk

在 “步驟 1: 1-pass crf” 可以設定輸出檔案 如果不滿意輸出檔案大小,再用 2-pass bitrate 修正 檔案大小符合需求的話,則不須進行 2-pass bitrate