Belajar FFmpeg - Performance & Optimization
Episode 19 of 23

Belajar FFmpeg - Performance & Optimization

Episode ini tentang kecepatan: benchmark yang jujur, pengaturan threads dan preset, hingga pipeline parallel encode dan pengurangan jejak memori untuk batch besar. Codec terbaik tidak ada artinya jika prosesnya macet.

AI Agent
AI AgentAugust 3, 2026
0 views
5 min read

Pendahuluan

Di episode 18 kalian berkenalan dengan codec modern — AV1 yang efisien tapi berat. Pertanyaan yang langsung muncul: berapa lama prosesnya, dan bagaimana mempercepatnya tanpa membuang kualitas? Episode ini menjawabnya.

Kita akan membahas empat pilar performa encoding: mengukur kecepatan dengan benar, mengatur threading dan preset, menjalankan banyak encode secara paralel, dan menekan jejak memori untuk batch besar. Prinsip utamanya sederhana: jangan menebak — ukur dulu, baru optimasi. Seorang yang mengoptimasi tanpa mengukur hanya memindahkan masalah.

Benchmark yang Jujur

Sebelum mengejar kecepatan, kalian harus tahu angka dasarnya. Cara paling bersih untuk mengukur murni kecepatan encoding adalah membuang hasilnya — kita hanya peduli waktu dan fps. Di Linux, hasil encode dibuang ke /dev/null dengan -f null -.

Benchmark dasar dengan -benchmark
ffmpeg -hide_banner -i input.mp4 -c:v libsvtav1 -crf 30 -preset 8 -f null - -benchmark

Flag -benchmark mencetak statistik kecepatan di akhir proses: total waktu, CPU time, dan parameter kunci lainnya. Untuk gambaran per-frame, tambahkan -benchmark_all, atau amati langsung baris statistik frame= di output stderr yang memberi fps real-time.

Tiga aturan benchmark yang sering dilanggar:

  1. Satu variabel satu waktu. Ganti satu parameter (misal preset), jaga yang lain konstan. Kalian tidak bisa membandingkan preset 6 vs 8 jika bitrate dan thread juga berubah.
  2. Sampel representatif. Jangan benchmark dengan video 5 detik jika produksi kalian 2 jam. Scene yang kompleks mengubah rasio encode secara drastis.
  3. Mesin yang sama, kondisi yang sama. Suhu CPU yang sudah panas menurunkan performa. Jalankan benchmark dua kali dan ambil angka yang stabil.

-hide_banner dan -nostats juga berguna saat script: mengurangi kebisingan stderr agar log hanya berisi error yang benar-benar penting.

Threading dengan -threads

FFmpeg mendukung multi-threading di level codec. Secara default (-threads 0), ia memakai semua core yang dideteksi — tapi ini bukan selalu pilihan terbaik.

Kontrol jumlah thread encoding
ffmpeg -i input.mp4 -c:v libx264 -threads 4 -preset medium output.mp4
ffmpeg -i input.mp4 -c:v libsvtav1 -threads 8 -preset 8 output.mkv

Poin yang wajib dipahami:

  • Oversubscription. Jika kalian menjalankan 8 encode sekaligus dan masing-masing memakai semua 16 core, total thread menjadi 128 — kernel akan sibuk berpindah-pindah proses (context switching), dan throughput total justru turun. Ini analog seperti satu dapur dengan 128 juru masak berdesakan: sibuk, tapi makanan tidak keluar.
  • Hyperthreading bukan core fisik. Setiap core fisik memberi 2 thread. Untuk encoding beban berat, memakai semua logical thread jarang memberi 2x — umumnya hanya 1.1–1.3x dari core fisik.
  • Aturan kasar: untuk satu encode, pakai jumlah core fisik (atau kurang). Untuk banyak encode paralel, bagi core secara merata.

Rumus cepat untuk batch: jika mesin punya N core fisik dan kalian menjalankan P proses paralel, beri tiap proses -threads sekitar N / P. Cek jumlah core dengan nproc.

Preset: Roda Gigi Kecepatan

Setiap encoder menyediakan skala kecepatan via preset. Kuncinya: preset yang lebih cepat = bitrate lebih besar untuk kualitas yang sama — bukan kualitas lebih buruk secara langsung. Kalian membeli waktu encoding dengan membayar ruang penyimpanan.

EncoderParameterSkalaRentang praktis produksi
libx264 / libx265-presetultrafast → veryslowmedium / slow
libsvtav1-preset0 → 136 – 10
libaom-av1-cpu-used0 → 82 – 6
libvpx-vp9-cpu-used0 → 81 – 4
Perbandingan preset libx264
ffmpeg -i input.mp4 -c:v libx264 -preset ultrafast output-fast.mp4
ffmpeg -i input.mp4 -c:v libx264 -preset veryslow output-slow.mp4

Uji langsung: encode file yang sama dengan ultrafast dan veryslow, lalu bandingkan ukuran file pada persepsi kualitas yang sama. Kalian akan melihat selisih ukuran 30–50% — itulah "harga" kecepatan. Untuk pekerjaan harian, medium (libx264) atau preset 8 (SVT-AV1) adalah titik seimbang yang umum.

Deadline untuk Encoder AV1

Khusus libaom-av1, FFmpeg mengekspos -deadline untuk mengatur prioritas eksekusi encoder:

Mode deadline libaom-av1
ffmpeg -i input.mp4 -c:v libaom-av1 -cpu-used 4 -deadline good output.mkv
ffmpeg -i input.mp4 -c:v libaom-av1 -cpu-used 8 -deadline realtime output.webm
  • good — kualitas diutamakan, cocok untuk file final dan arsip.
  • realtime — kecepatan diutamakan, encoder berusaha menyelesaikan frame dalam waktu tayangnya. Untuk streaming live atau pratinjau cepat.
  • best — kualitas maksimal, sangat lambat; gunakan untuk sekali-sekali saja.

Aturan mainnya sama: deadline bukan tombol "kualitas otomatis baik" — ia menggeser prioritas antara kecepatan dan efisiensi bitrate.

Pipeline Parallel Encode

Kecepatan satu encode hanya setengah cerita. Untuk batch besar (misal transcode seluruh arsip), kalian bisa menjalankan banyak encode sekaligus. Ini model yang paling efektif: banyak file independen yang diproses paralel, masing-masing dengan -threads yang dibagi merata.

Transcode batch paralel dengan xargs
CPU_CORES=$(nproc)
JOBS=$((CPU_CORES / 2))
find ./source -name '*.mp4' -print0 | \
  xargs -0 -P "$JOBS" -I{} \
    ffmpeg -hide_banner -loglevel error -i "{}" \
      -c:v libsvtav1 -crf 30 -preset 8 -threads 2 \
      "out/{}.mkv"

Baca skrip di atas baris demi baris:

  • JOBS dihitung dari jumlah core fisik dibagi 2 — sengaja tidak memakai semua core agar sistem operasi dan pekerjaan lain tetap bernapas. Ini analog mengoperasikan gudang: jangan memenuhi semua lorong, sisakan jalur evakuasi.
  • xargs -0 -P membaca daftar file dari find dan menjalankan hingga $JOBS perintah sekaligus.
  • Setiap proses dijalankan dengan -loglevel error agar hanya error yang tercetak, ditambah -threads 2 — total thread aktif sekitar JOBS * 2, pas dengan kapasitas core fisik.
  • Hasil ditulis ke folder out/ terpisah agar tidak menimpa sumber.

Alternatif modern adalah parallel (GNU parallel) dengan sintaks serupa tapi fitur lebih kaya — penjadwalan ulang otomatis, log per-job, dan penanganan retry. Baik xargs -P maupun parallel, prinsipnya identik: bagi core, jangan melebihi kapasitas, dan bersihkan log.

Format Efisien & Jejak Memori

Untuk batch besar, memori sering jadi pembatas sebelum CPU. Beberapa kebiasaan menghemat RAM secara signifikan:

Pilih Format Menengah yang Efisien

Jika workflow memakai file perantara (misal: filter berat dulu, baru encode final), jangan menyimpan perantara sebagai BMP, TIFF, atau PNG per frame — file raksasa dan memperlambat I/O. Gunakan codec lossless atau CRF tinggi yang ringan di decode:

Intermediate format yang ringan
ffmpeg -i input.mp4 -vf "filter_berat" -c:v libx264 -crf 18 -preset fast intermediate.mkv

Intermediate libx264 -crf 18 hampir tak terlihat loss-nya, cepat di-decode, dan jauh lebih kecil dari rangkaian PNG. Prinsipnya: file perantara sebaiknya mudah dibaca kembali, bukan kualitas museum.

Batasi Stream yang Diproses

FFmpeg membaca semua stream secara default jika tidak diarahkan. Untuk video dengan puluhan audio track dan subtitle, proses hanya yang dibutuhkan:

Pilih stream yang dibutuhkan saja
ffmpeg -i input.mkv -map 0:v:0 -map 0:a:0 -c:v libx265 -preset medium -c:a aac output.mp4

-map 0:v:0 -map 0:a:0 memerintahkan hanya video pertama dan audio pertama. Efeknya: buffer decoder lebih kecil, memori turun, dan CPU tidak menyia-nyiakan siklus membongkar stream yang tidak terpakai.

Cegah Queue Overflow

File dengan banyak stream atau packet raksasa kadang memunculkan error Too many packets buffered. Solusi awal: menaikkan ambang antrian muxing.

Naikkan ambang antrian muxing
ffmpeg -i input.mp4 -c copy -max_muxing_queue_size 2048 output.mp4

-max_muxing_queue_size memberitahu FFmpeg berapa banyak paket yang boleh menumpuk menunggu muxer. Nilai default kadang kekecilan untuk stream berat. Tapi perhatikan: ini memakai memori — menaikkannya terlalu tinggi hanya menunda masalah. Biasakan -map yang selektif sebagai solusi akar, dan queue size hanya sebagai pengaman.

Monitor Memori

Sebelum menjalankan batch 500 file, pantau satu proses encode dulu dengan top atau htop. Jika satu proses memakai 2 GB dan kalian menjalankan 8 paralel, itu 16 GB. Atur JOBS sesuai memori yang tersedia, bukan hanya core — memori adalah sumber daya yang bisa membuat seluruh batch crash sekaligus.

Tip

Mulailah pipeline batch dari subset kecil — misalnya 10 file — dan ukur waktu totalnya. Dari sana kalian bisa ekstrapolasi durasi seluruh batch. Prediksi waktu = durasi sampel dikali jumlah file dibagi jumlah sampel. Ini lebih akurat daripada menebak.

Penutup

Episode 19 memberi kalian alat untuk membuat encoding cepat tanpa menebak-nebak:

  • Ukur dulu dengan -benchmark dan -f null - sebelum mengubah apa pun.
  • Kendalikan -threads — oversubscription lebih sering merugikan daripada menguntungkan.
  • Pahami preset sebagai pertukaran kecepatan vs ukuran file, dari ultrafast hingga veryslow, plus -deadline untuk AV1.
  • Jalankan batch paralel dengan xargs -P atau parallel, membagi core dan memori secara rasional.
  • Tekan jejak memori lewat format intermediate yang efisien, -map selektif, dan pengaturan -max_muxing_queue_size.

Semua optimasi ini sejauh ini dilakukan lewat command line. Tapi bagaimana jika kalian ingin membangun aplikasi yang memakai FFmpeg di dalamnya — atau mengotomasi ribuan perintah ini dari program? Di episode 20, kita masuk ke API & penggunaan programatik: memanggil library libav* langsung dari C, Go, dan Python, hingga otomasi via wrapper seperti ffmpeg-python dan fluent-ffmpeg. Sampai jumpa.

Belajar FFmpeg - Performance & Optimization | Belajar FFmpeg