Software decoding — yazılım kütüphaneleri aracılığıyla merkezi işlemci (CPU) tarafından medya verilerinin sıkıştırmasının açılması işlemidir ve SoC'nin donanım blokları kullanılmaz. Yazılım kod çözücüler, platformlar arası kütüphaneler olarak uygulanır: FFmpeg, libavcodec ve AV1 için dav1d ile. FFmpeg dokümantasyonuna (2026) göre, libavcodec 200'den fazla codec'i destekler ve bu da software decoding'i nadir biçimleri oynatmanın tek yolu haline getirir.
Önemli Noktalar
Software decoding, tüm hesaplama işlemlerinin genel amaçlı CPU çekirdeklerinde gerçekleştirildiği bir medya verisi sıkıştırma açma yöntemidir. Her codec için özel bir fiziksel bloğun bulunduğu donanım kod çözmeden farklı olarak, yazılım kod çözücü, işlemci talimatlarını kullanarak aynı algoritmaları çalıştıran sıradan bir koddur.
Yazılım kod çözücüler, belirli CPU mimarileri için optimizasyonlarla C/C++ dilinde yazılır: mobil cihazlar için ARM NEON SIMD talimatları, masaüstü için Intel SSE/AVX. FFmpeg'deki libavcodec kütüphanesi, farklı platformlar için optimize edilmiş on binlerce satır assembly kodu içerir ve yazılım kod çözmenin güçlü CPU'larda AV1 gibi ağır biçimler için bile iyi bir performans elde etmesini sağlar.
Yazılım kod çözmenin ana avantajı çok yönlülüktür. Bir donanım kod çözücü yalnızca 4–5 ana biçimi (H.264, H.265, VP9, AV1) desteklerken, FFmpeg 200'den fazla codec'in kodunu çözebilir: modern AV1 ve H.265'ten arşivsel Sorenson Spark, RealVideo ve Motion JPEG'e kadar. Bu, yazılım kod çözmeyi, standart olmayan medya verileriyle çalışan uygulamalar için vazgeçilmez bir araç haline getirir — örneğin profesyonel video düzenleyiciler, video gözetim sistemleri ve özel oynatıcılar.
Yazılımsal kod çözme, donanım kod çözmeyle aynı aşamaları izler, ancak genel amaçlı bir CPU'da gerçekleşir. Her aşama, her makroblok veya kare için sırayla çağrılan işlevler olarak uygulanır. Temel fark esnekliktir: geliştirici işlem hattını değiştirebilir, kod çözme aşamaları arasına filtreler ve son işleme ekleyebilir.
Tipik bir yazılım kod çözücü, algoritmanın ayrı aşamalarını uygulayan modüllerden oluşur. Entropi kod çözme modülü bit akışını okur ve kuantize edilmiş DCT katsayılarını yeniden oluşturur. H.264 için bu modül, CABAC (Bağlam Uyarlamalı İkili Aritmetik Kodlama) uygular — koşullu dalları olan karmaşık bir algoritmadır, donanımda hızlandırılması zordur ancak iyi bir dal tahmincisine sahip CPU'da verimli bir şekilde çalışır.
Ters kuantizasyon modülü, katsayıları kuantizasyon adımıyla çarpar ve ters DCT modülü, ayrık kosinüs dönüşümünü uygular. Ters DCT'nin yazılım uygulaması, hızlı Chen algoritmasını veya Loeffler algoritmasını kullanır ve 8x8 blok için çarpma-biriktirme işlemlerinin sayısını 4096'dan 256'ya düşürür. NEON SIMD talimatları (ARM) veya SSE (x86), talimat başına 4–8 katsayı işlemeye izin verir ve skaler koda kıyasla 4–8 kat hızlanma sağlar.
Hareket telafisi modülü en fazla bellek tüketen modüldür. Hareket vektörlerine göre referans karelerden bölgeler çıkarır ve alt piksel enterpolasyonu uygular. H.265 için enterpolasyon doğruluğu 1/8 piksele ulaşır ve parlaklık için 8 dokunuşlu FIR filtre ve renklilik için 4 dokunuşlu filtre gerektirir. Yazılım uygulaması, önbellekten büyük miktarlarda referans kare verisi yüklemek zorundadır ve bu da CPU'da yüksek çözünürlüklerin kodunu çözerken hareket telafisini bir darboğaz haline getirir.
Apple A17 veya Qualcomm Snapdragon 8 Gen 2 gibi modern mobil işlemciler, kare düşürmeden 1080p H.264'ün yazılımsal kod çözümü için yeterli performansa sahip 6–8 çekirdeğe sahiptir. Ancak, özellikle H.265 ve AV1 biçimlerindeki 4K içerik için CPU'da yazılımsal kod çözme zorlanabilir: tüm çekirdeklerdeki tipik yük %70–90'a ulaşır ve bu çoklu görev için kritiktir. Büyük çekirdekler (Apple Performance, Qualcomm Kryo Prime), küçük enerji verimli çekirdeklere kıyasla ~4–5 kat performans sağlar, ancak orantılı olarak daha fazla güç tüketir.
Yazılım kod çözücü pazarında, her biri kendi alanı için optimize edilmiş birkaç önemli kütüphane bulunmaktadır. Kod çözücü seçimi, gereken biçimlere, platforma ve lisanslama kısıtlamalarına bağlıdır.
FFmpeg, sektörde yazılımsal kod çözme için fiili standarttır. libavcodec kütüphanesi, tüm ana ve çoğu nadir codec için kod çözücüler içerir, tüm konteynerleri (MP4, MKV, AVI, MOV, WebM) destekler ve tüm platformlarda çalışır. FFmpeg, LGPL/GPL altında lisanslanmıştır ve ticari kullanım için lisans koşullarına uyulmasını gerektirir. Mobil cihazlarda FFmpeg, sarmalayıcılar aracılığıyla kullanılır: iOS ve Android için ffmpeg-kit, React Native için mobile-ffmpeg.
Dav1d, SIMD optimizasyonlarıyla C dilinde yazılmış, VideoLAN'dan (VLC geliştiricileri) bir yazılım AV1 kod çözücüdür. Ana hedefi, donanım desteği olmayan CPU'larda AV1'in mümkün olan en hızlı yazılımsal kod çözümüdür. Dav1d, agresif optimizasyonlar sayesinde (manuel önbellek yönetimi, son işleme filtreleri için JIT derlemesi ve kritik işlevlerin vektörleştirilmesi) Alliance for Open Media'nın referans libaom kod çözücüsünden %30–50 daha hızlıdır.
Mobil cihazlarda dav1d, amiral gemisi SoC'lerde (Apple A16+, Snapdragon 8 Gen 2+) 1080p AV1'i gerçek zamanlı olarak çözebilir, ancak 4K için güçlü bir CPU gerekir. Örneğin, Apple M1'de yazılım dav1d, 4K AV1 için ~60 FPS'ye ulaşırken, Snapdragon 8 Gen 2'de ~35 FPS'ye ulaşır. Mobil cihazlarda kararlı 4K AV1 oynatma için donanım desteği hala önerilmektedir.
| Kod Çözücü | Biçimler | Platformlar | Lisans |
|---|---|---|---|
| libavcodec | 200+ codec | Tümü | LGPL/GPL |
| dav1d | AV1 | Tümü | BSD 2-Clause |
| libaom | AV1 | Tümü | BSD 2-Clause |
| MediaFoundation | H.264, H.265 | Windows | Özel mülk |
Yazılım ve donanım kod çözme arasındaki seçim, uyumluluk ve verimlilik arasında bir dengedir. Aşağıdaki tablo, temel özelliklerin ayrıntılı bir karşılaştırmasını sunmaktadır.
| Parametre | Software Decoding | Hardware Decoding |
|---|---|---|
| Desteklenen biçimler | 200+ codec | 4–6 codec |
| Güç tüketimi | 1,5–5 W | 0,2–0,8 W |
| Özelleştirme | İşlem hattı üzerinde tam kontrol | Yalnızca API aracılığıyla |
| Gecikme | 30–80 ms | 5–15 ms |
| Isı dağılımı | Yüksek (45–50 C) | Düşük (35–40 C) |
| Codec güncellemeleri | Kütüphane güncellemesiyle | Yalnızca yeni SoC ile |
Yazılımsal kod çözme maksimum esneklik sağlar: geliştirici algoritmaları değiştirebilir, özel filtreler ekleyebilir ve kendi işleme işlem hatlarını uygulayabilir. Örneğin, video düzenleme uygulamalarında, her kod çözme aşaması renk düzeltme veya efekt yerleştirme için GPU'ya yönlendirilebilir — bu yalnızca kod çözme üzerinde yazılım kontrolü ile mümkündür.
Ancak, esnekliğin bedeli güç tüketimidir. 3000–5000 mAh pile sahip mobil cihazlar için sürekli yazılımsal kod çözme, izleme süresini 10–15 saatten (donanım) 2–4 saate düşürür. CPU'nun 45–50 dereceye kadar ısınması, aşırı ısınmayı önlemek için işlemci frekansında düşüşe (throttling) neden olarak kare düşüşlerine ve kullanıcı deneyiminin bozulmasına yol açabilir.
Her iki mobil platformda yazılımsal kod çözmenin pratik uygulamasını inceleyelim. iOS'te yazılımsal kod çözme FFmpeg aracılığıyla kullanılırken, Android'de aynı kütüphane bir Java/Kotlin sarmalayıcı ile kullanılır.
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, yazılımsal kod çözme için minimum bir FFmpeg işlem hattını göstermektedir. avformat_open_input dosyayı açar ve konteyner biçimini belirler, avcodec_find_decoder herhangi bir codec için otomatik olarak uygun bir kod çözücü bulur. decodePacket yöntemi, gerçek zamanlı uygulamalar için AV_CODEC_FLAG_LOW_DELAY bayrağı etkinleştirilmiş çok iş parçacıklı kod çözmeyi destekleyen yeni API'yi (avcodec_send_packet / avcodec_receive_frame) kullanır.
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", "Finished with 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 örneği, bir videodan saniyede bir kare çıkarmak için FFmpegExecutor kullanır. -vf fps=1 parametresi, 60 kareden 59'unu atlayan bir filtre oluşturarak CPU yükünü azaltır. Bu yaklaşım, mobil uygulamalarda önizlemeler ve yer tutucular oluşturmak için kullanışlıdır. Gerçek zamanlı yazılımsal kod çözme için, JNI aracılığıyla doğrudan düşük seviyeli libavcodec API'sinin kullanılması önerilir.
#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, minimalist bir API sağlar: dav1d_open belirtilen sayıda iş parçacığıyla bir kod çözücü bağlamı oluşturur, dav1d_send_data sıkıştırılmış bit akışını kabul eder, dav1d_get_picture YUV420 biçiminde kodu çözülmüş kareyi döndürür. Mobil cihazlar için en uygun iş parçacığı sayısı (n_threads), performans CPU çekirdeği sayısı eksi birdir, böylece UI iş parçacığı için kaynak kalır. Dav1d ayrıca, bellek yönetimi ve kareleri GPU'ya aktarırken gereksiz kopyalamalardan kaçınmak için Dav1dPicAllocator'ı destekler.
Daha yüksek güç tüketimine rağmen, donanım kod çözmenin gerekli işlevselliği sağlayamadığı çeşitli senaryolarda yazılımsal kod çözme vazgeçilmezdir. Bu senaryoları anlamak, geliştiricilerin mimari kararlar almasına yardımcı olur.
Donanım kod çözücüler yalnızca modern biçimleri destekler. Uygulama arşiv kayıtları, video gözetim (MJPEG, H.263), profesyonel codec'ler (ProRes, DNxHD, CineForm) veya üçüncü taraf kaynaklardan içerikle çalışıyorsa — FFmpeg aracılığıyla yazılımsal kod çözme tek seçenek olacaktır. ProRes, donanım desteğine sahip Apple A13+ yongaları hariç tüm cihazlarda yalnızca yazılımla çözülür. H.263 için hiçbir modern SoC'de donanım desteği yoktur — yalnızca yazılımsal kod çözme.
Yazılımsal kod çözme, her kare işleme aşamasına tam erişim sağlar. Bu, çıktıdan önce kodu çözülmüş verilere doğrudan filtre (bulanıklaştırma, gürültü azaltma, keskinleştirme) uygulaması gereken uygulamalar için çok önemlidir. FFmpeg filtreleri karmaşık zincirler oluşturmaya izin verir: kod çözme -> renk düzeltme -> ölçekleme -> altyazı yerleştirme -> kodlama — tümü tek bir kütüphane içinde, farklı API'ler arasında veri aktarmadan.
Önerilen medya oynatıcı mimarisi hibrittir: birincil olarak donanım kod çözme, yedek olarak yazılımsal kod çözme. Oynatmadan önce uygulama, belirtilen codec için bir donanım kod çözücünün kullanılabilirliğini kontrol eder. Hiçbir kod çözücü bulunamazsa, FFmpeg aracılığıyla yazılımsal kod çözme başlatılır. Bu strateji, ana biçimler için performanstan ödün vermeden maksimum uyumluluk sağlar. Kullanılabilirlik kontrolleri her başlatmada yapılmalıdır, çünkü farklı SoC revizyonları nedeniyle aynı model cihazlarda bile donanım desteği değişebilir.
Sıkça Sorulan Sorular
CPU, birçok farklı görevi yerine getiren genel amaçlı bir işlemcidir. Kod çözme için, tek bir görevi gerçekleştirirken bile enerji tüketen paylaşımlı hesaplama birimlerini ve önbellek belleğini kullanır. Donanım kod çözücü, sabit bir işlem hattına sahip son derece uzmanlaşmış bir devredir ve her transistör yalnızca kod çözmeye adanmıştır, bu da güç tüketimini kökten azaltır.
H.264/H.265 için — SIMD optimizasyonları etkinleştirilmiş FFmpeg'deki libavcodec. AV1 için — referans libaom'dan %30–50 daha hızlı olan dav1d. Mobil cihazlarda dav1d'in performansı, amiral gemisi SoC'lerde (A16+, Dimensity 9200+) gerçek zamanlı 1080p AV1 kod çözmeye olanak tanır.
Evet, FFmpeg her iki platforma da taşınmıştır. iOS için ffmpeg-kit — tüm codec'leri ve biçimleri destekleyen hazır bir yapı kullanın. Android için — mobile-ffmpeg veya FFmpeg'i NDK aracılığıyla derleyin. Ticari dağıtım için GPL/LGPL lisans kısıtlamalarına dikkat edin.
Gerçek zamanlı kod çözme, CPU'nun kareleri ekranda görüntülendiklerinden daha hızlı çözebileceği anlamına gelir (genellikle 30 veya 60 FPS). 1080p H.264 için modern bir mobil CPU, bir performans çekirdeğinin yaklaşık %30–50'sini kullanarak bunu rahatça halleder. 4K H.265 için CPU'da gerçek zamanlı işleme, yalnızca tüm çekirdeklerde %70–90 yük bulunan amiral gemisi SoC'lerde mümkündür.
thread_count bayrağıyla FFmpeg aracılığıyla çok iş parçacıklı kod çözme (kare düzeyinde paralellik) kullanın, senaryo için kabul edilebilirse skip_frame'i B-karelerine ayarlayın, kod çözmeden önce scale filtresi aracılığıyla çözünürlüğü azaltın. dav1d ile AV1 için n_threads = CPU çekirdeği sayısı eksi bir kullanın.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun