?? skl_mpg4_v12.cpp
字號:
inline static int Read_MPEG2_Escape(SKL_FBB *FBB) { int Val = FBB->Get_Bits(12); if ((Val&2047)==0) return 0; // error if (Val>=2048) Val -= 4096; return Val;}//////////////////////////////////////////////////////////// -- MPEG-1 intra blockstatic void Read_Intra_Block_MPEG1(SKL_FBB *FBB, SKL_MB2 *MB, SKL_INT16 *Out){ const int * const Scan = SKL_MP4_I::Scan_Order[0]+64; // Note: sometimes, EOB occurs *exactly* at the end, for i==0. // We need to parse it however. That's why we're not using // a loop like "while(i<0)", but "while(1)" instead. // Note2: We unroll the Huffman table searching, because: // * EOB is only present on the 1rst chunk // * ESC is only present on the second // * Only the last chunk requires full 16bits // We re-ordered the search in a (small) logarithmic search // Note3: For code-cache coherency and branch prediction, we put // the 'Ok:' code *first* SKL_FBB_DECL; SKL_FBB_START(*FBB); SKL_FBB_LOAD_WORD(16); const SKL_DCT_VLC *Tab = 0; int i = -63; while(1) { if (Bits>=0x28000000) { Tab = Tab_B14_AC_0 - 5 + (Bits>>(16+11));Ok: if ((i += Tab->Run)>=0) break; // EOB SKL_INT32 Val = Tab->Level; Bits_Left -= Tab->Len+1; Bits <<= Tab->Len; if (Bits&0x80000000) Val = -Val; Bits <<= 1; SKL_FBB_LOAD_WORD(16); Out[Scan[i++]] = Val; continue; } else if (Bits>=0x08000000) { Tab = Tab_B14_AC_1 - 4 + (Bits>>(16+8)); goto Ok; } else if (Bits>=0x00800000) { if (Bits>=0x04000000) // ESC code only { // parse away 6bits for ESC code and 6bits for 'Skip' value SKL_UINT32 Skip = (Bits >> (32-12)) & 0x3f; if ((i += Skip)>=0) break; // error SKL_FBB_DISCARD_SAFE( 6+6 );// inlined version of 'Read_MPEG1_Escape()' SKL_FBB_LOAD_WORD(16); SKL_INT32 Val = SKL_FBB_BITS_SIGNED(8); SKL_FBB_DISCARD_SAFE(8); if ((Val&0x7f)==0) // Val=0 or 128 { Val = SKL_FBB_BITS(8) + 2*Val; SKL_FBB_DISCARD_SAFE(8); } Out[Scan[i++]] = Val; SKL_FBB_LOAD_WORD(16); continue; } else { if (Bits>=0x02000000) Tab = Tab_B14_AC_2 - 8 + (Bits>>(16+6)); else /* (Bits>=0x00800000) */ Tab = Tab_B14_AC_3 - 16 + (Bits>>(16+3)); goto Ok; } } else { if (Bits>=0x00200000) { Tab = Tab_B14_AC_4 - 16 + (Bits>>(16+1)); goto Ok; } else if (Bits>=0x00100000) { Tab = Tab_B14_AC_5 - 16 + (Bits>>(16+0)); SKL_FBB_LOAD_WORD(17); goto Ok; } /* else -> error */ } break; /* error */ } SKL_FBB_DISCARD_SAFE(Tab->Len); SKL_FBB_STOP(*FBB);}staticvoid Read_Intra_Block_DType_MPEG1(SKL_FBB *FBB, SKL_MB2 *MB, SKL_INT16 *Out){ /* nothing to do */ }//////////////////////////////////////////////////////////// MPEG-1 Inter blockstaticint Read_Inter_Block_MPEG1(SKL_FBB *FBB, SKL_MB2 *MB, SKL_INT16 *Out){ const int * const Scan = SKL_MP4_I::Scan_Order[0]+64; SKL_FBB Local; Local.Copy(FBB); const SKL_DCT_VLC *Tab; int i = -64; int Rows = 0x00; // we decode the first coeff DC the usual way. No optim worth. Local.Check_Bits(16 + 1); Tab = Skl_DCT_VLC_Search( B14_DC_Chunks, Local.Bits ); if (Tab->Run<0) goto ESC_Code; else goto Ok; while(1) { if (Local.Bits>=0x28000000) { Tab = Tab_B14_AC_0 - 5 + (Local.Bits>>(16+11));Ok: if ((i += Tab->Run)>=0) break; // EOB int Val = Tab->Level; Local.Bits_Left -= Tab->Len+1; Local.Bits <<= Tab->Len; if (Local.Bits&0x80000000) Val = -Val; Local.Bits <<= 1; Local.Check_Bits_Word(16); const int j = Scan[i++]; Out[j] = Val; Rows |= SKL_MP4_I::Row_From_Index[j]; continue; } else if (Local.Bits>=0x08000000) { Tab = Tab_B14_AC_1 - 4 + (Local.Bits>>(16+8)); goto Ok; } else if (Local.Bits>=0x00800000) { if (Local.Bits>=0x04000000) // ESC code only {ESC_Code: // parse away 6bits for ESC code and 6bits for 'Skip' value SKL_UINT32 Skip = (Local.Bits >> (32-12)) & 0x3f; if ((i += Skip)>=0) break; // error Local.Discard_Safe( 6+6 ); int Val = Read_MPEG1_Escape(&Local); Out[Scan[i++]] = Val; Local.Check_Bits_Word(16); continue; } else { if (Local.Bits>=0x02000000) Tab = Tab_B14_AC_2 - 8 + (Local.Bits>>(16+6)); else /*(Local.Bits>=0x00800000)*/ Tab = Tab_B14_AC_3 - 16 + (Local.Bits>>(16+3)); goto Ok; } } else { if (Local.Bits>=0x00200000) { Tab = Tab_B14_AC_4 - 16 + (Local.Bits>>(16+1)); goto Ok; } else if (Local.Bits>=0x00100000) { Tab = Tab_B14_AC_5 - 16 + (Local.Bits>>(16+0)); Local.Check_Bits(17); // loads 1 more byte goto Ok; } /* else -> error */ } break; /* error */ }// Error: Local.Discard_Safe(Tab->Len); FBB->Copy(&Local); return Rows;}//////////////////////////////////////////////////////////// -- MPEG-2 intra blockstaticvoid Read_Intra_Block_B14_MPEG2(SKL_FBB *FBB, SKL_MB2 *MB, SKL_INT16 *Out){ const int * const Scan = MB->Scan_Order; SKL_FBB Local; Local.Copy(FBB); SKL_INT32 Mismatch = Out[0]; int i = -63; while(1) { int Val; Local.Check_Bits(16); const SKL_DCT_VLC *Tab = Skl_DCT_VLC_Search( B14_AC_Chunks, Local.Bits ); if (Tab->Run<0) // ESC { // parse away 6bits for ESC code and 6bits for 'Skip' value SKL_UINT32 Skip = (Local.Bits >> (32-12)) & 0x3f; i += Skip; if (i>=0) break; // error Local.Discard_Safe( 6+6 ); Val = Read_MPEG2_Escape(&Local); } else { Local.Discard_Word(Tab->Len); i += Tab->Run; if (i>=0) break; // EOB2 Val = Tab->Level; if (Local.Get_Bits(1)) Val = -Val; } Out[Scan[i++]] = Val; Mismatch ^= Val; } Out[63] ^= Mismatch & 1; FBB->Copy(&Local);}staticvoid Read_Intra_Block_B15_MPEG2(SKL_FBB *FBB, SKL_MB2 *MB, SKL_INT16 *Out){ const int * const Scan = MB->Scan_Order; SKL_FBB Local; Local.Copy(FBB); SKL_INT32 Mismatch = Out[0]; int i = -63; while(1) { int Val; Local.Check_Bits(16); const SKL_DCT_VLC *Tab = Skl_DCT_VLC_Search( B15_AC_Chunks, Local.Bits ); if (Tab->Run<0) // ESC { // parse away 6bits for ESC code and 6bits for 'Skip' value SKL_UINT32 Skip = (Local.Bits >> (32-12)) & 0x3f; i += Skip; if (i>=0) break; // error Local.Discard_Safe( 6+6 ); Val = Read_MPEG2_Escape(&Local); } else { Local.Discard_Word(Tab->Len); i += Tab->Run; if (i>=0) break; // EOB2 Val = Tab->Level; if (Local.Get_Bits(1)) Val = -Val; } Out[Scan[i++]] = Val; Mismatch ^= Val; } Out[63] ^= Mismatch & 1; FBB->Copy(&Local);}//////////////////////////////////////////////////////////// MPEG-2 Inter blockstaticint Read_Inter_Block_MPEG2(SKL_FBB *FBB, SKL_MB2 *MB, SKL_INT16 *Out){ const int * const Scan = MB->Scan_Order; SKL_FBB Local; Local.Copy(FBB); Local.Check_Bits(16); const SKL_DCT_VLC *Tab = Skl_DCT_VLC_Search( B14_DC_Chunks, Local.Bits ); int i = -64; int Rows = 0x00; while(1) { int Val; SKL_ASSERT(Tab!=0); if (Tab->Run<0) // ESC { // parse away 6bits (=Tab->Len) for ESC code // and 6bits for 'Skip' value SKL_UINT32 Skip = (Local.Bits >> (32-12)) & 0x3f; i += Skip; if (i>=0) break; // error Local.Discard_Safe( 6+6 /*Tab->Len+6*/ ); Val = Read_MPEG2_Escape(&Local); } else { Local.Discard_Word(Tab->Len); i += Tab->Run; if (i>=0) break; // EOB Val = Tab->Level; if (Local.Get_Bits(1)) Val = -Val; } const int j = Scan[i++]; Out[j] = Val; Rows |= SKL_MP4_I::Row_From_Index[j]; // next lump Local.Check_Bits(16); Tab = Skl_DCT_VLC_Search( B14_AC_Chunks, Local.Bits ); } FBB->Copy(&Local); return Rows;}//////////////////////////////////////////////////////////// ISO/IEC 13818-2 section 7.2 -> 7.5// -- Intra blocksinline void SKL_MB2::Decode_Intra_Macroblock(){ SKL_INT16 Base[7*64+SKL_ALIGN]; SKL_INT16 * const In = (SKL_INT16*)SKL_ALIGN_PTR(Base, SKL_ALIGN); SKL_INT16 *Out = In + 1*64; SKL_ASSERT(Is_Intra()); if (!Has_Concealment_MV()) { Reset_Fwd(); // reset all PMV Reset_Bwd(); } else // read concealment motion vectors { if (Is_MPEG1()) Read_Motion_Vectors_MPEG1(this, 0); else if (Motion()==MC_FIELD) Read_Field_Motion_Vectors(this, 0); else Read_Motion_Vectors(this, 0); SKL_COPY_MV(PMV[1][0], PMV[0][0]); SKL_COPY_MV(PMV[1][1], PMV[0][1]); FBB->Discard(1); // marker bit } for(int blk=0; blk<6; ++blk) { VOL->Quant_Ops.Zero(In); const int cc = (blk<4) ? 0 : blk-3; DC[cc] += Read_DC_Diff_MPEG2(FBB, DCT_Chunks[cc]); In[0] = DC[cc]; Read_Intra(FBB, this, In); VOL->Quant_Ops.Dequant_Intra(Out, In, VOL->Q_Intra, Quant, DC_Q); Out += 64; } Copy_16To8(In+1*64); // ISO/IEC 11172-2 section 2.4.2.7 & 2.4.3.6 if (VOL->Is_D_VOP()) FBB->Get_Bits(1);}//////////////////////////////////////////////////////////// -- Inter blocksinline void SKL_MB2::Decode_Inter_Macroblock(){ SKL_ASSERT(!Is_Intra()); Reset_DC(); // note in 7.2.1 if (VOL->Is_P_VOP() && !Is_Forward()) // section 7.6.3.5 { Reset_Fwd(); // only reset fwd pmv Copy_Fwd(); // simply copy Reset_Motion_Type(); } else if (Has_Motion()) // section 6.2.5 { if (Is_MPEG1()) Predict_MPEG1(); else { switch (Motion()) { case MC_NONE: /* aieee! */ break; case MC_FIELD: Predict_Fields(); break; case MC_FRAME: Predict_Frame(); break; case MC_DMV: Predict_DMV(); break; } } } else Copy_Fwd(); if (Is_Pattern()) // coded { SKL_INT16 Base[7*64+SKL_ALIGN]; SKL_INT16 * const In = (SKL_INT16*)SKL_ALIGN_PTR(Base, SKL_ALIGN); SKL_INT16 *Out = In + 1*64; Cbp = Read_Coded_Block_Pattern(FBB); for(int blk=(1<<5); blk; blk>>=1) { if (Cbp & blk) // coded { VOL->Quant_Ops.Zero(In); const int Rows = Read_Inter(FBB, this, In); VOL->Quant_Ops.Dequant_Inter(Out, In, VOL->Q_Inter, Quant, Rows&0xff); } Out += 64; } Add_16To8(In + 1*64); }}//////////////////////////////////////////////////////////// section 7.6.3.4inline int SKL_MB2::Skip_Macroblock(int Skip){ if (Skip>1) { Reset_DC(); // section 7.2.1 if (VOL->Is_B_VOP()) { // => re-use previous motion vectors while(Skip-->1) { if (!Next()) break; Predict_Reuse(); } } else { if ( VOL->Is_P_VOP() ) Reset_Fwd(); // section 7.6.3.4 while(Skip-->1) { if (!Next()) break; Copy_Fwd(); } } Reset_Motion_Type(); } return !Next();}//////////////////////////////////////////////////////////// section 6.2.3.6 (picture data)SKL_MB2::SKL_MB2(const SKL_MP4_I *vol, SKL_FBB *fbb) : SKL_MB(vol), FBB(fbb){ DC_Prec = (vol->MPEG12_Ext_Flags>>12) & 0x03; DC_Q = 1<<(3-DC_Prec); Pic_Struct = (vol->MPEG12_Ext_Flags>>10) & 0x03; Frame_Pred_DCT = (vol->MPEG12_Ext_Flags>> 8) & 0x01; Concealment_MV = (vol->MPEG12_Ext_Flags>> 7) & 0x01; int Intra_VLC = (vol->MPEG12_Ext_Flags>> 5) & 0x01; if (Is_MPEG1()) { Read_Intra = ( VOL->Is_D_VOP() ? Read_Intra_Block_DType_MPEG1 : Read_Intra_Block_MPEG1 ); Read_Inter = Read_Inter_Block_MPEG1; } else { Read_Intra = ( (Intra_VLC==0) ? Read_Intra_Block_B14_MPEG2 : Read_Intra_Block_B15_MPEG2 ); Read_Inter = Read_Inter_Block_MPEG2; } Scan_Order = VOL->Alt_Vert_Scan ? SKL_MP4_I::Scan_Order[2] : SKL_MP4_I::Scan_Order[0]; Scan_Order += 64; Reset_DC(); // reset prediction (section 7.2.1) Reset_Fwd(); // reset all MV prediction (section 7.6.3.4) Reset_Bwd();}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -