2016-04-12 35 views
2

Şu anda, FFmpeg kaynak kodundan LZW sıkıştırma ve dekompresyon yöntemlerini projemde uygulamak için çalışıyorum. Tökezlediğim şey, çıktı tamponunun (sıkıştırılmış verilerin saklanacağı) boyutunun, sıkıştırmak istediğimiz girdi tamponunun boyutundan daha büyük olması gerektiğidir. Bu, sıkıştırmanın kendisiyle çelişmiyor mu?Sıkıştırılmış arabellek neden LZW sıkıştırmasında giriş arabelleğinden daha büyük olmalıdır?

Kodun sonraki kısmı, lzwenc.c kaynak dosyasının bir parçası olan ff_lzw_encode() işlevinde bulunur. benim özel Örneğin

if (insize * 3 > (s->bufsize - s->output_bytes) * 2) 
{ 
    printf("Size of output buffer is too small!\n"); 
    return -1; 
} 

i yerel göndermeden önce ham video karelerini sıkıştırmak için çalışıyorum. Ama (insize * 3)/2 (sıkıştırılmış veri depolanacak) boyutu olan bir arabellek için bellek ayırırsanız, insize boyutundaki ham arabelleği göndermek yerine send() işlevini kullanarak göndermek için daha fazla zaman gerekmiyor mu?

cevap

3

'Sıkıştırılmış' formun giriş olarak daha küçük veya eşit büyüklükte olduğunu garanti edemezsiniz. Herhangi bir şekilde sıkıştırılamayacak ve en iyi durumda, orijinal boyutunun% 100'üne kadar sıkıştırılacak olan, tamamen rastgele verilerin en kötü durumunu düşünün; ek olarak, bazı sıkıştırma meta verilerinin veya kaçış dizilerinin eklenmesi gerekmektedir. % 100 + 5 bayt. Aslında, sıkıştırılamaz verileri "yalnızca"% 100'e 'sıkıştırarak' orijinal boyutunun genellikle otomatik olarak gerçekleşmemesidir. Algoritma, girdiyi normal olarak sıkıştırmaya çalışırsa, sonuç, girişten bile önemli ölçüde büyük olabilir. Akıllı sıkıştırma araçları bu durumu algılar ve bu veri yığınını sıkıştırılmamış yerine göndermek için geri çekilir, ardından en azından parçanın sıkıştırılmamış olduğunu göstermek için bazı meta veriler ekler.

Tahsis ettiğiniz arabellek, en büyük 'sıkıştırılmış' bayt sayısını içerecek kadar büyük olmalı, bu nedenle bazı 'başlıklara' gereksinim duyulmalıdır.

değil

Evet, iyi giderdi ham tampon gönderme daha() fonksiyonunu göndermek kullanarak göndermek için daha fazla zaman alacaktır. Bu nedenle, tüm (ayrılmış) arabelleği değil, sıkıştırma işlevinin kullandığını belirttiği gibi, yalnızca bu arabelleğin kaç baytını göndermezsiniz.

+1

Evet, doğrudur. Çoğunlukla "yeşil" piksellerden (çoğu filmde ve film fragmanında ilk kare) oluşan çerçeveyi sıkıştırmaya çalıştım ve ayrılmış belleğin yalnızca% 4.87'si sıkıştırılmış veriler tarafından işgal edildi. Tamponun% 95.13'lük belleğinden kurtulmak için yaptığım şey, sadece% 4.87'lik önemli verileri göndermekti ve istemci tarafında sıkıştırdı. Dekompresyon yapıldıktan sonra, veriler bir dosyaya yazıldı ve InfraView ile önizlendi. Ve işe yaradı! Ben sunucu tarafında olduğu gibi ben istemci tarafında aynı bende (belki de% 100 aynı ben biraz karşılaştırmak değil) aynı var. –