步骤:
1. 对yuv 8×8 数据 8行分别1D DCT
2, 用8行 1D DCT 得到的数据生成中间8×8 块 Zj
3,对Zj 的8列再 1D DCT 后生成8列,用这8列组合成8*8的2D DCT 系数
准备用此1D DCT程序代替以前写的2D DCT,看能减少多少编码时间。
看网上文章,ffmpeg用的DCT也是1D DCT, 只是用了优化的AAN,再加入汇编代码处理。
把以前的jpeg编码程序中的2D dct换成1D的,程序运行时间从2秒多立马减少为0.3秒。太有效了。但用于摄像头压缩还不行,因为这样帧率不会超过5帧。
突然想了一个巧法,可以把64个循环的余弦值手算出来,用if查表法看能不能再大幅减少编码时间。此余弦值是随二个参数变化的,也可处理为这两个数的二维数组。
验证数据:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define PI 3.1415926int 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×8for(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 DCTdouble 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;
}