⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 skl_mpg4_enc.cpp

📁 mpeg4编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
      else Reduced_VOP = -1;    }  }}void SKL_MP4_ENC_I::Setup_Frame_Params(SKL_MP4_FRAME *Frame){  int Param;    // we ask the analyzer for the final non-VOL params.     // It might have better hints than we do.  Get_Analyzer()->Get_Param( "quant", &Frame->Quant );  Get_Analyzer()->Get_Param( "fcode", &Frame->Fwd_Code );  if (Frame->Coding==B_VOP)    Get_Analyzer()->Get_Param( "fcode-bwd", &Frame->Bwd_Code );  if (Frame->Reduced_VOP>=0) Frame->Reduced_VOP = 0;  if (Frame->Coding != B_VOP && Frame->Coding != S_VOP) {    int Reduc;    if (Get_Analyzer()->Get_Param( "reduced-frame", &Reduc)) {      if (Reduc>1) Reduc = 1;      Frame->Reduced_VOP = Reduc;    }  }  if (Frame->Coding==P_VOP || Frame->Coding==S_VOP) {    if (!Get_Analyzer()->Get_Param( "rounding", &Frame->Rounding))      Frame->Rounding ^= 1;  }  else {    if (Frame->Coding==B_VOP)      Frame->Rounding = 0;  }  if (Frame->Coding==S_VOP) {    Get_Analyzer()->Get_Param( "gmc-mode", &Param );    if (Param>0) {      Frame->Coding = S_VOP;      Sprite_Mode   = SPRITE_GMC;      Get_Analyzer()->Get_Param( "gmc-pts", &Sprite_Nb_Pts);      const int (*Warps)[2] = (int (*)[2])Get_Analyzer()->Get_Param( "gmc-warp-pts" );      for(int n=0; n<Sprite_Nb_Pts; ++n) {        S_Warp_Pts[n][0] = Warps[n][0];        S_Warp_Pts[n][1] = Warps[n][1];      }    }    else {      Frame->Coding = P_VOP;      Sprite_Mode = SPRITE_NONE;    }  }  Get_Analyzer()->Get_Param( "inter-threshold", &_Inter_Coding_Threshold );    Get_Analyzer()->Get_Param( "use-trellis", &Param );  Set_Trellis_Usage(!!Param);  Cur->Coding = Frame->Coding;  /* TODO: DC_Thresh? Alt_Vert_Scan? ... */}//////////////////////////////////////////////////////////// Main entry point//////////////////////////////////////////////////////////int SKL_MP4_ENC_I::Encode(SKL_BYTE *Buf, int Max_Len){  SKL_ASSERT(Width!=0 && Height!=0 && Get_Analyzer()!=0);  if (Last==0) {  // no user input. Check if we have a pending B-VOP in store...    return 0;  }  SKL_MP4_FRAME *Frame = this;  Cur = Last;                       // get Input frame  Last = 0;                         // mark it consumed  Frame->Time = Cur->Time_Ticks;    // set time  Cur->Map = All_Maps[Cur_Map].Map; // assign analysis map  Cur->MV  = All_Maps[Cur_Map].MV;  // assign analysis MV map  if (++Cur_Map==Nb_Maps)    Cur_Map = 0;  Future->Map = 0;                  // sanity check  Future->MV = 0;                   // ""    // Analyze new frame -> decide: Coding, MB types, Quant, dQ, ...      // 1rst pass: Motion analysis  Frame->Coding = Get_Analyzer()->Analyze(this);  if (Frame->Coding==I_VOP && _Key_VOL_Headers)    _Need_VOL_Header = 1;  Setup_VOL_Params();  // might trigger a _Need_VOL_Header    // We, as encoder, have the final word about frame Coding type.  if (_Need_VOL_Header)  {      // it's not a real scene change. Just a checkpoint: we must      // insert an I-VOP after a VOL header) => Don't reset the MVs!      // They might be useful for the next frame analysis.    Frame->Coding = I_VOP;  }  if (Frame->Coding==B_VOP) {}  else if (Frame->Coding==S_VOP) {}    // 2nd pass for spatial analysis (dQ)  Get_Analyzer()->Analyze_dQ(this, Frame->Coding==B_VOP);    // Frame params are now ready => code bitstream syntax  Setup_Frame_Params(Frame);  Code_Frame(Buf, Max_Len, this);    // send some stats to the analyzer  Get_Analyzer()->Post_Coding_Update( this );  Frame_Number++;    // display debug infos  if (Debug_Level) {    if (Debug_Level==4) Dump_Map(Cur, 0);    else if (Debug_Level==5) Dump_Map(Cur, 1);    else if (Debug_Level==6) Dump_Map(Cur, 2);  }    // reorder frames if needed  int Ticks;    // save current time first, before swapping  Get_Analyzer()->Get_Param( "frame-ticks", &Ticks );  SKL_UINT64 Next_Time_Ticks = Cur->Time_Ticks + Ticks;  if (Frame->Coding!=B_VOP) {    Aux    = Past;    Past   = Cur;    Cur    = Future;    Future = Aux;    Aux    = Cur;    Time_Last_Coded = Past->Time_Ticks;    Time_Ref = Past->Time_Ticks / Time_Frequency;   // sync-point#if 0       // secure tickers every 65k-ticks, to avoid overflows    if (Time_Last_Coded>0x10000) {      Time_Ref -= 0x10000;      Time_Last_Coded -= 0x10000;      Next_Time_Ticks -= 0x10000 * Time_Frequency;    }#endif  }    // setup time of next-to-be-encoded frame, just in    // case the user forgets to (or doesn't care doing so).  Aux->Time_Ticks = Next_Time_Ticks;  Aux->Time = (double)(SKL_INT64)Next_Time_Ticks / (double)(SKL_INT64)Time_Frequency;  Aux->Map = 0; // sanity check  Aux->MV  = 0; // ""  Aux->Coding = -1; // sanity check  return Coded_Bits/8;}//////////////////////////////////////////////////////////// class SKL_MP4_ENC_I//////////////////////////////////////////////////////////SKL_MP4_ENC_I::SKL_MP4_ENC_I(SKL_MEM_I *Mem)  : SKL_MP4_I(Mem)  , SKL_MP4_ENC()  , _Dflt_Analyzer(Skl_MP4_Get_Default_Analyzer(Mem)){  _Buf_Size     = 0;  _Buf          = 0;  _Buf_Len      = 0;    _In_Pic = 0;  _Need_VOL_Header = 1;  _Key_VOL_Headers = 0;   _Emit_SEQ_Codes = 0;  _Analyzer = 0;  _Use_Trellis = -1;  Set_Trellis_Usage(1);  Init_VOL(0);  Set_Analyzer( _Dflt_Analyzer );  Clear_Aux();}SKL_MP4_ENC_I::~SKL_MP4_ENC_I(){  Clear_Aux();  Clear_Buf();  if (_Analyzer!=0) _Analyzer->Shut_Down();  _Analyzer = 0;  Skl_MP4_Destroy_Default_Analyzer( _Dflt_Analyzer );}SKL_MP4_ANALYZER *SKL_MP4_ENC_I::Set_Analyzer(SKL_MP4_ANALYZER *Anl){  SKL_MP4_ANALYZER *Previous = _Analyzer;  if (_Analyzer!=0) _Analyzer->Shut_Down();  _Analyzer = (Anl==0) ? _Dflt_Analyzer : Anl;  _Analyzer->Wake_Up(Previous);  return Previous;}SKL_MP4_ANALYZER *SKL_MP4_ENC_I::Get_Analyzer() const{  return _Analyzer;}void SKL_MP4_ENC_I::Set_Slicer(SKL_MP4_SLICER Slicer, SKL_ANY Slicer_Data) {  SKL_MP4_I::Set_Slicer(Slicer, Slicer_Data);}SKL_MEM_I *SKL_MP4_ENC_I::Set_Memory_Manager(SKL_MEM_I *Mem){  return SKL_MP4_I::Set_Memory_Manager(Mem);}void SKL_MP4_ENC_I::Set_Custom_Matrix(int Intra, const SKL_BYTE *M) {  if (Set_Matrix(Intra, M))    _Need_VOL_Header = 1;}int SKL_MP4_ENC_I::Ioctl(SKL_CST_STRING Param){  if (Param==0) return -1;  if (!strcmp(Param, "emit-key-headers")) {    _Key_VOL_Headers = 1;    return 1;  }  else if (!strcmp(Param, "no-emit-key-headers")) {    _Key_VOL_Headers = 0;    return 1;  }  else if (!strcmp(Param, "emit-sequence-codes")) {    _Emit_SEQ_Codes = 1;    return 1;  }  else if (!strcmp(Param, "no-emit-sequence-codes")) {    _Emit_SEQ_Codes = 0;    return 1;  }  return 0;}//////////////////////////////////////////////////////////void SKL_MP4_ENC_I::Alloc_Aux() { /* nothing more needed, for now */ }void SKL_MP4_ENC_I::Clear_Aux() { /* nothing more needed, for now */ }SKL_MP4_PIC *SKL_MP4_ENC_I::Prepare_For_Input(int W, int H){  if (W<=0 || W>2048 || H<=0 || H>2048)    return 0;  if (Width!=W || Height!=H)  {    Init_Pics(W, H, 3, 2);  // will store new W/H    Alloc_Aux();            // init our own rest    _Need_VOL_Header = 1;        }   // user input is always 'Aux'   // Time_Ticks should be ok from last encoding  Last = Aux;  return Last;}void SKL_MP4_ENC_I::Set_CPU( SKL_CPU_FEATURE Cpu ){  SKL_MP4_I::Set_CPU(Cpu);  Set_Trellis_Usage(_Use_Trellis);}void SKL_MP4_ENC_I::Set_Trellis_Usage(const int Do_It){  _Use_Trellis = Do_It;}//////////////////////////////////////////////////////////// Interface Wrappersvoid SKL_MP4_ENC_I::Set_Debug_Level(int Level) {  SKL_MP4_I::Set_Debug_Level( Level );}const SKL_MP4_PIC *SKL_MP4_ENC_I::Prepare_Next_Frame(int Width, int Height){  _In_Pic = Prepare_For_Input(Width, Height);  return _In_Pic;}const SKL_MP4_PIC *SKL_MP4_ENC_I::Get_Next_Frame() const{  return _In_Pic;}const SKL_MP4_PIC *SKL_MP4_ENC_I::Get_Last_Coded_Frame() const{  return Past;   // TODO: this is wrong for B-vop}void SKL_MP4_ENC_I::Get_All_Frames(SKL_MP4_PIC *Pic) const{  SKL_MP4_I::Get_All_Frames(Pic);}int SKL_MP4_ENC_I::Encode(){  size_t Needed_Size = (_In_Pic->Width*_In_Pic->Height)*2; // TODO: safety factor?  int Buf_Size_Max = 0;  if (Get_Analyzer()->Get_Param("buffer-size", &Buf_Size_Max))    if (Buf_Size_Max>0 && Needed_Size>(size_t)Buf_Size_Max)      Needed_Size = Buf_Size_Max;  if (Needed_Size<4096) Needed_Size = 4096;  Check_Buf_Size( Needed_Size );  _Buf_Len = Encode(_Buf, _Buf_Len);  return _Buf_Len;}int SKL_MP4_ENC_I::Finish_Encoding(){  // TODO: Check for a pending B-VOP...  // TODO: should we emit a SEQ_END code?    if (_Emit_SEQ_Codes) {    SKL_FBB Bits(_Buf);    Bits.Put_DWord(SEQ_END_CODE);    _Buf_Len = 4;    return 4;  }  return 0;}const SKL_BYTE *SKL_MP4_ENC_I::Get_Bits() const {  return _Buf;}int SKL_MP4_ENC_I::Get_Bits_Length() const {  return _Buf_Len;}void SKL_MP4_ENC_I::Check_Buf_Size(const size_t Needed_Size){  if (Needed_Size>_Buf_Size)  {    SKL_BYTE *New_Buf = (Mem!=0) ? (SKL_BYTE*)Mem->New( Needed_Size )                                 : (SKL_BYTE*)malloc( Needed_Size );    if (New_Buf==0)      Skl_Throw( SKL_MEM_EXCEPTION("Byte buffer", Needed_Size) );    if (_Buf_Len>0)      SKL_MEMCPY(New_Buf, _Buf, _Buf_Len);    Clear_Buf();    _Buf      = New_Buf;    _Buf_Size = Needed_Size;  }  else {    // TODO: shrink the _Buf from time to time?  }}void SKL_MP4_ENC_I::Clear_Buf() {  if (_Buf_Size>0) {    if (Mem) Mem->Delete( _Buf, _Buf_Size );    else free( _Buf );  }  _Buf_Size = 0;  _Buf = 0;  /* Don't touch _Len, here. We might just be swapping buffers.. */}//////////////////////////////////////////////////////////// SKL_MP4_ENC//////////////////////////////////////////////////////////SKL_MP4_ENC::SKL_MP4_ENC() {}SKL_MP4_ENC::~SKL_MP4_ENC() {}//////////////////////////////////////////////////////////// C factoryextern "C" {SKL_EXPORTSKL_MP4_ENC *Skl_MP4_New_Encoder() {   return (SKL_MP4_ENC*)::new SKL_MP4_ENC_I((SKL_MEM_I*)0);}SKL_EXPORTvoid Skl_MP4_Delete_Encoder(SKL_MP4_ENC *Enc) { ::delete (SKL_MP4_ENC_I*)Enc; }} // extern "C"//////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -