FFmpeg — 25年間メディア世界を支えてきたスイスアーミーナイフ
アーキテクチャ、コーデック抽象化、フィルターチェーン、ハードウェアアクセラレーションまで — FFmpeg内部構造の解剖
FFmpegとは何か
FFmpegはCLIツールであり、ライブラリの集合体だ。「FF」はFast Forward、「mpeg」は動画規格グループ名に由来する。2000年にFabrice Bellardが作り、以降Michael Niedermayerをはじめ数百人の貢献者が開発を続けている。
一言でまとめると:ほぼすべてのメディアフォーマットを入力し、ほぼすべてのメディアフォーマットで出力できる。
ffmpeg -i input.mov -c:v libx264 -c:a aac output.mp4
この1行でMOVファイルをH.264ビデオ+AACオーディオのMP4に変換する。
コアコンポーネント
FFmpegプロジェクトは複数のバイナリとライブラリで構成される。
バイナリ:
ffmpeg— メディア変換・エンコードのメインCLIffprobe— メディアファイルのメタデータ・ストリーム情報照会ffplay— SDLベースの簡易メディアプレーヤー
ライブラリ(libav*):
libavcodec— コーデック実装(H.264、HEVC、VP9、AV1、AAC、Opus等)libavformat— コンテナフォーマット処理(MP4、MKV、WebM、FLV、HLS等)libavfilter— フィルターグラフ(スケーリング、クロップ、オーバーレイ、色補正等)libavutil— 共通ユーティリティ(数学、ピクセルフォーマット、エラーコード等)libswscale— ピクセルフォーマット変換+スケーリングlibswresample— オーディオリサンプリング+フォーマット変換libavdevice— キャプチャデバイスI/O(カメラ、マイク、画面キャプチャ)
処理パイプライン
FFmpegのデータフロー:
入力 → デマックス → デコード → フィルタリング → エンコード → マックス → 出力
- Demuxing(libavformat)— コンテナから個別ストリーム(ビデオ、オーディオ、字幕)を分離。圧縮パケット単位で抽出
- Decoding(libavcodec)— 圧縮パケットをrawフレームにデコード。ビデオはYUV/RGBピクセルデータ、オーディオはPCMサンプルに変換
- Filtering(libavfilter)— rawフレームにフィルターチェーン適用。スケーリング、クロップ、色補正、テキストオーバーレイ、ノイズ除去等
- Encoding(libavcodec)— 処理済みフレームを再圧縮。ターゲットコーデック・ビットレート・品質設定に従いエンコード
- Muxing(libavformat)— エンコード済みストリームをコンテナに格納し出力ファイルに書き込み
ストリームコピーモード(-c copy)ではデコード/エンコードをスキップし、パケットをそのままリマックスする。品質劣化なしにコンテナだけ変えたい時に使う。
コーデック抽象化構造
libavcodecの核心はAVCodec構造体だ。すべてのコーデック(H.264、HEVC、VP9、AV1、...)が同一インターフェースを実装する。
typedef struct AVCodec {
const char *name;
enum AVMediaType type;
enum AVCodecID id;
int (*init)(AVCodecContext *);
int (*encode2)(AVCodecContext *, AVPacket *, const AVFrame *, int *);
int (*decode)(AVCodecContext *, AVFrame *, int *, AVPacket *);
int (*close)(AVCodecContext *);
} AVCodec;
同じコーデックID(例:H.264)に複数の実装が存在できる:
libx264— ソフトウェアエンコーダ(CPU)h264_nvenc— NVIDIA GPUハードウェアエンコーダh264_qsv— Intel Quick Synch264_vaapi— VA-API(Linux)h264_videotoolbox— macOSハードウェアエンコーダ
ユーザーは-c:v libx264のようにエンコーダ名を変えるだけ。パイプラインの残りは同一に動作する。
フィルターグラフ
libavfilterは有向グラフ構造でフィルターを接続する。
ffmpeg -i input.mp4 -vf "scale=1280:720,fps=30,eq=brightness=0.1" output.mp4
3つのフィルターがチェーン接続:
1. scale — 解像度を1280x720に調整
2. fps — フレームレートを30fpsに変換
3. eq — 明るさを0.1上げる
複雑なフィルターグラフは複数の入出力を持てる:
ffmpeg -i main.mp4 -i logo.png \
-filter_complex "[0:v][1:v]overlay=10:10[out]" \
-map "[out]" output.mp4
メイン映像にロゴをオーバーレイする構造。
ハードウェアアクセラレーション
FFmpegはhwaccel APIでハードウェアアクセラレーションを抽象化する。
NVIDIA — NVDEC(デコード)+ NVENC(エンコード)+ CUDAフィルター
Intel — QSV(Quick Sync Video)
AMD — AMF(Advanced Media Framework)
VA-API — Linux汎用ハードウェアアクセラレーション
VideoToolbox — macOS/iOS
Vulkan — クロスプラットフォームGPUコンピューティング
GPUデコード→GPUフィルター→GPUエンコードのパイプラインを構成すれば、フレームがGPUメモリから出ないためCPU-GPU間データ転送オーバーヘッドがなくなる。
誰がFFmpegを使っているか
事実上、メディアを扱うほぼすべてのサービスとツール。
YouTube — アップロード映像のトランスコーディング
Netflix — コンテンツエンコーディングパイプライン
Meta — 1日数百億回実行(VOD+ライブストリーミング)
VLC — 再生エンジンの中核
OBS Studio — ストリーミング/録画
HandBrake — デスクトップトランスコーディング
Plex/Jellyfin — メディアサーバートランスコーディング
FFmpegなしに現代のメディアインフラは回らない。25年以上にわたりCで書かれた300万行以上のコードベースがこのすべてを支えている。
動作フロー
Demuxing — コンテナからビデオ・オーディオ・字幕ストリームを分離
Decoding — 圧縮パケットをrawフレーム(YUV/PCM)にデコード
Filtering — フィルターグラフでスケーリング・クロップ・色補正等を適用
Encoding — 処理済みフレームをターゲットコーデックで再圧縮
Muxing — エンコード済みストリームをコンテナ(MP4/MKV/WebM)に格納し出力