有损压缩

视频,音频等多媒体文件中,丢失一定的有用信息,来实现数据的高压缩率同时恢复后 媒体质量并未发生很大变化。其很大程度依 赖于人对媒体的敏感部分,如音频局限在 200~20kHz,所以理论上这两者之外的采样 数据都可以丢弃,同时在这个频带内不同频 率,敏感程度也不同,因此出现了对数转换 (a,μ率),傅里叶变换,小波变换,将数据 按照声音频率高低排序后,提取低频成分, 剔除高频成分,数据量大大减少。另外矢量 编码,预测编码,分形算法也有应用,一个 好的多媒体压缩算法往往是结合多种压缩 算法包括无损压缩而实现的。以下以开源的 

附:最近工作上接触到amr编码器,开源的工程不少,编译后,在x86系统工作得很好,在android手机上,却跑不起来,一定程度说明,算法还是比较复杂的。


H264 视频压缩算法为例,加以说明: 


#include 


"common.h" 


#include 


"bitstream.h" 


#include 


"mpegvideo.h" 


#include 


"h264data.h" 


/**


* Write out the provided data into a NAL 


unit. 


* @param nal_ref_idc NAL reference IDC


* @param nal_unit_type NAL unit payload 


type 


* @param dest the target buffer, dst+1 == 


src is allowed as a special case 


* @param destsize the length of the dst 


array 


* @param b2 the data which should be escaped 


* @returns pointer to current position in 


the output buffer or NULL if an error occured 


*/ 


static uint8_t 


*h264_write_nal_unit


(int 


nal_ref_idc


, int nal_unit_type


, uint8_t 





dest


, int *destsize





PutBitContext 





b2








PutBitContext 


b





int i


, destpos


, rbsplen


, escape_count 





uint8_t 


*rbsp





if (nal_unit_type 


!= NAL_END_STREAM


)


put_bits


(b2


,1,1); // rbsp_stop_bit 


// Align b2 on a byte boundary 


align_put_bits


(b2


); 


rbsplen 


= put_bits_count


(b2


)/8; 


flush_put_bits


(b2


); 


rbsp 


= b2


->buf





init_put_bits


(&b


,dest


,*destsize


); 


put_bits


(&b


,16,0); 


put_bits


(&b


,16,0x01); 


put_bits


(&b


,1,0); // forbidden zero bit 


put_bits


(&b


,2,nal_ref_idc


); // 


nal_ref_idc 


put_bits


(&b


,5,nal_unit_type


); // 


nal_unit_type 


flush_put_bits


(&b


); 


destpos 


= 5;


escape_count


= 0; 


for (i


=0; i


<rbsplen


; i


+=2) 





if (rbsp


[i


]) continue; 


if (i


>0 && rbsp


[i


-1]==0) 


i


--; 


if (i


+2<rbsplen 


&& rbsp


[i


+1]==0 && 


rbsp


[i


+2]<=3) 





escape_count


++; 


i


+=2; 








if(escape_count


==0) 





if(dest


+destpos 


!= rbsp








memcpy


(dest


+destpos


, rbsp





rbsplen


);


*destsize 


-= (rbsplen


+destpos 


); 





return dest


+rbsplen


+destpos








if(rbsplen 


+ escape_count 


+ 1> * 


destsize








av_log


(NULL


, AV_LOG_ERROR





"Destination buffer too small!\n"); 


return NULL








// this should be damn rare (hopefully) 


for (i 


= 0 ; i 


< rbsplen 


; i


++) 





if (i 


+ 2 < rbsplen 


&& (rbsp


[i


] == 


0 && rbsp


[i


+1] == 0 && rbsp


[i


+2] < 4)) 





dest


[destpos


++] = rbsp


[i


++]; 


dest


[destpos


++] = rbsp


[i


];


dest


[destpos


++] = 0x03; // 


emulation prevention byte 





else 


dest


[destpos


++] = rbsp


[i


]; 





*destsize 


-= destpos





return dest


+destpos











你可能感兴趣的:(有损压缩)