Software decoding — процес декомпресије медијских података од стране централног процесора (CPU) помоћу софтверских библиотека, без коришћења хардверских блокова SoC-а. Софтверски декодери су имплементирани као вишеплатформске библиотеке: FFmpeg са libavcodec и dav1d за AV1. Према FFmpeg документацији (2026), libavcodec подржава преко 200 кодека, што чини software decoding јединим начином репродукције ретких формата.
Главно
Software decoding — начин декомпресије медијских података при којем се све рачунске операције извршавају на универзалним језгрима CPU-а. За разлику од хардверског декодинга где сваки кодек има наменски физички блок, софтверски декодер је обичан код који извршава исте алгоритме инсТрукцијама процессора.
Софтверски декодери се пишу у C/C++ уз коришћење оптимизација за специфичне архитектуре CPU-а: SIMD инструкције ARM NEON за мобилне уређаје, Intel SSE/AVX за десктопе. Библиотека libavcodec из састава FFmpeg-a садржи десетине хиљада редова оптимизованог асемблерског кода за различите платформе, омогућавајући софтверском декодингу да постигне пристојне перформансе чак и за тешке формате попут AV1 на моћним CPU-има.
Главна предност софтверског декодинга је универзалност. Ако хардверски декодер подржава само 4–5 основних формата (H.264, H.265, VP9, AV1), FFmpeg може да декодира преко 200 кодека: од савремених AV1 и H.265 до архивских Sorenson Spark, RealVideo и Motion JPEG. То чини софтверски декодинг незаменљивим алатом за апликације које раде са нестандардним медијским подацима — на пример, професионалних видео едитора, система видео надзора и специјализованих плејера.
Софтверски декодинг понавља исте кораке као и хардверски, али на универзалном CPU-у. Сваки корак се имплементира као функције које се узастопно позивају за сваки макроблок или кадар. Кључна разлика је флексибилност: програмер може да мења pipeline, додаје филтере и пост-обраду између фаза декодинга.
Типичан софтверски декодер састоји се од модула који имплементирају појединачне фазе алгоритма. Модул ентропијског декодирања чита битни ток и реконструише квантоване DCT коефицијенте. За H.264 овај модул имплементира CABAC (Context-Adaptive Binary Arithmetic Coding) — сложени алгоритам са условним гранањем који се слабо поддаје хардверском убрзању, али се на CPU-у са добрим branch предиктором извршава ефикасно.
Модул инверзне kvantizacija множи коефицијенте кораком kvantizacija, а модул инверзног DCT-а примењује дискретну косинусну трансформацију. Софтверска имплементација инверзног DCT-а користи брзи Chen алгоритам или Loeffler алгоритам који смањују број операција множења-акумулације са 4096 на 256 за 8x8 блок. SIMD инструкције NEON (ARM) или SSE (x86) омогућавају обраду 4–8 коефицијената у једној инструкцији, што даје 4–8 пута убрзање у поређењу са скаларним кодом.
Модул компензације покрета — најзахтевнији за меморију. Он издваја области из референтних кадрова у складу са векторима покрета и примењује субпикселну интерполацију. За H.265 прецизнoct интерполације достиже 1/8 пиксела, што захтева филтрацију са 8-тапним FIR филтером за луму и 4-тапним за хрому. Софтверска имплементација je принуђена да учитава из кеша велике количине података референтних оквира, што чини компензацију покрета уским грлом при декодирању високих резолуција на CPU-у.
Савремени мобилни процесори, попут Apple A17 или Qualcomm Snapdragon 8 Gen 2, имају 6–8 језгара са довољном перформансом за софтверско декодирање 1080p H.264 без прескакања кадрова. Међутим, за 4K садржај, посебно у форматима H.265 и AV1, софтверско декодирање на CPU-у може да не успева: типично оптерећење свих језгара достиже 70–90%, што je критично за мултитаскинг. Велика језгра (Apple Performance, Qualcomm Kryo Prime) обезбеђују ~4–5x перформансу у поређењу са малим енергетски ефикасним језгрима, али троше пропорционално више енергије.
Тржиште софтверских декодера представљено је неколико кључних библиотека, од којих je свака оптимизована за своју нишу. Избор декодера зависи од потребних формата, платформе и лиценцних ограничења.
FFmpeg — де факто стандард софтверског декодинга у индустрији. Библиотека libavcodec укључује декодере за све главне и већину ретких кодека, подржава све контејнере (MP4, MKV, AVI, MOV, WebM) и ради на свим платформама. FFmpeg лиценциран под LGPL/GPL, што захтева уважавање лиценцних услова при комерцијалном коришћењу. На мобилним уређајима FFmpeg се користи преко омотача: ffmpeg-kit за iOS и Android, mobile-ffmpeg за React Native.
Dav1d — софтверски декодер AV1 од VideoLAN (развијача VLC), написан у C-у са оптимизацијама за SIMD. Његов главни задатак je најбрже могуће софтверско декодирање AV1 на CPU-у без хардверске подршке. Dav1d je 30–50% бржи од референтног libaom декодера од Alliance for Open Media захваљујући агресивним оптимизацијама: ручно управљање кешом, коришћење JIT-компајлације за филтере пост-обраде и векторизација критичних функција.
На мобилним уређајима dav1d може да декодира 1080p AV1 у реалном времену на водећим SoC-овима (Apple A16+, Snapdragon 8 Gen 2+), али за 4K je потребан моћан CPU. На пример, на Apple M1 софтверски dav1d достиже ~60 FPS за 4K AV1, а на Snapdragon 8 Gen 2 — ~35 FPS. За стабилну 4K репродукцију AV1 на мобилним уређајима и даље се препоручује хардверска подршка.
| Декодер | Формати | Платформе | Лиценца |
|---|---|---|---|
| libavcodec | 200+ кодека | Све | LGPL/GPL |
| dav1d | AV1 | Све | BSD 2-Clause |
| libaom | AV1 | Све | BSD 2-Clause |
| MediaFoundation | H.264, H.265 | Windows | Власничка |
Избор између софтверског и хардверског декодинга je компромис између компатибилности и ефикасности. У табели испод представљено je детаљно поређење кључних карактеристика.
| Параметар | Software Decoding | Hardware Decoding |
|---|---|---|
| Подржани формати | 200+ кодека | 4–6 кодека |
| Потрошња енергије | 1,5–5 W | 0,2–0,8 W |
| Прилагођавање | Потпуна контрола над pipeline-ом | Само преко API |
| Кашњење | 30–80 ms | 5–15 ms |
| Топлотно зрачење | Високо (45–50 °C) | Ниско (35–40 °C) |
| Ажурирање кодека | Кроз ажурирање библиотеке | Само са новим SoC |
Софтверски декодинг обезбеђује максималну флексибилност: програмер може да мења алгоритме, додаје прилагођене филтере, имплементира сопствене конвејере обраде. На пример, у апликацијама за монтажу видеа свака фаза декодинга може бити преусмерена на GPU за корекцију боја или наношење ефеката — то je могуће само при софтверској контроли над декодингом.
Мехутим, цена флексибилности je потрошња енергије. За мобилне уређаје са батеријом 3000–5000 mAh непрекидни софтверски декодинг скраћује време гледања са 10–15 сати (хардверски) на 2–4 сата. Загревање CPU-а до 45–50 степени такође може да изазове throttling — смањење фреквенције процессора ради заштите од прегревања, што доводи до прескакања кадрова и погоршања корисничког искуства.
Размотримо практичну имплементацију софтверског декодинга на обе мобилне платформе. На iOS-у се софтверски декодинг користи преко FFmpeg-а, на Android-у — кроз исту библиотеку са 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;
}
};
Код демонстрира минимални FFmpeg pipeline за софтверско декодирање. avformat_open_input отвара датотеку и одређује формат контејнера, avcodec_find_decoder аутоматски пропалази одговарајући декодер за било који кодек. Метода decodePacket користи нови API (avcodec_send_packet / avcodec_receive_frame) који подржава вишедентно декодирање када je укључен флаг AV_CODEC_FLAG_LOW_DELAY за апликације у реалном времену.
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("Декодер", "Завршено са 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
}
}
Пример у Kotlin-у користи FFmpegExecutor за издвајање једног кадра у секунди из видеa. Параметар -vf fps=1 ствара филтер који прескаче 59 од 60 кадрова, смањујући оптерећење CPU-а. Такав приступ je користан за креирање прегледа и placeholder-a у мобилним апликацијама. За софтверско декодирање у реалном времену препоручује се коришћење нивoа API-ја libavcodec директно преко 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 пружа минималистички API: dav1d_open креира контекст декодера са задатим бројем нити, dav1d_send_data прима компримовани битни ток, dav1d_get_picture враћа декодирани кадар у формату YUV420. За мобилне уређаје оптималан број нити (n_threads) je број продуктивних језгара CPU-а минус један, да би се оставио ресурс за UI нит. Dav1d такође подржава Dav1dPicAllocator за управљање меморијом и избегавање непотребних копирања при преносу кадра на GPU.
Упркос већој потрошњи енергије, софтверски декодинг je незаменљив у сценаријима где хардверски декодинг не може да обезбеди потребну функционалност. Разумевање ових сценарија помаже програмеру да доноси архитектуралне одлуке.
Хардверски декодери подржавају само савремене формате. Ако апликација ради са архивским снимцима, видео надзором (MJPEG, H.263), професионалним кодеком (ProRes, DNxHD, CineForm) или садржајем из трећих извора — софтверски декодинг преко FFmpeg-а биће једина опција. ProRes се декодира софтверски на свим уређајима осим чипова Apple A13+ са хардверском подршком. За H.263 нема хардверске подршке ни на једном савременом SoC-у — само софтверски декодинг.
Софтверски декодинг пружа потпуни приступ свакој фази обраде кадра. Ово je критично за апликације које захтевају примену филтера (замућење, смањење шума, повећање оштрине) директно на декодираним подацима пре приказа. FFmpeg филтери омогућавају изградњу сложених ланаца: декодирање -> корекција боја -> скалирање -> наношење титлова -> кодирање — све у оквиру једне библиотеке без преноса података између различитих API-ја.
Препоручена архитектура медија плејера je хибридна: хардверски декодинг као основни, софтверски као fallback. Пре репродукције апликација проверава доступност хардверског декодера за дати кодек. Ако декодер није пронађен — покреће се софтверски преко FFmpeg-а. Таква стратегија обезбеђује максималну компатибилност без губитка перформанси за основне формате. Проверу доступности треба извршити при сваком покретању, јер хардверска подршка може да се разликује чак и на уређајима истог модела због различитих ревизија SoC-а.
Често постављана питања
CPU je универзални процессор који извршава многе различите задатке. За декодирање користи заједничке рачунске блокове и кеш меморију који троше енергију чак и при извршавању једног задатка. Хардверски декодер je ускоспецијализовано коло са фиксним конвејером где je сваки транзистор ангажован само у декодирању, што радикално смањује потрошњу енергије.
За H.264/H.265 — libavcodec из FFmpeg-а са укљученим SIMD оптимизацијама. За AV1 — dav1d, који je 30–50% бржи од референтног libaom-а. На мобилним уређајима перформанса dav1d-а омогућава декодирање 1080p AV1 у реалном времену на водећим SoC-овима (A16+, Dimensity 9200+).
Да, FFmpeg je портован на обе платформе. За iOS користите ffmpeg-kit — готову компилацију са подршком за све кодека и формате. За Android — mobile-ffmpeg или компајлирајте FFmpeg кроз NDK. Узмите у обзир лиценцна ограничења GPL/LGPL при комерцијалној дистрибуцији.
Декодирање у реалном времену значи да CPU успева да декодира кадрове брже него што се приказују на екрану (обично 30 или 60 FPS). За 1080p H.264 савремени мобилни CPU се носи са лакоћом, користећи око 30–50% једног продуктивног језгра. За 4K H.265 у реалном времену на CPU-у могуће je само на водећим SoC-овима са 70–90% оптерећењем свих језгара.
Користите вишеденто декодирање (frame-level parallelism) кроз FFmpeg са флагом thread_count, поставите skip_frame на B-кадрове (ако je прихватљиво за сценарио), смањите резолуцију кроз scale филтер пре декодирања. За AV1 са dav1d користите n_threads = број језгара CPU-а минус један.
Закључци
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође