Software decoding — proses dekompresi data media oleh unit pemrosesan pusat (CPU) menggunakan pustaka perangkat lunak, tanpa menggunakan blok perangkat keras SoC. Decoder perangkat lunak diimplementasikan sebagai pustaka lintas platform: FFmpeg dengan libavcodec dan dav1d untuk AV1. Menurut dokumentasi FFmpeg (2026), libavcodec mendukung lebih dari 200 codec, menjadikan software decoding satu-satunya cara untuk memutar format langka.
Poin Utama
Software decoding — cara dekompresi data media di mana semua operasi komputasi dilakukan pada inti CPU universal. Berbeda dengan decoding perangkat keras di mana setiap codec memiliki blok fisik khusus, decoder perangkat lunak adalah kode biasa yang menjalankan algoritma yang sama melalui instruksi prosesor.
Decoder perangkat lunak ditulis dalam C/C++ dengan menggunakan optimasi untuk arsitektur CPU tertentu: instruksi SIMD ARM NEON untuk perangkat mobile, Intel SSE/AVX untuk desktop. Pustaka libavcodec dari FFmpeg berisi puluhan ribu baris kode assembler yang dioptimalkan untuk berbagai platform, memungkinkan decoding perangkat lunak mencapai kinerja yang layak bahkan untuk format berat seperti AV1 pada CPU yang kuat.
Keunggulan utama decoding perangkat lunak adalah universalitas. Jika decoder perangkat keras hanya mendukung 4–5 format dasar (H.264, H.265, VP9, AV1), FFmpeg dapat mendekode lebih dari 200 codec: dari AV1 dan H.265 modern hingga Sorenson Spark, RealVideo dan Motion JPEG arsip. Ini menjadikan decoding perangkat lunak alat yang sangat diperlukan untuk aplikasi yang bekerja dengan data media tidak standar — misalnya, editor video profesional, sistem pengawasan video, dan pemutar khusus.
Decoding perangkat lunak mengulangi tahapan yang sama dengan perangkat keras, tetapi pada CPU universal. Setiap tahap diimplementasikan sebagai fungsi yang dipanggil secara berurutan untuk setiap makroblok atau bingkai. Perbedaan utamanya adalah fleksibilitas: pengembang dapat mengubah pipeline, menambahkan filter, dan pasca-pemrosesan di antara tahap decoding.
Decoder perangkat lunak tipikal terdiri dari modul yang mengimplementasikan tahapan algoritma yang terpisah. Modul decoding entropi membaca aliran bit dan merekonstruksi koefisien DCT yang terkuantisasi. Untuk H.264, modul ini mengimplementasikan CABAC (Context-Adaptive Binary Arithmetic Coding) — algoritma kompleks dengan percabangan bersyarat yang sulit dipercepat secara perangkat keras, tetapi pada CPU dengan branch predictor yang baik, ia berjalan efisien.
Modul kuantisasi terbalik mengalikan koefisien dengan langkah kuantisasi, dan modul DCT terbalik menerapkan transformasi kosinus diskrit. Implementasi perangkat lunak DCT terbalik menggunakan algoritma cepat Chen atau algoritma Loeffler, yang mengurangi jumlah operasi perkalian-akumulasi dari 4096 menjadi 256 untuk blok 8x8. Instruksi SIMD NEON (ARM) atau SSE (x86) memungkinkan pemrosesan 4–8 koefisien dalam satu instruksi, memberikan percepatan 4–8 kali lipat dibandingkan dengan kode skalar.
Modul kompensasi gerak — yang paling membutuhkan memori. Modul ini mengekstrak area dari bingkai referensi sesuai dengan vektor gerak dan menerapkan interpolasi subpiksel. Untuk H.265, akurasi interpolasi mencapai 1/8 piksel, yang memerlukan filter FIR 8-tap untuk luminansi dan 4-tap untuk krominansi. Implementasi perangkat lunak harus memuat data bingkai referensi dalam jumlah besar dari cache, menjadikan kompensasi gerak sebagai hambatan dalam decoding resolusi tinggi pada CPU.
Prosesor mobile modern, seperti Apple A17 atau Qualcomm Snapdragon 8 Gen 2, memiliki 6–8 inti dengan kinerja yang cukup untuk decoding perangkat lunak 1080p H.264 tanpa melewatkan bingkai. Namun, untuk konten 4K, terutama dalam format H.265 dan AV1, decoding perangkat lunak pada CPU mungkin tidak dapat mengimbangi: beban tipikal semua inti mencapai 70–90%, yang kritis untuk multitasking. Inti besar (Apple Performance, Qualcomm Kryo Prime) memberikan ~4–5x kinerja dibandingkan dengan inti kecil hemat energi, tetapi mengonsumsi energi secara proporsional lebih banyak.
Pasar decoder perangkat lunak diwakili oleh beberapa pustaka kunci, masing-masing dioptimalkan untuk nichenya. Pemilihan decoder tergantung pada format yang diperlukan, platform, dan batasan lisensi.
FFmpeg — standar de facto decoding perangkat lunak di industri. Pustaka libavcodec mencakup decoder untuk semua codec utama dan sebagian besar codec langka, mendukung semua wadah (MP4, MKV, AVI, MOV, WebM) dan bekerja di semua platform. FFmpeg dilisensikan di bawah LGPL/GPL, yang mengharuskan pertimbangan persyaratan lisensi dalam penggunaan komersial. Pada perangkat mobile, FFmpeg digunakan melalui pembungkus: ffmpeg-kit untuk iOS dan Android, mobile-ffmpeg untuk React Native.
Dav1d — decoder perangkat lunak AV1 dari VideoLAN (pengembang VLC), ditulis dalam C dengan optimasi SIMD. Tugas utamanya adalah decoding perangkat lunak AV1 secepat mungkin pada CPU tanpa dukungan perangkat keras. Dav1d 30–50% lebih cepat dari decoder referensi libaom dari Alliance for Open Media berkat optimasi agresif: manajemen cache manual, penggunaan kompilasi JIT untuk filter pasca-pemrosesan, dan vektorisasi fungsi kritis.
Pada perangkat mobile, dav1d dapat mendekode 1080p AV1 secara real-time pada SoC flagship (Apple A16+, Snapdragon 8 Gen 2+), tetapi untuk 4K membutuhkan CPU yang kuat. Misalnya, pada Apple M1, dav1d perangkat lunak mencapai ~60 FPS untuk 4K AV1, dan pada Snapdragon 8 Gen 2 — ~35 FPS. Untuk pemutaran 4K AV1 yang stabil pada perangkat mobile, dukungan perangkat keras masih direkomendasikan.
| Decoder | Format | Platform | Lisensi |
|---|---|---|---|
| libavcodec | 200+ codec | Semua | LGPL/GPL |
| dav1d | AV1 | Semua | BSD 2-Clause |
| libaom | AV1 | Semua | BSD 2-Clause |
| MediaFoundation | H.264, H.265 | Windows | Proprieter |
Pilihan antara decoding perangkat lunak dan perangkat keras adalah kompromi antara kompatibilitas dan efisiensi. Tabel di bawah ini menyajikan perbandingan rinci dari karakteristik utama.
| Parameter | Software Decoding | Hardware Decoding |
|---|---|---|
| Format yang didukung | 200+ codec | 4–6 codec |
| Konsumsi daya | 1,5–5 W | 0,2–0,8 W |
| Kustomisasi | Kontrol penuh atas pipeline | Hanya melalui API |
| Latensi | 30–80 ms | 5–15 ms |
| Pelepasan panas | Tinggi (45–50 °C) | Rendah (35–40 °C) |
| Pembaruan codec | Melalui pembaruan pustaka | Hanya dengan SoC baru |
Decoding perangkat lunak memberikan fleksibilitas maksimum: pengembang dapat memodifikasi algoritma, menambahkan filter kustom, mengimplementasikan jalur pemrosesan sendiri. Misalnya, dalam aplikasi penyuntingan video, setiap tahap decoding dapat dialihkan ke GPU untuk koreksi warna atau penerapan efek — ini hanya mungkin dengan kontrol perangkat lunak atas decoding.
Namun, harga dari fleksibilitas adalah konsumsi daya. Untuk perangkat mobile dengan baterai 3000–5000 mAh, decoding perangkat lunak terus-menerus mengurangi waktu menonton dari 10–15 jam (perangkat keras) menjadi 2–4 jam. Pemanasan CPU hingga 45–50 derajat juga dapat menyebabkan throttling — penurunan frekuensi prosesor untuk melindungi dari panas berlebih, yang menyebabkan bingkai terlewat dan penurunan pengalaman pengguna.
Mari kita lihat implementasi praktis decoding perangkat lunak pada kedua platform mobile. Di iOS, decoding perangkat lunak digunakan melalui FFmpeg, di Android — melalui pustaka yang sama dengan pembungkus Java/Kotlin.
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}
class SoftwareDecoder {
AVCodecContext* codecCtx;
public:
bool init(const char* filename) {
AVFormatContext* fmtCtx = nullptr;
avformat_open_input(&fmtCtx, filename, nullptr, nullptr);
avformat_find_stream_info(fmtCtx, nullptr);
int videoStream = av_find_best_stream(
fmtCtx, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0
);
AVCodec* decoder = avcodec_find_decoder(
fmtCtx->streams[videoStream]->codecpar->codec_id
);
codecCtx = avcodec_alloc_context3(decoder);
avcodec_parameters_to_context(codecCtx,
fmtCtx->streams[videoStream]->codecpar);
avcodec_open2(codecCtx, decoder, nullptr);
return true;
}
AVFrame* decodePacket(AVPacket* packet) {
avcodec_send_packet(codecCtx, packet);
AVFrame* frame = av_frame_alloc();
int ret = avcodec_receive_frame(codecCtx, frame);
return (ret >= 0) ? frame : nullptr;
}
};
Kode ini menunjukkan pipeline FFmpeg minimal untuk decoding perangkat lunak. avformat_open_input membuka file dan menentukan format wadah, avcodec_find_decoder secara otomatis menemukan decoder yang sesuai untuk codec apa pun. Metode decodePacket menggunakan API baru (avcodec_send_packet / avcodec_receive_frame), yang mendukung decoding multi-thread saat flag AV_CODEC_FLAG_LOW_DELAY diaktifkan untuk aplikasi real-time.
class SoftwareDecoder(private val context: Context) {
fun decodeVideo(inputPath: String, outputFolder: String) {
val cmd = "-i $inputPath -vf fps=1 $outputFolder/frame_%04d.jpg"
FFmpegExecutor(context).executeCommand(cmd) { rc ->
Log.d("Decoder", "Selesai dengan rc: $rc")
}
}
fun getFrameCount(filePath: String): Int {
val probe = MediaMetadataRetriever()
probe.setDataSource(filePath)
val duration = probe.extractMetadata(
MediaMetadataRetriever.METADATA_KEY_DURATION
)?.toIntOrNull() ?: 0
val fps = probe.extractMetadata(
MediaMetadataRetriever.METADATA_KEY_VIDEO_FRAME_COUNT
)?.toIntOrNull() ?: 0
probe.release()
return fps
}
}
Contoh dalam Kotlin menggunakan FFmpegExecutor untuk mengekstrak satu bingkai per detik dari video. Parameter -vf fps=1 membuat filter yang melewatkan 59 dari 60 bingkai, mengurangi beban CPU. Pendekatan ini berguna untuk membuat pratinjau dan placeholder dalam aplikasi mobile. Untuk decoding perangkat lunak real-time, disarankan menggunakan API tingkat rendah libavcodec secara langsung melalui JNI.
#include <dav1d/dav1d.h>
int decode_av1_frame(const uint8_t* data, size_t size) {
Dav1dContext* ctx = nullptr;
Dav1dSettings settings = { 0 };
dav1d_default_settings(&settings);
settings.n_threads = 4;
dav1d_open(&ctx, &settings);
Dav1dData dav1d_data = { 0 };
dav1d_data_wrap(&dav1d_data, data, size, nullptr, nullptr);
Dav1dPicture pic = { 0 };
if (dav1d_send_data(ctx, &dav1d_data) == 0) {
dav1d_get_picture(ctx, &pic);
}
dav1d_close(&ctx);
return pic.p.w;
}
Dav1d menyediakan API minimalis: dav1d_open membuat konteks decoder dengan jumlah thread yang ditentukan, dav1d_send_data menerima aliran bit terkompresi, dav1d_get_picture mengembalikan bingkai yang didekode dalam format YUV420. Untuk perangkat mobile, jumlah thread optimal (n_threads) adalah jumlah inti CPU produktif dikurangi satu, untuk menyisakan sumber daya bagi thread UI. Dav1d juga mendukung Dav1dPicAllocator untuk manajemen memori dan menghindari penyalinan yang tidak perlu saat mentransfer bingkai ke GPU.
Meskipun konsumsi dayanya lebih tinggi, decoding perangkat lunak sangat diperlukan dalam sejumlah skenario di mana decoding perangkat keras tidak dapat memberikan fungsionalitas yang diperlukan. Memahami skenario ini membantu pengembang dalam mengambil keputusan arsitektur.
Decoder perangkat keras hanya mendukung format modern. Jika aplikasi bekerja dengan rekaman arsip, pengawasan video (MJPEG, H.263), codec profesional (ProRes, DNxHD, CineForm) atau konten dari sumber pihak ketiga — decoding perangkat lunak melalui FFmpeg akan menjadi satu-satunya pilihan. ProRes didekode secara perangkat lunak di semua perangkat kecuali chip Apple A13+ dengan dukungan perangkat keras. Untuk H.263 tidak ada dukungan perangkat keras pada SoC modern mana pun — hanya decoding perangkat lunak.
Decoding perangkat lunak memberikan akses penuh ke setiap tahap pemrosesan bingkai. Ini sangat penting untuk aplikasi yang memerlukan penerapan filter (pengaburan, pengurangan noise, peningkatan ketajaman) langsung pada data yang didekode sebelum ditampilkan. Filter FFmpeg memungkinkan pembangunan rantai yang kompleks: decoding -> koreksi warna -> penskalaan -> penambahan subtitle -> encoding — semuanya dalam satu pustaka tanpa transfer data antara API yang berbeda.
Arsitektur yang direkomendasikan untuk pemutar media adalah hibrida: decoding perangkat keras sebagai utama, perangkat lunak sebagai fallback. Sebelum pemutaran, aplikasi memeriksa ketersediaan decoder perangkat keras untuk codec tertentu. Jika decoder tidak ditemukan — decoding perangkat lunak melalui FFmpeg dimulai. Strategi ini memastikan kompatibilitas maksimum tanpa kehilangan kinerja untuk format dasar. Pemeriksaan ketersediaan harus dilakukan setiap kali dijalankan, karena dukungan perangkat keras dapat berbeda bahkan pada perangkat model yang sama karena revisi SoC yang berbeda.
Pertanyaan yang Sering Diajukan
CPU adalah prosesor universal yang menjalankan banyak tugas berbeda. Untuk decoding, ia menggunakan blok komputasi bersama dan memori cache yang mengonsumsi energi bahkan saat menjalankan satu tugas. Decoder perangkat keras adalah sirkuit khusus dengan saluran tetap di mana setiap transistor hanya terlibat dalam decoding, yang secara drastis mengurangi konsumsi daya.
Untuk H.264/H.265 — libavcodec dari FFmpeg dengan optimasi SIMD diaktifkan. Untuk AV1 — dav1d, yang 30–50% lebih cepat dari libaom referensi. Pada perangkat mobile, kinerja dav1d memungkinkan decoding 1080p AV1 real-time pada SoC flagship (A16+, Dimensity 9200+).
Ya, FFmpeg telah diporting ke kedua platform. Untuk iOS, gunakan ffmpeg-kit — build siap pakai dengan dukungan untuk semua codec dan format. Untuk Android — mobile-ffmpeg atau bangun FFmpeg melalui NDK. Perhatikan batasan lisensi GPL/LGPL dalam distribusi komersial.
Decoding real-time berarti CPU dapat mendekode bingkai lebih cepat daripada ditampilkan di layar (biasanya 30 atau 60 FPS). Untuk 1080p H.264, CPU mobile modern dapat mengatasinya dengan mudah, menggunakan sekitar 30–50% dari satu inti produktif. Untuk 4K H.265 real-time pada CPU hanya mungkin dilakukan pada SoC flagship dengan beban 70–90% pada semua inti.
Gunakan decoding multi-thread (frame-level parallelism) melalui FFmpeg dengan flag thread_count, atur skip_frame ke bingkai-B (jika dapat diterima untuk skenario), kurangi resolusi melalui filter scale sebelum decoding. Untuk AV1 dengan dav1d, gunakan n_threads = jumlah inti CPU dikurangi satu.
Kesimpulan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga