📄 skl_mpg4i.h
字号:
/******************************************************** * Some code. Copyright (C) 2003 by Pascal Massimino. * * All Rights Reserved. (http://skal.planet-d.net) * * For Educational/Academic use ONLY. See 'LICENSE.TXT'.* ********************************************************//* * skl_mpg4i.h * * internal MPEG4 header ********************************************************/#ifndef _SKL_MPG4I_H_#define _SKL_MPG4I_H_#include "skl.h"#include "skl_syst/skl_mpg4.h"#include "skl_syst/skl_bits.h"#include "skl_syst/skl_dsp.h"#include <math.h>struct SKL_MP4_I; // internal opaque structureclass SKL_MP4_ENC_I; // ditto.class SKL_MP4_DEC_I; // ditto.struct SKL_MB;struct SKL_MB_ENC; // subclass for encoderstruct SKL_MB_DATA;//////////////////////////////////////////////////////////// #defines // section 6.2.1, Table 6-3#define FIRST_CODE 0x00000100#define VOL_CODE 0x00000120#define SEQ_START_CODE 0x000001b0#define SEQ_END_CODE 0x000001b1#define USER_DATA_CODE 0x000001b2#define VOP_GROUP_CODE 0x000001b3#define VSESSION_ERR_CODE 0x000001b4#define VO_START_CODE 0x000001b5#define VOP_CODE 0x000001b6#define MPEG2_SEQ_END_CODE 0x000001b7#define MPEG2_GOP_CODE 0x000001b8#define SYSTEM_MIN_CODE 0x000001b9#define LAST_CODE 0x000001ffenum { // table 6-20 I_VOP = 0, P_VOP = 1, B_VOP = 2, S_VOP = 3, D_VOP = 3, // <- old MPEG1 D-mode NC_VOP = 4, // not coded BAD_VOP = 5};enum { // table V2-2 SPRITE_NONE = 0, SPRITE_STATIC = 1, SPRITE_GMC = 2, // table 6-22 SPRITE_STOP = 0, SPRITE_PIECE = 1, SPRITE_UPDATE = 2, SPRITE_PAUSE = 3}; // Macroblock sub-types for B_VOP. // WARNING! they're not the same as the norm...#define SKL_MB_DIRECT 0#define SKL_MB_BWD 1#define SKL_MB_FWD 2#define SKL_MB_INTERP 3// Useful 'macros'// Motion vectors are restricted to [-2048,2047]+Prediction (~VOP size)// So we have some bits left for coding some special case within the 32b storage.static inline void MARK_INVALID_MV(SKL_MV MV) { *(SKL_UINT32*)MV = 0x7fff7fff; }static inline int IS_VALID_MV(const SKL_MV MV) { return *(SKL_UINT32*)MV != 0x7fff7fff; }static inline int IS_EQUAL_MV(const SKL_MV a, const SKL_MV b) { return *(SKL_UINT32*)a == *(SKL_UINT32*)b; }static inline int IS_ZERO_MV(const SKL_MV MV) { return *(SKL_UINT32*)MV == 0; }//////////////////////////////////////////////////////////// alignment macros#ifdef SKL_USE_ASM#define SKL_ALIGN 15#else#define SKL_ALIGN 0#endif#define SKL_ALIGN_PTR(P,ALGN) ( ((SKL_SAFE_INT)(P) + (ALGN)) & ~(ALGN) )//////////////////////////////////////////////////////////// internal structs // coding infosstruct SKL_MP4_FRAME : public SKL_MP4_INFOS{ int Coding; /**< Frame type: 0:I, 1:P, 2:B, 3:S(/D), 4:not coded */ int Quant; int Fwd_Code, Bwd_Code; int Rounding; int Reduced_VOP; /**< -1: disabled, >=0: possibly enabled (0:off, 1:on) */ int DC_Thresh; int Top_Field_First; int Alt_Vert_Scan; int Sprite_Nb_Pts; /**< max: 4 for static sprite, 3 for GMC. -1 = disable */ int S_Warp_Pts[4][2]; int Sprite_Accuracy; SKL_UINT64 Time; /**< in ticks */ void Dump_Map(SKL_MP4_PIC *Pic, int What=0) const; /**< intended for debugging */};//////////////////////////////////////////////////////////// struct used for DC/AC predictionstruct SKL_MB_DATA { SKL_INT16 Q; /**< Q=0 means: not intra coded, Q=-1 means: not coded */ SKL_INT16 DC; SKL_INT16 AC[7]; void Set_Not_Intra() { Q = 0; DC = 1024; } /* should be: 1<<(Bpp+2) */ int Choose_Pred_Dir(const SKL_MB_DATA *Top); void Add_DC_AC_Pred(SKL_INT16 In[64], int Dir, SKL_INT16 Left_AC[7], const SKL_MB_DATA *Top, int AC_Q, int DC_Q);}; /** @internal it's a cursor (only 1 instance) */struct SKL_MB{ int x, y; int Pos; /**< absolute position in an MB_WxMB_H array */ int MB_Count; /**< Counter from first macroblock of slice */ int ABits; /**< Neighbour-availability bits. Bit0: left *not* available, Bit1:top available, Bit2:top-right available */ int MB_W; /**< Pic width, in macroblock units */ int Prev_Quant; int Quant; /**< Duplicated from VOL */ int Use_AC_Pred; int Cbp; int MB_Type; int Field_DCT; /**< -1: none. 0: frame, 1:field */ int Field_Pred; int Field_Dir; /**< fwd/dir field selection => bits 3:bwd top, 2:bwd bottom */ /**< 1:fwd top, 0:fwd bottom */ int MC_Sel; SKL_MV Limit_Mins; /**< Left/Top clipping limits for Luma */ SKL_MV Limit_Maxs; /**< Right/Bottom clipping limits for Luma */ SKL_MV Limit_Mins_UV; /**< Left/Top clipping limits for Chroma */ SKL_MV Limit_Maxs_UV; /**< Right/Bottom clipping limits for Chroma */ int MB_Pels; /**< macroblock size in mv unit */ const SKL_MP4_I * const VOL; SKL_BYTE *Y1; /**< current macroblock reference (or 1rst field) */ SKL_BYTE *Y2; /**< 2nd field for Field-DCT */ SKL_BYTE *U, *V; const int BpS, BpS8; /**< Pixel strides, duplicated from VOL */ int YBpS; /**< strides for Field DCT */ const int Fwd_CoLoc; /**< Forward colocation */ const int Bwd_CoLoc; /**< Backward colocation */ SKL_BYTE * const YTmp; /**< 16x17 scratch buffer for vertical qpel interp. */ SKL_MB_DATA *Tops[6]; /**< top blocks data for each block */ SKL_MB_DATA *Curs[6]; /**< cur blocks data */ SKL_INT16 *Lefts[6]; /**< pointer to left ACs of each blocks */ SKL_INT16 Left_ACs[4][7]; /**< left ACs for 2 lum rows + (1+1) chroma row */ SKL_MV *MVs; /**< motion vectors starting at block 0 */ SKL_MV *MVs2; /**< second row of motion vectors */ int MV_Stride; /**< =2*EMB_W (stride for Motion Vectors) */ SKL_MP4_MAP * const Map; /**< MB infos map (for B-VOP and encoder) */ int Resync; /**< Resync marker len (0: disabled) */ // constructor. Will initialize the scan. SKL_MB(const SKL_MP4_I * const VOL); ~SKL_MB(); // stach useful infos static const SKL_UINT8 MB_To_Map_Type[SKL_MB_LAST]; /**< Convert from internal MB_Type to SKL_MP4_MAP::Type public type */ inline void Store_Map_Infos() const { Map[Pos].Type = MB_To_Map_Type[MB_Type]; Map[Pos].Fields = Field_Dir; } // debug void Dump_Line(int What, const SKL_MP4_I * const VOL) const; // 16b->8b block ops inline void Set_Field_DCT(int fDCT); inline void Set_No_Field(); inline void Copy_16To8(SKL_INT16 In[6*64]) const; inline void Add_16To8 (SKL_INT16 In[6*64]) const; // spatial prediction int Top_Ok() const { return MB_Count>=MB_W; } int Top_Right_Ok() const { return MB_Count>=MB_W-1 && x<MB_W-1; } int Left_Ok() const { return MB_Count>0 && x>0; } void Start_Scan() { ABits = 1; MB_Count = 0; } void Init_Scanline(const SKL_MP4_I * const VOL, int x); void operator++(int); void Next_Reduced(); void Next_Line_Preds(); void Init_Offset(); void Resync_Cursor(const SKL_MP4_I * const VOL, int New_Pos); void Set_Not_Intra(); // MV prediction void Predict_Motion_Vector(SKL_MV MV, const SKL_MV * const Src, const int Blk) const; void Predict_Motion_Vector_Blk0(SKL_MV MV, const SKL_MV * const Src, const SKL_MV * const Left) const; inline void Store_Zero_MV() const; inline void Store_16x16_MV() const; inline void Store_16x8_MV(SKL_MV *Dst, SKL_MV MV[2]) const; static const int Rnd_Tab_76[16]; static const int Rnd_Tab_78[8]; static const int Rnd_Tab_79[4]; inline void Derive_uv_MV_From_1MV(SKL_MV MV, const SKL_MV MVo) const; inline void Derive_uv_MV_From_4MV(SKL_MV MV, const SKL_MV MV1[2], const SKL_MV MV2[2]) const; inline void Derive_uv_MVs_Fields(SKL_MV Out, const SKL_MV MVo) const; inline void Clip(SKL_MV Out, const SKL_MV In) const; inline void Clip_Chroma(SKL_MV Out, const SKL_MV In) const; inline void Clip_Field(SKL_MV Out, const SKL_MV In) const; inline void Clip_Chroma_Field(SKL_MV Out, const SKL_MV In) const; inline void Predict_16x16(SKL_BYTE * const Dst, const SKL_BYTE *Src, const SKL_MV MV, const SKL_MB_FUNCS * const Ops) const; inline void Predict_16x8(SKL_BYTE * const Dst, const SKL_BYTE *Src, const SKL_MV MV, const SKL_MB_FUNCS * const Ops) const; inline void Predict_16x8_Field(SKL_BYTE * const Dst, const SKL_BYTE *Src, const SKL_MV MV, const SKL_MB_FUNCS * const Ops) const; inline void Predict_8x8(SKL_BYTE * const Dst, const SKL_BYTE *Src, const SKL_MV MV, const SKL_MB_FUNCS * const Ops) const; inline void Predict_16x16_QP(SKL_BYTE * const Dst, const SKL_BYTE *Src, const SKL_MV MV, const SKL_MB_FUNCS * const Ops) const; inline void Predict_16x8_Field_QP(SKL_BYTE * const Dst, const SKL_BYTE *Src, const SKL_MV MV, const SKL_MB_FUNCS * const Ops) const; inline void Predict_8x8_QP(SKL_BYTE * const Dst, const SKL_BYTE *Src, const SKL_MV MV, const SKL_MB_FUNCS * const Ops) const; inline void Predict_With_0MV(const SKL_MB_FUNCS * const Ops, const int Fwd) const; inline void Predict_With_1MV(const SKL_MV MV, const SKL_MB_FUNCS * const Ops, const int Fwd) const; inline void Predict_Fields(const SKL_MV MV[2], const SKL_MB_FUNCS * const Ops, const int Fwd, const int Fld_Dirs) const; inline void Predict_With_4MV(const SKL_MV MV1[2], const SKL_MV MV2[2], const SKL_MB_FUNCS * const Ops, const int Fwd) const; inline void Predict_GMC() const; // reduced predictions void Copy_16To8_Upsampled(SKL_INT16 In[6*64]) const; void Add_16To8_Upsampled (SKL_INT16 In[6*64]) const; void Predict_Reduced_With_0MV() const; void Predict_Reduced_With_1MV(const SKL_MV MV) const; void Predict_Reduced_Fields(const SKL_MV MV[2], const int Fld_Dirs) const; void Predict_Reduced_With_4MV(const SKL_MV MV1[2], const SKL_MV MV2[2]) const; void Expand_Reduced() const; // bitstream parsing void Decode_Intra_Infos(SKL_FBB * const Bits); void Decode_Inter_Infos(SKL_FBB * const Bits, const SKL_MV * const Left_Predictor); void Decode_Intra_Blocks(SKL_FBB * const Bits, SKL_INT16 * const In, const SKL_MP4_I * const VOL) const; void Decode_Inter_Blocks(SKL_FBB * const Bits, SKL_INT16 * const In, const SKL_MP4_I * const VOL) const; int Resync_Marker(SKL_FBB * const Bits); /**< returns true if resync marker encountered */};//////////////////////////////////////////////////////////// SKL_MP4_I : internal data///////////////////////////////////////////////////////////** Note: we've gathered useful informations, passed to the analyzer, into SKL_MP4_INFOS, although most of the managment of this class is done by the SKL_MP4_I one. */struct SKL_MP4_I : public SKL_MP4_FRAME{ public: /* index: zigzag/horizontal/vertical/transposed-zigzag */ static const int Scan_Order[4][64]; static const SKL_BYTE Dflt_Mtx[3][64]; // [Intra/Inter/Intra-MPEG2][] static const int Row_From_Index[64]; // row number from index static const int DC_Scales[2][31]; // index: [Lum][AC_Q-1] // Frame-based parameters int EMB_W, EMB_H; // macroblocks size (w/ edges) SKL_MB_DATA *Y_Preds[3], *C_Preds[2]; SKL_MP4_PIC *Aux, *Last; int Cur_Map; int Is_I_VOP() const { return (Coding==I_VOP); } int Is_P_VOP() const { return (Coding==P_VOP); } int Is_B_VOP() const { return (Coding==B_VOP); } int Is_S_VOP() const { return (Coding==S_VOP); } int Is_D_VOP() const { return (Coding==D_VOP); } // VOL global params int MPEG_Version; int VOL_Id; int Shape; int Low_Delay; int Not_8b, Quant_Prec, Bpp; int Interlace; int Quant_Type; // should be private. Use Get/Set()! int Time_Frequency; int Ticks_Bits; int Ticks_Per_VOP; /* Fixed VOP rate. Unused for decoding. */ void Set_Time_Frequency(int Freq); /* sets Time_Frequency and Ticks_Bits */ int Resync; int Data_Partitioned; int Rev_VLC; int Quarter; SKL_UINT64 Time_Ref; SKL_UINT64 Time_Last_Coded; SKL_UINT64 Time_TFrame; int New_Pred; int Sprite_Mode; int Sprite_Brightness; int Sprite_Transmit; int Sprite_Low_Latency; void Read_Sprite_Trajectory(SKL_FBB * const Bits); int Read_Sprite_Params(SKL_FBB * const Bits); int Field_Dir; // inter-frame persistant field selectors SKL_UINT32 CE_Flags; // complexity estimation flags (22b) int Scalability; int Debug_Level; void Set_Debug_Level(int Level) { Debug_Level = Level; } int Nb_Preds; SKL_MB_DATA *Preds; int Sanity_Check_Preds() const; enum { MAX_PICS = 3, MAX_MAPS = 2 }; SKL_MP4_PIC All_Pics[MAX_PICS]; int Nb_Pics; struct { SKL_MP4_MAP *Map; SKL_MV *MV; } All_Maps[MAX_MAPS]; // aux frame queue int Nb_Maps; int Pic_Size; SKL_BYTE *Pic_Base; int Custom_Intra, Custom_Inter; SKL_BYTE Intra_Matrix[64], Inter_Matrix[64]; SKL_ANY Q_Base; SKL_QUANTIZER Q_Intra, Q_Inter; SKL_MP4_SLICER Slicer;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -