Software decoding — proces dekomprese mediálních dat centrální procesorovou jednotkou (CPU) pomocí softwarových knihoven, bez použití hardwarových bloků SoC. Softwarové dekodéry jsou implementovány jako multiplatformní knihovny: FFmpeg s libavcodec a dav1d pro AV1. Podle dokumentace FFmpeg (2026) podporuje libavcodec více než 200 kodeků, což činí software decoding jediným způsobem přehrávání vzácných formátů.
Hlavní body
Software decoding — způsob dekomprese mediálních dat, při kterém jsou všechny výpočetní operace prováděny na univerzálních jádrech CPU. Na rozdíl od hardwarového dekódování, kde má každý kodek vyhrazený fyzický blok, je softwarový dekodér běžný kód, který provádí stejné algoritmy pomocí instrukcí procesoru.
Softwarové dekodéry jsou psány v C/C++ s využitím optimalizací pro konkrétní architektury CPU: instrukce SIMD ARM NEON pro mobilní zařízení, Intel SSE/AVX pro stolní počítače. Knihovna libavcodec z FFmpeg obsahuje desítky tisíc řádků optimalizovaného assemblerového kódu pro různé platformy, což umožňuje softwarovému dekódování dosáhnout slušného výkonu i pro těžké formáty jako AV1 na výkonných CPU.
Hlavní výhodou softwarového dekódování je univerzálnost. Zatímco hardwarový dekodér podporuje pouze 4–5 základních formátů (H.264, H.265, VP9, AV1), FFmpeg dokáže dekódovat více než 200 kodeků: od moderních AV1 a H.265 až po archivní Sorenson Spark, RealVideo a Motion JPEG. To činí softwarové dekódování nepostradatelným nástrojem pro aplikace pracující s nestandardními mediálními daty — například profesionální videostřihače, systémy videodohledu a specializované přehrávače.
Softwarový dekódink opakuje stejné fáze jako hardwarový, ale na univerzálním CPU. Každá fáze je implementována jako funkce, které jsou postupně volány pro každý makroblok nebo snímek. Klíčovým rozdílem je flexibilita: vývojář může měnit pipeline, přidávat filtry a následné zpracování mezi fázemi dekódování.
Typický softwarový dekodér se skládá z modulů implementujících jednotlivé fáze algoritmu. Modul entropického dekódování čte bitový tok a rekonstruuje kvantované DCT koeficienty. Pro H.264 tento modul implementuje CABAC (Context-Adaptive Binary Arithmetic Coding) — komplexní algoritmus s podmíněnými větvemi, který se špatně hodí pro hardwarové urychlení, ale na CPU s dobrým branch prediktorem běží efektivně.
Modul inverzní kvantizace násobí koeficienty krokem kvantizace a modul inverzní DCT aplikuje diskrétní kosinovou transformaci. Softwarová implementace inverzní DCT používá rychlý Chenův algoritmus nebo Loefflerův algoritmus, které snižují počet operací násobení-akumulace z 4096 na 256 pro blok 8x8. Instrukce SIMD NEON (ARM) nebo SSE (x86) umožňují zpracovat 4–8 koeficientů jednou instrukcí, což poskytuje 4–8násobné zrychlení oproti skalárnímu kódu.
Modul kompenzace pohybu — nejnáročnější na paměť. Extrahuje oblasti z referenčních snímků podle vektorů pohybu a aplikuje subpixelovou interpolaci. Pro H.265 dosahuje přesnost interpolace 1/8 pixelu, což vyžaduje filtraci s 8-tapovým FIR filtrem pro luminanci a 4-tapovým pro chrominanci. Softwarová implementace je nucena načítat z cache velké objemy dat referenčních snímků, což činí kompenzaci pohybu úzkým hrdlem při dekódování vysokých rozlišení na CPU.
Moderní mobilní procesory, jako Apple A17 nebo Qualcomm Snapdragon 8 Gen 2, mají 6–8 jader s výkonem dostatečným pro softwarové dekódování 1080p H.264 bez přeskakování snímků. U 4K obsahu, zejména ve formátech H.265 a AV1, však softwarové dekódování na CPU nemusí stačit: typické zatížení všech jader dosahuje 70–90%, což je kritické pro multitasking. Velká jádra (Apple Performance, Qualcomm Kryo Prime) poskytují ~4–5x výkon ve srovnání s malými energeticky účinnými jádry, ale spotřebovávají proporcionálně více energie.
Trh softwarových dekodérů je zastoupen několika klíčovými knihovnami, z nichž každá je optimalizována pro svou niku. Výběr dekodéru závisí na požadovaných formátech, platformě a licenčních omezeních.
FFmpeg — de facto standard softwarového dekódování v průmyslu. Knihovna libavcodec zahrnuje dekodéry pro všechny hlavní a většinu vzácných kodeků, podporuje všechny kontejnery (MP4, MKV, AVI, MOV, WebM) a funguje na všech platformách. FFmpeg je licencován pod LGPL/GPL, což vyžaduje zohlednění licenčních podmínek při komerčním použití. Na mobilních zařízeních se FFmpeg používá přes obálky: ffmpeg-kit pro iOS a Android, mobile-ffmpeg pro React Native.
Dav1d — softwarový dekodér AV1 od VideoLAN (tvůrců VLC), napsaný v C s optimalizacemi SIMD. Jeho hlavním úkolem je co nejrychlejší softwarové dekódování AV1 na CPU bez hardwarové podpory. Dav1d je o 30–50% rychlejší než referenční dekodér libaom od Alliance for Open Media díky agresivním optimalizacím: ruční správa cache, použití JIT kompilace pro filtry následného zpracování a vektorizace kritických funkcí.
Na mobilních zařízeních může dav1d dekódovat 1080p AV1 v reálném čase na vlajkových SoC (Apple A16+, Snapdragon 8 Gen 2+), ale pro 4K vyžaduje výkonný CPU. Například na Apple M1 dosahuje softwarový dav1d ~60 FPS pro 4K AV1, a na Snapdragon 8 Gen 2 — ~35 FPS. Pro stabilní přehrávání 4K AV1 na mobilních zařízeních se stále doporučuje hardwarová podpora.
| Dekodér | Formáty | Platformy | Licence |
|---|---|---|---|
| libavcodec | 200+ kodeků | Všechny | LGPL/GPL |
| dav1d | AV1 | Všechny | BSD 2-Clause |
| libaom | AV1 | Všechny | BSD 2-Clause |
| MediaFoundation | H.264, H.265 | Windows | Proprietární |
Volba mezi softwarovým a hardwarovým dekódováním je kompromisem mezi kompatibilitou a efektivitou. Níže uvedená tabulka představuje podrobné srovnání klíčových charakteristik.
| Parametr | Software Decoding | Hardware Decoding |
|---|---|---|
| Podporované formáty | 200+ kodeků | 4–6 kodeků |
| Spotřeba energie | 1,5–5 W | 0,2–0,8 W |
| Přizpůsobení | Plná kontrola nad pipeline | Pouze přes API |
| Zpoždění | 30–80 ms | 5–15 ms |
| Výdej tepla | Vysoké (45–50 °C) | Nízké (35–40 °C) |
| Aktualizace kodeků | Aktualizací knihovny | Pouze s novým SoC |
Softwarové dekódování poskytuje maximální flexibilitu: vývojář může měnit algoritmy, přidávat vlastní filtry, implementovat vlastní zpracovatelské řetězce. Například v aplikacích pro střih videa může být každá fáze dekódování přesměrována na GPU pro korekci barev nebo aplikaci efektů — to je možné pouze při softwarové kontrole nad dekódováním.
Cenou za flexibilitu je však spotřeba energie. Pro mobilní zařízení s baterií 3000–5000 mAh zkracuje nepřetržité softwarové dekódování dobu sledování z 10–15 hodin (hardwarové) na 2–4 hodiny. Zahřívání CPU na 45–50 stupňů může také způsobit throttling — snížení frekvence procesoru na ochranu před přehřátím, což vede k přeskakování snímků a zhoršení uživatelského zážitku.
Podívejme se na praktickou implementaci softwarového dekódování na obou mobilních platformách. Na iOS se softwarové dekódování používá přes FFmpeg, na Androidu — přes stejnou knihovnu s obálkou 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;
}
};
Kód demonstruje minimální pipeline FFmpeg pro softwarové dekódování. avformat_open_input otevře soubor a určí formát kontejneru, avcodec_find_decoder automaticky najde vhodný dekodér pro jakýkoli kodek. Metoda decodePacket používá nové API (avcodec_send_packet / avcodec_receive_frame), které podporuje vícevláknové dekódování při zapnutém příznaku AV_CODEC_FLAG_LOW_DELAY pro aplikace v reálném čase.
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("Dekodér", "Dokončeno s 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
}
}
Příklad v Kotlin používá FFmpegExecutor pro extrakci jednoho snímku za sekundu z videa. Parametr -vf fps=1 vytváří filtr, který přeskočí 59 z 60 snímků, čímž snižuje zatížení CPU. Tento přístup je užitečný pro vytváření náhledů a placeholderů v mobilních aplikacích. Pro softwarové dekódování v reálném čase se doporučuje používat nízkoúrovňové API libavcodec přímo přes 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 poskytuje minimalistické API: dav1d_open vytváří kontext dekodéru s daným počtem vláken, dav1d_send_data přijímá komprimovaný bitový tok, dav1d_get_picture vrací dekódovaný snímek ve formátu YUV420. Pro mobilní zařízení je optimální počet vláken (n_threads) počet výkonných jader CPU minus jedna, aby zůstal zdroj pro UI vlákno. Dav1d také podporuje Dav1dPicAllocator pro správu paměti a vyhnutí se zbytečnému kopírování při předávání snímku GPU.
Navzdory vyšší spotřebě energie je softwarové dekódování nepostradatelné v řadě scénářů, kde hardwarové dekódování nemůže poskytnout potřebnou funkcionalitu. Pochopení těchto scénářů pomáhá vývojáři při architektonických rozhodnutích.
Hardwarové dekodéry podporují pouze moderní formáty. Pokud aplikace pracuje s archivními nahrávkami, videodohledem (MJPEG, H.263), profesionálními kodeky (ProRes, DNxHD, CineForm) nebo obsahem z třetích stran — softwarové dekódování přes FFmpeg bude jedinou možností. ProRes je dekódován softwarově na všech zařízeních kromě čipů Apple A13+ s hardwarovou podporou. Pro H.263 neexistuje hardwarová podpora na žádném moderním SoC — pouze softwarové dekódování.
Softwarové dekódování poskytuje plný přístup ke každé fázi zpracování snímku. To je kritické pro aplikace, kde je třeba aplikovat filtry (rozmazání, redukce šumu, doostření) přímo na dekódovaná data před výstupem. FFmpeg filtry umožňují vytvářet složité řetězce: dekódování -> korekce barev -> škálování -> překrytí titulků -> kódování — vše v rámci jedné knihovny bez přenosu dat mezi různými API.
Doporučená architektura multimediálního přehrávače je hybridní: hardwarové dekódování jako primární, softwarové jako fallback. Před přehráváním aplikace zkontroluje dostupnost hardwarového dekodéru pro daný kodek. Pokud dekodér není nalezen — spustí se softwarové dekódování přes FFmpeg. Tato strategie zajišťuje maximální kompatibilitu bez ztráty výkonu pro základní formáty. Kontrolu dostupnosti je třeba provádět při každém spuštění, protože hardwarová podpora se může lišit i na zařízeních stejného modelu kvůli různým revizím SoC.
Často kladené otázky
CPU je univerzální procesor provádějící mnoho různých úloh. Pro dekódování používá sdílené výpočetní bloky a cache paměť, které spotřebovávají energii i při provádění jedné úlohy. Hardwarový dekodér je specializovaný obvod s pevným řetězcem, kde je každý tranzistor zapojen pouze do dekódování, což radikálně snižuje spotřebu energie.
Pro H.264/H.265 — libavcodec z FFmpeg s zapnutými optimalizacemi SIMD. Pro AV1 — dav1d, který je o 30–50% rychlejší než referenční libaom. Na mobilních zařízeních umožňuje výkon dav1d dekódování 1080p AV1 v reálném čase na vlajkových SoC (A16+, Dimensity 9200+).
Ano, FFmpeg je portován na obě platformy. Pro iOS použijte ffmpeg-kit — hotový build s podporou všech kodeků a formátů. Pro Android — mobile-ffmpeg nebo sestavte FFmpeg přes NDK. Zohledněte licenční omezení GPL/LGPL při komerční distribuci.
Dekódování v reálném čase znamená, že CPU zvládá dekódovat snímky rychleji, než jsou zobrazovány na obrazovce (obvykle 30 nebo 60 FPS). Pro 1080p H.264 si moderní mobilní CPU poradí s rezervou, využívaje přibližně 30–50% jednoho výkonného jádra. Pro 4K H.265 v reálném čase na CPU je možné pouze na vlajkových SoC s 70–90% zatížením všech jader.
Použijte vícevláknové dekódování (frame-level parallelism) přes FFmpeg s příznakem thread_count, nastavte skip_frame na B-snímky (pokud je to pro scénář přijatelné), snižte rozlišení pomocí filtru scale před dekódováním. Pro AV1 s dav1d použijte n_threads = počet jader CPU minus jedna.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také