[FFmpeg] H.264 編碼基本說明

FFmpeg

簡介與其他資料:
  http://www.mobile01.com/topicdetail.php?f=510&t=3734550

其他範例:
  http://www.mobile01.com/topicdetail.php?f=510&t=4487462


參考資料

FFmpeg 官網:
  https://trac.ffmpeg.org/wiki/Encode/H.264


簡介

H.264 / MPEG-4 AVC 是目前最被廣泛被應用的視訊編碼格式,它的壓縮效率比 MPEG-2、MPEG-4、RV40 ...等舊視訊編碼格式還要高許多。它通常使用在 MP4 容器內;副檔名為 .mp4。第二常見使用是在 MKV (Matroska) 檔內,因為它比 MP4 支援更多以文字為基礎的軟字幕 (例如 ass, ssa...)。本文中的範例將使用 MP4 副檔名。

如果要使用編碼輸出 h.264 / AVC 視訊編碼,你需要 libx264 編碼器,此為額外的函式庫,FFmpeg 的 configuration 之中必須有 --enable-libx264 則 libx264 才可用。


速率控制 (Rate control)

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


Constant Rate Factor (CRF)

此方法允許編碼器自動分配位元速率來試著達到一定輸出品質。讓每個畫格得到它需要的位元數來保持所需的品質等級。CRF 會得到最佳的位元速率分配結果,缺點是你不能直接指定一個目標位元率或是檔案大小。

設定值範圍為 0–51.0,0 為最高品質,預設值為 23。比較低的數值會得到比較高的品質,合理的範圍 18 - 28。CRF 18 為視覺無損 (或接近),所以它看起來應該與輸入相同 (或接近) 但它技術上不是無損。

CRF 18:
ffmpeg -i INPUT -c:v libx264 -crf 18 OUTPUT


2-Pass Bitrate

此方法會在 1st-Pass 得到一個位元速率分配結果,在 2nd-Pass 時會參考 1st-Pass 時得到的結果再加以分析並編碼來得到一個比較合理的結果。位元速率分配結果會越接近 CRF,缺點是耗費大量時間,所以如果不需要強制控制輸出大小則改用 CRF 即可。

1st-Pass:
ffmpeg -y -i INPUT -an -pass 1 -c:v libx264 -b:v 5000k -f null -

2nd-Pass:
ffmpeg -i INPUT -pass 2 -c:v libx264 -b:v 5000k output.mp4

在每個 Pass 都必須指定相同的位元率值,若無特殊需求 1st-Pass 使用與 2nd-Pass 相同的編碼參數設定即可。由於編碼器兩次的輸入必須是相同的,如果有使用 Video filters 的話,則 1st-Pass 與 2nd-Pass 的 Filter 設定必須完全一樣。

若要加速 1st-Pass 可以在 1st-Pass 使用 -fastfirstpass 1,某些參數將使用較低的預設值將使用較低的值取代,但是最終位元率分配結果會比較差。


Preset

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

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


覆蓋 Preset 設定

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

VerySlow Preset:
ref=16:bframes=8:b-adapt=2:direct=auto:me=umh:merange=24:subq=10:rc-lookahead=60:analyse=all:trellis=2

如果要覆蓋 ref 與 bframes 的值為 4 與 5,可以使用 "-refs 4 -bf 5" 或 "-x264opts ref=4:bframes=6"。

覆蓋 ref 值為 4:
ffmpeg -i input.m2ts -c:v libx264 -crf 18 -refs 4 -preset:v veryslow output.mp4


x264 選項

x264 的部分選項被對應到 FFmpeg 選項,例如: --crf (-crf), --ref (-refs), --bframes (-bf), --preset (-preset)。但並不是全部的 x264 選項都有對應到 FFmpeg 選項,如果你要使用那些選項就必須透過 -x264opts 或 -x264-params。

語法:
key[=value][:key[=value]][:key[=value]]...

注意,key 必須使用 x264 的選項名稱。

而某些 x264 選項有對應到 FFmpeg 選項但無法使用 -x264opts 或 -x264-params 來設定,例如 --profile (-profile), --preset (-preset), --slow-firstpass (-fsatfirstpass 0)。

例如:
x264 --preset veryslow --crf 18 --ref 4 --bframes 5 --output output.mp4 input.m2ts

相同編碼參數在 FFmpeg:
ffmpeg -i input.m2ts -c:v libx264 -preset:v veryslow -x264opts crf=18:ref=4:bframes=5 output.mp4

某些選項 x264 與 FFmpeg 的預設值是不同的,例如在 x264 預設不使用 --slow-firstpass,但在 FFmpeg 中 -fsatfirstpass 0 (--slow-firstpass) 預設是使用,如果要關掉 --slow-firstpass 必須設定 -fsatfirstpass 1 。


無損 H.264

你可以使用 -qp 0 來編碼無損輸出。兩個有用的 Presets 是 ultrafast 或 veryslow,因為無論是高編碼速度或是高壓縮通常都是最重要的因素。大多數非 FFmpeg 基礎的播放器會無法解碼無損 (但 YouTube 可以),因此,如果有相容性問題的話則不應該使用無損。如果要輸出 YUV 4:4:4 可以使用 libx264rgb 編碼器。

無損範例 (高速度壓縮編碼):
ffmpeg -i INPUT -c:v libx264 -preset ultrafast -qp 0 OUTPUT

無損範例 (高效率壓縮編碼):
ffmpeg -i INPUT -c:v libx264 -preset veryslow -qp 0 OUTPUT


相容性

一般而言要輸出影片相容某播放設備,通常只要影片的 Profile 與 Level 符合或低於播放設備標示規格即可。

對於較舊 iOS 或 Android 設備,你可以嘗試 Baseline Profile, Level 3.0:
-profile:v baseline -level:v 3.0

Profile 或 Level 越低則會得到更差的壓縮 (畫質-位元率比 或 畫質-檔案大小比),但可以提高相容性與降低對播放設備的性能需求。通常情況下你也許不需要這些設定 (因此,若無必要則避免使用 -profile, -level)。

Level 由解析度與 Reference frame (ref) 數量來決定,越高的解析度與 ref 則代表 Level 越高。若指定一個 Level 則編碼器會自動限制 ref 數量以符合解析度與 Level 設定,除非你也強制設定 ref 數量。

越低的 Profile 會禁用越多進階功能但提供了更好的相容性:
https://en.wikipedia.org/wiki/H.264/MPEG-4_AVC#Profiles


可變位元率 (VBR) 範圍控制

瞬間位元率過高可以能發生播放不流暢的情形,可能由於硬體解碼運性能不足算或是儲存媒介讀取速度不足。你可以使用 -maxrate 選項來設定最大流量容許值 (bps, bits/sec) 與 -bufsize 選項來設定流量控制緩衝區大小 (bits) 來解決此問題。或是用於網路直播時限制最大位元率不超過網路上傳速度。

如果一儲存媒介的讀取速度只有 18Mbps (18000Kbps),若要在該儲存媒介上開啟並流暢播放(或錄製)影片,則影片最大位元率不應超過 18Mbps,若音訊位元率為恆定 448kbps,則你可以將視訊最大位元率限制為 17500kbps。

限制影片最大位元率不超過 17.5Mbps:
-maxrate:v 17500k -bufsize:v 17500k

限制最大位元率可能會得到較差的品質,但可以提高相容性與降低對播放設備的性能需求。通常情況下你也許不需要這些設定 (因此,若無必要則避免使用 -maxrate, -bufsize)。


範例

AVCHD / Blu-Ray Video 編碼範例
http://www.mobile01.com/topicdetail.php?f=510&t=3782292
2015-08-17 0:15 發佈
很棒的資訊
希望您持續分享!
謝謝!

kingdragon wrote:
ffmpeg -i INPUT -c:v libx264 -preset veryslow -qp 0 OUTPUT


假若 輸入 與 輸出 皆為同格式,可能只是remux。。。
那麼用 -c:v copy 與 -qp 0 是否結果相同???
笑看風雲 wrote:
那麼用 -c:v copy 與 -qp 0 是否結果相同???

-c:v copy 是直接複製視訊串流 (video stream)
所以在輸出檔案內的視訊與片原是完全相同的 (無論畫質或大小)

-qp 0 是 libx264 編碼設定選項,用來輸出無損的 H.264 視訊
它的大小比 Raw video 還要小很多
例如 RGB 24bit 之類的 無壓縮視訊 (Uncompressed video) 格式
但缺點是很消耗時間與硬體資源,而且檔案大小還是 CRF 18 的數倍
而 CRF 18 已經很趨近於輸入,所以通常都建議使用 CRF 18 即可
除非你的輸入影片的畫面非常單調 不然... 我相信你無法接受 QP 0 編碼輸出的檔案大小

如果輸入視訊是 AVC / H.264 、 HEVC / H.265 ... 之類的視訊壓縮編碼格式
QP 0 會讓你看到比輸入龐大數倍的輸出檔案

笑看風雲 wrote:
假若 輸入 與 輸出 皆為同格式,可能只是remux。。。

只有 "copy" 才是 remux
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Stream #0:1 -> #0:1 (copy)

就算輸出格式相同,只要經過轉換就不是remux
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
Stream #0:1 -> #0:1 (aac (native) -> aac (libfdk_aac))

Stream #N:N -> #N:N (輸入格式 (解碼器) -> 輸出格式 (編碼器))

2-Pass Bitrate 的選項,我使用 xvid編碼,但不管設定 600k 或 1,200k,出來居然都是 2,751k,導致檔案都不是我要的大小,不知是何原因?
內文搜尋
X
評分
評分
複製連結
Mobile01提醒您
您目前瀏覽的是行動版網頁
是否切換到電腦版網頁呢?