📄 skl_mpg4_tbl.cpp
字号:
/******************************************************** * 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_mpg4_tbl.cpp * * MPEG4 tables and utils ********************************************************/#include "./skl_mpg4i.h"#include "skl_syst/skl_exception.h"#define MB_FENCE 0 // number of extraneous edges (for Valgrind/purify)//////////////////////////////////////////////////////////const int SKL_MP4_I::Scan_Order[4][64] = { /* zigzag */ { 0, 1, 8, 16, 9, 2, 3, 10 , 17, 24, 32, 25, 18, 11, 4, 5 , 12, 19, 26, 33, 40, 48, 41, 34 , 27, 20, 13, 6, 7, 14, 21, 28 , 35, 42, 49, 56, 57, 50, 43, 36 , 29, 22, 15, 23, 30, 37, 44, 51 , 58, 59, 52, 45, 38, 31, 39, 46 , 53, 60, 61, 54, 47, 55, 62, 63 }, /* horiz. */ { 0, 1, 2, 3, 8, 9, 16, 17 , 10, 11, 4, 5, 6, 7, 15, 14 , 13, 12, 19, 18, 24, 25, 32, 33 , 26, 27, 20, 21, 22, 23, 28, 29 , 30, 31, 34, 35, 40, 41, 48, 49 , 42, 43, 36, 37, 38, 39, 44, 45 , 46, 47, 50, 51, 56, 57, 58, 59 , 52, 53, 54, 55, 60, 61, 62, 63 }, /* vert. */ { 0, 8, 16, 24, 1, 9, 2, 10 , 17, 25, 32, 40, 48, 56, 57, 49 , 41, 33, 26, 18, 3, 11, 4, 12 , 19, 27, 34, 42, 50, 58, 35, 43 , 51, 59, 20, 28, 5, 13, 6, 14 , 21, 29, 36, 44, 52, 60, 37, 45 , 53, 61, 22, 30, 7, 15, 23, 31 , 38, 46, 54, 62, 39, 47, 55, 63 }, /* transposed zigzag */ { 0, 8, 1, 2, 9, 16, 24, 17 , 10, 3, 4, 11, 18, 25, 32, 40 , 33, 26, 19, 12, 5, 6, 13, 20 , 27, 34, 41, 48, 56, 49, 42, 35 , 28, 21, 14, 7, 15, 22, 29, 36 , 43, 50, 57, 58, 51, 44, 37, 30 , 23, 31, 38, 45, 52, 59, 60, 53 , 46, 39, 47, 54, 61, 62, 55, 63 }};const SKL_BYTE SKL_MP4_I::Dflt_Mtx[3][64] = { { // Dflt_Intra 8, 17, 18, 19, 21, 23, 25, 27, 17, 18, 19, 21, 23, 25, 27, 28, 20, 21, 22, 23, 24, 26, 28, 30, 21, 22, 23, 24, 26, 28, 30, 32, 22, 23, 24, 26, 28, 30, 32, 35, 23, 24, 26, 28, 30, 32, 35, 38, 25, 26, 28, 30, 32, 35, 38, 41, 27, 28, 30, 32, 35, 38, 41, 45 }, { // Dflt_Inter 16, 17, 18, 19, 20, 21, 22, 23, 17, 18, 19, 20, 21, 22, 23, 24, 18, 19, 20, 21, 22, 23, 24, 25, 19, 20, 21, 22, 23, 24, 26, 27, 20, 21, 22, 23, 25, 26, 27, 28, 21, 22, 23, 24, 26, 27, 28, 30, 22, 23, 24, 26, 27, 28, 30, 31, 23, 24, 25, 27, 28, 30, 31, 33 }, { // Dflt_Intra_MPEG2 8, 16, 19, 22, 26, 27, 29, 34, 16, 16, 22, 24, 27, 29, 34, 37, 19, 22, 26, 27, 29, 34, 34, 38, 22, 22, 26, 27, 29, 34, 37, 40, 22, 26, 27, 29, 32, 35, 40, 48, 26, 27, 29, 32, 35, 40, 48, 58, 26, 27, 29, 34, 38, 46, 56, 69, 27, 29, 35, 38, 46, 56, 69, 83 }};static const SKL_BYTE DC_Q_Tab_MPEG1[31] = { 2, 4, 6, 8, 10, 12, 14 , 16, 18, 20, 22, 24, 26, 28, 30 , 32, 34, 36, 38, 40, 42, 44, 46 , 48, 50, 52, 54, 56, 58, 60, 62 };static const SKL_BYTE DC_Q_Tab_MPEG2_0[31] = { 1, 2, 3, 4, 5, 6, 7 , 8, 9, 10, 11, 12, 13, 14, 15 , 16, 17, 18, 19, 20, 21, 22, 23 , 24, 25, 26, 27, 28, 29, 30, 31 };static const SKL_BYTE DC_Q_Tab_MPEG2_1[31] = { 1, 2, 3, 4, 5, 6, 7 , 8, 10, 12, 14, 16, 18, 20, 22 , 24, 28, 32, 36, 40, 44, 48, 52 , 56, 64, 72, 80, 88, 96, 104, 112 };static const SKL_BYTE * Q_Scale_Maps[] = { 0L, 0L, // MPEG4 DC_Q_Tab_MPEG1, // MPEG1 DC_Q_Tab_MPEG1, DC_Q_Tab_MPEG2_1 // MPEG2 qscale_type=0,1};//////////////////////////////////////////////////////////// Used as hint for sparse DCTs// bit8: if set, Input is not only upper-left 4x4// bit0-7: corresponding row has non-zero coeffconst int SKL_MP4_I::Row_From_Index[64] ={ 0x001,0x001,0x001,0x001, 0x101,0x101,0x101,0x101, 0x002,0x002,0x002,0x002, 0x102,0x102,0x102,0x102, 0x004,0x004,0x004,0x004, 0x104,0x104,0x104,0x104, 0x008,0x008,0x008,0x008, 0x108,0x108,0x108,0x108, 0x110,0x110,0x110,0x110, 0x110,0x110,0x110,0x110, 0x120,0x120,0x120,0x120, 0x120,0x120,0x120,0x120, 0x140,0x140,0x140,0x140, 0x140,0x140,0x140,0x140, 0x180,0x180,0x180,0x180, 0x180,0x180,0x180,0x180};//////////////////////////////////////////////////////////// Table for converting from internal MB_Type // to SKL_MP4_MAP::Type public type.const SKL_UINT8 SKL_MB::MB_To_Map_Type[SKL_MB_LAST] ={ SKL_MAP_16x16, SKL_MAP_16x16, SKL_MAP_8x8, SKL_MAP_INTRA, SKL_MAP_INTRA, SKL_MAP_SKIPPED};///////////////////////////////////////////////////////////* // TODO: test in progress...extern const SKL_INT32 Skl_Div18[];#define BITS 18 // minimum allowed.#define FIX(a) ((1<<BITS)/(a) + 1)const SKL_INT32 Skl_Div18[47] = { FIX( 1),FIX( 2),FIX( 3),FIX( 4),FIX( 5),FIX( 6),FIX( 7), FIX( 8),FIX( 9),FIX(10),FIX(11),FIX(12),FIX(13),FIX(14),FIX(15), FIX(16),FIX(17),FIX(18),FIX(19),FIX(20),FIX(21),FIX(22),FIX(23), FIX(24),FIX(25),FIX(26),FIX(27),FIX(28),FIX(29),FIX(30),FIX(31), FIX(32),FIX(33),FIX(34),FIX(35),FIX(36),FIX(37),FIX(38),FIX(39), FIX(40),FIX(41),FIX(42),FIX(43),FIX(44),FIX(45),FIX(46),FIX(47)};#define FDIV(a,b) ( (((a)+((b)>>1))*Skl_Div18[(b)-1])>>BITS )#define RDIV(a,b) ( ((a)+((b)>>1))/(b) )#define DIV_ROUND(x,y) (FDIV((x),(y))-((x)<0))*///////////////////////////////////////////////////////////// SKL_MP4_INFOS//////////////////////////////////////////////////////////SKL_MP4_INFOS::SKL_MP4_INFOS(SKL_MEM_I *Memory) : Mem(Memory) {}SKL_MEM_I *SKL_MP4_INFOS::Set_Memory_Manager(SKL_MEM_I *New_Mem){ SKL_MEM_I *Old_Mem = Mem; Mem = New_Mem; return Old_Mem;}//////////////////////////////////////////////////////////// SKL_MP4_I//////////////////////////////////////////////////////////SKL_MP4_I::SKL_MP4_I(SKL_MEM_I *Memory){ Set_Memory_Manager(Memory); Cpu = SKL_CPU_LAST; Set_Slicer(0,0); const int Q_Size = 4*sizeof(Q_Intra[0]) + SKL_ALIGN; Q_Base = (SKL_ANY)malloc(2*Q_Size + SKL_ALIGN); if (Q_Base==0) Skl_Throw( SKL_MEM_EXCEPTION("Q_Base", 2*Q_Size) ); Q_Intra = (SKL_QUANTIZER)SKL_ALIGN_PTR( Q_Base, SKL_ALIGN ); Q_Inter = &Q_Intra[2]; Quant_Type = 1; Get_Default_Matrix( Intra_Matrix, 0 ); Get_Default_Matrix( Inter_Matrix, 1 ); Custom_Intra = 0; Custom_Inter = 0; Set_CPU( SKL_CPU_C ); // default guess MPEG_Version = 0; // unknown yet Debug_Level = 0; VOL_Id = -1; Frame_Number = 0; Time_Ref = 0; Time_Last_Coded = 0; Time_TFrame = 0; Set_Time_Frequency( 25 ); // default: 25hz clock Ticks_Per_VOP = 0; // disabled Coding = I_VOP; Rounding = 0; Set_Rounding(); // sanity check Fwd_Code = -1; // sanity check.. Bwd_Code = -1; // this is decided Quant = -1; // .. by the analyzer DC_Thresh = 0; Top_Field_First = 1; Alt_Vert_Scan = 0; Field_Dir = 0x00; Pic_Base = 0; Preds = 0; Nb_Pics = 0; Nb_Maps = 0; Reset_VOL(); Clear_Pics();}SKL_MP4_I::~SKL_MP4_I(){ Clear_Pics(); free(Q_Base);}void SKL_MP4_I::Set_Slicer(SKL_MP4_SLICER S, SKL_ANY Data){ Slicer = S; Slicer_Data = Data;}//////////////////////////////////////////////////////////void SKL_MP4_I::Set_Rounding(){ Add_Ops = MB_Ops.Add; // rounding is always 0 for B-vop Copy_Ops = MB_Ops.Copy[Rounding];}void SKL_MP4_I::Make_Edges_Dec(const SKL_MP4_PIC * const Pic) const{ SKL_BYTE * const YUV[3] = { Pic->Y, Pic->U, Pic->V }; MB_Ops.Make_Edges( YUV, MB_W<<4, MB_H<<4, BpS);}void SKL_MP4_I::Make_Edges_Enc(const SKL_MP4_PIC * const Pic) const{ SKL_BYTE * const YUV[3] = { Pic->Y, Pic->U, Pic->V }; MB_Ops.Make_Edges( YUV, Pic->Width, Pic->Height, BpS);}//////////////////////////////////////////////////////////void SKL_MP4_I::Set_CPU(SKL_CPU_FEATURE New_Cpu){ if (New_Cpu==SKL_CPU_LAST) New_Cpu = Skl_Detect_CPU_Feature(); if (New_Cpu==Cpu) return; Cpu = New_Cpu; Skl_Init_Img_DSP( &Img_Ops, Cpu ); Skl_Init_Mb_DSP ( &MB_Ops, Cpu ); Skl_Init_GMC_DSP( &GMC_Ops, Cpu ); int Saved_Quant_Type = Quant_Type; Quant_Type = -1; // will force re-init of _Quant_Ops... Set_Quant_Type( Saved_Quant_Type ); Img_Dsp = &Img_Ops; // in SKL_MP4_INFOS MB_Dsp = &MB_Ops; // in SKL_MP4_INFOS GMC_Dsp = &GMC_Ops; // in SKL_MP4_INFOS Add_Ops = 0; // sanity check Copy_Ops = 0; // ""}//////////////////////////////////////////////////////////void SKL_MP4_I::Set_Time_Frequency(int Freq){ Time_Frequency = Freq; Ticks_Bits = SKL_BMASKS::Log2( Freq-1 ); if (Ticks_Bits<1) Ticks_Bits = 1;}void SKL_MP4_I::Init_VOL(int id){ SKL_ASSERT(id>=0 && id<=0x1f); // TODO: improve id managment for multi-VOL? if (VOL_Id!=id) { VOL_Id = id; } MPEG_Version = 4; Reset_VOL();}void SKL_MP4_I::Reset_VOL() // this is roughly table 6-24{ Shape = 0; Low_Delay = 1; Not_8b = 0; Quant_Prec = 5; Bpp = 8; Interlace = 0; Quarter = 0; Resync = 0; Reduced_VOP =-1; // disabled New_Pred = 0; Sprite_Mode = SPRITE_NONE; Sprite_Nb_Pts = 0; Sprite_Accuracy = 3; Sprite_Transmit = SPRITE_PIECE; Data_Partitioned = 0; Rev_VLC = 0; CE_Flags = 0; Time_TFrame = 0; // invalided. Will be computed when first BVop is encountered.}//////////////////////////////////////////////////////////void SKL_MP4_I::Set_Quant_Type(int Type){ if (Type!=Quant_Type) { Quant_Type = Type; Skl_Init_Quant_DSP( &Quant_Ops, Cpu, (Quant_Type>=2) ? 2 : Quant_Type ); Quant_Ops.Init_Quantizer(Q_Intra, Intra_Matrix, Q_Scale_Maps[Quant_Type], 1); Quant_Ops.Init_Quantizer(Q_Inter, Inter_Matrix, Q_Scale_Maps[Quant_Type], 0); }}void SKL_MP4_I::Get_Default_Matrix(SKL_BYTE M[64], int What){ if (What<3) for(int i=0; i<64; ++i) M[i] = Dflt_Mtx[What][i]; else /*if (What==3)*/ for(int i=0; i<64; ++i) M[i] = 16; // Dflt_Inter_MPEG2}int SKL_MP4_I::Set_Matrix(int Intra, const SKL_BYTE *M){ SKL_BYTE * const Dst = Intra ? Intra_Matrix : Inter_Matrix; int Diff = 0; for(int i=0; i<64; ++i) { Diff |= (Dst[i] != M[i]); Dst[i] = M[i]; } if (Intra) { Custom_Intra = Diff; if (Diff) Quant_Ops.Init_Quantizer(Q_Intra, Intra_Matrix, Q_Scale_Maps[Quant_Type], 1); } else { Custom_Inter = Diff; if (Diff) Quant_Ops.Init_Quantizer(Q_Inter, Inter_Matrix, Q_Scale_Maps[Quant_Type], 0); } return Diff;}//////////////////////////////////////////////////////////// Frame memory allocationvoid SKL_MP4_I::Init_Pics(int W, int H, int Nb_pics, int Nb_maps){ int i; SKL_ASSERT(Nb_Pics<=MAX_PICS && Nb_Maps<=MAX_MAPS); const int w = (W+15)/16; const int h = (H+15)/16; if (w==MB_W && h==MB_H && Nb_Pics==Nb_pics && Nb_Maps==Nb_maps) return; Clear_Pics(); Width = W; Height = H; MB_W = w; MB_H = h; EMB_W = w+2*(1+MB_FENCE); EMB_H = h+2*(1+MB_FENCE); BpS = EMB_W*16; MV_Stride = 2*EMB_W; Nb_Pics = Nb_pics; Nb_Maps = Nb_maps; const int YUV_Size = EMB_H*8*BpS * 3; const int MV_Size = (EMB_W*EMB_H)*4 * sizeof(SKL_MV); const int Map_Size = (MB_W*MB_H)*sizeof(SKL_MP4_MAP); const int New_Size = YUV_Size * Nb_Pics + (Map_Size+MV_Size) * Nb_Maps + SKL_ALIGN; Pic_Base = (Mem==0) ? (SKL_BYTE*)malloc(New_Size) : (SKL_BYTE*)Mem->New(New_Size); if (Pic_Base==0) Skl_Throw( SKL_MEM_EXCEPTION("Pic_Base", New_Size) ); Pic_Size = New_Size; const int Edge_Offset = (16*BpS + 16)*(1+MB_FENCE); int Y_Off = Edge_Offset; int U_Off = (EMB_W*EMB_H)*16*16 + Edge_Offset/2; int V_Off = U_Off + EMB_W*8; SKL_BYTE *YUV_Base = (SKL_BYTE*)SKL_ALIGN_PTR(Pic_Base, SKL_ALIGN); SKL_BYTE *MV_Base = YUV_Base + Nb_Pics*YUV_Size; SKL_BYTE *Map_Base = MV_Base + Nb_Maps*MV_Size; const int MV_Offset = (2+MB_FENCE)*(1 + (EMB_W*2)) * sizeof(SKL_MV); MV_Base += MV_Offset; // + edge offset for(i=0; i<Nb_Pics; ++i)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -