步骤:
1.? 对yuv 8×8? ?数据? 8行分别1D DCT
2,? 用8行 1D? DCT 得到的数据生成中间8×8 块 Zj
2,对Zj? 的8列再 1D? DCT 后生成8列,用这8列组合成8*8的2D DCT 系数
准备用此1D DCT程序代替以前写的2D DCT,看能减少多少编码时间。
看网上文章,ffmpeg用的DCT也是1D DCT, 只是用了优化的AAN,再加入汇编代码处理。
验证数据:
?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define PI 3.1415926
int main(void){
//--------------1D DCT-----------------------------------------
int DCT(double i[8],double o[8]){ //ID DCT 参数类型不能用unsigned char ,因为中间系数已超char取值范围
double s=0.0;
for(int k=0;k<8;k++){
for(int n=0;n<8;n++){
s=s+i[n]*cos(PI*(2*n+1)*k/16);
}
if(k==0){
s=s*(1.0/(2*sqrt(2)));
}else{
s=s*(1.0/2);
}
o[k]=s;
s=0.0;
}
return 0;
}
//--------------------------------------------------------------------
double i[64]={
-76,-73,-67,-62,-58,-67,-64,-55,
-65,-69,-73,-38,-19,-43,-59,-56,
-66,-69,-60,-15,16,-24,-62,-55,
-65,-70,-57,-6,26,-22,-58,-59,
-61,-67,-60,-24,-2,-40,-60,-58,
-49,-63,-68,-58,-51,-60,-70,-53,
-43,-57,-64,-69,-73,-67,-63,-45,
-41,-49,-59,-60,-63,-52,-50,-34
};
//-------------8行分别1D DCT---------------------
double w[64]={}; //中间8×8
for(int a=0;a<64;a=a+8){
double ls_o[8]={};
double ls_i[8]={};
memcpy(ls_i,&(i[a]),64);
DCT(ls_i,ls_o);
memcpy(&(w[a]),ls_o,64);
}
//----------对中间8×8 列1D DCT-------------------------
double zj[8][8]={}; //取中间w的8个8列
int t=0;
for(int a=0;a<8;a++){
for(int b=0;b<8;b++){
zj[t][b]=w[b*8+a];
}
t++;
}
double ll[64]={}; //现在的列是水平放置的,也就是列变成了行,要转为列
for(int a=0;a<8;a++){ //对8列1D DCT
double zz[8]={};
DCT(zj[a],zz);
memcpy(&(ll[8*a]),zz,64);
}
int k=0;
double out[64]={}; //2D DCT 系数
for(int a=0;a<8;a++){
for(int b=0;b<8;b++){
out[8*b+a]=ll[k];
k++;
}
}
//----------显示--------------------------------------------
for(int a=0;a<8;a++){
for(int b=0;b<8;b++){
printf("%f ,",out[a*8+b]);
}
puts("");
}
return 0;
}
?
?
?
?
?
?
?