📄 skl_mpg4_v12.cpp
字号:
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 + -