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

📄 skl_mpg4_v12.cpp

📁 mpeg4编解码器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
inline static int Read_MPEG2_Escape(SKL_FBB *FBB) {  int Val = FBB->Get_Bits(12);  if ((Val&2047)==0) return 0;  // error  if (Val>=2048) Val -= 4096;  return Val;}//////////////////////////////////////////////////////////// -- MPEG-1 intra blockstatic void Read_Intra_Block_MPEG1(SKL_FBB *FBB, SKL_MB2 *MB, SKL_INT16 *Out){  const int * const Scan = SKL_MP4_I::Scan_Order[0]+64;    // Note: sometimes, EOB occurs *exactly* at the end, for i==0.    // We need to parse it however. That's why we're not using    // a loop like "while(i<0)", but "while(1)" instead.    // Note2: We unroll the Huffman table searching, because:    //  * EOB is only present on the 1rst chunk    //  * ESC is only present on the second    //  * Only the last chunk requires full 16bits    // We re-ordered the search in a (small) logarithmic search    // Note3: For code-cache coherency and branch prediction, we put    // the 'Ok:' code *first*  SKL_FBB_DECL;  SKL_FBB_START(*FBB);  SKL_FBB_LOAD_WORD(16);  const SKL_DCT_VLC *Tab = 0;  int i = -63;  while(1)  {    if (Bits>=0x28000000) {      Tab = Tab_B14_AC_0 -  5 + (Bits>>(16+11));Ok:      if ((i += Tab->Run)>=0) break;  // EOB      SKL_INT32 Val = Tab->Level;      Bits_Left -= Tab->Len+1;      Bits <<= Tab->Len;      if (Bits&0x80000000) Val = -Val;      Bits <<= 1;      SKL_FBB_LOAD_WORD(16);      Out[Scan[i++]] = Val;      continue;    }    else if (Bits>=0x08000000) {      Tab = Tab_B14_AC_1 -  4 + (Bits>>(16+8));      goto Ok;    }    else if (Bits>=0x00800000) {      if (Bits>=0x04000000) // ESC code only      {          // parse away 6bits for ESC code and 6bits for 'Skip' value        SKL_UINT32 Skip = (Bits >> (32-12)) & 0x3f;        if ((i += Skip)>=0) break;  // error        SKL_FBB_DISCARD_SAFE( 6+6 );//        inlined version of 'Read_MPEG1_Escape()'        SKL_FBB_LOAD_WORD(16);        SKL_INT32 Val = SKL_FBB_BITS_SIGNED(8);        SKL_FBB_DISCARD_SAFE(8);        if ((Val&0x7f)==0)  // Val=0 or 128        {          Val = SKL_FBB_BITS(8) + 2*Val;          SKL_FBB_DISCARD_SAFE(8);        }        Out[Scan[i++]] = Val;        SKL_FBB_LOAD_WORD(16);        continue;      }      else {        if (Bits>=0x02000000)          Tab = Tab_B14_AC_2 -  8 + (Bits>>(16+6));        else /* (Bits>=0x00800000) */          Tab = Tab_B14_AC_3 - 16 + (Bits>>(16+3));        goto Ok;      }    }    else {      if (Bits>=0x00200000) {        Tab = Tab_B14_AC_4 - 16 + (Bits>>(16+1));        goto Ok;      }      else if (Bits>=0x00100000) {        Tab = Tab_B14_AC_5 - 16 + (Bits>>(16+0));        SKL_FBB_LOAD_WORD(17);        goto Ok;      }      /* else -> error */    }    break;  /* error */  }  SKL_FBB_DISCARD_SAFE(Tab->Len);  SKL_FBB_STOP(*FBB);}staticvoid Read_Intra_Block_DType_MPEG1(SKL_FBB *FBB, SKL_MB2 *MB, SKL_INT16 *Out){ /* nothing to do */ }//////////////////////////////////////////////////////////// MPEG-1 Inter blockstaticint Read_Inter_Block_MPEG1(SKL_FBB *FBB, SKL_MB2 *MB, SKL_INT16 *Out){  const int * const Scan = SKL_MP4_I::Scan_Order[0]+64;  SKL_FBB Local;  Local.Copy(FBB);  const SKL_DCT_VLC *Tab;  int i = -64;  int Rows = 0x00;    // we decode the first coeff DC the usual way. No optim worth.  Local.Check_Bits(16 + 1);  Tab = Skl_DCT_VLC_Search( B14_DC_Chunks, Local.Bits );  if (Tab->Run<0) goto ESC_Code;  else goto Ok;  while(1)  {    if (Local.Bits>=0x28000000)  {      Tab = Tab_B14_AC_0 - 5 + (Local.Bits>>(16+11));Ok:      if ((i += Tab->Run)>=0) break; // EOB      int Val = Tab->Level;      Local.Bits_Left -= Tab->Len+1;      Local.Bits <<= Tab->Len;      if (Local.Bits&0x80000000) Val = -Val;      Local.Bits <<= 1;      Local.Check_Bits_Word(16);      const int j = Scan[i++];      Out[j] = Val;      Rows |= SKL_MP4_I::Row_From_Index[j];      continue;    }    else if (Local.Bits>=0x08000000) {      Tab = Tab_B14_AC_1 - 4 + (Local.Bits>>(16+8));      goto Ok;    }    else if (Local.Bits>=0x00800000) {      if (Local.Bits>=0x04000000) // ESC code only      {ESC_Code:          // parse away 6bits for ESC code and 6bits for 'Skip' value        SKL_UINT32 Skip = (Local.Bits >> (32-12)) & 0x3f;        if ((i += Skip)>=0) break;  // error        Local.Discard_Safe( 6+6 );        int Val = Read_MPEG1_Escape(&Local);            Out[Scan[i++]] = Val;        Local.Check_Bits_Word(16);        continue;      }      else {        if (Local.Bits>=0x02000000)          Tab = Tab_B14_AC_2 - 8 + (Local.Bits>>(16+6));        else /*(Local.Bits>=0x00800000)*/          Tab = Tab_B14_AC_3 - 16 + (Local.Bits>>(16+3));        goto Ok;      }    }    else {      if (Local.Bits>=0x00200000) {        Tab = Tab_B14_AC_4 - 16 + (Local.Bits>>(16+1));        goto Ok;      }      else if (Local.Bits>=0x00100000) {        Tab = Tab_B14_AC_5 - 16 + (Local.Bits>>(16+0));        Local.Check_Bits(17);   // loads 1 more byte        goto Ok;      }      /* else -> error */    }    break; /* error */  }// Error:  Local.Discard_Safe(Tab->Len);  FBB->Copy(&Local);  return Rows;}//////////////////////////////////////////////////////////// -- MPEG-2 intra blockstaticvoid Read_Intra_Block_B14_MPEG2(SKL_FBB *FBB, SKL_MB2 *MB, SKL_INT16 *Out){  const int * const Scan = MB->Scan_Order;  SKL_FBB Local;  Local.Copy(FBB);  SKL_INT32 Mismatch = Out[0];  int i = -63;  while(1)  {    int Val;    Local.Check_Bits(16);    const SKL_DCT_VLC *Tab = Skl_DCT_VLC_Search( B14_AC_Chunks, Local.Bits );    if (Tab->Run<0) // ESC    {        // parse away 6bits for ESC code and 6bits for 'Skip' value      SKL_UINT32 Skip = (Local.Bits >> (32-12)) & 0x3f;      i += Skip;      if (i>=0) break;  // error      Local.Discard_Safe( 6+6 );      Val = Read_MPEG2_Escape(&Local);    }    else {      Local.Discard_Word(Tab->Len);      i += Tab->Run;      if (i>=0) break;  // EOB2      Val = Tab->Level;      if (Local.Get_Bits(1)) Val = -Val;    }    Out[Scan[i++]] = Val;    Mismatch ^= Val;  }  Out[63] ^= Mismatch & 1;  FBB->Copy(&Local);}staticvoid Read_Intra_Block_B15_MPEG2(SKL_FBB *FBB, SKL_MB2 *MB, SKL_INT16 *Out){  const int * const Scan = MB->Scan_Order;  SKL_FBB Local;  Local.Copy(FBB);  SKL_INT32 Mismatch = Out[0];  int i = -63;  while(1)  {    int Val;    Local.Check_Bits(16);    const SKL_DCT_VLC *Tab = Skl_DCT_VLC_Search( B15_AC_Chunks, Local.Bits );    if (Tab->Run<0) // ESC    {        // parse away 6bits for ESC code and 6bits for 'Skip' value      SKL_UINT32 Skip = (Local.Bits >> (32-12)) & 0x3f;      i += Skip;      if (i>=0) break;  // error      Local.Discard_Safe( 6+6 );      Val = Read_MPEG2_Escape(&Local);    }    else {      Local.Discard_Word(Tab->Len);      i += Tab->Run;      if (i>=0) break;  // EOB2      Val = Tab->Level;      if (Local.Get_Bits(1)) Val = -Val;    }    Out[Scan[i++]] = Val;    Mismatch ^= Val;  }  Out[63] ^= Mismatch & 1;  FBB->Copy(&Local);}//////////////////////////////////////////////////////////// MPEG-2 Inter blockstaticint Read_Inter_Block_MPEG2(SKL_FBB *FBB, SKL_MB2 *MB, SKL_INT16 *Out){  const int * const Scan = MB->Scan_Order;  SKL_FBB Local;  Local.Copy(FBB);  Local.Check_Bits(16);  const SKL_DCT_VLC *Tab = Skl_DCT_VLC_Search( B14_DC_Chunks, Local.Bits );  int i = -64;  int Rows = 0x00;  while(1)  {    int Val;    SKL_ASSERT(Tab!=0);    if (Tab->Run<0) // ESC    {        // parse away 6bits (=Tab->Len) for ESC code        // and 6bits for 'Skip' value      SKL_UINT32 Skip = (Local.Bits >> (32-12)) & 0x3f;      i += Skip;      if (i>=0) break;  // error      Local.Discard_Safe( 6+6 /*Tab->Len+6*/ );      Val = Read_MPEG2_Escape(&Local);    }    else {      Local.Discard_Word(Tab->Len);      i += Tab->Run;      if (i>=0) break;  // EOB      Val = Tab->Level;      if (Local.Get_Bits(1)) Val = -Val;    }    const int j = Scan[i++];    Out[j] = Val;    Rows |= SKL_MP4_I::Row_From_Index[j];      // next lump    Local.Check_Bits(16);    Tab = Skl_DCT_VLC_Search( B14_AC_Chunks, Local.Bits );  }  FBB->Copy(&Local);  return Rows;}//////////////////////////////////////////////////////////// ISO/IEC 13818-2 section 7.2 -> 7.5// -- Intra blocksinline void SKL_MB2::Decode_Intra_Macroblock(){  SKL_INT16 Base[7*64+SKL_ALIGN];  SKL_INT16 * const In = (SKL_INT16*)SKL_ALIGN_PTR(Base, SKL_ALIGN);  SKL_INT16 *Out = In + 1*64;  SKL_ASSERT(Is_Intra());  if (!Has_Concealment_MV())  {    Reset_Fwd(); // reset all PMV    Reset_Bwd();  }  else // read concealment motion vectors  {    if (Is_MPEG1()) Read_Motion_Vectors_MPEG1(this, 0);    else if (Motion()==MC_FIELD) Read_Field_Motion_Vectors(this, 0);    else Read_Motion_Vectors(this, 0);    SKL_COPY_MV(PMV[1][0], PMV[0][0]);    SKL_COPY_MV(PMV[1][1], PMV[0][1]);    FBB->Discard(1); // marker bit  }  for(int blk=0; blk<6; ++blk)  {    VOL->Quant_Ops.Zero(In);    const int cc = (blk<4) ? 0 : blk-3;    DC[cc] += Read_DC_Diff_MPEG2(FBB, DCT_Chunks[cc]);    In[0] = DC[cc];    Read_Intra(FBB, this, In);    VOL->Quant_Ops.Dequant_Intra(Out, In, VOL->Q_Intra, Quant, DC_Q);    Out += 64;  }  Copy_16To8(In+1*64);      // ISO/IEC 11172-2 section 2.4.2.7 & 2.4.3.6  if (VOL->Is_D_VOP()) FBB->Get_Bits(1);}//////////////////////////////////////////////////////////// -- Inter blocksinline void SKL_MB2::Decode_Inter_Macroblock(){  SKL_ASSERT(!Is_Intra());  Reset_DC();  // note in 7.2.1  if (VOL->Is_P_VOP() && !Is_Forward()) // section 7.6.3.5  {    Reset_Fwd();  // only reset fwd pmv    Copy_Fwd();   // simply copy    Reset_Motion_Type();  }  else if (Has_Motion())   // section 6.2.5  {    if (Is_MPEG1())  Predict_MPEG1();    else {      switch (Motion()) {        case MC_NONE:  /* aieee! */        break;        case MC_FIELD:          Predict_Fields();        break;        case MC_FRAME:          Predict_Frame();        break;        case MC_DMV:          Predict_DMV();        break;      }    }  }  else Copy_Fwd();  if (Is_Pattern())     // coded  {    SKL_INT16 Base[7*64+SKL_ALIGN];    SKL_INT16 * const In = (SKL_INT16*)SKL_ALIGN_PTR(Base, SKL_ALIGN);    SKL_INT16 *Out = In + 1*64;    Cbp = Read_Coded_Block_Pattern(FBB);    for(int blk=(1<<5); blk; blk>>=1)    {      if (Cbp & blk)      // coded      {        VOL->Quant_Ops.Zero(In);        const int Rows = Read_Inter(FBB, this, In);        VOL->Quant_Ops.Dequant_Inter(Out, In, VOL->Q_Inter, Quant, Rows&0xff);      }      Out += 64;    }    Add_16To8(In + 1*64);  }}//////////////////////////////////////////////////////////// section 7.6.3.4inline int SKL_MB2::Skip_Macroblock(int Skip){  if (Skip>1)  {    Reset_DC();   // section 7.2.1    if (VOL->Is_B_VOP()) { // => re-use previous motion vectors      while(Skip-->1) {        if (!Next()) break;        Predict_Reuse();      }    }    else {      if ( VOL->Is_P_VOP() )        Reset_Fwd(); // section 7.6.3.4      while(Skip-->1) {        if (!Next()) break;        Copy_Fwd();      }    }    Reset_Motion_Type();  }  return !Next();}//////////////////////////////////////////////////////////// section 6.2.3.6 (picture data)SKL_MB2::SKL_MB2(const SKL_MP4_I *vol, SKL_FBB *fbb)   : SKL_MB(vol), FBB(fbb){  DC_Prec = (vol->MPEG12_Ext_Flags>>12) & 0x03;  DC_Q    = 1<<(3-DC_Prec);  Pic_Struct     = (vol->MPEG12_Ext_Flags>>10) & 0x03;  Frame_Pred_DCT = (vol->MPEG12_Ext_Flags>> 8) & 0x01;  Concealment_MV = (vol->MPEG12_Ext_Flags>> 7) & 0x01;  int Intra_VLC  = (vol->MPEG12_Ext_Flags>> 5) & 0x01;  if (Is_MPEG1()) {    Read_Intra = ( VOL->Is_D_VOP() ? Read_Intra_Block_DType_MPEG1                                   : Read_Intra_Block_MPEG1 );    Read_Inter = Read_Inter_Block_MPEG1;  }  else  {    Read_Intra = ( (Intra_VLC==0) ? Read_Intra_Block_B14_MPEG2                                  : Read_Intra_Block_B15_MPEG2 );    Read_Inter = Read_Inter_Block_MPEG2;  }  Scan_Order = VOL->Alt_Vert_Scan ? SKL_MP4_I::Scan_Order[2]                                  : SKL_MP4_I::Scan_Order[0];  Scan_Order += 64;  Reset_DC();  // reset prediction (section 7.2.1)  Reset_Fwd(); // reset all MV prediction (section 7.6.3.4)    Reset_Bwd();}

⌨️ 快捷键说明

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