📄 skl_mpg4_dec.cpp
字号:
SKL_COPY_MV(MVs[5], MVs[4]); SKL_COPY_MV(MVs[6], MVs[4]); SKL_COPY_MV(MVs[7], MVs[4]); MB.Predict_With_4MV(&MVs[0], &MVs[2], VOP->Copy_Ops, 1); MB.Predict_With_4MV(&MVs[4], &MVs[6], VOP->Add_Ops, 0); } } else { MVs[1][0] = dMV[0] + (SKL_INT16)( Trb*Ref[ 1][0]/Trd ); MVs[1][1] = dMV[1] + (SKL_INT16)( Trb*Ref[ 1][1]/Trd ); MVs[2][0] = dMV[0] + (SKL_INT16)( Trb*Ref[S+0][0]/Trd ); MVs[2][1] = dMV[1] + (SKL_INT16)( Trb*Ref[S+0][1]/Trd ); MVs[3][0] = dMV[0] + (SKL_INT16)( Trb*Ref[S+1][0]/Trd ); MVs[3][1] = dMV[1] + (SKL_INT16)( Trb*Ref[S+1][1]/Trd ); if (dMV[0]==0) { MVs[5][0] = (SKL_INT16)( (Trb-Trd)*Ref[ 1][0]/Trd ); MVs[6][0] = (SKL_INT16)( (Trb-Trd)*Ref[S+0][0]/Trd ); MVs[7][0] = (SKL_INT16)( (Trb-Trd)*Ref[S+1][0]/Trd ); } else { MVs[5][0] = MVs[1][0] - Ref[ 1][0]; MVs[6][0] = MVs[2][0] - Ref[S+0][0]; MVs[7][0] = MVs[3][0] - Ref[S+1][0]; } if (dMV[1]==0) { MVs[5][1] = (SKL_INT16)( (Trb-Trd)*Ref[ 1][1]/Trd ); MVs[6][1] = (SKL_INT16)( (Trb-Trd)*Ref[S+0][1]/Trd ); MVs[7][1] = (SKL_INT16)( (Trb-Trd)*Ref[S+1][1]/Trd ); } else { MVs[5][1] = MVs[1][1] - Ref[ 1][1]; MVs[6][1] = MVs[2][1] - Ref[S+0][1]; MVs[7][1] = MVs[3][1] - Ref[S+1][1]; } MB.Predict_With_4MV(&MVs[0], &MVs[2], VOP->Copy_Ops, 1); MB.Predict_With_4MV(&MVs[4], &MVs[6], VOP->Add_Ops, 0); } } else // colocated MB is field-predicted. This is the worst case :( { if (Trdf==0) { const SKL_UINT64 T = VOP->Time_TFrame; Trbf = 2*(int)( ( Cur->Time_Ticks+(T>>1))/T - (VOP->Time_Last_Coded+(T>>1))/T ); Trdf = 2*(int)( (Next->Time_Ticks+(T>>1))/T - (VOP->Time_Last_Coded+(T>>1))/T ); } // hardcoded Table 7-12 const int Flds = Map[MB.Pos].Fields; // future field directions int delta0 = ( (Flds>>1)&1 ); // future Top field dir int delta1 = ( (Flds>>0)&1 ) - 1; // future Bottom field dir if (VOP->Top_Field_First) { delta0 = -delta0; delta1 = -delta1; } MVs[0][0] = dMV[0] + (SKL_INT16)( (Trbf+delta0)*Ref[0][0]/(Trdf+delta0) ); MVs[0][1] = dMV[1] + (SKL_INT16)( (Trbf+delta0)*Ref[0][1]/(Trdf+delta0) ); MVs[1][0] = dMV[0] + (SKL_INT16)( (Trbf+delta1)*Ref[1][0]/(Trdf+delta1) ); MVs[1][1] = dMV[1] + (SKL_INT16)( (Trbf+delta1)*Ref[1][1]/(Trdf+delta1) ); if (dMV[0]==0) { MVs[4][0] = (SKL_INT16)( (Trbf-Trdf)*Ref[0][0]/(Trdf+delta0) ); MVs[5][0] = (SKL_INT16)( (Trbf-Trdf)*Ref[1][0]/(Trdf+delta1) ); } else { MVs[4][0] = MVs[0][0] - Ref[0][0]; MVs[5][0] = MVs[1][0] - Ref[1][0]; } if (dMV[1]==0) { MVs[4][1] = (SKL_INT16)( (Trbf-Trdf)*Ref[0][1]/(Trdf+delta0) ); MVs[5][1] = (SKL_INT16)( (Trbf-Trdf)*Ref[1][1]/(Trdf+delta1) ); } else { MVs[4][1] = MVs[0][1] - Ref[0][1]; MVs[5][1] = MVs[1][1] - Ref[1][1]; }/* printf( "x,y=%d,%d dmv=%d,%d sel=%d,%d/%d,%d Fwd: Flds=%d ref=(%d,%d) mv=(%d,%d)/(%d,%d) Bwd: Flds=%d ref=(%d,%d) mv=(%d,%d)/(%d,%d)\n", MB.x, MB.y, dMV[0], dMV[1], (MB.Field_Dir>>1)&1,(MB.Field_Dir>>0)&1,(MB.Field_Dir>>3)&1,(MB.Field_Dir>>2)&1, (Flds>>1)&1, Ref[0][0], Ref[0][1], MVs[0][0],MVs[0][1], MVs[4][0],MVs[4][1], (Flds>>0)&1, Ref[1][0], Ref[1][1], MVs[1][0],MVs[1][1], MVs[5][0],MVs[5][1]);*/ MB.Predict_Fields(&MVs[0], VOP->Copy_Ops, 1, MB.Field_Dir& 3); MB.Predict_Fields(&MVs[4], VOP->Add_Ops, 0, MB.Field_Dir>>2); } // end of DIRECT mode } else { // INTERPOLATE/FWD/BWD. // We don't use MB.MVs[], but directly Preds[] instead const SKL_MB_FUNCS * Ops = VOP->Copy_Ops; if (MB.Field_Pred) { if (B_Type!=SKL_MB_BWD) { Preds[0][1] /= 2; Preds[1][1] /= 2; // descale predictors. See section 7.7.2.1 Read_Vector( Bits, VOP->Fwd_Code, Preds[0] ); Read_Vector( Bits, VOP->Fwd_Code, Preds[1] ); MB.Predict_Fields(&Preds[0], Ops, 1, MB.Field_Dir); Preds[0][1] *= 2; Preds[1][1] *= 2; // restore predictors to frame scale Ops = VOP->Add_Ops; } if (B_Type!=SKL_MB_FWD) { Preds[2][1] /= 2; Preds[3][1] /= 2; // descale predictors. Read_Vector( Bits, VOP->Bwd_Code, Preds[2] ); Read_Vector( Bits, VOP->Bwd_Code, Preds[3] ); MB.Predict_Fields(&Preds[2], Ops, 0, MB.Field_Dir>>2); Preds[2][1] *= 2; Preds[3][1] *= 2; // restore predictors. } } else { if (B_Type!=SKL_MB_BWD) { Read_Vector(Bits, VOP->Fwd_Code, Preds[0]); SKL_COPY_MV(Preds[1], Preds[0]); // update 2nd predictor MB.Predict_With_1MV(Preds[0], Ops, 1); Ops = VOP->Add_Ops; } if (B_Type!=SKL_MB_FWD) { Read_Vector(Bits, VOP->Bwd_Code, Preds[2]); SKL_COPY_MV(Preds[3], Preds[2]); // update 2nd predictor MB.Predict_With_1MV(Preds[2], Ops, 0); } } } MB.MB_Type = SKL_MB_INTER; if (MB.Cbp) { SKL_INT16 Base[7*64+SKL_ALIGN]; SKL_INT16 * const In = (SKL_INT16*)SKL_ALIGN_PTR(Base, SKL_ALIGN); MB.Decode_Inter_Blocks(Bits, In, VOP); MB.Add_16To8(In + 1*64); } // no need to MB.Set_Not_Intra() (B-VOP content cannot be used for pred) if (VOP->Debug_Level==5) { if (Map[MB.Pos].Type==SKL_MAP_SKIPPED) printf("s"); else if (MB.Field_Pred) printf( "%c", "DBFI."[B_Type] ); else if (B_Type==SKL_MB_DIRECT) { if (ModB1!=0) printf( "0" ); else if (Map[MB.Pos].Type==SKL_MAP_16x16) printf( "d" ); else printf("4"); } else printf( "%c", "?+-=."[B_Type] ); if (MB.x==VOP->MB_W-1) { printf( "\n" ); if (MB.y==VOP->MB_H-1) printf( "\n" ); } } } if (!MB.Resync || !MB.Resync_Marker(Bits)) MB++; else { // reset predictors for RESYNC SKL_ZERO_MV(Preds[0]); SKL_ZERO_MV(Preds[1]); SKL_ZERO_MV(Preds[2]); SKL_ZERO_MV(Preds[3]); } } if (VOP->Debug_Level==2) VOP->Dump_Line(1, &MB); if (VOP->Slicer) VOP->Slicer(VOP->Cur, MB.y*16, 16, VOP->Slicer_Data); MB.y++; } if (VOP->Debug_Level==1) // only draw past MVs (Cur are trashed) if (Prev->MV!=0) VOP->Dump_MVs(Prev, 2); }//////////////////////////////////////////////////////////// S-frame (GMC) // sprite trajectorystatic int Get_Sprite_Point_Size(SKL_FBB *Bits){ const SKL_VLC *VLC = &Spr_Tab_B33[ Bits->See_Bits(3) ]; if (VLC->Val>=0) { Bits->Discard(VLC->Len); return VLC->Val; } Bits->Discard(3); int Len = 6; while(Bits->Get_Bits(1)) Len++; return Len;}void SKL_MP4_I::Read_Sprite_Trajectory(SKL_FBB * const Bits){ int n; for(n=0; n<Sprite_Nb_Pts; ++n) { int Val, Size; Size = Get_Sprite_Point_Size(Bits); if (Size) { Val = Bits->Get_Bits(Size); if (!(Val&SKL_BMASKS::Or[Size])) // MSB not set Val -= SKL_BMASKS::And[Size]; S_Warp_Pts[n][0] = Val; } else S_Warp_Pts[n][0] = 0; Bits->Discard(1); // marker bit Size = Get_Sprite_Point_Size(Bits); if (Size) { Val = Bits->Get_Bits(Size); if (!(Val&SKL_BMASKS::Or[Size])) // MSB not set Val -= SKL_BMASKS::And[Size]; S_Warp_Pts[n][1] = Val; } else S_Warp_Pts[n][1] = 0; Bits->Discard(1); // marker bit } for( ; n<4; ++n) S_Warp_Pts[n][0] = S_Warp_Pts[n][1] = 0; GMC_Ops.Setup(Width,Height, S_Warp_Pts, Sprite_Nb_Pts, Sprite_Accuracy);} // misc useless stuffstatic int Read_Sprite_Brightness_Change(SKL_FBB * const Bits){ /* TODO: rather untested stuff... */ int Size; int Code = Bits->See_Bits(4); if (!Bits->Get_Bits(1)) Size = 5; else { const SKL_VLC *VLC = &Spr_Tab_B34[Bits->See_Bits(3)]; Bits->Discard(VLC->Len); Size = VLC->Val; } Code = Bits->Get_Bits(Size); if (Size<=7) { if (!(Code&SKL_BMASKS::Or[Size])) // MSB not set Code -= SKL_BMASKS::And[Size]; if (Code<0) Code += 15; else Code -= 15; } else if (Size==9) Code += 113; else if (Size==10) Code += 625; return Code; /* -> float factor = Code/100.f + 1.f */}int SKL_MP4_I::Read_Sprite_Params(SKL_FBB * const Bits){ if (Sprite_Brightness!=0) Sprite_Brightness = Read_Sprite_Brightness_Change(Bits); if (Sprite_Mode==SPRITE_STATIC) { if (Sprite_Transmit!=SPRITE_STOP && Sprite_Low_Latency) { fprintf( stderr, "Sprite transmission not supported\n" ); return 0; } } return 1;}//////////////////////////////////////////////////////////// higher-level syntactic element decoding//////////////////////////////////////////////////////////static void Read_Matrix(SKL_FBB * const Bits, SKL_BYTE * const M){ int Value = 16; int i = 0; while(i<64) { int Tmp = Bits->Get_Bits(8); if (Tmp==0) break; Value = Tmp; M[SKL_MP4_I::Scan_Order[0][i++]] = Value; } while(i<64) M[SKL_MP4_I::Scan_Order[0][i++]] = Value;}static int Read_VOL_Header(SKL_FBB * const Bits, SKL_MP4_I * const VOL){ SKL_UINT32 Code; int Verid = 1; // section 6.2.3 Bits->Discard(1); // random accessible Code = Bits->Get_Bits(8); // VO type indication if (Code!=0 && Code!=1 && Code !=3 && Code!=4 && Code<=9) // support for Simple, Core and Main obj only. fprintf( stderr, "Warning: VO type '%d' might be unsupported.\n", Code ); if (Bits->Get_Bits(1)) { // is object layer identified Verid = Bits->Get_Bits(4); // layer version id Bits->Discard(3); // layer priority } if (Bits->Get_Bits(4)==0xf) // aspect ratio info == extended_PAR? Bits->Discard(8+8); // -> par_width + par_height if (Bits->Get_Bits(1)) { // control params Code = Bits->Get_Bits(2+1+1); // chroma format (01=420) + low delay + vbv param VOL->Low_Delay = !!(Code & 2); if (Code&1) { // vbv param Bits->Discard(15+1); // first_half bit rate + marker bit Bits->Discard(15+1); // latter_half bit rate + marker bit Bits->Discard(15+1); // first_half vbv size + marker bit Bits->Discard(3); // latter_half vbv size rate Bits->Discard(11+1); // first_half vbv occupancy + marker bit Bits->Discard(15+1); // latter_half vbv occupancy + marker bit } } else VOL->Low_Delay = 1; VOL->Shape = Bits->Get_Bits(2); // layer shape if (VOL->Shape != RECTANGULAR) { fprintf( stderr, "WARNING: Shape (%d) is not RECTANGULAR\n", VOL->Shape ); return 0; } if (VOL->Shape==GRAYSCALE && Verid!=1) Bits->Get_Bits(4); // shape extension in version 2 Bits->Discard(1); // marker bit int Freq = Bits->Get_Bits(16); // time increment resolution Bits->Discard(1); // marker bit VOL->Set_Time_Frequency(Freq); if (Bits->Get_Bits(1)) // fixed vop time incr VOL->Ticks_Per_VOP = Bits->Get_Bits(VOL->Ticks_Bits); else VOL->Ticks_Per_VOP = 0; // disabled /* note: Ticks_Per_VOP is not used for decoding. */ if (VOL->Shape!=BINARY_ONLY) { if (VOL->Shape==RECTANGULAR) { Bits->Discard(1); // marker bit int Width = Bits->Get_Bits(13); Bits->Discard(1); // marker bit int Height = Bits->Get_Bits(13); Bits->Discard(1); // marker bit // we cannot trust (DivX) the value of Low_Delay. // So we always allocated 1 auxiliary frame, and Map[]s. // We need to allocated the maps for cur/past frames // just for in case some B-VOP shows up. // Note: If it was not for these damned DIRECT macroblocks // in B-VOP, we wouldn't need to store the MVs for each // frames, too :( VOL->Init_Pics( Width, Height, 3, 1 ); } VOL->Interlace = Bits->Get_Bits(1); if (Bits->Get_Bits(1)!=1) { // overlapped motion comp. disable fprintf( stderr, "WARNING: overlapped motion comp not supported (who does?)\n" ); return 0; } VOL->Sprite_Mode = Bits->Get_Bits(Verid==1 ? 1 : 2); if (VOL->Sprite_Mode!=SPRITE_NONE) // sprite enable { if (VOL->Sprite_Mode==SPRITE_STATIC) { printf( "WARNING! Static sprite not supported!\n" ); Bits->Discard(13+1); // sprite width + marker bit Bits->Discard(13+1); // sprite height + marker bit Bits->Discard(13+1); // sprite left coord + marker bit Bits->Discard(13+1); // sprite top coord + marker bit } VOL->Sprite_Nb_Pts = Bits->Get_Bits(6); VOL->Sprite_Accuracy = Bits->Get_Bits(2); VOL->Sprite_Brightness = Bits->Get_Bits(1); if (VOL->Sprite_Mode==SPRITE_STATIC) VOL->Sprite_Low_Latency = Bits->Get_Bits(1); } if (VOL->Shape!=RECTANGULAR && Verid!=1) Bits->Discard(1); // sadct disable VOL->Not_8b = Bits->Get_Bits(1); if (VOL->Not_8b) { // not 8 bit VOL->Quant_Prec = Bits->Get_Bits(4); // quant prec VOL->Bpp = Bits->Get_Bits(4); // bits per pixel SKL_ASSERT(VOL->Quant_Prec>=3 && VOL->Quant_Prec<=9); SKL_ASSERT(VOL->Bpp>=4 && VOL->Bpp<=12); fprintf( stderr, "WARNING: Not_8b unsupported!\n" ); } if (VOL->Shape==GRAYSCALE) Bits->Discard(1+1+1); // no gray quant update, composition, linear comp. VOL->Set_Quant_Type( Bits->Get_Bits(1) ); // quant type if (VOL->Get_Quant_Type()==1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -