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

📄 skl_mpg4_v12.cpp

📁 mpeg4编解码器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
void SKL_MB2::Print_Infos() const {  printf( "Q:%d DC-prec:%d Frm_Pred:%d IntraVLC:%d\n",    Quant, DC_Prec, Frame_Pred_DCT, Read_Intra==Read_Intra_Block_B15_MPEG2);}static int Read_Frame_Slice(SKL_FBB * const Bits, int yPos, const SKL_MP4_I *VOL){  SKL_MB2 MB(VOL, Bits);    // (section 6.2.4) (Yet Another Patch)  if (VOL->MPEG_Version==2 && VOL->Width>2800)    yPos += Bits->Get_Bits(3) << 7;    // partition breakpoint ignored, here  MB.Quant = Bits->Get_Bits(5);    // We ignore Intra_Slice_Flag (1b), Intra_Slice(1b) and    // Reserved field (7b) and discard them all:  while(Bits->Get_Bits(1)) Bits->Discard(8);  MB.Init_Scan(yPos, Read_Addr_Incr(Bits) - 1);  if (VOL->Debug_Level==3) MB.Print_Infos();    // now, go for it. Reconstruct.  while(1)  {      // Macroblock_Modes (section 6.2.5.1)    // no scale extension, here    MB.MB_Type = Read_MBlk_Type( Bits, VOL->Coding );    // no STWCF here    if (MB.Has_Motion() && !MB.Is_DC_Predicted()) // frame motion type (~Table 6-17)      MB.MB_Type |= Bits->Get_Bits(2) << 8;    else MB.MB_Type |= MC_FRAME;      // set DCT_Type    if ( !MB.Is_DC_Predicted() && MB.Is_Intra_Pattern() )      MB.Set_Field_DCT( Bits->Get_Bits(1) );    else      MB.Set_Field_DCT( -1 );    if (MB.Is_Quant())      MB.Quant = Bits->Get_Bits(5);    if (MB.Is_Intra())      MB.Decode_Intra_Macroblock();    else      MB.Decode_Inter_Macroblock();    if (Bits->See_Bits(23)==0)      break;    int Skip = Read_Addr_Incr(Bits);    if (Skip==0) break;           // error or end-of-slice    if (MB.Skip_Macroblock(Skip)) //section 7.6.3.4      break;  }  return MB.Finished();}/*static int Read_Field_Slice(SKL_FBB * const Bits, int yPos,                             const SKL_MP4_I *VOL, int Bottom_Field){  SKL_MB2 MB(VOL, Bits);  MB.Set_Field_DCT( 1 );  MB.Set_Field_Pred();      // (section 6.2.4)  if (VOL->MPEG_Version==2 && VOL->Width>2800)    yPos += Bits->Get_Bits(3) << 7;    // partition breakpoint ignored, here  MB.Quant = Bits->Get_Bits(5);    // We ignore Intra_Slice_Flag (1b), Intra_Slice(1b) and    // Reserved field (7b) and discard them all:  while(Bits->Get_Bits(1)) Bits->Discard(8);  MB.Init_Scan(yPos, Read_Addr_Incr(Bits) - 1);    // now, go for it. Reconstruct.  while(1)  {        // Macroblock_Modes (section 6.2.5.1)    // no scale extension, here    MB.MB_Type = Read_MBlk_Type( Bits, VOL->Coding );    // no STWCF here    if (MB.Has_Motion()) {      MB.MB_Type |= Bits->Get_Bits(2) << 8;      // if (MB.Motion()==MC_16x8)   =>  MV_Count = 2;    }    else {      if (MB.Is_Intra() && MB.Has_Concealment_MV())        MB.MB_Type |= MC_FIELD;      else        MB.MB_Type |= MC_FRAME;    }          if (MB.Is_Quant())      MB.Quant = Bits->Get_Bits(5);    if (MB.Is_Intra())      MB.Decode_Intra_Macroblock();    else      MB.Decode_Inter_Macroblock();    if (Bits->See_Bits(23)==0)      break;    int Skip = Read_Addr_Incr(Bits);    if (Skip==0) break;  // error or end-of-slice    if (MB.Skip_Macroblock(Skip)) //section 7.6.3.4      break;  }  return MB.Finished();}*///////////////////////////////////////////////////////////// Headers decoding//////////////////////////////////////////////////////////void SKL_MP4_I::Init_MPEG12(int Version){  SKL_ASSERT(Version==1 || Version==2);  Init_VOL(0);  MPEG_Version = Version;  Low_Delay  = 0;  // force  Quarter    = 0;  Rounding   = 0;  Set_Rounding();  if (Version==1) {    Set_Quant_Type(2);/*    Is_Progressive    = 1;    Progressive_Frame = 1;    DC_Prec           = 0;    Pic_Struct        = MPEG12_FRAME_PIC;    Frame_Pred_DCT    = 1;    QScale_Type       = 0;    Intra_VLC         = 0;    Concealment_MV    = 0;        Matrix_Coeffs     = 5;*/        MPEG12_Flags = 0x01;    MPEG12_Ext_Flags = (3<<10) | (1<<8);  }  if (Version==2) {    Set_Quant_Type(3);    MPEG12_Flags = 0x01;    MPEG12_Ext_Flags = (3<<10) | (1<<8);  }}static void Init_MPEG1_Constrained_Param(SKL_MP4_I * const VOP){}//////////////////////////////////////////////////////////static int Read_Picture_Header(SKL_FBB * const Bits, SKL_MP4_I * const VOP){  static const int Cvrt[8] = {     BAD_VOP, I_VOP, P_VOP, B_VOP, D_VOP, BAD_VOP, BAD_VOP, BAD_VOP };  Bits->Discard(10);                       // temporal ref.  VOP->Coding = Cvrt[Bits->Get_Bits(3)];   // coding type  if (VOP->Coding==BAD_VOP) return 0;      // D-VOP?!  Bits->Discard(16);                       // VBV delay  if ( !VOP->Is_I_VOP() ) {                // MPEG-1 Fwd/Bwd code    VOP->Fwd_Code = Bits->Get_Bits(4);     // 1 + 3bits    if (VOP->Is_B_VOP())      VOP->Bwd_Code = Bits->Get_Bits(4);   // 1 + 3bits  }  if (VOP->Debug_Level==4) {    printf( "  Coding=[%c] ", "IPBD"[VOP->Coding] );    printf( " Fwd/Bwd: %d/%d\n", VOP->Fwd_Code, VOP->Bwd_Code );  }  VOP->Last = 0;  if (VOP->Is_B_VOP()) {  // reorder    VOP->Cur = VOP->Aux;  }  else {    VOP->Cur    = VOP->Past;    VOP->Past   = VOP->Future;    VOP->Future = VOP->Cur;  }  if (VOP->Cur==0) return 0; // no Sequence header seen yet?!?  VOP->Cur->Time = VOP->Past->Time + 1;   // artificial clock  return 1;}//////////////////////////////////////////////////////////// Sequence (section 6.2.2.1)/*static const float Frame_Rate_Table[] = {  0.,              // Forbidden  24000.f/1001.f,  24.f, 25.f,   30000.f/1001.f,  30.f, 50.f,   60000.f/1001.f,  60.f};static const float MPEG1_Aspect_Ratio_Table[] = {  0.0, // Forbidden  1.0000f, 0.6735f, 0.7031f, 0.7615f,  0.8055f, 0.8437f, 0.8935f, 0.9375f,  0.9815f, 1.0255f, 1.0695f, 1.1250f,  1.1575f, 1.2015f,   0.0 // reserved};static const float MPEG2_Aspect_Ratio_Table[] = {  0.0, // Forbidden  1.0f, 3.0f/4.0f, 9.0f/16.0f, 12.0f/21.0f};*/static int Read_Sequence(SKL_FBB * const Bits, SKL_MP4_I * const VOP){  VOP->Init_MPEG12(1);  int Width        = Bits->Get_Bits(12);  int Height       = Bits->Get_Bits(12);#if 0  int Aspect_Ratio = Bits->Get_Bits(4);  int Frame_Rate   = (int)( 1000.f*Frame_Rate_Table[Bits->Get_Bits(4)] );  int Bit_Rate     = Bits->Get_Bits(18);  Bits->Discard(1);  // marker bit  int VBV_Size     = Bits->Get_Bits(10);#else  Bits->Discard( 4+18 );  Bits->Discard( 4+1+10 );#endif  VOP->Init_Pics( Width, Height, VOP->Low_Delay ? 2 : 3, 0 );  if (Bits->Get_Bits(1))    Init_MPEG1_Constrained_Param(VOP);  int i;  SKL_BYTE Mo[64];  if (Bits->Get_Bits(1))    for(i=0; i<64; i++) Mo[SKL_MP4_I::Scan_Order[0][i]] = Bits->Get_Bits(8);  else    VOP->Get_Default_Matrix(Mo, 2);  VOP->Set_Matrix(1, Mo);  if (Bits->Get_Bits(1))    for(i=0; i<64; i++) Mo[SKL_MP4_I::Scan_Order[0][i]] = Bits->Get_Bits(8);  else    VOP->Get_Default_Matrix(Mo, 3);  VOP->Set_Matrix(0, Mo);  return 1;}static int Read_Sequence_Extension(SKL_FBB * const Bits, SKL_MP4_I * const VOP){  SKL_UINT32 Code;  VOP->Init_MPEG12(2);  Code = Bits->Get_Bits(15);  /* Profile_And_Level = (Code>>7) & 0xff; */ // 8bits    int Is_Progressive = (Code>>6) & 0x01;      // 1bit  VOP->MPEG12_Flags |= Is_Progressive;  int Chroma_Fmt = (Code>>4) & 0x03;          // 2bits  if (Chroma_Fmt!=1)  // 4:2:0  {    fprintf( stderr, "Only chroma format 4:2:0 is supported!\n" );    return 0;  }  if (Code&0x0f) {    int W  = VOP->Width  & 0xfff;    W |= ((Code>>2)&0x03) << 12;              // 2bits    int H  = VOP->Height & 0xfff;    H |= ((Code>>0)&0x03) << 12;              // 2bits    VOP->Init_Pics( W, H, 3, 0);   }#if 0    // the rest (Bit_Rate_Ext, VBVSize, Low_Delay, Frame_Rate_Ext...) is ignored  Code = Bits->Get_Bits(21);  Bit_Rate |= ((Code>>9) & 0x3ff) << 18;      // 12bits  Mark = (Code>>8)&0x01;                      // 1bit marker  int VBVS = Get_VBV_Size() & 0x3ff;  VBVS |= ((Code>>0)&0xff) << 10;             // 8bits  Set_VBV_Size(VBVS);#else  Bits->Discard(12+1+8);#endif  return 1;}static int Read_Coding_Extension(SKL_FBB * const Bits, SKL_MP4_I *VOP){  SKL_UINT32 Code;  Code = Bits->Get_Bits(16);  VOP->Fwd_Code = (Code >> 8) & 0xff;          // 4+4 bits  VOP->Bwd_Code = (Code >> 0) & 0xff;          // 4+4 bits  Code = Bits->Get_Bits(14);  VOP->MPEG12_Ext_Flags = Code;  int QScale_Type      = (Code>> 6) & 0x01;    // 1bit  VOP->Set_Quant_Type( 3+QScale_Type );  VOP->Top_Field_First = (Code>> 9) & 0x01;    // 1bit  VOP->Alt_Vert_Scan   = (Code>> 4) & 0x01;    // 1bit/*  Repeat_First_Field   = (Code>> 3) & 0x01;    // 1bit  Chroma_420_Type      = (Code>> 2) & 0x01;    // 1bit  Progressive_Frame    = (Code>> 1) & 0x01;    // 1bit*/  // the rest (Composite_Display,...) is ignored (20bits)  if (Code&0x01) Bits->Discard(20);  return 1;}static int Read_Extensions(SKL_FBB * const Bits, SKL_MP4_I * const VOP){  switch(Bits->Get_Bits(4)) // Id  {    case MPEG12_SEQ_EXT_ID:      if (!Read_Sequence_Extension(Bits,VOP))        return 0;    break;    case MPEG12_QMATRIX_EXT_ID:    // Matrix Extension    {          // Format 4:4:4 is not supported. We discard the matrices...      int i;      if (Bits->Get_Bits(1)) for(i=0; i<64; i++) Bits->Get_Bits(8);      if (Bits->Get_Bits(1)) for(i=0; i<64; i++) Bits->Get_Bits(8);    }    break;    case MPEG12_PIC_CODING_EXT_ID:       if (!Read_Coding_Extension(Bits,VOP))        return 0;    break;    default:  // ignore (scalable-ext, video-ext, etc...)    break;  }  return 1;}static int Read_GOP_Header(SKL_FBB * const Bits, SKL_MP4_I * const VOP){  SKL_UINT32 Code;  Code = Bits->Get_Bits(19);  /* int Drop = (Code>>18)&0x01;*/   int Tc_Hours = (Code>>13)&0x1f; // 5bits  int Tc_Mins = (Code>>7)&0x3f;   // 6bits  /* (Code>>6)&0x01 -> marker bit */  int Tc_Secs = (Code>>0)&0x3f;   // 6bits  (void)Tc_Hours; (void)Tc_Mins; (void)Tc_Secs;  Code = Bits->Get_Bits(8);/*  int Pic_Count = (Code>>2)&0x3f;    6bits  int Closed    = (Code>>1)&0x01;    1bit  int Broken    = (Code>>0)&0x01;    1bit*/  return 1;}//////////////////////////////////////////////////////////// Main entry point for MPEG1/2 decoding//////////////////////////////////////////////////////////int SKL_MP4_I::Decode_MPEG12(const SKL_BYTE *Buf, int Len){  SKL_UINT32 Code = 0xdeadc0de;  SKL_ASSERT(MPEG_Version<=2); // don't mix!  if (Len==0) { // special case: post very last residual frame    Last = Cur;    Cur  = 0;    Frame_Number++;    return 0;  }  const SKL_BYTE * const Buf_End = Buf + Len;  while(1)  {    do {      Code = (Code<<8) | (*Buf++);      if (Buf>=Buf_End) return Len;    }    while (Code>MPEG12_LAST_CODE);    if (Code<MPEG12_PICTURE_START) continue;    SKL_FBB Bits(Buf);    if (Code<=MPEG12_SLICE_MAX)    {      if (Code==MPEG12_PICTURE_START)    // 0x100      {        if (!Read_Picture_Header(&Bits, this)) break;      }      else /*Code<=MPEG12_SLICE_MAX*/    // 0x101-0x1af      {        int Pic_Struct = (MPEG12_Ext_Flags>>10) & 0x03;        int Finished;        if (Pic_Struct==MPEG12_FRAME_PIC)           Finished = Read_Frame_Slice(&Bits, Code-MPEG12_SLICE_MIN, this);        else//        Finished = Read_Field_Slice(&Bits, Code-MPEG12_SLICE_MIN, this, //                                    (Pic_Struct==MPEG12_BOTTOM_FIELD));          continue; // FIELD picture structure not supported (it's a mess)...        Switch_Off();    // reset (emms)        Buf = Bits.Pos();        if (Finished) {   // post previous frame to user          if (Frame_Number==0) Last = 0;          else if (Is_B_VOP()) Last = Cur;          else                 Last = Past;          Frame_Number++;          break;        }      }    }    else    {      if (Code==MPEG12_USER_START)  // 0x1b2      {        continue;  // -skip-      }      else if (Code==MPEG12_SEQ_START)   // 0x1b3      {        if (!Read_Sequence(&Bits, this)) break;      }      else if (Code==MPEG12_EXT_START)   // 0x1b5      {        if (!Read_Extensions(&Bits, this)) break;      }      else if (Code==MPEG12_SEQ_END)     // 0x1b7      {        break;      }      else if (Code==MPEG12_GOP_START)   // 0x1b8      {        if (!Read_GOP_Header(&Bits,this)) break;      }      else if (Code>=SYSTEM_MIN_CODE) {        fprintf( stderr, "Unexpected system code 0x%x. Is stream still multiplexed?\n", Code );        continue;      }      else {//        fprintf( stderr, "Unhandled code 0x%x.\n", Code );      }    }    Buf = Bits.Pos();  }  return Len - (Buf_End - Buf);}//////////////////////////////////////////////////////////

⌨️ 快捷键说明

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