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

📄 skl_mpg4_dec.cpp

📁 mpeg4编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    int Level = VLC->Level;    int Last  = (Level<0);    if (Run>=0) {      if (Last) Level = -Level;      Code = Bits->Get_Bits(VLC->Len+1);      if (Code&1) Level = -Level;    }    else  // Escape. Note: can only occur in Intra_B16_2[]    {      Bits->Discard(VLC->Len);      if (Run==-3)    // 3rd escape      {        Code = Bits->Get_Bits(1+6+1+12+1);        Last  = (Code>>20);        Run   = (Code>>14) & 0x3f;        Level = (Code>> 1) & 0xfff;        if (Level&0x800) Level |= (-1)^0xfff;      }      else {  // 1rst and 2nd escape        const int Esc2 = (Run==-2);        Bits->Check_Bits(12);        Code = Bits->Bits;        SKL_ASSERT(Code>=0x00800000);             if (Code>=0x30000000) VLC = Intra_B16_0 - 12 + (Code>>(20+6));        else if (Code>=0x13000000) VLC = Intra_B16_1 - 19 + (Code>>(20+4));        else if (Code>=0x06000000) VLC = Intra_B16_2 - 48 + (Code>>(20+1));        else /*if (Code>=0x00800000)*/ VLC = Intra_B16_3 -  8 + (Code>>(20+0));        // else break; /* error */        SKL_ASSERT(VLC->Run>=0); // Hope it's not an ESCAPE code again! ;)        Code  = Bits->Get_Bits(VLC->Len+1);        Level = VLC->Level;        Last  = (VLC->Level<0);        if (Last) Level = -Level;        Run = VLC->Run;        if (Esc2) Run += Max_RUN[0][Last][Level-1];    // 2nd escape        else      Level += Max_LEVEL[0][Last][Run];    // 1rst escape        if (Code&1) Level = -Level;      }    }    i += Run;    if (i<64) {       const int j = Zigzag[i++];      Coeff[j] = (SKL_INT16)Level;      if (Last) break;    }    else break; /* error */  }}static int Read_Inter_AC(SKL_FBB *Bits, SKL_INT16 *Coeff,                         const int * const Zigzag){  int i = 0;  int Rows = 0x00;  while(1)  {    const SKL_DCT_VLC *VLC;    Bits->Check_Bits_Word(12);    SKL_UINT32 Code = Bits->Bits;    SKL_ASSERT(Code>=0x00800000);    if      (Code>=0x30000000) VLC = Inter_B17_0 - 12 + (Code>>(20+6));    else if (Code>=0x13000000) VLC = Inter_B17_1 - 19 + (Code>>(20+4));    else if (Code>=0x06000000) VLC = Inter_B17_2 - 24 + (Code>>(20+2));    else if (Code>=0x00800000) VLC = Inter_B17_3 -  8 + (Code>>(20+0));    else break; /* error */    int Run   = VLC->Run;    int Level = VLC->Level;    int Last  = (Level<0);    if (Run>=0) {      if (Last) Level = -Level;      if (Bits->Get_Bits(VLC->Len+1) & 1)        Level = -Level;    }    else  // Escape. Note: can only occur in Inter_B17_2[]    {      Bits->Discard_Safe(VLC->Len);      if (Run==-3)    // 3rd escape      {        SKL_UINT32 Pack = Bits->Get_Bits(1+6+1+12+1);        Last  = (Pack>>20);        Run   = (Pack>>14) & 0x3f;        Level = ((SKL_INT32)Pack<<19)>>20;        // Level = (Pack>> 1) & 0xfff;        // if (Level&0x800) Level |= (-1)^0xfff;      }      else    // 1rst and 2nd escape      {        const int Esc2 = (Run==-2);        Bits->Check_Bits_Word(12);        Code = Bits->Bits;        SKL_ASSERT(Code>=0x00800000);        if      (Code>=0x30000000) VLC = Inter_B17_0 - 12 + (Code>>(20+6));        else if (Code>=0x13000000) VLC = Inter_B17_1 - 19 + (Code>>(20+4));        else if (Code>=0x06000000) VLC = Inter_B17_2 - 24 + (Code>>(20+2));        else if (Code>=0x00800000) VLC = Inter_B17_3 -  8 + (Code>>(20+0));        else break; /* error */        SKL_ASSERT(VLC->Run>=0); // Hope it's not an ESCAPE code again! ;)        Run = VLC->Run;        Level = VLC->Level;        Last = (VLC->Level<0);        if (Last) Level = -Level;        if (Esc2) Run += Max_RUN[1][Last][Level-1];    // 2nd escape        else      Level += Max_LEVEL[1][Last][Run];    // 1rst escape        if (Bits->Get_Bits(VLC->Len+1) & 1)          Level = -Level;      }    }    i += Run;    if (i<64) {       const int j = Zigzag[i++];      Coeff[j] = (SKL_INT16)Level;      Rows |= SKL_MP4_I::Row_From_Index[j];      if (Last) break;    }    else break; /* error */  }  return Rows;}//////////////////////////////////////////////////////////// Macroblock Cursor// TODO: this could be incrementalized (with 'Off')//////////////////////////////////////////////////////////SKL_MB::SKL_MB(const SKL_MP4_I * const Vol)  : VOL(Vol)  , BpS(Vol->BpS)  , BpS8(8*Vol->BpS)  , Fwd_CoLoc(Vol->Past->Y - Vol->Cur->Y)  , Bwd_CoLoc(Vol->Future->Y - Vol->Cur->Y)  , YTmp(Vol->Cur->Y - 16 - 16*Vol->BpS)     // size: 17x16  , Map(Vol->Cur->Map){    // HACK! about YTmp: We form the qpel intermediate prediction in the     // top left (margin) macroblock of the current edged picture. Since     // the current picture is not supposed to be motion-searched for, we    // can happily trash the edges.     //(Note: I'm somewhat ashamed of such a hack :)  Quant = VOL->Quant;  Prev_Quant = Quant;  Field_DCT = VOL->Interlace ? 0 : -1;  MV_Stride = VOL->MV_Stride;  y = 0;  MC_Sel = 0;  Field_Dir = VOL->Field_Dir;    // Init scan DC/AC predictors  int i;  MB_W = VOL->MB_W;  if (VOL->Reduced_VOP>0) MB_W >>= 1;  for(i=0; i<2*MB_W; ++i)    VOL->Y_Preds[0][i].Set_Not_Intra();             // reset Top Y  for(i=0; i<MB_W; ++i) {    VOL->C_Preds[0][            i].Set_Not_Intra(); // reset Top U    VOL->C_Preds[0][VOL->MB_W+2+i].Set_Not_Intra(); // reset Top V  }    // invariants along each scan lines  Lefts[0] = Left_ACs[0];  Lefts[1] = Left_ACs[0];  Lefts[2] = Left_ACs[1];  Lefts[3] = Left_ACs[1];  Lefts[4] = Left_ACs[2];  Lefts[5] = Left_ACs[3];    // compute resync marker len  if (VOL->Resync) {    int Len;    if (VOL->Coding==I_VOP) Len = 16 + 1;    else if (VOL->Coding==B_VOP) {      Len = 16 + ((VOL->Bwd_Code > VOL->Fwd_Code) ? VOL->Bwd_Code                                                  : VOL->Fwd_Code);      if (VOL->Quarter) Len += 1;    }    else  /* P/S-VOP */      Len = 16 + VOL->Fwd_Code + (VOL->Quarter ? 1 : 0);    Resync = Len;  }  else Resync = 0;  Start_Scan();}SKL_MB::~SKL_MB() {    // Store field parity for next frame  ((SKL_MP4_I*)VOL)->Field_Dir = Field_Dir;}void SKL_MB::Set_Not_Intra(){  Curs[0]->Set_Not_Intra();  Curs[1]->Set_Not_Intra();  Curs[2]->Set_Not_Intra();  Curs[3]->Set_Not_Intra();  Curs[4]->Set_Not_Intra();  Curs[5]->Set_Not_Intra();}void SKL_MB::Init_Offset(){  const SKL_MP4_PIC * const Pic = VOL->Cur;  const int Off = (x + y*BpS) * 8;  Y1  = Pic->Y + Off * 2;  U   = Pic->U + Off;  V   = Pic->V + Off;  if (Field_DCT<=0) {    YBpS = BpS;    Y2 = Y1 + BpS8;    Field_Pred = 0;  }  else { SKL_ASSERT( (Y2=0, 1) ); /* sanity check */ }  const int Shift = 1 + VOL->Quarter - (VOL->Reduced_VOP>0);  MB_Pels = 16 << (Shift);  Limit_Mins[0] = (-x*16         -16) << Shift;  Limit_Maxs[0] = (-x*16+VOL->Width ) << Shift;  Limit_Mins[1] = (-y*16         -16) << Shift;  Limit_Maxs[1] = (-y*16+VOL->Height) << Shift;  Limit_Mins_UV[0] = (-x*8            -8) << 1;  Limit_Maxs_UV[0] = (-x*8+VOL->Width/2 ) << 1;  Limit_Mins_UV[1] = (-y*8            -8) << 1;  Limit_Maxs_UV[1] = (-y*8+VOL->Height/2) << 1;}void SKL_MB::Resync_Cursor(const SKL_MP4_I * const VOL,                           int New_Pos){  Start_Scan();  const int xo = New_Pos % VOL->MB_W;  y = New_Pos / VOL->MB_W;  Init_Scanline(VOL, xo);    // mark left column/top row as invalid ("out-of-video-packet")  int To_Fill = VOL->MB_W - xo;  int Fill_Left = xo;  if (VOL->Reduced_VOP>0) {     SKL_ASSERT((y&1)==0 && (xo&1)==0);    To_Fill >>= 1;    Fill_Left >>= 1;  }  int i;  for(i=0; i<2*To_Fill; ++i)       // top rows    Tops[0][i].Set_Not_Intra();  for(i=0; i<To_Fill; ++i) {    Tops[4][i].Set_Not_Intra();    Tops[5][i].Set_Not_Intra();  }  for(i=-2*Fill_Left; i<0; ++i)    // left rows    Curs[2][i].Set_Not_Intra();  for(i=-Fill_Left; i<0; ++i) {    Curs[4][i].Set_Not_Intra();    Curs[5][i].Set_Not_Intra();  }    Curs[0][-1].Set_Not_Intra();  Prev_Quant = Quant = VOL->Quant;}void SKL_MB::Init_Scanline(const SKL_MP4_I * const VOL, int xo){    // 'y' should have been initialized prior to getting here  x = xo;  Pos = x + y*VOL->MB_W;  ABits = (Top_Ok()<<1) | (Top_Right_Ok()<<2) | 1;  // left is never available.    // reset left predictors to zero  for(int k=0; k<4; ++k)    for(int i=0; i<7; ++i)      Left_ACs[k][i] = 0;  int yo = y;  if (VOL->Reduced_VOP>0) { yo >>= 1; xo >>= 1; }  if (!VOL->Is_B_VOP()) {    MVs  = VOL->Cur->MV + 2*(xo + yo*MV_Stride);    MVs2 = MVs + MV_Stride;  }  else {    // sanity check    MVs  = 0;    MVs2 = 0;  }    // swap the block scan lines  if (!(yo&1)) {    Curs[2] = VOL->Y_Preds[2] + 2*xo;    Tops[0] = VOL->Y_Preds[0] + 2*xo;    Tops[4] = VOL->C_Preds[0] + xo;    Curs[4] = VOL->C_Preds[1] + xo;  }  else {    Curs[2] = VOL->Y_Preds[0] + 2*xo;    Tops[0] = VOL->Y_Preds[2] + 2*xo;    Tops[4] = VOL->C_Preds[1] + xo;    Curs[4] = VOL->C_Preds[0] + xo;  }    // invariants along each scan lines  const int W = VOL->MB_W;  Curs[0] = VOL->Y_Preds[1] + 2*xo;  Curs[1] = Curs[0] + 1;  Tops[2] = Curs[0];  Tops[3] = Curs[1];  Tops[1] = Tops[0] + 1;  Curs[3] = Curs[2] + 1;  Tops[5] = Tops[4] + W + 2;  Curs[5] = Curs[4] + W + 2;  Init_Offset();    // Sanity check: Boundary blocks are invariants  SKL_ASSERT( VOL->Sanity_Check_Preds() );}void SKL_MB::operator++(int){  SKL_ASSERT(VOL->Reduced_VOP<=0);  Tops[0] += 2;  Tops[1] += 2;  Tops[2] += 2;  Tops[3] += 2;  Tops[4] += 1;  Tops[5] += 1;  Curs[0] += 2;  Curs[1] += 2;  Curs[2] += 2;  Curs[3] += 2;  Curs[4] += 1;  Curs[5] += 1;  MVs  += 2;  MVs2 += 2;  Y1  += 16;  Y2  += 16;  U   += 8;  V   += 8;  Limit_Mins[0] -= MB_Pels;  Limit_Maxs[0] -= MB_Pels;  Limit_Mins_UV[0] -= 16;  Limit_Maxs_UV[0] -= 16;  x++;  Pos++;  MB_Count++;  ABits = ((ABits>>1) & 0x02) | (Top_Right_Ok()<<2);}#if 0    /* TODO: BROKEN FOR NOW */void SKL_MB::Next_Line_Preds(){  SKL_MB_DATA *Tmp;#define SWAP(a,b) Tmp = (a); (a) = (b); (b) = Tmp  SWAP(Tops[0], Curs[2]);  SWAP(Tops[4], Curs[4]);  SWAP(Tops[5], Curs[5]);#undef SWAP  for(int k=0; k<4; ++k)    for(int i=0; i<7; ++i)      Left_ACs[k][i] = 0;  MVs += 4; // skip edges  MVs2+= 4; // "}#endif//////////////////////////////////////////////////////////// MV prediction//////////////////////////////////////////////////////////  // Map from Availability-bits to Prediction Type:  //  Pred Type is the following, used in descending probability:  //  . Median with 3 vectors  //  . Median with 2 vectors (!Top/!Top_Right/!Left) + zero-vector  //  . Copy vector (Left, Top, Top_Right)  //  . Zero vector

⌨️ 快捷键说明

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