🎬 FFmpeg Multimedia Framework β€” Arsitektur & Pipeline Transcoding

FFmpeg adalah kerangka multimedia universal yang menangani 400+ format kontainer, 300+ codec, dan 200+ filter. Arsitekturnya terdiri dari 6 pustaka inti ( libavformat, libavcodec, libavfilter, libavutil, libswscale, libswresample) yang dirangkai dalam pipeline demux β†’ decode β†’ filter β†’ encode β†’ mux. Dokumen ini membedah arsitektur internal FFmpeg, model data (AVPacket/AVFrame), pipeline transkoding, dan mengapa ia menjadi "pisau lipat Swiss" multimedia sejak 2000.


1. Sejarah & Posisi

  • 2000: Fabrice Bellard merilis FFmpeg (awalnya hanya MPEG encoder)
  • 2004: Michael Niedermayer mengambil alih; libavcodec dan libavformat lahir
  • 2011: Fork menjadi FFmpeg (aktif) vs Libav (stagnan). FFmpeg menang
  • 2026: ~100+ kontributor aktif, di-port ke setiap arsitektur CPU (x86, ARM, RISC-V, MIPS, PowerPC)

Yang memakai FFmpeg:

  • YouTube, Vimeo, Twitch (server-side transcoding)
  • Chromium, Firefox, Safari (HTML5 <video> β€” via FFmpeg WebCodecs)
  • Android (MediaCodec β€” FFmpeg di belakangnya)
  • iOS/macOS (AVFoundation β€” sebagian codec via FFmpeg)
  • Hampir semua aplikasi konversi video (HandBrake, OBS, Kdenlive, Davinci Resolve)

2. Arsitektur FFmpeg

2.1 Enam Pustaka Inti

LibraryFungsiFile PentingDigunakan di
libavformatDemux/Mux kontaineravformat.hBaca/tulis MP4, MKV, AVI, FLV, TS
libavcodecEncoder/Decoder codecavcodec.hH.264, H.265, VP9, AV1, AAC, MP3
libavfilterFilter graphavfilter.hScale, crop, drawtext, volume
libavutilUtilitas (mem, math, log)avutil.hAVFrame, AVPacket, matematika
libswscaleKonversi warna & scalingswscale.hYUV↔RGB, resolusi scaling
libswresampleResampling audioswresample.h44.1KHz↔48KHz, mono↔stereo

2.2 Model Data β€” AVPacket & AVFrame

AVPacket: Data terkompresi. Berisi bitstream sebelum/sesudah encode.

typedef struct AVPacket {
    AVBufferRef *buf;    // Buffer reference
    int64_t pts;         // Presentation timestamp
    int64_t dts;         // Decoding timestamp
    uint8_t *data;       // Compressed bitstream
    int   size;          // Size in bytes
    int   stream_index;  // Which stream (0=video, 1=audio...)
    AVPacketSideData *side_data; // Metadata (HDR, AV1 OBU...)
} AVPacket;

AVFrame: Data mentah (tidak terkompresi). Berisi piksel YUV atau sampel PCM.

typedef struct AVFrame {
    uint8_t *data[AV_NUM_DATA_POINTERS]; // Plane pointers (Y, U, V)
    int linesize[AV_NUM_DATA_POINTERS];  // Stride per plane
    int width, height;                   // Untuk video
    int nb_samples;                      // Untuk audio
    int format;                          // PIX_FMT_* atau AV_SAMPLE_FMT_*
    int64_t pts;                         // Presentation timestamp
    AVBufferRef *buf[AV_NUM_DATA_POINTERS];
} AVFrame;

2.3 Pipeline Transcoding

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   AVPacket     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   AVFrame    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Input    │──────────────→│ Decoder  │──────────────→│ Filter   β”‚
β”‚ File     β”‚  (compressed)  β”‚          β”‚  (raw)       β”‚ Graph    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜               β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜
                                                             β”‚ AVFrame
                                                             β”‚ (filtered)
                                                            β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   AVPacket     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   AVFrame    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Output   │←──────────────│ Encoder  │←──────────────│          β”‚
β”‚ File     β”‚  (compressed)  β”‚          β”‚  (raw)       β”‚          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Kode pipeline (sederhana):

// 1. Open input
AVFormatContext *fmt_ctx = avformat_open_input("input.mp4");
 
// 2. Find decoder
const AVCodec *decoder = avcodec_find_decoder(fmt_ctx->streams[video_idx]->codecpar->codec_id);
AVCodecContext *dec_ctx = avcodec_alloc_context3(decoder);
avcodec_open2(dec_ctx, decoder, NULL);
 
// 3. Decode loop
AVPacket *pkt = av_packet_alloc();
AVFrame *frame = av_frame_alloc();
while (av_read_frame(fmt_ctx, pkt) >= 0) {
    avcodec_send_packet(dec_ctx, pkt);
    while (avcodec_receive_frame(dec_ctx, frame) >= 0) {
        // 4. Frame siap β€” kirim ke encoder atau filter
    }
}

3. Demuxing β€” libavformat

3.1 Format Detection

FFmpeg mendeteksi format kontainer dengan probing β€” membaca beberapa byte pertama file lalu mencocokkan dengan signature yang dikenal:

FormatMagic BytesEkstensi
MP4/ISOBMFFftyp (4 byte).mp4, .m4a, .mov
Matroska/WebMEBML header.mkv, .webm
AVIRIFF + AVI .avi
FLVFLV.flv
MPEG-TS0x47 sync byte.ts, .m2ts
OggOggS.ogg, .opus
WAVRIFF + WAVE.wav

3.2 Stream Discovery

Setelah format terdeteksi, avformat_find_stream_info() membaca:

  • Jumlah streams (video, audio, subtitle, data)
  • Codec ID (H.264 = 27, AAC = 86017)
  • Resolution, framerate, bitrate
  • Durasi, keyframe index
  • Metadata (title, artist, rotation)

4. Filtering β€” libavfilter

4.1 Filter Graph Model

Filter di FFmpeg dirangkai sebagai directed acyclic graph (DAG):

[Input 0: Video] ─→ scale ─→ crop ─→ drawtext ─→ [Output 0]
                                            ↑
[Input 1: PNG] β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ (watermark)

[Input 2: Audio] ─→ volume ─→ equalizer ─→ [Output 1]

Setiap filter memiliki pads β€” input pad (masuk) dan output pad (keluar). Filter graph bisa sangat kompleks (puluhan filter).

4.2 Filter Populer & Kinerja

FilterFungsiKompleksitasSIMD?
scaleUbah resolusiO(widthΓ—height)βœ… AVX-512, SSE, NEON
cropPotong frameO(area)βœ… Memory copy
yadifDeinterlaceO(area)βœ… SSE2
drawtextTulis teksO(area)❌ (CPU-bound)
fpsUbah framerateO(1) per frameβ€”
volumeUbah volume audioO(samples)βœ… SIMD
atempoUbah tempo audioO(n)❌ WSOLA algorithm
equalizerAudio EQO(n) per band❌ IIR filter

5. Konversi Warna β€” libswscale

5.1 Color Space

libswscale menangani konversi antar pixel format:

FormatDeskripsiBits per PixelDigunakan di
YUV420PYUV planar, chroma subsampled 4:2:012H.264, H.265 β€” standar video
YUV422PYUV planar, 4:2:216ProRes, broadcast
YUV444PYUV planar, 4:4:424High-end, screen capture
NV12YUV semi-planar (Y + UV interleaved)12GPU, hardware decoder
RGB24RGB packed24Screenshot, display
BGRARGB + alpha, byte order B-G-R-A32OpenGL, compositor
GRAY8Grayscale8Monochrome, depth maps

5.2 Algoritma Scaling

libswscale menggunakan filter scaling dengan kualitas bervariasi:

FilterKualitasKecepatanDigunakan
Nearest neighborRendahTercepatPreview, pixel art
BilinearSedangCepatDefault
BicubicTinggiSedangTranscoding kualitas
LanczosSangat tinggiLambatProduction broadcast
SplineTertinggiTerlambatMastering

6. Kasus Spesifik: YouTube Transcoding Pipeline

Di YouTube, setiap video yang diupload melewati pipeline FFmpeg:

  1. Probe: Deteksi format input, codec, metadata
  2. Decode: Bongkar ke raw frames
  3. Segmentasi: Potong video menjadi segmen 6-10 detik
  4. Multi-encode: Encode segmen ke berbagai format/resolusi secara paralel:
    • 4K HDR: AV1 (libaom)
    • 1080p: H.264 (x264) β€” baseline compatibility
    • 720p/480p: VP9 (libvpx) β€” bandwidth hemat
    • Audio: Opus (libopus) 128kbps, AAC (libfdk_aac) 256kbps
  5. DASH/HLS: Mux segmen ke MPEG-DASH + HLS kontainer
  6. Manifest: Generate MPD + m3u8

Estimasi beban: YouTube memproses ~500 jam video per menit (2025). Setiap menit = ~300,000 FFmpeg transcoding jobs berjalan di server Google.


References

  1. FFmpeg Documentation. https://ffmpeg.org/doxygen/trunk/index.html
  2. FFmpeg Wiki. β€œH.264 Video Encoding Guide.” https://trac.ffmpeg.org/wiki/Encode/H.264
  3. Libavformat API. https://ffmpeg.org/doxygen/trunk/group__libavf.html
  4. Libavfilter API. https://ffmpeg.org/doxygen/trunk/group__lavfi.html
  5. Swscale Documentation. https://ffmpeg.org/doxygen/trunk/swscale_8h.html
  6. W. Fisher. β€œInside YouTube’s Video Processing Pipeline.” (2019).
  7. Google. β€œYouTube DASH Implementation.” (2013-2025).

Koneksi ke Vault

CatatanKoneksi
hierarchy-digital-plumbingΒ§3 Level 6 β€” Orkestrator FFmpeg
codec-architecture-x264-x265-deepdiveLevel 5 β€” codec video yang FFmpeg panggil
forensic-imaging-analysisFFmpeg ekstraksi frame CCTV, metadata
deepfake-detectionWajib tahu codec artifact vs AI artifact