⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 intra_pred.c

📁 decode the h264 video
💻 C
字号:
#include "common.h"#include "mbmodes.h"#include "mode_pred.h"#include "intra_pred.h"//////////////////////////////////////////////////// INTRA_4X4 PREDICTION /////#define p(x,y)  L_pixel(f,bx+(x),by+(y))#define left(y) ref[3-(y)]#define top(x)  ref[5+(x)]static inline void Intra_4x4_Vertical(frame *f, int *ref, int bx, int by) {  int x,y;  for(y=0; y<4; ++y)    for(x=0; x<4; ++x)      p(x,y)=top(x);}static inline void Intra_4x4_Horizontal(frame *f, int *ref, int bx, int by) {  int x,y;  for(y=0; y<4; ++y)    for(x=0; x<4; ++x)      p(x,y)=left(y);}static inline void Intra_4x4_DC(frame *f, mode_pred_info *mpi, int x, int y) {  int i, sum=0, count=0;  if(x>0 && ModePredInfo_Intra4x4PredMode(mpi,(x>>2)-1,y>>2)>=0)    for(i=0; i<4; ++i, ++count)      sum+=L_pixel(f,x-1,y+i);  if(y>0 && ModePredInfo_Intra4x4PredMode(mpi,x>>2,(y>>2)-1)>=0)    for(i=0; i<4; ++i, ++count)      sum+=L_pixel(f,x+i,y-1);  if(count==8) sum=(sum+4)>>3; else  if(count==4) sum=(sum+2)>>2; else               sum=128;  sum=Clip(sum);  for(i=0; i<4; ++i)    memset(&L_pixel(f,x,y+i),sum,4);}static inline void Intra_4x4_Diagonal_Down_Left(frame *f, int *ref, int bx, int by) {  int x,y,i;  for(y=0; y<4; ++y)    for(x=0; x<4; ++x) {      if((x&y)==3) i=top(6)+3*top(7)+2;      else         i=top(x+y)+2*top(x+y+1)+top(x+y+2)+2;      p(x,y)=i>>2;    }}static inline void Intra_4x4_Diagonal_Down_Right(frame *f, int *ref, int bx, int by) {  int x,y,i;  for(y=0; y<4; ++y)    for(x=0; x<4; ++x) {           if(x>y) i=top(x-y-2)+2*top(x-y-1)+top(x-y)+2;      else if(x<y) i=left(y-x-2)+2*left(y-x-1)+left(y-x)+2;      else         i=top(0)+2*top(-1)+left(0)+2;      p(x,y)=i>>2;    }}static inline void Intra_4x4_Vertical_Right(frame *f, int *ref, int bx, int by) {  int x,y,i,zVR;  for(y=0; y<4; ++y)    for(x=0; x<4; ++x) {      zVR=2*x-y;           if(zVR<-1) i=left(y-1)+2*left(y-2)+left(y-3)+2;      else if(zVR<0)  i=left(0)+2*left(-1)+top(-1)+2;      else if(zVR&1)  i=top(x-(y>>1)-2)+2*top(x-(y>>1)-1)+top(x-(y>>1))+2;      else            i=2*top(x-(y>>1)-1)+2*top(x-(y>>1))+2;      p(x,y)=i>>2;    }}static inline void Intra_4x4_Horizontal_Down(frame *f, int *ref, int bx, int by) {  int x,y,i,zHD;  for(y=0; y<4; ++y)    for(x=0; x<4; ++x) {      zHD=2*y-x;           if(zHD<-1) i=top(x-1)+2*top(x-2)+top(x-3)+2;      else if(zHD<0)  i=left(0)+2*left(-1)+top(0)+2;      else if(zHD&1)  i=left(y-(x>>1)-2)+2*left(y-(x>>1)-1)+left(y-(x>>1))+2;      else            i=2*left(y-(x>>1)-1)+2*left(y-(x>>1))+2;      p(x,y)=i>>2;    }}static inline void Intra_4x4_Vertical_Left(frame *f, int *ref, int bx, int by) {  int x,y,i;  for(y=0; y<4; ++y)    for(x=0; x<4; ++x) {      if(y&1) i=top(x+(y>>1))+2*top(x+(y>>1)+1)+top(x+(y>>1)+2)+2;      else    i=2*top(x+(y>>1))+2*top(x+(y>>1)+1)+2;      p(x,y)=i>>2;    }}static inline void Intra_4x4_Horizontal_Up(frame *f, int *ref, int bx, int by) {  int x,y,i,zHU;  for(y=0; y<4; ++y)    for(x=0; x<4; ++x) {      zHU=x+2*y;           if(zHU>5)  i=4*left(3);      else if(zHU==5) i=left(2)+3*left(3)+2;      else if(zHU&1)  i=left(y+(x>>1))+2*left(y+(x>>1)+1)+left(y+(x>>1)+2)+2;      else            i=2*left(y+(x>>1))+2*left(y+(x>>1)+1)+2;      p(x,y)=i>>2;    }}                      ////////////////////////////////void Intra_4x4_Dispatch(frame *f, mode_pred_info *mpi, int x, int y, int luma4x4BlkIdx) {  int ref[13];  int mode=ModePredInfo_Intra4x4PredMode(mpi,x>>2,y>>2);  if(mode!=2) {    int i;    if(x>0) {      for(i=0; i<4; ++i) left(i)=L_pixel(f,x-1,y+i);      if(y>0) left(-1)=L_pixel(f,x-1,y-1);    }    if(y>0) {      for(i=0; i<4; ++i) top(i)=L_pixel(f,x+i,y-1);      if((luma4x4BlkIdx&3)==3 || luma4x4BlkIdx==13 ||         (luma4x4BlkIdx==5 && x>=f->Lwidth-4))        for(i=4; i<8; ++i) top(i)=top(3);      else        for(i=4; i<8; ++i) top(i)=L_pixel(f,x+i,y-1);    }  }  switch(mode) {    case 0: Intra_4x4_Vertical(f,ref,x,y); break;    case 1: Intra_4x4_Horizontal(f,&ref[0],x,y); break;    case 2: Intra_4x4_DC(f,mpi,x,y); break;    case 3: Intra_4x4_Diagonal_Down_Left(f,&ref[0],x,y); break;    case 4: Intra_4x4_Diagonal_Down_Right(f,&ref[0],x,y); break;    case 5: Intra_4x4_Vertical_Right(f,&ref[0],x,y); break;    case 6: Intra_4x4_Horizontal_Down(f,&ref[0],x,y); break;    case 7: Intra_4x4_Vertical_Left(f,&ref[0],x,y); break;    case 8: Intra_4x4_Horizontal_Up(f,&ref[0],x,y); break;    default: printf("unsupported Intra4x4PredMode %d at %d,%d!\n",mode,x,y);  } }#undef p#undef top#undef left////////////////////////////////////////////////// INTRA_16X16 PREDICTION /////#define p(x,y)  L_pixel(f,bx+(x),by+(y))static inline void Intra_16x16_Vertical(frame *f, int bx, int by) {  int x,y;  for(y=0; y<16; ++y)    for(x=0; x<16; ++x)      p(x,y)=p(x,-1);}static inline void Intra_16x16_Horizontal(frame *f, int bx, int by) {  int x,y;  for(y=0; y<16; ++y)    for(x=0; x<16; ++x)      p(x,y)=p(-1,y);}static inline void Intra_16x16_DC(frame *f, mode_pred_info *mpi, int bx, int by, int constrained_intra_pred) {  int i, sum=0, count=0;  i=get_mb_mode(mpi,(bx>>4)-1,by>>4);  if(!((i==NA) || (IsInter(i) && constrained_intra_pred)))    for(i=0; i<16; ++i, ++count)      sum+=p(-1,i);  i=get_mb_mode(mpi,bx>>4,(by>>4)-1);  if(!((i==NA) || (IsInter(i) && constrained_intra_pred)))    for(i=0; i<16; ++i, ++count)      sum+=p(i,-1);  if(count==32) sum=(sum+16)>>5; else  if(count==16) sum=(sum+8)>>4;  else                sum=128;  sum=Clip(sum);  for(i=0; i<16; ++i)    memset(&p(0,i),sum,16);}static inline void Intra_16x16_Plane(frame *f, int bx, int by) {  int a,b,c,H,V,x,y;  for(x=0, H=0; x<8; ++x) H+=(x+1)*(p(8+x,-1)-p(6-x,-1));  for(y=0, V=0; y<8; ++y) V+=(y+1)*(p(-1,8+y)-p(-1,6-y));  a=16*(p(-1,15)+p(15,-1));  b=(5*H+32)>>6; c=(5*V+32)>>6;  for(y=0; y<16; ++y) for(x=0; x<16; ++x)    p(x,y)=Clip((a+b*(x-7)+c*(y-7)+16)>>5);  }void Intra_16x16_Dispatch(frame *f, mode_pred_info *mpi, int mode, int x, int y, int constrained_intra_pred) {  switch(mode) {    case 0: Intra_16x16_Vertical(f,x,y); break;    case 1: Intra_16x16_Horizontal(f,x,y); break;    case 2: Intra_16x16_DC(f,mpi,x,y,constrained_intra_pred); break;    case 3: Intra_16x16_Plane(f,x,y); break;    default: printf("unsupported Intra16x16PredMode %d at %d,%d!\n",mode,x,y);  }}#undef p///////////////////////////////////////////////// INTRA_CHROMA PREDICTION /////#define r(x,y)  Cr_pixel(f,bx+(x),by+(y))#define b(x,y)  Cb_pixel(f,bx+(x),by+(y))#define ICDCsumL(chan,offs) chan(-1,offs)+chan(-1,offs+1)+chan(-1,offs+2)+chan(-1,offs+3)#define ICDCsumT(chan,offs) chan(offs,-1)+chan(offs+1,-1)+chan(offs+2,-1)+chan(offs+3,-1)#define ICDCfill(offx,offy,valr,valb) \  do { \    int sy,vr=valr,vb=valb; \    for(sy=0; sy<4; ++sy) { \      memset(&r(offx,offy+sy),vr,4); \      memset(&b(offx,offy+sy),vb,4); \    } \  } while(0)static inline void Intra_Chroma_DC(frame *f, mode_pred_info *mpi, int bx, int by, int constrained_intra_pred) {  int i;  int left=1, top=1;  int l0r=512,l0b=512,l4r=512,l4b=512;  int t0r=512,t0b=512,t4r=512,t4b=512;  i=get_mb_mode(mpi,(bx>>3)-1,by>>3);  if((i==NA) || (IsInter(i) && constrained_intra_pred)) left=0;  if(left) {    l0r=ICDCsumL(r,0); l0b=ICDCsumL(b,0);    l4r=ICDCsumL(r,4); l4b=ICDCsumL(b,4);  }  i=get_mb_mode(mpi,bx>>3,(by>>3)-1);  if((i==NA) || (IsInter(i) && constrained_intra_pred)) top=0;  if(top) {    t0r=ICDCsumT(r,0); t0b=ICDCsumT(b,0);    t4r=ICDCsumT(r,4); t4b=ICDCsumT(b,4);  }  if(top) {    if(left)    ICDCfill(0,0,(l0r+t0r+4)>>3,(l0b+t0b+4)>>3);        else    ICDCfill(0,0,(t0r+2)>>2,(t0b+2)>>2);  } else {    if(left)    ICDCfill(0,0,(l0r+2)>>2,(l0b+2)>>2);        else    ICDCfill(0,0,128,128);  }       if(top)  ICDCfill(4,0,(t4r+2)>>2,(t4b+2)>>2);  else if(left) ICDCfill(4,0,(l0r+2)>>2,(l0b+2)>>2);  else          ICDCfill(4,0,128,128);       if(left) ICDCfill(0,4,(l4r+2)>>2,(l4b+2)>>2);  else if(top)  ICDCfill(0,4,(t0r+2)>>2,(t0b+2)>>2);  else          ICDCfill(0,4,128,128);  if(top) {    if(left)    ICDCfill(4,4,(l4r+t4r+4)>>3,(l4b+t4b+4)>>3);        else    ICDCfill(4,4,(t4r+2)>>2,(t4b+2)>>2);  } else {    if(left)    ICDCfill(4,4,(l4r+2)>>2,(l4b+2)>>2);        else    ICDCfill(4,4,128,128);  }}void Intra_Chroma_Horizontal(frame *f, int bx, int by) {  int x,y;  for(y=0; y<8; ++y)    for(x=0; x<8; ++x) {      r(x,y)=r(-1,y);      b(x,y)=b(-1,y);    }}void Intra_Chroma_Vertical(frame *f, int bx, int by) {  int x,y;  for(y=0; y<8; ++y)    for(x=0; x<8; ++x) {      r(x,y)=r(x,-1);      b(x,y)=b(x,-1);    }}void Intra_Chroma_Plane(frame *f, int bx, int by) {  int A,B,C,H,V,x,y;  // Intra_Chroma_Plane prediction for Cr channel  for(x=0, H=0; x<4; ++x) H+=(x+1)*(r(4+x,-1)-r(2-x,-1));  for(y=0, V=0; y<4; ++y) V+=(y+1)*(r(-1,4+y)-r(-1,2-y));  A=16*(r(-1,7)+r(7,-1));  B=(17*H+16)>>5; C=(17*V+16)>>5;  for(y=0; y<8; ++y) for(x=0; x<8; ++x)    r(x,y)=Clip((A+B*(x-3)+C*(y-3)+16)>>5);  // Intra_Chroma_Plane prediction for Cr channel  for(x=0, H=0; x<4; ++x) H+=(x+1)*(b(4+x,-1)-b(2-x,-1));  for(y=0, V=0; y<4; ++y) V+=(y+1)*(b(-1,4+y)-b(-1,2-y));  A=16*(b(-1,7)+b(7,-1));  B=(17*H+16)>>5; C=(17*V+16)>>5;  for(y=0; y<8; ++y) for(x=0; x<8; ++x)    b(x,y)=Clip((A+B*(x-3)+C*(y-3)+16)>>5);}void Intra_Chroma_Dispatch(frame *f, mode_pred_info *mpi, int mode, int x, int y, int constrained_intra_pred) {  switch(mode) {    case 0: Intra_Chroma_DC(f,mpi,x,y,constrained_intra_pred); break;    case 1: Intra_Chroma_Horizontal(f,x,y); break;    case 2: Intra_Chroma_Vertical(f,x,y); break;    case 3: Intra_Chroma_Plane(f,x,y); break;    default: printf("unsupported IntraChromaPredMode %d at %d,%d!\n",mode,x<<1,y<<1);  }}#undef r#undef b

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -