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

📄 skl_mpg4_dec.cpp

📁 mpeg4编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// I-framevoid SKL_MB::Decode_Intra_Infos(SKL_FBB * const Bits){  const SKL_VLC *VLC;  while(Bits->See_Bits(9)==1) Bits->Discard(9);    // MCBPC stuffing  VLC = &MCBPC_Intra_B6_0[Bits->See_Bits(6)-1];  Bits->Discard(VLC->Len);  MB_Type = VLC->Val >> 2;  Cbp = VLC->Val & 3;  // Cbpc  Use_AC_Pred = Bits->Get_Bits(1);  VLC = &CBPY_Tab[Bits->See_Bits(6)-2];  Bits->Discard(VLC->Len);  Cbp |= VLC->Val;  if (MB_Type==SKL_MB_INTRA_Q) {    Prev_Quant = Quant;    Quant += DQuant_Tab[ Bits->Get_Bits(2) ];    if      (Quant>31) Quant = 31;    else if (Quant< 1) Quant =  1;  }  if (Field_DCT>=0) Set_Field_DCT( Bits->Get_Bits(1) );  else { SKL_ASSERT(Field_DCT==-1 && Field_Pred==0); }}static void Read_I_VOP(SKL_FBB * const Bits,                       const SKL_MP4_I * const VOP){  SKL_MB MB(VOP);  SKL_INT16 Base[7*64+SKL_ALIGN];  SKL_INT16 * const In = (SKL_INT16*)SKL_ALIGN_PTR(Base, SKL_ALIGN);  while(MB.y<VOP->MB_H)  {    MB.Init_Scanline(VOP, 0);    while(MB.x<VOP->MB_W)    {      MB.Decode_Intra_Infos(Bits);      MB.Decode_Intra_Blocks(Bits, In, VOP);      MB.Copy_16To8(In+1*64);      MB.Store_Map_Infos();      MB.Store_Zero_MV();      if (!MB.Resync || !MB.Resync_Marker(Bits))        MB++;      if (VOP->Debug_Level==5) {        printf( "%c", "*-="[1+MB.Field_DCT] );        if (MB.x==VOP->MB_W) {          printf( "\n" );          if (MB.y==VOP->MB_H-1) printf( "\n" );        }      }    }    if (VOP->Debug_Level==2) VOP->Dump_Line(0, &MB);    if (VOP->Slicer) VOP->Slicer(VOP->Cur, MB.y*16, 16, VOP->Slicer_Data);    MB.y++;  }}//////////////////////////////////////////////////////////// P-framevoid SKL_MB::Decode_Inter_Infos(SKL_FBB * const Bits,                                const SKL_MV * const Left_Predictor){  while(Bits->See_Bits(10)==1)    Bits->Discard(10);      // MCBPC stuffing  const SKL_VLC *VLC;       // Chroma MB type and block pattern  if (Bits->Get_Bits(1))    // test leading bit first    VLC = &MCBPC_Inter_B7_0[0];  else {    Bits->Check_Bits(8);    const SKL_UINT32 Code = Bits->Bits;    if (Code>=0x30000000)      VLC = MCBPC_Inter_B7_0 - 3+1 + (Code>>(24+4));    else /* if (Code>=0x02000000) */      VLC = MCBPC_Inter_B7_1 - 2   + (Code>>(24+0));    Bits->Discard(VLC->Len);  }  MB_Type = VLC->Val >> 2;  Cbp = VLC->Val & 3;       // Cbpc  if (MB_Type >= SKL_MB_INTRA)            /* INTRA or INTRA_Q */    Use_AC_Pred = Bits->Get_Bits(1);  else {    Use_AC_Pred = 0;    Cbp |= 0x0f<<2;    if (MB_Type<=SKL_MB_INTER_Q && VOL->Is_S_VOP() && VOL->Sprite_Mode==SPRITE_GMC)       MC_Sel = Bits->Get_Bits(1);    else      MC_Sel = 0;  }  VLC = &CBPY_Tab[ Bits->See_Bits(6)-2 ]; // block pattern for luminance  Bits->Discard(VLC->Len);  Cbp ^= VLC->Val;  if (MB_Type==SKL_MB_INTER_Q || MB_Type==SKL_MB_INTRA_Q)  {    Prev_Quant = Quant;    Quant += DQuant_Tab[ Bits->Get_Bits(2) ];    if      (Quant>31) Quant = 31;     // TODO: should be quant_prec here    else if (Quant< 1) Quant =  1;  }  if (Field_DCT>=0)                       // <- equivalent to testing 'VOL->Interlace'  {    if (MB_Type<=SKL_MB_INTER_Q && !MC_Sel) /* INTER or INTER_Q */    {                int DCT = (Cbp!=0) ? (int)Bits->Get_Bits(1) : 0;      Set_Field_DCT( DCT );      Field_Pred = Bits->Get_Bits(1);      if (Field_Pred)        Field_Dir = (Field_Dir&~0x03) | Bits->Get_Bits(2);    // top/bottom    }    else {      Field_Pred = 0;      if (MB_Type>=SKL_MB_INTRA || Cbp!=0) // for INTRA in P-VOP or INTER4V        Set_Field_DCT( Bits->Get_Bits(1) );      else        Set_Field_DCT( 0 );    }  }  else { SKL_ASSERT(Field_DCT==-1 && Field_Pred==0); }  if (MB_Type<=SKL_MB_INTER4V && !MC_Sel)  {    Predict_Motion_Vector_Blk0( MVs[0], &MVs[0], Left_Predictor );    if (!Field_Pred) {      Read_Vector( Bits, VOL->Fwd_Code, MVs[0] );      if (MB_Type==SKL_MB_INTER4V)      {        Predict_Motion_Vector( MVs[1], &MVs[1], 1 );        Read_Vector( Bits, VOL->Fwd_Code, MVs[1] );        Predict_Motion_Vector( MVs2[0], &MVs2[0], 2 );        Read_Vector( Bits, VOL->Fwd_Code, MVs2[0] );        Predict_Motion_Vector( MVs2[1], &MVs2[1], 3 );        Read_Vector( Bits, VOL->Fwd_Code, MVs2[1] );      }    }    else    {      MVs[0][1] /= 2;                 // see section 7.7.2.1      SKL_COPY_MV(MVs[1], MVs[0]);    // Both fields use the same predictor      Read_Vector( Bits, VOL->Fwd_Code, MVs[0] );      Read_Vector( Bits, VOL->Fwd_Code, MVs[1] );    }  }}static void Read_P_VOP(SKL_FBB * const Bits, const SKL_MP4_I * const VOP){  SKL_MB MB(VOP);  SKL_INT16 Base[7*64+SKL_ALIGN];  SKL_INT16 * const In = (SKL_INT16*)SKL_ALIGN_PTR(Base, SKL_ALIGN);  while(MB.y<VOP->MB_H)  {    MB.Init_Scanline(VOP, 0);    const SKL_MV *Left_Predictor = 0;    while(MB.x<VOP->MB_W)    {      if (Bits->Get_Bits(1)) // not coded      {        MB.MC_Sel = (VOP->Is_S_VOP() && VOP->Sprite_Mode==SPRITE_GMC);        if (!MB.MC_Sel) {          MB.MB_Type = SKL_MB_SKIPPED;          MB.Predict_With_0MV(VOP->Copy_Ops, 1);          MB.Store_Zero_MV();        }        else {          MB.MB_Type = SKL_MB_INTER;    // skipped GMC mb are not really 'skipped'          MB.Predict_GMC();             // 16x16 mode        }        MB.Set_Not_Intra();        Left_Predictor = &MB.MVs[1];      }      else      {        MB.Decode_Inter_Infos(Bits, Left_Predictor);        if (MB.MB_Type >= SKL_MB_INTRA)         /* INTRA or INTRA_Q */        {          MB.Decode_Intra_Blocks(Bits, In, VOP);          MB.Copy_16To8(In+1*64);          MB.Store_Zero_MV();          Left_Predictor = &MB.MVs[1];        }        else        {          MB.Decode_Inter_Blocks(Bits, In, VOP);          MB.Set_Not_Intra();          if (MB.MC_Sel) {            MB.MB_Type = SKL_MB_INTER;            MB.Predict_GMC();             // 16x16 mode            Left_Predictor = &MB.MVs[1];          }          else {            if (MB.MB_Type != SKL_MB_INTER4V)     /*  INTER or INTER_Q */            {              if (!MB.Field_Pred) {                MB.Predict_With_1MV(MB.MVs[0], VOP->Copy_Ops, 1);                MB.Store_16x16_MV();          // 16x16 mode                Left_Predictor = &MB.MVs[1];              }              else              {                  // Impl: we don't multiply the final field                   // vectors by 2 (cf. Store_16x8_MV())                MB.Predict_Fields(MB.MVs, VOP->Copy_Ops, 1, MB.Field_Dir);                MB.Store_16x8_MV(&MB.MVs2[0], &MB.MVs[0]); // field MV mode                Left_Predictor = &MB.MVs2[1]; // wow!              }             }            else                                  /* INTER4V */            {              MB.Predict_With_4MV(MB.MVs, MB.MVs2, VOP->Copy_Ops, 1);              Left_Predictor = &MB.MVs[1];            }          }          MB.Add_16To8(In + 1*64);        }      }      MB.Store_Map_Infos();      if (!MB.Resync || !MB.Resync_Marker(Bits))        MB++;      if (VOP->Debug_Level==5) {        if (MB.MC_Sel==1) printf( MB.MB_Type==SKL_MB_SKIPPED ? "G" : "g" );         else if (MB.MB_Type==SKL_MB_SKIPPED) printf( "s" );                else if (MB.Field_Pred==1) printf( "=" );        else if (MB.MB_Type==SKL_MB_INTER4V) printf( "4" );        else if (MB.MB_Type>=SKL_MB_INTRA) printf( "*" );        else printf( "%c", ".-="[1+MB.Field_DCT] );        if (MB.x==VOP->MB_W) {          printf( "\n" );          if (MB.y==VOP->MB_H-1) printf( "\n" );        }      }    }    if (VOP->Debug_Level==2) VOP->Dump_Line(0, &MB);    if (VOP->Slicer) VOP->Slicer(VOP->Cur, MB.y*16, 16, VOP->Slicer_Data);    MB.y++;  }  if (VOP->Debug_Level==1) {    if (VOP->Is_S_VOP()) VOP->Draw_GMC(VOP->Cur);    VOP->Dump_MVs(VOP->Cur, 2);  }}//////////////////////////////////////////////////////////// B-framestatic void Read_B_VOP(SKL_FBB * const Bits, const SKL_MP4_I * const VOP){  SKL_ASSERT(VOP->Rounding==0);    // Note: at this point, due to re-ordering, the Past frame    // is VOP->Future and the future one be VOP->Past!        SKL_MP4_PIC * const Cur  = VOP->Cur;  const SKL_MP4_PIC * const Next = VOP->Future;  const SKL_MP4_PIC * const Prev = VOP->Past;    // Note: we don't store the Map[] values for B-VOPs,    // but we need the future Map  const SKL_MP4_MAP * const Map = Next->Map;  SKL_ASSERT(Map!=0);  const int Trb = (int)( Cur->Time_Ticks  - VOP->Time_Last_Coded );  const int Trd = (int)( Next->Time_Ticks - VOP->Time_Last_Coded  );  int Trbf = 0, Trdf = 0;  SKL_MB MB(VOP);  const int S = VOP->MV_Stride;  while(MB.y<VOP->MB_H)  {      // note: MVs are not used nor stored for B-VOPs      // 4 special predictors are used, except for MB_DIRECT      // They are resetted at start of new row      // Indexes: #0/1: fwd frame/field preds.  #2/3: bwd preds    SKL_MV Preds[4] = { {0,0}, {0,0}, {0,0}, {0,0} };    MB.Init_Scanline(VOP, 0);    while(MB.x<VOP->MB_W)    {      if ( Map[MB.Pos].Type==SKL_MAP_SKIPPED ) // skipped in the future?      {          // we don't need no MV. Simply copy.        MB.Cbp = 0;        MB.Set_No_Field();        MB.Predict_With_0MV(VOP->Copy_Ops, 1);        if (VOP->Debug_Level==5) {          printf( "s" );          if (MB.x==VOP->MB_W-1) {            printf( "\n" );            if (MB.y==VOP->MB_H-1) printf( "\n" );          }        }      }      else      {        int B_Type;        int ModB1 = Bits->Get_Bits(1);  // ModeB (hardcoded table B-3)        if (ModB1)        {          MB.Cbp = 0;          B_Type = SKL_MB_DIRECT;          MB.Set_No_Field();        }        else        {          const int ModB2 = Bits->Get_Bits(1);          const SKL_VLC *VLC = &BType_Tab_B4[Bits->See_Bits(4) - 1];          B_Type = VLC->Val;          Bits->Discard( VLC->Len );          MB.Cbp = ModB2 ? 0 : Bits->Get_Bits(6);          if ( B_Type!=SKL_MB_DIRECT && MB.Cbp!=0 ) {            if (Bits->Get_Bits(1)) {              MB.Prev_Quant = MB.Quant;              MB.Quant += DBQuant_Tab[ Bits->Get_Bits(1) + 2 ];              if      (MB.Quant>31) MB.Quant = 31;     // TODO: should be quant_prec here              else if (MB.Quant< 1) MB.Quant =  1;            }          }                    if (MB.Field_DCT>=0) {            MB.Set_Field_DCT( MB.Cbp ? (int)Bits->Get_Bits(1) : 0 );            if (B_Type!=SKL_MB_DIRECT)            {              MB.Field_Pred = Bits->Get_Bits(1);              if (MB.Field_Pred) {                if (B_Type!=SKL_MB_BWD)                  MB.Field_Dir = (MB.Field_Dir&~0x03) | Bits->Get_Bits(2);                if (B_Type!=SKL_MB_FWD)                  MB.Field_Dir = (MB.Field_Dir&~0x0c) | (Bits->Get_Bits(2) << 2);              }            }            else { MB.Field_Pred = 0; }          }          else            SKL_ASSERT(MB.Field_DCT==-1 && MB.Field_Pred==0);        }            // here we go for the predictions        if (B_Type==SKL_MB_DIRECT)         // Grrrr!        {          SKL_MV dMV = {0,0};          if (!ModB1)                      // need a differential MV?            Read_Vector( Bits, 1, dMV );   // FCode=1, always.            // interpolate the 4 bwd/fwd vectors (section 7.6.9.5.2)          const int Offset = 2 * (MB.x + MB.y*S);          const SKL_MV * const Ref = Next->MV + Offset;          SKL_MV MVs[8];  // no need to store the MVs => use local var          if (Map[MB.Pos].Type!=SKL_MAP_16x8)           {            MVs[0][0] = dMV[0] + (SKL_INT16)( Trb*Ref[0][0]/Trd );            MVs[0][1] = dMV[1] + (SKL_INT16)( Trb*Ref[0][1]/Trd );            if (dMV[0]==0) MVs[4][0] = (SKL_INT16)( (Trb-Trd)*Ref[0][0]/Trd );            else           MVs[4][0] = MVs[0][0] - Ref[0][0];            if (dMV[1]==0) MVs[4][1] = (SKL_INT16)( (Trb-Trd)*Ref[0][1]/Trd );            else           MVs[4][1] = MVs[0][1] - Ref[0][1];            if (Map[MB.Pos].Type==SKL_MAP_16x16) {              if (!VOP->Quarter) {                MB.Predict_With_1MV(MVs[0], VOP->Copy_Ops, 1);                MB.Predict_With_1MV(MVs[4], VOP->Add_Ops,  0);              }              else {                  // For QPel, because of mirroring, we must split                  // the 16x16 block into four 8x8 ones.                SKL_COPY_MV(MVs[1], MVs[0]);                SKL_COPY_MV(MVs[2], MVs[0]);                SKL_COPY_MV(MVs[3], MVs[0]);

⌨️ 快捷键说明

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