?? skl_mpg4_enc.cpp
字號:
SKL_ASSERT(Bits->Is_Flushed() && _Need_VOL_Header!=0); Bits->Put_DWord(FIRST_CODE|0x00); // VO start: start + id[0x00..0x1f] Bits->Put_DWord(VOL_CODE |VOL_Id); // VOL start: start code + id[0x20..0x2f] Bits->Put_Bits(0, 1); // random access Bits->Put_Bits(1, 8); // VO type indication (1=Simple Object) Bits->Put_Bits(1, 1); // obj-layer identified. Bits->Put_Bits(Verid, 4); // version id Bits->Put_Bits(1, 3); // priority Bits->Put_Bits(1, 4); // aspect-ratio = 1 if (!Low_Delay) { // control params? Bits->Put_Bits(1, 1); Bits->Put_Bits(1, 2); // Chroma format: 420 Bits->Put_Bits(Low_Delay, 1); // low delay. '1' means: no B-VOP in VOP Bits->Put_Bits(0, 1); // vbv param -skip- } else Bits->Put_Bits(0, 1); // -skip- Bits->Put_Bits(0, 2); // VOL shape = rect. Bits->Put_Bits(1, 1); // marker bit Bits->Put_Bits(Time_Frequency, 16); // time increment Bits->Put_Bits(1, 1); // marker bit if (Ticks_Per_VOP) { Bits->Put_Bits(1, 1); // fixed rate = yes Bits->Put_Bits(Ticks_Per_VOP, Ticks_Bits); } else Bits->Put_Bits(0, 1); // fixed rate = no Bits->Put_Bits(1, 1); // marker bit Bits->Put_Bits(Width, 13); // Width Bits->Put_Bits(1, 1); // marker bit Bits->Put_Bits(Height, 13); // Height Bits->Put_Bits(1, 1); // marker bit Bits->Put_Bits(!!Interlace, 1); // interlacing (impl note:Interlace=[0..6]) Bits->Put_Bits(1, 1); // overlapped motion comp. Bits->Put_Bits(Sprite_Mode, Verid==1 ? 1 : 2); // sprite enable if (Sprite_Mode>SPRITE_NONE) { SKL_ASSERT(Sprite_Mode!=SPRITE_STATIC); // not supported. Only GMC is. Bits->Put_Bits(Sprite_Nb_Pts, 6); Bits->Put_Bits(Sprite_Accuracy, 2); Bits->Put_Bits(Sprite_Brightness, 1); } if (Shape!=0 && Verid>1) Bits->Put_Bits(1,1); // sadct disable Bits->Put_Bits(Not_8b, 1); // not 8 bit if (Not_8b) { Bits->Put_Bits(Quant_Prec, 4); // quant prec Bits->Put_Bits(Bpp, 4); // bits per pixel } Bits->Put_Bits(Get_Quant_Type(), 1); // quant type if (Get_Quant_Type()==1) { // MPEG4 custom matrix Bits->Put_Bits(Custom_Intra, 1); // intra matrix if (Custom_Intra) Write_Matrix(Bits, Intra_Matrix); Bits->Put_Bits(Custom_Inter, 1); // inter matrix if (Custom_Inter) Write_Matrix(Bits, Inter_Matrix); } if (Verid!=1) Bits->Put_Bits(Quarter, 1); // QPel Bits->Put_Bits(1, 1); // complexity est. Bits->Put_Bits(!Resync, 1); // resync marker disable Bits->Put_Bits(Data_Partitioned, 1); // partitioned if (Data_Partitioned) Bits->Put_Bits(Rev_VLC, 1); // reversible vlc if (Verid!=1) { Bits->Put_Bits(0, 1); // new pred Bits->Put_Bits((Reduced_VOP>=0), 1); // reduced VOP } Bits->Put_Bits(0, 1); // scalability Stuffed_Align(Bits); if (Debug_Level==3) Print_Infos();} // section 6.2.5void SKL_MP4_ENC_I::Write_VOP_Header(SKL_FBB * const Bits, const SKL_MP4_FRAME *VOP) const{ SKL_ASSERT(Bits->Is_Flushed()); if (VOP->Frame_Number==0) Write_User_Data(Bits, 1+strlen(ID_STRING), (const SKL_BYTE *)ID_STRING); Bits->Put_DWord(VOP_CODE); // 32b marker Bits->Put_Bits(VOP->Coding, 2); // Coding type SKL_INT64 Elapsed = VOP->Time - Time_Ref*Time_Frequency; SKL_INT64 Seconds = Elapsed / Time_Frequency; if (Elapsed<0) Elapsed = 0; // hoho, wrong time stamp, it seems... else Elapsed -= Seconds * Time_Frequency;// printf( "Ref:%lld Last_Coded:%lld Time:%lld Elapsed:%d Seconds:%d\n",// Time_Ref, Time_Last_Coded, VOP->Time, Elapsed, Seconds );// printf( "Tick bits:%d, Time_Freq:%d\n", Ticks_Bits, Time_Frequency); while(Seconds-->0) Bits->Put_Bits(1, 1); // seconds elapsed Bits->Put_Bits(0, 1); Bits->Put_Bits(1, 1); // marker bit Bits->Put_Bits((SKL_UINT32)Elapsed, Ticks_Bits); // time ticks increment Bits->Put_Bits(1, 1); // marker bit Bits->Put_Bits(1, 1); // coded if (VOP->Coding==P_VOP || VOP->Coding==S_VOP) Bits->Put_Bits(VOP->Rounding, 1); // rounding type if ( VOP->Reduced_VOP>=0 && VOP->Coding!=B_VOP ) Bits->Put_Bits(VOP->Reduced_VOP>0, 1); Bits->Put_Bits(VOP->DC_Thresh, 3); // intra dc vlc thresh. if (Interlace) { // interlacing mode Bits->Put_Bits(!!VOP->Top_Field_First, 1); // display top field first Bits->Put_Bits(!!VOP->Alt_Vert_Scan, 1); // alt. vert. scan } if (VOP->Coding==S_VOP && VOP->Sprite_Nb_Pts>0) { Write_Sprite_Trajectory(Bits, VOP->S_Warp_Pts, VOP->Sprite_Nb_Pts); SKL_ASSERT(Sprite_Brightness==0); // no brightness change supported } Bits->Put_Bits(VOP->Quant, Quant_Prec); // global frame quantizer if (VOP->Coding!=I_VOP) Bits->Put_Bits(VOP->Fwd_Code, 3); // fcode if (VOP->Coding==B_VOP) Bits->Put_Bits(VOP->Bwd_Code, 3); // bcode}//////////////////////////////////////////////////////////// VOP Codingvoid SKL_MP4_ENC_I::Write_I_VOP(SKL_FBB * const Bits){ SKL_INT16 Base[12*64+SKL_ALIGN]; SKL_INT16 * const In = (SKL_INT16*)SKL_ALIGN_PTR(Base, SKL_ALIGN); SKL_MB_ENC MB(this); while(MB.y<MB_H) { MB.Init_Scanline(this, 0); while(MB.x<MB_W) { MB.MB_Type = SKL_MB_INTRA; // force INTRA type MB.Set_Final_Params(); MB.Decimate_Intra(In); MB.Encode_Intra(Bits, In, 1); MB++; } if (Debug_Level==2) Dump_Line(0, &MB); if (Slicer) Slicer(Cur, MB.y*16, 16, Slicer_Data); MB.y++; } Texture_Bits = MB.Get_Texture_Bits(); MV_Bits = MB.Get_MV_Bits();}void SKL_MP4_ENC_I::Write_P_VOP(SKL_FBB * const Bits){ SKL_INT16 Base[12*64+SKL_ALIGN]; SKL_INT16 * const In = (SKL_INT16*)SKL_ALIGN_PTR(Base, SKL_ALIGN); SKL_MB_ENC MB(this); while(MB.y<MB_H) { MB.Init_Scanline(this, 0); while(MB.x<MB_W) { MB.Set_Type(); if (MB.MB_Type==SKL_MB_INTRA) MB.Decimate_Intra(In); else MB.Decimate_Inter(In); if (MB.MB_Type==SKL_MB_SKIPPED) { Bits->Put_Bits( 1, 1 ); // not_coded MB.Set_Not_Intra(); } else { Bits->Put_Bits( 0, 1 ); // coded if (MB.MB_Type>=SKL_MB_INTRA) MB.Encode_Intra(Bits, In, 0); else MB.Encode_Inter(Bits, In, Fwd_Code); } MB.Store_Map_Infos(); MB++; } if (Debug_Level==2) Dump_Line(0, &MB); if (Slicer) Slicer(Cur, MB.y*16, 16, Slicer_Data); MB.y++; } Texture_Bits = MB.Get_Texture_Bits(); MV_Bits = MB.Get_MV_Bits(); if (Debug_Level==1) Dump_MVs(Cur, 2); // will trash the encoded frame}void SKL_MP4_ENC_I::Write_S_VOP(SKL_FBB * const Bits){ SKL_INT16 Base[12*64+SKL_ALIGN]; SKL_INT16 * const In = (SKL_INT16*)SKL_ALIGN_PTR(Base, SKL_ALIGN); SKL_ASSERT(Sprite_Nb_Pts>0); // otherwise, it should be a P-VOP SKL_ASSERT(Sprite_Mode==SPRITE_GMC && Sprite_Brightness==0); GMC_Ops.Setup(Width, Height, S_Warp_Pts, Sprite_Nb_Pts, Sprite_Accuracy); SKL_MB_ENC MB(this); while(MB.y<MB_H) { MB.Init_Scanline(this, 0); while(MB.x<MB_W) { MB.Set_Type(); SKL_ASSERT(MB.MB_Type!=SKL_MB_SKIPPED); if (MB.MB_Type==SKL_MB_INTRA) MB.Decimate_Intra(In); else if (MB.MC_Sel) MB.Decimate_Inter_GMC(In); else MB.Decimate_Inter(In); if (MB.MB_Type==SKL_MB_SKIPPED) { Bits->Put_Bits( 1, 1 ); // 'GMC' not_coded (but predicted...) MB.MB_Type = SKL_MB_INTER; MB.Set_Not_Intra(); } else { Bits->Put_Bits( 0, 1 ); // coded if (MB.MB_Type>=SKL_MB_INTRA) MB.Encode_Intra(Bits, In, 0); else MB.Encode_Inter(Bits, In, Fwd_Code); } MB.Store_Map_Infos(); MB++; } if (Debug_Level==2) Dump_Line(0, &MB); if (Slicer) Slicer(Cur, MB.y*16, 16, Slicer_Data); MB.y++; } Texture_Bits = MB.Get_Texture_Bits(); MV_Bits = MB.Get_MV_Bits(); if (Debug_Level==1) Dump_MVs(Cur, 2); // will trash the encoded frame}void SKL_MP4_ENC_I::Write_B_VOP(SKL_FBB * const Bits){ SKL_INT16 Base[6*64+6*64+SKL_ALIGN]; SKL_INT16 * const In = (SKL_INT16*)SKL_ALIGN_PTR(Base, SKL_ALIGN); if (Time_TFrame==0) // First B-VOP. => store Tframe of section 7.7.2.2 Time_TFrame = Cur->Time_Ticks - Time_Last_Coded; SKL_MB_ENC MB(this); while(MB.y<MB_H) { MB.Init_Scanline(this, 0); while(MB.x<MB_W) { MB.Set_Type(); if (MB.MB_Type==SKL_MB_INTRA) { // Oops!! No INTRA in B-VOP!!! fprintf(stderr, "INTRA requested in B-VOP!!\n"); } MB.Decimate_Inter(In); if (MB.MB_Type==SKL_MB_SKIPPED) { Bits->Put_Bits( 1, 1 ); // not_coded MB.Store_Zero_MV(); MB.Set_Not_Intra(); } else { Bits->Put_Bits( 0, 1 ); // coded MB.Encode_Inter_B(Bits, In, Fwd_Code, Bwd_Code); } MB.Store_Map_Infos(); MB++; } if (Debug_Level==2) Dump_Line(0, &MB); if (Slicer) Slicer(Cur, MB.y*16, 16, Slicer_Data); MB.y++; } Texture_Bits = MB.Get_Texture_Bits(); MV_Bits = MB.Get_MV_Bits(); if (Debug_Level==1) Dump_MVs(Cur, 2); // will trash frame}void SKL_MP4_ENC_I::Code_Frame(SKL_BYTE * const Buf, int Max_Len, const SKL_MP4_FRAME * const Frame){ // Codes 'Cur' frame into bitstream SKL_FBB Bits(Buf); if (_Need_VOL_Header) { if (_Emit_SEQ_Codes==1) { Bits.Put_DWord(SEQ_START_CODE); Bits.Put_Bits( 0x02, 8 ); // Simple Profile, Level 2 Bits.Flush_Write(); _Emit_SEQ_Codes = 2; } Write_VOL_Header(&Bits); _Need_VOL_Header = 0; } Write_VOP_Header(&Bits, Frame); Set_Rounding(); Cur->Coding = Frame->Coding; if (Slicer) Slicer(Cur, 0, 0, Slicer_Data); // "start of scan" call if (Frame->Coding==I_VOP) { if (Reduced_VOP<1) Write_I_VOP(&Bits); else Write_Reduced_I_VOP(&Bits); } else if (Frame->Coding==B_VOP) Write_B_VOP(&Bits); else { /* P/S-VOP */ if (Reduced_VOP<1) { if (Frame->Coding==P_VOP) Write_P_VOP(&Bits); else Write_S_VOP(&Bits); } else Write_Reduced_P_VOP(&Bits); } Make_Edges_Enc(Cur); // replicate edges of *decimated* frame Switch_Off(); if (Slicer) Slicer(Cur, Cur->Height, 0, Slicer_Data); // "end of scan" call Stuffed_Align(&Bits); Coded_Bits = 8*(Bits.Write_Pos() - Buf); // done coding.}//////////////////////////////////////////////////////////// Input analysis and frame coding preparation//////////////////////////////////////////////////////////void SKL_MP4_ENC_I::Setup_VOL_Params(){ int IParam; if (Get_Analyzer()->Get_Param( "bframe", &IParam )) if (Low_Delay!=(!IParam)) { _Need_VOL_Header = 1; Low_Delay = (!IParam); } { int Mode, Acc, Nb; if (Get_Analyzer()->Get_Param( "gmc-mode", &Mode ) && Get_Analyzer()->Get_Param( "gmc-pts", &Nb ) && Get_Analyzer()->Get_Param( "gmc-accuracy", &Acc ) ) { Mode = (Mode>=0) ? SPRITE_GMC : SPRITE_NONE; if (Frame_Number==0 || Sprite_Mode!=Mode) _Need_VOL_Header = 1; Sprite_Mode = Mode; if (Mode==SPRITE_GMC && (Sprite_Nb_Pts!=Nb || Sprite_Accuracy!=Acc)) { _Need_VOL_Header = 1; Sprite_Brightness = 0; Sprite_Accuracy = Acc; Sprite_Nb_Pts = Nb; } } } if (Get_Analyzer()->Get_Param( "subpixel", &IParam )) { int Sub = (IParam==2); if (Quarter!=Sub) { _Need_VOL_Header = 1; Quarter = Sub; } } if (Get_Analyzer()->Get_Param( "quant-type", &IParam )) if (Get_Quant_Type()!=IParam) { _Need_VOL_Header = 1; Set_Quant_Type( IParam ); } int Intl = 0; if (Get_Analyzer()->Get_Param( "interlace-dct", &IParam )) Intl |= IParam; // bits 0,1 if (Get_Analyzer()->Get_Param( "interlace-field", &IParam )) Intl |= (IParam<<2); // bits 2,3 if (Interlace!=Intl) { _Need_VOL_Header = 1; Interlace = Intl; } if (Get_Analyzer()->Get_Param( "frequency", &IParam )) if (Time_Frequency!=IParam) { _Need_VOL_Header = 1; Set_Time_Frequency( IParam ); } if (Get_Analyzer()->Get_Param( "reduced-frame", &IParam )) { if ((Reduced_VOP>=0)!=(IParam>=0)) { _Need_VOL_Header = 1; if (IParam>=0) Reduced_VOP = 0;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -