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

📄 skl_mpg4_v12.cpp

📁 mpeg4编解码器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/******************************************************** * Some code. Copyright (C) 2003 by Pascal Massimino.   * * All Rights Reserved.      (http://skal.planet-d.net) * * For Educational/Academic use ONLY. See 'LICENSE.TXT'.* ********************************************************//* * skl_mpg4_v12.cpp * * simple, approximative, MPEG1/2 decoder * Are incorrect: oddification (MPEG1), mismatch control of *  MPEG2 inter blocks. And most probably, field motion is broken, even... * Not supported:  *   Field frames (Bweurrrk) and of course scalable modes (who does??:). *  ********************************************************/#include "./skl_mpg4i.h"//////////////////////////////////////////////////////////enum {    // Start codes  MPEG12_PICTURE_START    = 0x00000100, MPEG12_SLICE_MIN        = 0x00000101, MPEG12_SLICE_MAX        = 0x000001af/*    reserved            = 0x000001b0 *//*    reserved            = 0x000001b1 */, MPEG12_USER_START       = 0x000001b2, MPEG12_SEQ_START        = 0x000001b3, MPEG12_SEQUENCE_ERROR   = 0x000001b4, MPEG12_EXT_START        = 0x000001b5/*    reserved            = 0x000001b6 */, MPEG12_SEQ_END          = 0x000001b7, MPEG12_GOP_START        = 0x000001b8, MPEG12_LAST_CODE        = 0x000001ff    // extension code id. (Table 6-2)., MPEG12_SEQ_EXT_ID                   = 1, MPEG12_SEQ_DISPLAY_EXT_ID           = 2, MPEG12_QMATRIX_EXT_ID               = 3, MPEG12_SEQ_SCALABLE_EXT_ID          = 5, MPEG12_PIC_DISPLAY_EXT_ID           = 7, MPEG12_PIC_CODING_EXT_ID            = 8, MPEG12_PIC_SPATIAL_SCALABLE_EXT_ID  = 9, MPEG12_PIC_TEMPORAL_SCALABLE_EXT_ID = 10    // picture structure, MPEG12_TOP_FIELD    = 1, MPEG12_BOTTOM_FIELD = 2, MPEG12_FRAME_PIC    = 3    // MB types, MPEG12_MBLK_ERROR   = 0x00, MPEG12_MBLK_INTRA   = 0x01, MPEG12_MBLK_PATTERN = 0x02, MPEG12_MBLK_MBWD    = 0x04, MPEG12_MBLK_MFWD    = 0x08, MPEG12_MBLK_QUANT   = 0x10, MPEG12_MBLK_STWCF   = 0x20  // Spatial-Temporal Weight Code Flag, MPEG12_MBLK_PSTWC   = 0x40  // Permitted Spatial-Temporal Weight Class, MPEG12_MBLK_MOTION = (MPEG12_MBLK_MFWD  | MPEG12_MBLK_MBWD), MPEG12_MBLK_QI     = (MPEG12_MBLK_INTRA | MPEG12_MBLK_QUANT), MPEG12_MBLK_PI     = (MPEG12_MBLK_INTRA | MPEG12_MBLK_PATTERN), MC_NONE  = 0x000, MC_FIELD = 0x100, MC_FRAME = 0x200, MC_16x8  = 0x200, MC_DMV   = 0x300 /* dual prime */, MC_ALL   = 0x300};struct SKL_MB2 : public SKL_MB    // special cursor for MPEG1/2{  int DC[3];  int DC_Q;  int DC_Prec;  SKL_MV PMV[2][2];   // [fwd/bwd][1rst pred/2nd pred]  int Pic_Struct;  int Concealment_MV;  int Frame_Pred_DCT;  const int *Scan_Order;  void (*Read_Intra)(SKL_FBB*, SKL_MB2 *MB, SKL_INT16*);  int (*Read_Inter)(SKL_FBB*, SKL_MB2 *MB, SKL_INT16*);  SKL_FBB * const FBB;  int Is_Intra() const         { return ((MB_Type & MPEG12_MBLK_INTRA)!=0); }  int Is_Quant() const         { return ((MB_Type & MPEG12_MBLK_QUANT)!=0); }  int Is_Intra_Quant() const   { return ((MB_Type & MPEG12_MBLK_QI)!=0); }  int Is_Intra_Pattern() const { return ((MB_Type & MPEG12_MBLK_PI)!=0); }  int Is_Pattern() const       { return ((MB_Type & MPEG12_MBLK_PATTERN)!=0); }  int Is_Forward() const       { return ((MB_Type & MPEG12_MBLK_MFWD)!=0); }  int Is_Backward() const      { return ((MB_Type & MPEG12_MBLK_MBWD)!=0); }  int Has_Motion() const       { return ((MB_Type&MPEG12_MBLK_MOTION)!=0); }  int Has_B_Motion() const     { return ((MB_Type&MPEG12_MBLK_MOTION)==MPEG12_MBLK_MOTION); }  int Motion() const           { return (MB_Type&MC_ALL); }  int Is_Frame() const           { return (Pic_Struct==MPEG12_FRAME_PIC); }  int Has_Concealment_MV() const { return (Concealment_MV!=0); }  int Is_DC_Predicted() const    { return (Frame_Pred_DCT!=0); }  void Reset_DC() {    DC[0] = DC[1] = DC[2] = 1<<(7+DC_Prec);  }  void Reset_Motion_Type();  void Reset_Field_Motion_Type();  void Reset_Fwd() { SKL_ZERO_MV(PMV[0][0]); SKL_ZERO_MV(PMV[0][1]); }  void Reset_Bwd() { SKL_ZERO_MV(PMV[1][0]); SKL_ZERO_MV(PMV[1][1]); }  inline int MV_Outside(const SKL_MV MV) const;  inline int Field_MVs_Outside(const SKL_MV MV[2]) const;  void Predict_MPEG1();  void Predict_Frame();  void Predict_Fields();  void Predict_DMV();  void Predict_Reuse();  void Copy_Fwd() const { Predict_With_0MV(VOL->Copy_Ops, 1); }  inline void Predict_MPEG12(const SKL_MV MVo,                             const SKL_MB_FUNCS * const Ops,                             const int CoLoc) const;  inline void Predict_Fields_MPEG12(const SKL_MV MVo[2],                                    const SKL_MB_FUNCS * const Ops,                                    const int Src_Fields,                                    const int CoLoc) const;  int Is_MPEG1() const { return (VOL->MPEG_Version==1); }  SKL_MB2(const SKL_MP4_I *vol, SKL_FBB *FBB);  inline void Decode_Intra_Macroblock();  inline void Decode_Inter_Macroblock();  void Init_Scan(int yPos, int xPos) {    y = yPos;    if (xPos!=0) {      y += xPos / VOL->MB_W;      x = xPos % VOL->MB_W;    }    else x = 0;    Init_Offset();  }  int Finished() const { return (y==VOL->MB_H-1 && x==VOL->MB_W-1); }  int Next() {    (*this)++;    if (x>=VOL->MB_W) {      y++;      if (y>=VOL->MB_H) return 0;   // oh,oh      x = 0;      Init_Scanline(VOL, x);    }    return 1;  }  inline int Skip_Macroblock(int Skip);  void Print_Infos() const;};//////////////////////////////////////////////////////////// VLC reading helpersstruct SKL_VLC { SKL_INT16 Value, Len; };struct SKL_DCT_VLC { SKL_INT16 Run; SKL_BYTE Level, Len; };struct SKL_VLC_CHUNK {   const SKL_VLC *Tab;     // <- table pointer is pre-offset  SKL_UINT32 Thresh;  int Shift;};struct SKL_DCT_CHUNK {  const SKL_DCT_VLC *Tab; // <- table pointer is pre-offset  SKL_UINT32 Thresh;   int Shift;};inline static const SKL_VLC *Skl_VLC_Search(const SKL_VLC_CHUNK *Chk, SKL_UINT32 Code){  while(Code<Chk->Thresh) Chk++;  SKL_ASSERT(Chk->Tab!=0);  return &Chk->Tab[ Code >> Chk->Shift ];}inline static const SKL_DCT_VLC *Skl_DCT_VLC_Search(const SKL_DCT_CHUNK *Chk, SKL_UINT32 Code){  while(Code<Chk->Thresh) Chk++;  SKL_ASSERT(Chk->Tab!=0);  return &Chk->Tab[ Code >> Chk->Shift ];}////////////////////////////////////////////////////////////  VLC for Motion Code// ISO/IEC 13818-2 section 6.2.5// Tables B-10static const SKL_VLC MV_Tab_B10_0[14] = {  { 3, 4},{-3, 4},{ 2, 3},{ 2, 3},{-2, 3},{-2, 3}, { 1, 2},{ 1, 2},{ 1, 2},{ 1, 2},{-1, 2},{-1, 2},{-1, 2},{-1, 2}};static const SKL_VLC MV_Tab_B10_1[10] = {  { 7, 7},{-7, 7}, { 6, 7},{-6, 7},{ 5, 7},{-5, 7},{ 4, 6},{ 4, 6},{-4, 6},{-4, 6}};static const SKL_VLC MV_Tab_B10_2[24] = {  {16,10},{-16,10},{15,10},{-15,10},{14,10},{-14,10},{13,10},{-13,10}, {12,10},{-12,10},{11,10},{-11,10},{10, 9},{10, 9},{-10, 9},{-10, 9}, { 9, 9},{ 9, 9},{-9, 9},{-9, 9},{ 8, 9},{ 8, 9},{-8, 9},{-8, 9}};static const SKL_VLC MV_Tab_B11[4] = {  {0, 1}, {0,1}, { 1,2}, {-1,2}};static void Read_Motion_Vector(SKL_FBB * const Bits, SKL_INT32 Fix, SKL_INT16 &MV){  if (Bits->Get_Bits(1)) return;  Bits->Check_Bits_Word(9+1);  SKL_UINT32 Code = Bits->Bits;  const SKL_VLC *VLC;  if      (Code>=0x20000000)   VLC = MV_Tab_B10_0 -  2 + (Code>>(22+6));  else if (Code>=0x0c000000)   VLC = MV_Tab_B10_1 -  6 + (Code>>(22+3));  else  /*(Code>=0x06000000)*/ VLC = MV_Tab_B10_2 - 24 + (Code>>(22+0));  Bits->Discard(VLC->Len);  const int High  = 1 << (Fix+3);  int Val = VLC->Value;  if (--Fix) {    const int Res = Bits->Get_Bits(Fix) + 1;    if (Val<0) {      MV += ((Val+1)<<Fix) - Res;      if (MV<-High) MV += 2*High;    }    else {      MV += ((Val-1)<<Fix) + Res;      if (MV>=High) MV -= 2*High;    }  }  else {    if (Val<0) {      MV += Val;      if (MV<-High) MV += 2*High;    }    else {      MV += Val;      if (MV>=High) MV -= 2*High;    }  }}static inline int Read_DMV(SKL_FBB * const Bits){  const SKL_VLC * const VLC = &MV_Tab_B11[Bits->See_Bits(2)];  Bits->Discard(VLC->Len);  return VLC->Value;}static inline void Read_Vector(SKL_FBB * const Bits, SKL_MV MV,                 SKL_INT32 xFCode, SKL_INT32 yFCode){  Read_Motion_Vector(Bits, xFCode, MV[0]);  Read_Motion_Vector(Bits, yFCode, MV[1]);}static void Read_Motion_Vectors(SKL_MB2 *MB, int Bwd){  SKL_ASSERT(!MB->Is_MPEG1() && MB->Motion()!=MC_DMV);  const int FCode = (Bwd ? MB->VOL->Bwd_Code : MB->VOL->Fwd_Code);  Read_Vector(MB->FBB, MB->PMV[Bwd][0], FCode>>4, FCode&0xf);  SKL_COPY_MV(MB->PMV[Bwd][1], MB->PMV[Bwd][0]); // update 2nd predictor}static inline void Read_DMV_Vector(SKL_FBB * const Bits, SKL_MV MV, SKL_MV DMV, SKL_INT32 FCode){  Read_Motion_Vector(Bits, FCode>>4, MV[0]);  DMV[0] = Read_DMV(Bits);  Read_Motion_Vector(Bits, FCode&0xf, MV[1]);  DMV[1] = Read_DMV(Bits);}static int Read_Field_Motion_Vectors(SKL_MB2 *MB, int Bwd){  SKL_ASSERT(!MB->Is_MPEG1() && MB->Motion()!=MC_DMV);  const int FCode = (Bwd ? MB->VOL->Bwd_Code : MB->VOL->Fwd_Code);  int Dirs = MB->FBB->Get_Bits(1) << 1;  Read_Vector(MB->FBB, MB->PMV[Bwd][0], FCode>>4, FCode&0xf);  Dirs |= MB->FBB->Get_Bits(1);  Read_Vector(MB->FBB, MB->PMV[Bwd][1], FCode>>4, FCode&0xf);  return Dirs;}static void Read_Motion_Vectors_MPEG1(SKL_MB2 *MB, int Bwd){  const int FCode = (Bwd ? MB->VOL->Bwd_Code : MB->VOL->Fwd_Code);  if (!(FCode&8))    Read_Vector(MB->FBB, MB->PMV[Bwd][0], FCode&0x7, FCode&0x7);  else {  // full-pix motion vector    MB->PMV[Bwd][0][0] >>= 1; MB->PMV[Bwd][0][1] >>= 1;    Read_Vector(MB->FBB, MB->PMV[Bwd][0], FCode&0x7, FCode&0x7);    MB->PMV[Bwd][0][0] <<= 1; MB->PMV[Bwd][0][1] <<= 1;  }  SKL_COPY_MV(MB->PMV[Bwd][1], MB->PMV[Bwd][0]);  // update 2nd predictor}void SKL_MB2::Reset_Motion_Type(){    // derive motion_type (section 6.3.17.1)  SKL_ASSERT(Is_Frame());  Set_Field_DCT(-1);  MB_Type &= ~MC_ALL;  MB_Type |= MC_FRAME;}//////////////////////////////////////////////////////////// MPEG1-2 specific predictioninlineint SKL_MB2::MV_Outside(const SKL_MV MV) const{  return (MV[0]<Limit_Mins[0] || MV[0]>Limit_Maxs[0] ||          MV[1]<Limit_Mins[1] || MV[1]>Limit_Maxs[1] );}inlineint SKL_MB2::Field_MVs_Outside(const SKL_MV MV[2]) const{  return (MV[0][0]<Limit_Mins[0] || MV[0][0]>Limit_Maxs[0] ||          MV[1][0]<Limit_Mins[0] || MV[1][0]>Limit_Maxs[0] ||          2*MV[0][1]<Limit_Mins[0] || 2*MV[0][1]>Limit_Maxs[1] ||          2*MV[1][1]<Limit_Mins[0] || 2*MV[1][1]>Limit_Maxs[1] );}inlinevoid SKL_MB2::Predict_MPEG12(const SKL_MV MVo,                             const SKL_MB_FUNCS * const Ops,                             const int Fwd) const{  if (MV_Outside(MVo)) return;  int Halves, Off;  const int CoLoc = (Fwd ? Fwd_CoLoc : Bwd_CoLoc);  SKL_BYTE * const Dst = Y1;  Halves = (MVo[0]&1) | ((MVo[1]&1)<<1);  Off = CoLoc + (MVo[1]>>1)*BpS + (MVo[0]>>1);  Ops->HP_16x8[Halves](Dst,      Dst+Off,      BpS);  Ops->HP_16x8[Halves](Dst+BpS8, Dst+BpS8+Off, BpS);  SKL_MV uv_MV;  uv_MV[0] = MVo[0] / 2; uv_MV[1] = MVo[1] / 2;  Halves = (uv_MV[0]&1) | ((uv_MV[1]&1)<<1);  Off = (uv_MV[1]>>1)*BpS + (uv_MV[0]>>1);  Off += CoLoc;  Ops->HP_8x8[Halves](U, U+Off, BpS);  Ops->HP_8x8[Halves](V, V+Off, BpS);}inlinevoid SKL_MB2::Predict_Fields_MPEG12(const SKL_MV MVo[2],                                    const SKL_MB_FUNCS * const Ops,                                    const int Src_Fields,                                    const int Fwd) const{  if (Field_MVs_Outside(MVo)) return;  int x, y, Halves, Off;  const int CoLoc = (Fwd ? Fwd_CoLoc : Bwd_CoLoc);  SKL_BYTE * const Dst = Y1;    // 1rst field  Halves = (MVo[0][0]&1) | ((MVo[0][1]&1)<<1);  Off = CoLoc + (MVo[0][1]&~1)*BpS + (MVo[0][0]>>1);  if (Src_Fields&2) Off += BpS;  Ops->HP_16x8[Halves](Dst, Dst+Off, 2*BpS);  x = MVo[0][0] / 2; y = MVo[0][1] / 2;  Halves = (x&1) | ((y&1)<<1);  Off = CoLoc + (y&~1)*BpS + (x>>1);  if (Src_Fields&2) Off += BpS;  Ops->HP_8x4[Halves](U, U+Off, 2*BpS);  Ops->HP_8x4[Halves](V, V+Off, 2*BpS);    // 2nd field  Halves = (MVo[1][0]&1) | ((MVo[1][1]&1)<<1);  Off = CoLoc + (MVo[1][1]&~1)*BpS + (MVo[1][0]>>1);  if (Src_Fields&1) Off += BpS;  Ops->HP_16x8[Halves](Dst+BpS, Dst+Off, 2*BpS);  x = MVo[1][0] / 2; y = MVo[1][1] / 2;  Halves = (x&1) | ((y&1)<<1);  Off = CoLoc + (y&~1)*BpS + (x>>1);  if (Src_Fields&1) Off += BpS;  Ops->HP_8x4[Halves](U+BpS, U+Off, 2*BpS);  Ops->HP_8x4[Halves](V+BpS, V+Off, 2*BpS);}//////////////////////////////////////////////////////////void SKL_MB2::Predict_MPEG1(){  SKL_ASSERT(Has_Motion());  const SKL_MB_FUNCS *Ops = VOL->Copy_Ops;  if (Is_Forward()) {    Read_Motion_Vectors_MPEG1(this, 0);    Predict_MPEG12(PMV[0][0], Ops, 1);    Ops = VOL->Add_Ops;  }  if (Is_Backward()) {    Read_Motion_Vectors_MPEG1(this, 1);    Predict_MPEG12(PMV[1][0], Ops, 0);  }}void SKL_MB2::Predict_Reuse(){  SKL_ASSERT(Has_Motion());  const SKL_MB_FUNCS *Ops = VOL->Copy_Ops;  if (Is_Forward()) {    Predict_MPEG12(PMV[0][0], Ops, 1);    Ops = VOL->Add_Ops;  }  if (Is_Backward()) {    Predict_MPEG12(PMV[1][0], Ops, 0);  }}void SKL_MB2::Predict_Frame(){  SKL_ASSERT(Has_Motion());  const SKL_MB_FUNCS *Ops =  VOL->Copy_Ops;  if (Is_Forward()) {    Read_Motion_Vectors(this, 0);    Predict_MPEG12(PMV[0][0], Ops, 1);    Ops = VOL->Add_Ops;  }  if (Is_Backward()) {    Read_Motion_Vectors(this, 1);    Predict_MPEG12(PMV[1][0], Ops, 0);  }}void SKL_MB2::Predict_Fields(){  SKL_ASSERT(Has_Motion());  const SKL_MB_FUNCS *Ops =  VOL->Copy_Ops;  if (Is_Forward())  {    PMV[0][0][1]>>=1; PMV[0][1][1]>>=1;    int Dir = Read_Field_Motion_Vectors(this, 0);    Predict_Fields_MPEG12(PMV[0], Ops, Dir, 1);    PMV[0][0][1]<<=1; PMV[0][1][1]<<=1;    Ops = VOL->Add_Ops;  }  if (Is_Backward()) {    PMV[1][0][1]>>=1; PMV[1][1][1]>>=1;    int Dir = Read_Field_Motion_Vectors(this, 1);    Predict_Fields_MPEG12(PMV[1], Ops, Dir, 0);    PMV[1][0][1]<<=1; PMV[1][1][1]<<=1;  }}#define RND2(x,P) (((x)*(P)+((x)>0))>>1)void SKL_MB2::Predict_DMV()   // Dual prime arithmetic (section 7.6.3.6){  SKL_ASSERT(Has_Motion() && Is_Forward() && Motion()==MC_DMV);  SKL_MV dMV;  SKL_MV cMV[2];

⌨️ 快捷键说明

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