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

📄 skl_mpg4_dec.cpp

📁 mpeg4编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
static const SKL_BYTE Pred_Type_ABits[8][4] = { // index: [ABits (3b)][Blk=0..3]  {1, 1, 0, 0}, {7, 1, 2, 0}, {4, 4, 0, 0}, {5, 4, 2, 0}, {3, 3, 0, 0}, {6, 3, 2, 0}, {0, 0, 0, 0}, {2, 0, 2, 0}};  // hardcoded Fig 7-20. There's always 2 fixed predictors exactly  // on left and on top. Only the third is wandering on top, according to:static const int Top_Neighbors[4] = { 2, 1, 1, -1 };static inline SKL_INT16 Median(SKL_INT16 x, SKL_INT16 y, SKL_INT16 z) {  SKL_INT16 m = x;  SKL_INT16 M = x;  if (y < m) m = y;  else       M = y;  if      (z <= m) return m;  else if (z >= M) return M;  else             return z;}void SKL_MB::Predict_Motion_Vector(SKL_MV MV, const SKL_MV * const Src,                                    const int Blk) const{  SKL_ASSERT(Blk>=0 && Blk<4);  const SKL_MV * const MV_L  = Src - 1;  const SKL_MV * const MV_T  = Src - MV_Stride;  const SKL_MV * const MV_TR = MV_T + Top_Neighbors[Blk];  const int Pred_Type = Pred_Type_ABits[ABits][Blk];  switch(Pred_Type) {    default:    case 0:      MV[0] = Median(MV_L[0][0], MV_T[0][0], MV_TR[0][0]);      MV[1] = Median(MV_L[0][1], MV_T[0][1], MV_TR[0][1]);      return;    break;    case 1:      SKL_COPY_MV(MV, *MV_L);      return;    break;    case 2:      MV[0] = Median(0, MV_T[0][0], MV_TR[0][0]);      MV[1] = Median(0, MV_T[0][1], MV_TR[0][1]);      return;    break;    case 3:      MV[0] = Median(MV_L[0][0], 0, MV_TR[0][0]);      MV[1] = Median(MV_L[0][1], 0, MV_TR[0][1]);      return;    break;    case 4:      MV[0] = Median(MV_L[0][0], MV_T[0][0], 0);      MV[1] = Median(MV_L[0][1], MV_T[0][1], 0);      return;    break;    case 5:      SKL_COPY_MV(MV, *MV_T);      return;    break;    case 6:      SKL_COPY_MV(MV, *MV_TR );      return;    break;    case 7:      SKL_ZERO_MV(MV);      return;    break;  }}void SKL_MB::Predict_Motion_Vector_Blk0(SKL_MV MV, const SKL_MV *Src,                                        const SKL_MV * const MV_L) const{  const SKL_MV * const MV_T = Src - MV_Stride;  const SKL_MV * const MV_TR = MV_T + 2;  const int Pred_Type = Pred_Type_ABits[ABits][0];  switch(Pred_Type) {    default:    case 0:      MV[0] = Median(MV_L[0][0], MV_T[0][0], MV_TR[0][0]);      MV[1] = Median(MV_L[0][1], MV_T[0][1], MV_TR[0][1]);      return;    break;    case 1:      SKL_COPY_MV(MV, *MV_L);      return;    break;    case 2:      MV[0] = Median(0, MV_T[0][0], MV_TR[0][0]);      MV[1] = Median(0, MV_T[0][1], MV_TR[0][1]);      return;    break;    case 3:      MV[0] = Median(MV_L[0][0], 0, MV_TR[0][0]);      MV[1] = Median(MV_L[0][1], 0, MV_TR[0][1]);      return;    break;    case 4:      MV[0] = Median(MV_L[0][0], MV_T[0][0], 0);      MV[1] = Median(MV_L[0][1], MV_T[0][1], 0);      return;    break;    case 5:      SKL_COPY_MV(MV, *MV_T);      return;    break;    case 6:      SKL_COPY_MV(MV, *MV_TR );      return;    break;    case 7:      SKL_ZERO_MV(MV);      return;    break;  }}//////////////////////////////////////////////////////////// DC / AC prediction//////////////////////////////////////////////////////////#define ABS(x)  (((x)<0) ? -(x) : (x))#define DIV_ROUND(x,y)  ( (x)>=0 ? ((x)+((y)>>1))/(y) : ((x)-((y)>>1))/(y) )#define FDIV(x,y)   ((x)+((y)>>1)) / (y)  // section 7.4.3int SKL_MB_DATA::Choose_Pred_Dir(const SKL_MB_DATA *Top){  const SKL_INT16 A = this[-1].DC;  // wow  const SKL_INT16 B = Top[-1].DC;  const SKL_INT16 C = Top[ 0].DC;  if (ABS(A-B)<ABS(C-B)) {    DC = C;    return 1;  // vertical  }  else {    DC = A;    return 2;  // horizontal  }}#define BITS 16#define FIX(a) ((1<<BITS)/(a) + 1)static const int Div_AC[31] = {          FIX( 1),FIX( 2),FIX( 3),FIX( 4),FIX( 5),FIX( 6),FIX( 7),  FIX( 8),FIX( 9),FIX(10),FIX(11),FIX(12),FIX(13),FIX(14),FIX(15),  FIX(16),FIX(17),FIX(18),FIX(19),FIX(20),FIX(21),FIX(22),FIX(23),  FIX(24),FIX(25),FIX(26),FIX(27),FIX(28),FIX(29),FIX(30),FIX(31),};#define FDIV_SIGN(x,r,y)   ( (x)>=0 ? ((((x)+((r)>>1))*(y))>>BITS) : -(((-(x)+((r)>>1))*(y))>>BITS) )void SKL_MB_DATA::Add_DC_AC_Pred(SKL_INT16 In[64],                                 int Dir,                                 SKL_INT16 Left_AC[7],                                 const SKL_MB_DATA *Top,                                 int AC_Q,                                 int DC_Q){  int i;    if (Dir==1) {              // vertical    if (Top[0].Q>0) {        // intra block?      if (Top[0].Q==AC_Q) {        for(i=0; i<7; ++i) In[i+1] += Top->AC[i];      }      else {        const int Div = Div_AC[AC_Q-1]; // (1<<16) / AC_Q;        for(i=0; i<7; ++i) {          if (Top->AC[i]!=0)            In[i+1] += FDIV_SIGN(Top[0].Q*Top->AC[i], AC_Q, Div);        }      }    }  }  else if (Dir==2) {         // horizontal    if (this[-1].Q>0) {      // intra block?      if (this[-1].Q==AC_Q) {        for(i=0; i<7; ++i) In[8*(i+1)] += Left_AC[i];      }      else {        const int Div = Div_AC[AC_Q-1]; // (1<<16) / AC_Q;        for(i=0; i<7; ++i) {          if (Left_AC[i]!=0)            In[8*(i+1)] += FDIV_SIGN(this[-1].Q*Left_AC[i], AC_Q, Div);        }      }    }  }  for(i=0; i<7; ++i) {    AC[i] = In[i+1];    Left_AC[i] = In[8*(i+1)];  }  if (DC>0)    In[0] += FDIV(DC, DC_Q);  DC = In[0] * DC_Q;     // TODO: redundant with Dequant? (except saturation?)  SKL_ASSERT(In[0]>=0 && DC>=0);  Q = AC_Q;              // this will mark the block as 'Intra'}#undef FDIV_SIGN#undef BITS#undef FIX//////////////////////////////////////////////////////////// I/P(/B) VOP decodingstatic SKL_UINT64 Read_VOP_Time(SKL_FBB *Bits, SKL_MP4_I *VOP){  SKL_UINT64 Time = VOP->Time_Ref;  while(Bits->Get_Bits(1)) Time++;// elapsed seconds since last GOV, or I/P VOP  Bits->Discard(1);               // marker bit  Time *= VOP->Time_Frequency;    // switch to tick scale  Time += Bits->Get_Bits( VOP->Ticks_Bits );  Bits->Discard(1);               // marker bit  return Time;}//////////////////////////////////////////////////////////static int Read_Video_Packet(SKL_FBB * const Bits, SKL_MP4_I * const VOP){  int Ext_Code = 0;  if (VOP->Shape!=RECTANGULAR) {    Ext_Code = Bits->Get_Bits(1);    if (Ext_Code)                    // header extension code    {      if (!(VOP->Sprite_Mode==SPRITE_STATIC && VOP->Is_I_VOP())) {        Bits->Discard(13+1);         // sprite width  + marker bit        Bits->Discard(13+1);         // sprite height + marker bit        Bits->Discard(13+1);         // sprite left coord + marker bit        Bits->Discard(13+1);         // sprite top coord  + marker bit      }    }  }      const int Nb = SKL_BMASKS::Log2( VOP->MB_W*VOP->MB_H-1 );  const int Pos = (Nb==0) ? 0 : Bits->Get_Bits(Nb);  if (VOP->Shape!=BINARY_ONLY)    VOP->Quant = Bits->Get_Bits(VOP->Quant_Prec);    // now, The Question: why didn't they put the extension    // code at the same position, whatever shape, hmm? Why? :(  if (VOP->Shape==RECTANGULAR)    Ext_Code = Bits->Get_Bits(1);      if (Ext_Code)                     // header extension code  {    /* SKL_UINT64 Time = */ Read_VOP_Time(Bits, VOP);    Bits->Discard(2);               // coding type (should match current one)    if (VOP->Shape!=RECTANGULAR) {      Bits->Discard(1);             // change conv. ratio disable.      if (!VOP->Is_I_VOP())        Bits->Discard(1);           // shape coding type    }    if (VOP->Shape!=BINARY_ONLY)    {      VOP->DC_Thresh =         DC_Thresh_Tab[ Bits->Get_Bits(3) ];   // intra dc vlc thresh.      if (VOP->Sprite_Mode==SPRITE_GMC && VOP->Is_S_VOP() && VOP->Sprite_Nb_Pts>0)        VOP->Read_Sprite_Trajectory(Bits);      if (VOP->Shape==RECTANGULAR && VOP->Reduced_VOP>=0) {        if (VOP->Is_I_VOP() || VOP->Is_P_VOP())          VOP->Reduced_VOP = Bits->Get_Bits(1);        else VOP->Reduced_VOP = 0;  // disabled for B-VOP      }      if (!VOP->Is_I_VOP())        VOP->Fwd_Code = Bits->Get_Bits(3);    // fwd fixed code      if (VOP->Is_B_VOP())        VOP->Bwd_Code = Bits->Get_Bits(3);    // bwd fixed code    }  }  if (VOP->New_Pred) {    int Nb = VOP->Ticks_Bits + 3;    if (Nb>15) Nb = 15;    int Id_For_Pred = Bits->Get_Bits( Nb );    if (Bits->Get_Bits(1)) {            // id for pred. indications      Id_For_Pred = Bits->Get_Bits( Nb );      }    Bits->Discard(1);                 // marker bit  }  return Pos;}int SKL_MB::Resync_Marker(SKL_FBB * const Bits){  const int Len = Resync - 17;  // bit count expected  SKL_ASSERT(Len>=0 && Len<=7);  SKL_BYTE *Pos = Bits->Pos();  int To_Align = Bits->Bits_Left & 7;  if (To_Align==0) { To_Align = 8; Pos++; }      // bit stuffing  if (Bits->See_Bits(To_Align)!=SKL_BMASKS::And[To_Align-1])    return 0;      // marker check  if ( Pos[0]!=0 || Pos[1]!=0 || ((Pos[2]>>(7-Len)) != 0x00000001) )    return 0;  Bits->Discard( To_Align );  Bits->Discard( 16+1 + Len );//  fprintf( stderr, " RESYNC: (%d,%d)", x, y );  const int New_Pos = Read_Video_Packet(Bits, (SKL_MP4_I*)VOL);  Resync_Cursor(VOL, New_Pos);//  fprintf( stderr, " -> (%d,%d)\n", x, y );  return 1;}//////////////////////////////////////////////////////////// block DCT decoding//////////////////////////////////////////////////////////void SKL_MB::Decode_Intra_Blocks(SKL_FBB * const Bits,                                 SKL_INT16 * const In,                                 const SKL_MP4_I * const VOL) const{  SKL_INT16 *Out = In + 1*64;  for(int blk=0; blk<6; ++blk)  {    const int DC_Q = SKL_MP4_I::DC_Scales[(blk<4)][Quant-1];    int Pred_Dir = Curs[blk]->Choose_Pred_Dir( Tops[blk] );    const int * const Zigzag =        VOL->Alt_Vert_Scan ? SKL_MP4_I::Scan_Order[2]                          : Use_AC_Pred ? SKL_MP4_I::Scan_Order[Pred_Dir]                                        : SKL_MP4_I::Scan_Order[0];    VOL->Quant_Ops.Zero(In);    int Off;    if (Prev_Quant<VOL->DC_Thresh)    {      In[0] = Read_DC_Diff( Bits, (blk<4) );      Off = 1;    }    else Off = 0;    if (Cbp & (1<<(5-blk)))     // coded      Read_Intra_AC(Bits, In, Zigzag, Off);    Curs[blk]->Add_DC_AC_Pred(In,                               Use_AC_Pred ? Pred_Dir : 0,                              Lefts[blk],                              Tops[blk],                              Quant,                              DC_Q);    VOL->Quant_Ops.Dequant_Intra(Out, In, VOL->Q_Intra, Quant, DC_Q);    Out += 64;  }}void SKL_MB::Decode_Inter_Blocks(SKL_FBB * const Bits,                                 SKL_INT16 * const In,                                 const SKL_MP4_I * const VOL) const{  SKL_INT16 *Out = In + 1*64;  const int * const Zigzag =     VOL->Alt_Vert_Scan ? SKL_MP4_I::Scan_Order[2]                       : SKL_MP4_I::Scan_Order[0];  for(int blk=(1<<5); blk; blk>>=1)  {    if (Cbp & blk)      // coded    {      VOL->Quant_Ops.Zero(In);      const int Rows = Read_Inter_AC(Bits, In, Zigzag);      VOL->Quant_Ops.Dequant_Inter(Out, In, VOL->Q_Inter, Quant, Rows&0xff);    }    Out += 64;  }}//////////////////////////////////////////////////////////

⌨️ 快捷键说明

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