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

📄 skl_mpg4_enc.cpp

📁 mpeg4编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        Level2 = Level1 + 1;        Tbl_L1      = (Level1>=-24) ? B16_17_Code_Len[Level1^-1]      : Code_Len0;        Tbl_L2      = (Level2>=-24) ? B16_17_Code_Len[Level2^-1]      : Code_Len0;        Tbl_L1_Last = (Level1>=- 6) ? B16_17_Code_Len_Last[Level1^-1] : Code_Len0;        Tbl_L2_Last = (Level2>=- 6) ? B16_17_Code_Len_Last[Level2^-1] : Code_Len0;      }      const SKL_UINT32 Dist1 = Lambda*dQ1*dQ1;      const SKL_UINT32 Dist2 = Lambda*dQ2*dQ2;      const int dDist21 = Dist2-Dist1;      for(int Run=i-Run_Start; Run>0; --Run)      {        const SKL_UINT32 Cost_Base = Dist1 + Run_Costs[i-Run];// for sub-optimal (but slightly worth it, speed-wise) search, uncomment the following://        if (Cost_Base>=Best_Cost) continue;        SKL_UINT32 Cost1, Cost2;        int bLevel;        Cost1 = Cost_Base + (Tbl_L1[Run-1]<<16);        Cost2 = Cost_Base + (Tbl_L2[Run-1]<<16) + dDist21;        if (Cost2<Cost1) { Cost1 = Cost2; bLevel = Level2; }        else bLevel = Level1;        if (Cost1<Best_Cost)        {          Best_Cost = Cost1;          Nodes[i].Run   = Run;          Nodes[i].Level = bLevel;        }        Cost1 = Cost_Base + (Tbl_L1_Last[Run-1]<<16);        Cost2 = Cost_Base + (Tbl_L2_Last[Run-1]<<16) + dDist21;        if (Cost2<Cost1) { Cost1 = Cost2; bLevel = Level2; }        else bLevel = Level1;        if (Cost1<Last_Cost)        {          Last_Cost  = Cost1;          Last.Run   = Run;          Last.Level = bLevel;          Last_Node  = i;        }      }      if (DBG==1) {        Run_Costs[i] = Best_Cost;        printf( "Costs #%2d: ", i);        for(j=-1;j<=Non_Zero;++j) {          if (j==Run_Start)            printf( " %3.0d|", Run_Costs[j]>>12 );          else if (j>Run_Start && j<i) printf( " %3.0d|", Run_Costs[j]>>12 );          else if (j==i)               printf( "(%3.0d)", Run_Costs[j]>>12 );          else                         printf( "  - |" );        }        printf( "<%3.0d %2d %d>", Min_Cost>>12, Nodes[i].Level, Nodes[i].Run );        printf( "  Last:#%2d {%3.0d %2d %d}", Last_Node, Last_Cost>>12, Last.Level, Last.Run );        printf( " AC:%3.0d Dist0:%3d Dist(%2d):%3d Dist(%2d):%3d", AC, Dist0>>12, Level1, Dist1>>12, Level2, Dist2>>12 );        printf( "\n" );      }    }    else       // Very very high levels, with no chance of being optimizable => Simply pick best Run.    {      Best_Cost = 0xf0000000;      for(int Run=i-Run_Start; Run>0; --Run)      {        const SKL_UINT32 Cost = (30<<16) + Run_Costs[i-Run];    // 30 bits + no distortion        if (Cost<Best_Cost)        {          Best_Cost = Cost;          Nodes[i].Run   = Run;          Nodes[i].Level = Level1;        }        if (Cost<Last_Cost)        {          Last_Cost  = Cost;          Last.Run   = Run;          Last.Level = Level1;          Last_Node  = i;        }      }    }    Run_Costs[i] = Best_Cost;    if (Best_Cost < Min_Cost + Dist0) {      Min_Cost = Best_Cost;      Run_Start = i;    }    else    {        // as noticed by Michael Niedermayer (michaelni at gmx.at), there's        // a code shorter by 1 bit for a larger run (!), same level. We give        // it a chance by not moving the left barrier too much.      while( Run_Costs[Run_Start]>Min_Cost+(1<<16) )        Run_Start++;        // spread on preceding coeffs the cost incurred by skipping this one      for(j=Run_Start; j<i; ++j) Run_Costs[j] += Dist0;      Min_Cost += Dist0;    }  }  if (DBG) {    Last_Cost = Evaluate_Cost(Out, Zigzag, Non_Zero, Lambda);    if (DBG==1) {      printf( "=> " );      for(i=0; i<=Non_Zero; ++i) printf( "[%3.0d] ", Out[Zigzag[i]] );      printf( "\n" );   }  }  if (Last_Node<0)    return -1;       // reconstruct optimal sequence backward with surviving paths  SKL_BZERO(Out, 64*sizeof(*Out));  Out[Zigzag[Last_Node]] = Last.Level;  i = Last_Node - Last.Run;  while(i>=0) {    Out[Zigzag[i]] = Nodes[i].Level;    i -= Nodes[i].Run;  }  if (DBG) {    SKL_UINT32 Cost = Evaluate_Cost(Out, Zigzag, Non_Zero, Lambda);    if (DBG==1) {      printf( "<= " );       for(i=0; i<=Last_Node; ++i) printf( "[%3.0d] ", Out[Zigzag[i]] );      printf( "\n--------------------------------\n" );    }    if (Cost>Last_Cost) printf( "!!! %d > %d\n", Cost, Last_Cost );  }  return Last_Node;}#undef DBG////////////////////////////////////////////////////////////// Main decimation calls////////////////////////////////////////////////////////////void SKL_MP4_ENC_I::Decimate_Intra(SKL_INT16 * const Out,                                    SKL_INT16 * const In,                                    SKL_INT32 Q, SKL_INT32 DC_Q) const{  Quant_Ops.Dct(In);  Quant_Ops.Quant_Intra(Out, In, Q_Intra, Q, DC_Q);// this is WRONG 2 out of 3 times, due to DC/AC prediction//  if (_Use_Trellis && Trellis_Quantize(Out, Q, SKL_MP4_I::Scan_Order[0]+1, 62)<0)//    return;  Quant_Ops.Dequant_Intra(In, Out, Q_Intra, Q, DC_Q);}int SKL_MP4_ENC_I::Decimate_Inter(SKL_INT16 * const Out,                                   SKL_INT16 * const In,                                   const SKL_INT32 Q) const{  Quant_Ops.Dct(In);  int SAV = Quant_Ops.Quant_Inter(Out, In, Q_Inter, Q);  if (SAV<_Inter_Coding_Threshold) return 0;  if (_Use_Trellis && Trellis_Quantize(Out, Q, SKL_MP4_I::Scan_Order[0], 63)<0)    return 0;  Quant_Ops.Dequant_Inter(In, Out, Q_Inter, Q, 0xff);  return SAV;}//////////////////////////////////////////////////////////// Macroblock params polishing//////////////////////////////////////////////////////////const int SKL_MB_ENC::Map_To_Type[SKL_MAP_LAST] ={  SKL_MB_SKIPPED, SKL_MB_INTRA, SKL_MB_INTER /*(GMC)*/,   SKL_MB_INTER, SKL_MB_INTER, SKL_MB_INTER4V};static inline void Set_dMV(SKL_MV dMV, const SKL_MV MVo){    // dMV contains predictor  dMV[0] = MVo[0] - dMV[0];  dMV[1] = MVo[1] - dMV[1];}void SKL_MB_ENC::Substract_Prediction(){  SKL_ASSERT(MB_Type<=SKL_MB_INTER4V && Field_Pred==0);    // INTER or INTER4V  Predict_Motion_Vector_Blk0( dMVs[0], &MVs[0], MVs-1 );  Set_dMV(dMVs[0], MVs[0]);  if (MB_Type==SKL_MB_INTER4V)  {    Predict_Motion_Vector( dMVs[1], &MVs[1], 1 );    Set_dMV(dMVs[1], MVs[ 1]);    Predict_Motion_Vector( dMVs[2], &MVs2[0], 2 );    Set_dMV(dMVs[2], MVs2[0]);    Predict_Motion_Vector( dMVs[3], &MVs2[1], 3 );    Set_dMV(dMVs[3], MVs2[1]);  }}void SKL_MB_ENC::Substract_Field_Prediction(){  SKL_ASSERT(MB_Type<SKL_MB_INTER4V && Field_Pred==1);  // INTER+field only  Predict_Motion_Vector_Blk0( dMVs[0], &MVs[0], MVs-1 );  dMVs[0][1] /= 2;               // Both fields use the same predictor  MVs[0][1] >>= 1;               // descale to field-MV...  MVs[1][1] >>= 1;               // Scale will be restored after coding.  SKL_COPY_MV(dMVs[1], dMVs[0]);  Set_dMV(dMVs[0], MVs[0]);  Set_dMV(dMVs[1], MVs[1]);}void SKL_MB_ENC::Set_Final_Params(){    // update dQ  if (Map[Pos].dQ) {    dQuant = Map[Pos].dQ;    Prev_Quant = Quant;    Quant += dQuant;    SKL_ASSERT(Quant>=1 && Quant<=31);  }  else dQuant = 0;    // set up field params  if (VOL->Interlace) {    if (VOL->Interlace&0x3) Set_Field_DCT( (Map[Pos].Flags&1)!=0 );    else SKL_ASSERT(Field_DCT==0);    if (VOL->Interlace&0xc)  {      if (Map[Pos].Type==SKL_MAP_16x8) {        Field_Pred = 1;        Field_Dir = ((MVs[0][1]&1)<<1) | ((MVs[1][1]&1)^1);        Substract_Field_Prediction();      }      else Field_Pred = 0;    }    else SKL_ASSERT(Field_Pred==0);   }  else SKL_ASSERT(Field_DCT==-1 && Field_Pred==0);  if (MB_Type!=SKL_MB_INTRA && !MC_Sel && !Field_Pred)    Substract_Prediction();}//////////////////////////////////////////////////////////// I-MB codingvoid SKL_MB_ENC::Encode_Intra(SKL_FBB * const Bits, SKL_INT16 In[12*64], int Is_I_VOP){  SKL_INT16 *C;  int blk;  const int * Zigzags[6];  int Pred_Dirs[6];  Use_AC_Pred = Select_DC_AC_Pred(In, Pred_Dirs);  Cbp = 0;  C = In;  for(blk=0; blk<6; ++blk)  {    Zigzags[blk] = Use_AC_Pred ? SKL_MP4_I::Scan_Order[Pred_Dirs[blk]]                               : SKL_MP4_I::Scan_Order[0];    Last[blk] = Find_Last(C, Zigzags[blk], 63);    Cbp <<= 1;    if (Last[blk]>0) Cbp |= 1;    C += 64;  }    // time to really set the MB_Type  if (dQuant!=0) {    SKL_ASSERT(MB_Type!=SKL_MB_INTER4V);    MB_Type += 1;  // INTRA->INTRA_Q or INTER->INTER_Q  }  const SKL_VLC *VLC;  if (Is_I_VOP) VLC = &MCBPC_Intra_B6[ MB_Type-3 ][ Cbp & 3 ];  else VLC = &MCBPC_Inter_B7[ MB_Type ][ Cbp & 3 ];  Bits->Put_Bits( VLC->Val, VLC->Len );  Bits->Put_Bits( Use_AC_Pred, 1 );  int CbpY = Cbp >> 2;  if (MB_Type<=SKL_MB_INTER_Q) CbpY ^= 0x0f;  VLC = &CBPY_B8[ CbpY ];  Bits->Put_Bits( VLC->Val, VLC->Len );  if (dQuant!=0)  { /* INTRA_Q or INTER_Q */     SKL_ASSERT(dQuant>=-2 && dQuant<=2);    Bits->Put_Bits( DQuant_Tab[dQuant+2], 2 );  }  if (Field_DCT>=0)     // interlace?    Bits->Put_Bits( Field_DCT, 1 );  const SKL_SAFE_INT Pos2 = Bits->Write_Bit_Pos();    C = In;  for(blk=0; blk<6; ++blk)  {      // TODO: DC_Thresh here...    Write_DC_Coeff(Bits, C[0], (blk<4));  // DC-coeff    if (Last[blk]>0)      Write_Coeffs( Bits, C, Zigzags[blk]+1, Last[blk]-1, B16_17_Tabs[1]);    C += 64;  }  Texture_Bits += Bits->Write_Bit_Pos() - Pos2;  Store_Zero_MV();}//////////////////////////////////////////////////////////// P-MB codingvoid SKL_MB_ENC::Encode_Inter(SKL_FBB * const Bits, SKL_INT16 In[12*64], int Fwd_Code){  SKL_ASSERT(MB_Type <= SKL_MB_INTER4V);    // time to really set the MB_Type  if (dQuant!=0) {    SKL_ASSERT(MB_Type<SKL_MB_INTER4V);    MB_Type = SKL_MB_INTER_Q;  }  const SKL_VLC *VLC;  VLC = &MCBPC_Inter_B7[ MB_Type ][ Cbp & 3 ];  Bits->Put_Bits( VLC->Val, VLC->Len );  if (MB_Type<=SKL_MB_INTER_Q && VOL->Is_S_VOP() && VOL->Sprite_Mode==SPRITE_GMC)     Bits->Put_Bits(MC_Sel, 1);  VLC = &CBPY_B8[ (Cbp>>2) ^ 0xf ];  Bits->Put_Bits( VLC->Val, VLC->Len );  if (dQuant!=0) {  /* INTER_Q */    SKL_ASSERT(dQuant>=-2 && dQuant<=2);    Bits->Put_Bits( DQuant_Tab[dQuant+2], 2 );  }  if (Field_DCT>=0)   // interlace?  (this costs 0.1% in file size)  {    if (Cbp!=0) Bits->Put_Bits( Field_DCT, 1 );    if (MB_Type<=SKL_MB_INTER_Q && !MC_Sel)  /* INTER or INTER_Q */    {      Bits->Put_Bits( Field_Pred, 1 );      if (Field_Pred)        Bits->Put_Bits( Field_Dir&3, 2 ); // Fwd Top/Bottom field select.    }      // Note: no field pred for INTER4V or INTRA, or GMC  }  if (!MC_Sel)    // no vector for GMC  {    const SKL_SAFE_INT Pos = Bits->Write_Bit_Pos();    Write_Vector(Bits, dMVs[0], Fwd_Code);    if (MB_Type==SKL_MB_INTER4V)    {      Write_Vector(Bits, dMVs[1], Fwd_Code);      Write_Vector(Bits, dMVs[2], Fwd_Code);      Write_Vector(Bits, dMVs[3], Fwd_Code);    }    else  /*  INTER or INTER_Q */    {      if (Field_Pred)        Write_Vector(Bits, dMVs[1], Fwd_Code);    }    MV_Bits += Bits->Write_Bit_Pos() - Pos;  }  const SKL_SAFE_INT Pos2 = Bits->Write_Bit_Pos();    SKL_INT16 *C = In;  for(int blk=0; blk<6; ++blk) {    if (Last[blk]>=0)      Write_Coeffs( Bits, C, SKL_MP4_I::Scan_Order[0], Last[blk], B16_17_Tabs[0]);    C += 64;  }  Texture_Bits += Bits->Write_Bit_Pos() - Pos2;  Set_Not_Intra();}//////////////////////////////////////////////////////////// B-MB codingvoid SKL_MB_ENC::Encode_Inter_B(SKL_FBB * const Bits, SKL_INT16 In[12*64],                                int Fwd_Code, int Bwd_Code){  int ModB1 = (B_Type==SKL_MB_DIRECT && dMVs[0][0]==0 && dMVs[0][1]==0);  if (Cbp==0) {    if (ModB1)      Bits->Put_Bits( 1, 1 );   // ModB1    else      Bits->Put_Bits( 1, 2 );   // ModB2  }  else {    Bits->Put_Bits( 0, 2 );     // ModB1/B2    Bits->Put_Bits( Cbp, 6 );    if (B_Type!=SKL_MB_DIRECT) {      if (dQuant==-2) Bits->Put_Bits( 2, 2 );      else if (dQuant==2) Bits->Put_Bits( 3, 2 );      else {        SKL_ASSERT(dQuant==0);        Bits->Put_Bits( 0, 1 );      }

⌨️ 快捷键说明

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