视频,音频等多媒体文件中,丢失一定的有用信息,来实现数据的高压缩率同时恢复后 媒体质量并未发生很大变化。其很大程度依 赖于人对媒体的敏感部分,如音频局限在 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
;
}