📄 skl_mpg4i.h
字号:
SKL_ANY Slicer_Data; void Set_Slicer(SKL_MP4_SLICER S, SKL_ANY Data); static void Get_Default_Matrix(SKL_BYTE M[64], int What); void Set_Quant_Type(int Quant_Type); int Get_Quant_Type() const { return Quant_Type; } int Set_Matrix(int Intra, const SKL_BYTE *M); SKL_CPU_FEATURE Cpu; void Set_CPU( SKL_CPU_FEATURE Cpu=SKL_CPU_LAST ); // LAST=choose best SKL_IMG_DSP Img_Ops; SKL_MB_DSP MB_Ops; SKL_QUANT_DSP Quant_Ops; SKL_GMC_DSP GMC_Ops; const SKL_MB_FUNCS *Add_Ops; const SKL_MB_FUNCS *Copy_Ops; void Set_Rounding(); // will set *Add_Ops and *Copy_Ops up void Make_Edges_Dec(const SKL_MP4_PIC * const Pic) const; // Replicate edges for decoder (padded to MB offsets) void Make_Edges_Enc(const SKL_MP4_PIC * const Pic) const; // Replicate edges for encoder (padded to input WidthxHeight only) void Switch_Off() const { MB_Ops.Switch_Off(); } // MPEG1/2 bwd compat. void Init_MPEG12(int MPG_Version); // version = 1 or 2 SKL_UINT32 MPEG12_Flags; // various flags... SKL_UINT32 MPEG12_Ext_Flags; // 14bits void Read_Reduced_VOP(SKL_FBB * const Bits) const; public: SKL_MP4_I(SKL_MEM_I *Mem); ~SKL_MP4_I(); void Init_VOL(int id); void Reset_VOL(); void Init_Pics(int W, int H, int Nb_Frames, int Nb_Maps); void Clear_Pics(); void Copy_Pic(SKL_MP4_PIC *Dst, const SKL_MP4_PIC *Src) const; // debug void Get_All_Frames(SKL_MP4_PIC *Pic) const; void Dump_MVs(const SKL_MP4_PIC * const Pic, int Incr=1) const; void Draw_GMC(const SKL_MP4_PIC * const Pic) const; void Dump_Line(int What, const SKL_MB * const MB) const; void Print_Infos() const; // main call int Decode(const SKL_BYTE *Buf, int Len); int Decode_MPEG12(const SKL_BYTE *Buf, int Len);};////////////////////////////////////////////////////////// // SKL_MP4_DEC_I////////////////////////////////////////////////////////// // Warning: Slicing problem. Inherit from SKL_MP4_I first // so that cast to SKL_MP4_I* is ok.class SKL_MP4_DEC_I : public SKL_MP4_I, private SKL_MP4_DEC{ public: SKL_MP4_DEC_I(SKL_MEM_I *Mem); virtual ~SKL_MP4_DEC_I(); public: // Top class' implementation. virtual int Decode(const SKL_BYTE *Buf, int Len); virtual int Decode_MPEG12(const SKL_BYTE *Buf, int Len); virtual int Get_Frame_Number() const; virtual int Is_Frame_Ready() const; virtual void Consume_Frame(SKL_MP4_PIC *Pic); virtual SKL_MEM_I *Set_Memory_Manager(SKL_MEM_I *Mem=0); virtual void Set_CPU(SKL_CPU_FEATURE Cpu = SKL_CPU_DETECT); virtual void Set_Slicer(SKL_MP4_SLICER Slicer, SKL_ANY Slicer_Data=0); virtual void Set_Debug_Level(int Level=0); virtual void Get_All_Frames(SKL_MP4_PIC *Pic) const; virtual int Ioctl(SKL_CST_STRING Param);};//////////////////////////////////////////////////////////// Inlined enc/dec common functions for 8b<->8b ops////////////////////////////////////////////////////////////#define DIV2RND(x) ( ( (x) + ((x)>=0) ) >> 1 )#define DIV2RND(x) ( (x)/2 )inlinevoid SKL_MB::Derive_uv_MV_From_1MV(SKL_MV Out, const SKL_MV MVo) const{ int x = MVo[0]; int y = MVo[1]; if (VOL->Quarter) { x = DIV2RND(x); y = DIV2RND(y); } // Trick! using Rnd_Tab_79[] is equivalent to the following Div2Round(): // => This mean we can use this func for MV Field-Chroma rounding too. Out[0] = (x>>1) | (x&1); // eq. to: Out[0] = (x>>1) + Rnd_Tab_79[ x & 0x3 ]; Out[1] = (y>>1) | (y&1); // eq. to: Out[1] = (y>>1) + Rnd_Tab_79[ y & 0x3 ];}inlinevoid SKL_MB::Derive_uv_MVs_Fields(SKL_MV Out, const SKL_MV MVo) const{ int x = MVo[0], y = MVo[1]; if (VOL->Quarter) { x = DIV2RND(x); y = y>>1; } // Note: WARNING! It's really "y>>1", not DIV2RND(y) ! Out[0] = (x>>1) | (x&1); Out[1] = (y>>1) | (y&1); Clip_Chroma_Field(Out, Out);}inlinevoid SKL_MB::Derive_uv_MV_From_4MV(SKL_MV Out, const SKL_MV MV1[2], const SKL_MV MV2[2]) const{ int x, y; if (VOL->Quarter) { x = DIV2RND(MV1[0][0]) + DIV2RND(MV1[1][0]); x += DIV2RND(MV2[0][0]) + DIV2RND(MV2[1][0]); y = DIV2RND(MV1[0][1]) + DIV2RND(MV1[1][1]); y += DIV2RND(MV2[0][1]) + DIV2RND(MV2[1][1]); } else { x = MV1[0][0] + MV1[1][0] + MV2[0][0] + MV2[1][0]; y = MV1[0][1] + MV1[1][1] + MV2[0][1] + MV2[1][1]; } Out[0] = (x>>3) + Rnd_Tab_76[ x & 0xf ]; Out[1] = (y>>3) + Rnd_Tab_76[ y & 0xf ]; Clip_Chroma(Out, Out);}#undef DIV2RND//////////////////////////////////////////////////////////// Half-pixel interpolation//////////////////////////////////////////////////////////inlinevoid SKL_MB::Clip(SKL_MV cMV, const SKL_MV MV) const { cMV[0] = (MV[0]<Limit_Mins[0] ) ? Limit_Mins[0] : (MV[0]>Limit_Maxs[0] ) ? Limit_Maxs[0] : MV[0]; cMV[1] = (MV[1]<Limit_Mins[1] ) ? Limit_Mins[1] : (MV[1]>Limit_Maxs[1] ) ? Limit_Maxs[1] : MV[1];}inlinevoid SKL_MB::Clip_Chroma(SKL_MV cMV, const SKL_MV MV) const { cMV[0] = (MV[0]<Limit_Mins_UV[0] ) ? Limit_Mins_UV[0] : (MV[0]>Limit_Maxs_UV[0] ) ? Limit_Maxs_UV[0] : MV[0]; cMV[1] = (MV[1]<Limit_Mins_UV[1] ) ? Limit_Mins_UV[1] : (MV[1]>Limit_Maxs_UV[1] ) ? Limit_Maxs_UV[1] : MV[1];}inlinevoid SKL_MB::Clip_Field(SKL_MV cMV, const SKL_MV MV) const { cMV[0] = (MV[0]<Limit_Mins[0] ) ? Limit_Mins[0] : (MV[0]>Limit_Maxs[0] ) ? Limit_Maxs[0] : MV[0]; cMV[1] = (2*MV[1]<Limit_Mins[1] ) ? (Limit_Mins[1]>>1) : (2*MV[1]>Limit_Maxs[1] ) ? (Limit_Maxs[1]>>1) : MV[1];}inlinevoid SKL_MB::Clip_Chroma_Field(SKL_MV cMV, const SKL_MV MV) const { cMV[0] = (MV[0]<Limit_Mins_UV[0] ) ? Limit_Mins_UV[0] : (MV[0]>Limit_Maxs_UV[0] ) ? Limit_Maxs_UV[0] : MV[0]; cMV[1] = (2*MV[1]<Limit_Mins_UV[1] ) ? (Limit_Mins_UV[1]>>1) : (2*MV[1]>Limit_Maxs_UV[1] ) ? (Limit_Maxs_UV[1]>>1) : MV[1];}//////////////////////////////////////////////////////////inlinevoid SKL_MB::Predict_8x8(SKL_BYTE * const Dst, const SKL_BYTE *Src, const SKL_MV MV, const SKL_MB_FUNCS * const Ops) const{ const int Halves = (MV[0]&1) | ((MV[1]&1)<<1); Src += (MV[1]>>1)*BpS + (MV[0]>>1); Ops->HP_8x8[Halves](Dst, Src, BpS);}inlinevoid SKL_MB::Predict_16x8(SKL_BYTE * const Dst, const SKL_BYTE *Src, const SKL_MV MV, const SKL_MB_FUNCS * const Ops) const{ const int Halves = (MV[0]&1) | ((MV[1]&1)<<1); Src += (MV[1]>>1)*BpS + (MV[0]>>1); Ops->HP_16x8[Halves](Dst, Src, BpS);}inlinevoid SKL_MB::Predict_16x8_Field(SKL_BYTE * const Dst, const SKL_BYTE *Src, const SKL_MV MV, const SKL_MB_FUNCS * const Ops) const{ const int Halves = (MV[0]&1) | ((MV[1]&1)<<1); Src += (MV[1]&~1)*BpS + (MV[0]>>1); Ops->HP_16x8[Halves](Dst, Src, 2*BpS);}inlinevoid SKL_MB::Predict_16x16(SKL_BYTE * const Dst, const SKL_BYTE *Src, const SKL_MV MV, const SKL_MB_FUNCS * const Ops) const{ const int Halves = (MV[0]&1) | ((MV[1]&1)<<1); Src += (MV[1]>>1)*BpS + (MV[0]>>1); Ops->HP_16x8[Halves](Dst, Src, BpS); Ops->HP_16x8[Halves](Dst+BpS8, Src+BpS8, BpS);}//////////////////////////////////////////////////////////inlinevoid SKL_MB::Predict_With_0MV(const SKL_MB_FUNCS * const Ops, const int Fwd) const{ const int CoLoc = (Fwd ? Fwd_CoLoc : Bwd_CoLoc); Ops->HP_16x8[0](Y1, Y1 + CoLoc, BpS); Ops->HP_16x8[0](Y1+BpS8, Y1+BpS8 + CoLoc, BpS); Ops->HP_8x8 [0](U, U + CoLoc, BpS); Ops->HP_8x8 [0](V, V + CoLoc, BpS);}inlinevoid SKL_MB::Predict_With_1MV(const SKL_MV MV, const SKL_MB_FUNCS * const Ops, const int Fwd) const{ const int CoLoc = (Fwd ? Fwd_CoLoc : Bwd_CoLoc); SKL_MV cMV; Clip(cMV, MV); if (!VOL->Quarter) Predict_16x16 (Y1, Y1+CoLoc, cMV, Ops); else Predict_16x16_QP(Y1, Y1+CoLoc, cMV, Ops); Derive_uv_MV_From_1MV(cMV, cMV); // we re-use the *clipped* Y-vector const int Halves = (cMV[0]&1) | ((cMV[1]&1)<<1); const int Off = CoLoc + (cMV[1]>>1)*BpS + (cMV[0]>>1); Ops->HP_8x8[Halves](U, U+Off, BpS); Ops->HP_8x8[Halves](V, V+Off, BpS);}inlinevoid SKL_MB::Predict_Fields(const SKL_MV MV[2], const SKL_MB_FUNCS * const Ops, const int Fwd, const int Fld_Dirs) const{ const int CoLoc = (Fwd ? Fwd_CoLoc : Bwd_CoLoc); int Off, Halves; SKL_MV uv_MV, cMV; // 1rst field Clip_Field(cMV, MV[0]); Off = CoLoc; if (Fld_Dirs&2) Off += BpS; if (!VOL->Quarter) Predict_16x8_Field (Y1, Y1+Off, cMV, Ops); else Predict_16x8_Field_QP(Y1, Y1+Off, cMV, Ops); Derive_uv_MVs_Fields(uv_MV, MV[0]); Halves = (uv_MV[0]&1) | ((uv_MV[1]&1)<<1); Off += (uv_MV[0]>>1) + (uv_MV[1]&~1)*BpS; Ops->HP_8x4[Halves](U, U+Off, 2*BpS); Ops->HP_8x4[Halves](V, V+Off, 2*BpS); // 2nd field Clip_Field(cMV, MV[1]); Off = CoLoc; if (Fld_Dirs&1) Off += BpS; if (VOL->Quarter) Predict_16x8_Field_QP(Y1+BpS, Y1+Off, cMV, Ops); else Predict_16x8_Field (Y1+BpS, Y1+Off, cMV, Ops); Derive_uv_MVs_Fields(uv_MV, MV[1]); Halves = (uv_MV[0]&1) | ((uv_MV[1]&1)<<1); Off += (uv_MV[0]>>1) + (uv_MV[1]&~1)*BpS; Ops->HP_8x4[Halves](U+BpS, U+Off, 2*BpS); Ops->HP_8x4[Halves](V+BpS, V+Off, 2*BpS);}inlinevoid SKL_MB::Predict_With_4MV(const SKL_MV MV1[2], const SKL_MV MV2[2], const SKL_MB_FUNCS * const Ops, const int Fwd) const{ const int CoLoc = ( Fwd ? Fwd_CoLoc : Bwd_CoLoc ); SKL_MV cMV[2]; if (!VOL->Quarter) { Clip(cMV[0], MV1[0]); Clip(cMV[1], MV1[1]); SKL_BYTE * Y = Y1; if (SKL_IS_SAME_MV(cMV[0], cMV[1])) Predict_16x8(Y, Y+CoLoc, cMV[0], Ops); else { Predict_8x8 (Y, Y +CoLoc, cMV[0], Ops); Predict_8x8 (Y+8,Y+8+CoLoc, cMV[1], Ops); } Y += BpS8; Clip(cMV[0], MV2[0]); Clip(cMV[1], MV2[1]); if (SKL_IS_SAME_MV(cMV[0], cMV[1])) Predict_16x8(Y, Y+CoLoc, cMV[0], Ops); else { Predict_8x8 (Y, Y +CoLoc, cMV[0], Ops); Predict_8x8 (Y+8,Y+8+CoLoc, cMV[1], Ops); } } else { SKL_MV cMV[2]; Clip(cMV[0], MV1[0]); Clip(cMV[1], MV1[1]); SKL_BYTE * Y = Y1; Predict_8x8_QP(Y, Y+ CoLoc, cMV[0], Ops); Predict_8x8_QP(Y+8, Y+8+CoLoc, cMV[1], Ops); Y += BpS8; Clip(cMV[0], MV2[0]); Clip(cMV[1], MV2[1]); Predict_8x8_QP(Y, Y +CoLoc, cMV[0], Ops); Predict_8x8_QP(Y+8, Y+8+CoLoc, cMV[1], Ops); } SKL_MV uv_MV; Derive_uv_MV_From_4MV(uv_MV, MV1, MV2); const int Halves = (uv_MV[0]&1) | ((uv_MV[1]&1)<<1); const int Off = CoLoc + (uv_MV[1]>>1)*BpS + (uv_MV[0]>>1); Ops->HP_8x8[Halves](U, U+Off, BpS); Ops->HP_8x8[Halves](V, V+Off, BpS);}//////////////////////////////////////////////////////////// GMC predictioninline void SKL_MB::Predict_GMC() const{ const SKL_BYTE * const ySrc = VOL->Cur->Y + Fwd_CoLoc; const SKL_BYTE * const uSrc = VOL->Cur->U + Fwd_CoLoc; const SKL_SAFE_INT UV_Offset = VOL->Cur->V - VOL->Cur->U; SKL_BYTE *yDst = Y1; SKL_BYTE *uDst = U; VOL->GMC_Ops.Predict_16x16(&VOL->GMC_Ops, yDst, ySrc, BpS, x,y, VOL->Rounding); VOL->GMC_Ops.Predict_8x8 (&VOL->GMC_Ops, uDst, uSrc, UV_Offset, BpS, x,y, VOL->Rounding); int mv[2]; VOL->GMC_Ops.Get_Average_MV(mv, x, y, VOL->Quarter); const int High = 1 << (VOL->Fwd_Code+4); if (mv[0]<-High) MVs[0][0] = -High; else if (mv[0]>=High) MVs[0][0] = High-1; else MVs[0][0] = mv[0]; if (mv[1]<-High) MVs[0][1] = -High; else if (mv[1]>=High) MVs[0][1] = High-1; else MVs[0][1] = mv[1]; Store_16x16_MV();}//////////////////////////////////////////////////////////// 16b->8b MB Prediction ops//////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -