Software decoding — SoC ning apparat bloklaridan foydalanmasdan, markaziy protsessor (CPU) tomonidan dasturiy kutubxonalar yordamida media ma'lumotlarini dekompressiya qilish jarayoni. Dasturiy dekoderlar krossplatforma kutubxonalari sifatida amalga oshirilgan: FFmpeg libavcodec bilan va AV1 uchun dav1d. FFmpeg hujjatlariga (2026) ko'ra, libavcodec 200 dan ortiq kodekni qo'llab-quvvatlaydi, bu esa software decoding ni noyob formatlarni ijro etishning yagona usuliga aylantiradi.
Asosiy fikrlar
Software decoding — barcha hisoblash operatsiyalari CPU ning universal yadrolarida bajariladigan media ma'lumotlarini dekompressiya qilish usuli. Apparat dekodingidan farqli o'laroq, har bir kodek ajratilgan fizik blokka ega, dasturiy dekoder esa xuddi shu algoritmlarni protsessor ko'rsatmalari bilan bajaradigan oddiy koddir.
Dasturiy dekoderlar muayyan CPU arxitekturalari uchun optimallashtirishlardan foydalanib C/C++ da yoziladi: mobil qurilmalar uchun ARM NEON SIMD ko'rsatmalari, desktoplar uchun Intel SSE/AVX. FFmpeg tarkibidagi libavcodec kutubxonasi turli platformalar uchun o'n minglab satr optimallashtirilgan assembler kodini o'z ichiga oladi, bu esa dasturiy dekodingga kuchli CPU larda AV1 kabi og'ir formatlar uchun ham munosib ishlashga erishish imkonini beradi.
Dasturiy dekodingning asosiy afzalligi — universallik. Apparat dekoderi faqat 4–5 asosiy formatni (H.264, H.265, VP9, AV1) qo'llab-quvvatlasa, FFmpeg 200 dan ortiq kodekni dekodlashi mumkin: zamonaviy AV1 va H.265 dan arxiv Sorenson Spark, RealVideo va Motion JPEG gacha. Bu dasturiy dekodingni nostandart media ma'lumotlari bilan ishlaydigan ilovalar uchun — masalan, professional video muharrirlari, videokuzatuv tizimlari va ixtisoslashtirilgan pleerlar uchun ajralmas vositaga aylantiradi.
Dasturiy dekoding apparat bilan bir xil bosqichlarni takrorlaydi, lekin universal CPU da. Har bir bosqich har bir makroblok yoki kadr uchun ketma-ket chaqiriladigan funksiyalar shaklida amalga oshiriladi. Asosiy farq — moslashuvchanlik: ishlab chiquvchi pipeline ni o'zgartirishi, dekoding bosqichlari orasiga filtrlarni va qayta ishlashni qo'shishi mumkin.
Odatiy dasturiy dekoder algoritmning alohida bosqichlarini amalga oshiradigan modullardan iborat. Entropiya dekodlash moduli bit oqimini o'qiydi va kvantlangan DCT koeffitsiyentlarini tiklaydi. H.264 uchun bu modul CABAC (Context-Adaptive Binary Arithmetic Coding) — shartli o'tishlarga ega murakkab algoritmni amalga oshiradi, bu apparat tezlashtirishiga yomon mos keladi, lekin yaxshi branch prediktoriga ega CPU da samarali ishlaydi.
Teskari kvantlash moduli koeffitsiyentlarni kvantlash qadamiga ko'paytiradi, teskari DCT moduli esa diskret kosinus konvertatsiyasini qo'llaydi. Teskari DCT ning dasturiy tatbiqi 8x8 blok uchun ko'paytirish-akkumulyatsiya operatsiyalari sonini 4096 dan 256 gacha kamaytiradigan tezkor Chen algoritmi yoki Loeffler algoritmidan foydalanadi. NEON SIMD ko'rsatmalari (ARM) yoki SSE (x86) bir ko'rsatmada 4–8 koeffitsiyentni qayta ishlashga imkon beradi, bu skalyar kod bilan solishtirganda 4–8 marta tezlashishni beradi.
Harakat kompensatsiyasi moduli — xotira uchun eng talabchan modul. Harakat vektorlariga muvofiq mos yozuvlar kadrlaridan sohalarni chiqaradi va subpiksel interpolyatsiyasini qo'llaydi. H.265 uchun interpolyatsiya aniqligi 1/8 pikselga etadi, bu luma uchun 8-tapli FIR filtri va xroma uchun 4-tapli filtrni talab qiladi. Dasturiy tatbiq mos yozuvlar kadrlarining katta hajmdagi ma'lumotlarini keshdan yuklashga majbur bo'ladi, bu esa yuqori rezolyutsiyalarni CPU da dekodlashda harakat kompensatsiyasini tor bo'yniga aylantiradi.
Apple A17 yoki Qualcomm Snapdragon 8 Gen 2 kabi zamonaviy mobil protsessorlar kadrlarni tashlamasdan 1080p H.264 dasturiy dekodlash uchun etarli ishlashga ega 6–8 yadroga ega. Biroq 4K kontenti, ayniqsa H.265 va AV1 formatlarida, CPU da dasturiy dekoding bardosh bera olmasligi mumkin: barcha yadrolarning odatdagi yuklamasi 70–90% ga etadi, bu ko'p vazifalilik uchun juda muhim. Katta yadrolar (Apple Performance, Qualcomm Kryo Prime) kichik energiya tejamkor yadrolarga nisbatan ~4–5x ishlashni ta'minlaydi, lekin mutanosib ravishda ko'proq energiya sarflaydi.
Dasturiy dekoderlar bozori bir nechta asosiy kutubxonalar bilan ifodalanadi, ularning har biri o'z o'rni uchun optimallashtirilgan. Dekoderni tanlash talab qilinadigan formatlarga, platformaga va litsenziya cheklovlariga bog'liq.
FFmpeg — sanoatda dasturiy dekodingning de-fakto standarti. libavcodec kutubxonasi barcha asosiy va aksariyat noyob kodeklar uchun dekoderlarni o'z ichiga oladi, barcha konteynerlarni (MP4, MKV, AVI, MOV, WebM) qo'llab-quvvatlaydi va barcha platformalarda ishlaydi. FFmpeg LGPL/GPL ostida litsenziyalangan, bu tijoriy foydalanishda litsenziya shartlarini hisobga olishni talab qiladi. Mobil qurilmalarda FFmpeg qobiqlar orqali ishlatiladi: iOS va Android uchun ffmpeg-kit, React Native uchun mobile-ffmpeg.
Dav1d — VideoLAN dan (VLC yaratuvchilari) SIMD optimallashtirishlari bilan C da yozilgan dasturiy AV1 dekoderi. Uning asosiy vazifasi apparat qo'llab-quvvatlovisiz CPU da AV1 ni imkon qadar tez dasturiy dekodlashdir. Dav1d agressiv optimallashtirishlar tufayli Alliance for Open Media dan mos yozuvlar libaom dekoderidan 30–50% tezroq: keshnii qo'lda boshqarish, qayta ishlash filtrlari uchun JIT-kompilyatsiyadan foydalanish va muhim funksiyalarni vektorlashtirish.
Mobil qurilmalarda dav1d flagman SoC larda (Apple A16+, Snapdragon 8 Gen 2+) real vaqtda 1080p AV1 dekodlashi mumkin, lekin 4K uchun kuchli CPU talab qilinadi. Masalan, Apple M1 da dasturiy dav1d 4K AV1 uchun ~60 FPS ga, Snapdragon 8 Gen 2 da esa ~35 FPS ga etadi. Mobil qurilmalarda barqaror 4K AV1 ijro etish uchun baribir apparat qo'llab-quvvatlashi tavsiya etiladi.
| Dekoder | Formatlar | Platformalar | Litsenziya |
|---|---|---|---|
| libavcodec | 200+ kodek | Barchasi | LGPL/GPL |
| dav1d | AV1 | Barchasi | BSD 2-Clause |
| libaom | AV1 | Barchasi | BSD 2-Clause |
| MediaFoundation | H.264, H.265 | Windows | Xususiy |
Dasturiy va apparat dekodingi o'rtasidagi tanlov moslik va samaradorlik o'rtasidagi murosadir. Quyidagi jadval asosiy xususiyatlarning batafsil solishtirilishini taqdim etadi.
| Parametr | Software Decoding | Hardware Decoding |
|---|---|---|
| Qo'llab-quvvatlanadigan formatlar | 200+ kodek | 4–6 kodek |
| Energiya sarfi | 1,5–5 Vt | 0,2–0,8 Vt |
| Moslashtirish | Pipeline ustidan to'liq nazorat | Faqat API orqali |
| Kechikish | 30–80 ms | 5–15 ms |
| Issiqlik chiqarish | Yuqori (45–50 °C) | Past (35–40 °C) |
| Kodek yangilash | Kutubxona yangilash orqali | Faqat yangi SoC bilan |
Dasturiy dekoding maksimal moslashuvchanlikni ta'minlaydi: ishlab chiquvchi algoritmlarni o'zgartirishi, moslashtirilgan filtrlarni qo'shishi, o'z ishlov berish konveyerlarini amalga oshirishi mumkin. Masalan, video montaj ilovalarida dekodingning har bir bosqichi rang tuzatish yoki effektlarni qo'llash uchun GPU ga yo'naltirilishi mumkin — bu faqat dekoding ustidan dasturiy nazorat bo'lganda mumkin.
Biroq moslashuvchanlikning narxi - energiya sarfi. Batareyasi 3000–5000 mA*soat bo'lgan mobil qurilmalar uchun uzluksiz dasturiy dekoding tomosha vaqtini 10–15 soatdan (apparat) 2–4 soatgacha qisqartiradi. CPU ning qizishi 45–50 darajagacha, shuningdek, trottlingga — qizib ketishdan himoya qilish uchun protsessor chastotasini pasaytirishga olib kelishi mumkin, bu esa kadrlarning tushib qolishiga va foydalanuvchi tajribasining yomonlashishiga sabab bo'ladi.
Ikkala mobil platformada dasturiy dekodingning amaliy tatbiqini ko'rib chiqamiz. iOS da dasturiy dekoding FFmpeg orqali, Android da esa xuddi shu kutubxona Java/Kotlin qobig'i bilan ishlatiladi.
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;
}
};
Kod dasturiy dekoding uchun minimal FFmpeg pipeline ni namoyish etadi. avformat_open_input faylni ochadi va konteyner formatini aniqlaydi, avcodec_find_decoder har qanday kodek uchun avtomatik ravishda mos dekoderni topadi. decodePacket metodi real vaqt ilovalari uchun AV_CODEC_FLAG_LOW_DELAY bayrog'i yoqilganida ko'p oqimli dekodlashni qo'llab-quvvatlaydigan yangi API dan (avcodec_send_packet / avcodec_receive_frame) foydalanadi.
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("Dekoder", "$rc bilan tugadi")
}
}
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 namunasi videodan sekundiga bitta kadr olish uchun FFmpegExecutor dan foydalanadi. -vf fps=1 parametri 60 kadrdan 59 tasini o'tkazib yuboruvchi filtr yaratadi, CPU yuklamasini kamaytiradi. Bunday yondashuv mobil ilovalarda oldindan ko'rish va placeholder yaratish uchun foydalidir. Real vaqtda dasturiy dekoding uchun JNI orqali to'g'ridan-to'g'ri libavcodec ning past darajali API sidan foydalanish tavsiya etiladi.
#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 minimalistik API ni ta'minlaydi: dav1d_open belgilangan oqimlar soni bilan dekoder kontekstini yaratadi, dav1d_send_data siqilgan bit oqimini qabul qiladi, dav1d_get_picture YUV420 formatida dekodlangan kadrni qaytaradi. Mobil qurilmalar uchun optimal oqimlar soni (n_threads) UI oqimi uchun resurs qoldirish uchun CPU ning samarali yadrolari sonidan bitta kam. Dav1d shuningdek xotirani boshqarish va kadrni GPU ga uzatishda keraksiz nusxalashlarning oldini olish uchun Dav1dPicAllocator ni qo'llab-quvvatlaydi.
Yuqori energiya sarfiga qaramay, dasturiy dekoding apparat dekodingi kerakli funksionallikni ta'minlay olmaydigan bir qator stsenariylarda ajralmasdir. Ushbu stsenariylarni tushunish ishlab chiquvchiga arxitektura qarorlarini qabul qilishga yordam beradi.
Apparat dekoderlari faqat zamonaviy formatlarni qo'llab-quvvatlaydi. Ilova arxiv yozuvlari, videokuzatuv (MJPEG, H.263), professional kodeklar (ProRes, DNxHD, CineForm) yoki uchinchi tomon manbalaridan kontent bilan ishlasa — FFmpeg orqali dasturiy dekoding yagona variant bo'ladi. ProRes apparat qo'llab-quvvatloviga ega Apple A13+ chiplaridan tashqari barcha qurilmalarda dasturiy ravishda dekodlanadi. H.263 uchun hech qanday zamonaviy SoC da apparat qo'llab-quvvatlovi yo'q — faqat dasturiy dekoding.
Dasturiy dekoding kadrni qayta ishlashning har bir bosqichiga to'liq kirishni beradi. Bu chiqishdan oldin dekodlangan ma'lumotlarga to'g'ridan-to'g'ri filtrlarni (xiralashtirish, shovqinni kamaytirish, aniqlikni oshirish) qo'llash talab qilinadigan ilovalar uchun juda muhimdir. FFmpeg filtrlari murakkab zanjirlarni qurishga imkon beradi: dekodlash -> rang tuzatish -> masshtablash -> taglavha qo'shish -> kodlash — hammasi bitta kutubxona doirasida, ma'lumotlarni turli API lar o'rtasida uzatmasdan.
Media pleer uchun tavsiya etilgan arxitektura gibrid: asosiy sifatida apparat dekodingi, fallback sifatida dasturiy. Ijro etishdan oldin ilova berilgan kodek uchun apparat dekoderining mavjudligini tekshiradi. Dekoder topilmasa — FFmpeg orqali dasturiy dekoding ishga tushiriladi. Bunday strategiya asosiy formatlar uchun ishlash yo'qotilmasdan maksimal moslikni ta'minlaydi. Mavjudlikni tekshirish har bir ishga tushirishda amalga oshirilishi kerak, chunki apparat qo'llab-quvvatlovi hatto bir xil modeldagi qurilmalarda ham turli SoC reviziyalari tufayli farqlanishi mumkin.
Tez-tez beriladigan savollar
CPU ko'plab turli vazifalarni bajaradigan universal protsessordir. Dekodlash uchun u hatto bitta vazifani bajarayotganda ham energiya sarflaydigan umumiy hisoblash bloklari va kesh xotirasidan foydalanadi. Apparat dekoderi esa har bir tranzistor faqat dekodlashda ishtirok etadigan sobit konveyerli ixtisoslashtirilgan sxema bo'lib, bu energiya sarfini tubdan kamaytiradi.
H.264/H.265 uchun — SIMD optimallashtirishlari yoqilgan FFmpeg dan libavcodec. AV1 uchun — mos yozuvlar libaom dan 30–50% tezroq bo'lgan dav1d. Mobil qurilmalarda dav1d ning ishlashi flagman SoC larda (A16+, Dimensity 9200+) real vaqtda 1080p AV1 dekodlash imkonini beradi.
Ha, FFmpeg ikkala platformaga ko'chirilgan. iOS uchun ffmpeg-kit — barcha kodek va formatlarni qo'llab-quvvatlaydigan tayyor yig'ilmani ishlating. Android uchun — mobile-ffmpeg yoki NDK orqali FFmpeg ni yarating. Tijoriy tarqatishda GPL/LGPL litsenziya cheklovlarini hisobga oling.
Real vaqtda dekodlash CPU kadrlarni ekranda ko'rsatilishidan (odatda 30 yoki 60 FPS) tezroq dekodlashga ulgurishini anglatadi. 1080p H.264 uchun zamonaviy mobil CPU zaxira bilan, bitta samarali yadroning taxminan 30–50% ini ishlatib, bardosh beradi. 4K H.265 real vaqtda CPU da faqat flagman SoC larda barcha yadrolarning 70–90% yuklamasi bilan mumkin.
thread_count bayrog'i bilan FFmpeg orqali ko'p oqimli dekodlashdan (frame-level parallelism) foydalaning, stsenariy uchun maqbul bo'lsa skip_frame ni B-kadrlarga o'rnating, dekodlashdan oldin scale filtri bilan rezolyutsiyani kamaytiring. dav1d bilan AV1 uchun n_threads = CPU yadrolari soni minus birdan foydalaning.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.