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

📄 tvideocodecxvid4.cpp

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 CPP
📖 第 1 页 / 共 2 页
字号:
     p1.rtStop=rtStop+(rtStop-rtStart);
    }
   p1.setRO(true);
   return sinkD->deliverDecodedSample(p1);
  }
}

//-------------------------- compression ----------------------------
LRESULT TvideoCodecXviD4::beginCompress(int cfgcomode,int csp,const Trect &r)
{
 xvid_enc_create_t cr;
 memset(&cr,0,sizeof(cr));
 cr.version=XVID_VERSION;
 std::vector<xvid_enc_plugin_t> plugins;
 xvid_enc_zone_t zoneQual;
 if (coCfg->numthreads>1 && sup_threads(coCfg->codecId))
 cr.num_threads=deci->getParam2(IDFF_numthreads);
 else
 cr.num_threads=0;
 switch (cfgcomode)
  {
   case ENC_MODE::UNKNOWN:
   case ENC_MODE::CBR:
   case ENC_MODE::VBR_QUAL:
    {
     xvid_plugin_single_t single;
     memset(&single,0,sizeof(single));
     single.version=XVID_VERSION;
     single.bitrate=coCfg->bitrate1000*1000;
     single.reaction_delay_factor=coCfg->xvid_rc_reaction_delay_factor;
     single.averaging_period=coCfg->xvid_rc_averaging_period;
     single.buffer=coCfg->xvid_rc_buffer;
     xvid_enc_plugin_t plg;
     plg.func=xvid_plugin_single;
     plg.param=&single;
     plugins.push_back(plg);
     if (cfgcomode==ENC_MODE::VBR_QUAL)
      {
       cr.zones=&zoneQual;
       cr.num_zones=1;
       zoneQual.frame=0;
       zoneQual.mode=XVID_ZONE_QUANT;
       zoneQual.increment=3200-31*coCfg->qual;
       zoneQual.base=100;
      }
     break;
    }
   case ENC_MODE::VBR_QUANT:
   case ENC_MODE::PASS2_1:
   case ENC_MODE::PASS2_2_EXT:
   case ENC_MODE::PASS2_2_INT:
    break;
   default:
    return ICERR_ERROR;
  }
 cr.width=r.dx;cr.height=r.dy;
 cr.fbase=deci->getParam2(IDFF_enc_fpsRate);cr.fincr=deci->getParam2(IDFF_enc_fpsScale);

 if (coCfg->isQuantControlActive())
  {
   cr.min_quant[0]=coCfg->limitq(coCfg->q_i_min);cr.max_quant[0]=coCfg->limitq(coCfg->q_i_max);
   cr.min_quant[1]=coCfg->limitq(coCfg->q_p_min);cr.max_quant[1]=coCfg->limitq(coCfg->q_p_max);
   cr.min_quant[2]=coCfg->limitq(coCfg->q_b_min);cr.max_quant[2]=coCfg->limitq(coCfg->q_b_max);
  }
 else
  {
   cr.min_quant[0]=cr.min_quant[1]=cr.min_quant[2]=coCfg->getMinMaxQuant().first ;
   cr.max_quant[0]=cr.max_quant[1]=cr.max_quant[2]=coCfg->getMinMaxQuant().second;
  }

 cr.max_key_interval=coCfg->max_key_interval;

 if (coCfg->isBframes)
  {
   cr.max_bframes=coCfg->max_b_frames;
   cr.bquant_ratio=coCfg->b_quant_factor;
   cr.bquant_offset=coCfg->b_quant_offset;
   if (coCfg->packedBitstream) cr.global|=XVID_GLOBAL_PACKED;
   if (coCfg->dx50bvop) cr.global|=XVID_GLOBAL_CLOSED_GOP;
  }

 psnr=deci->getParam2(IDFF_enc_psnr);
 if (psnr) cr.global|=XVID_GLOBAL_EXTRASTATS_ENABLE;

 if (coCfg->xvid_lum_masking)
  {
   xvid_enc_plugin_t plg;
   plg.func=xvid_plugin_lumimasking;
   plg.param=NULL;
   plugins.push_back(plg);
  }

 cr.plugins=&plugins[0];
 cr.num_plugins=(int)plugins.size();

 int res=xvid_encore(NULL,XVID_ENC_CREATE,&cr,NULL);
 switch (res)
  {
   case XVID_ERR_FAIL:return ICERR_ERROR;
   case XVID_ERR_MEMORY:return ICERR_MEMORY;
   case XVID_ERR_FORMAT:return ICERR_BADFORMAT;
  }
 enchandle=cr.handle;

 memset(frame,0,sizeof(*frame));
 frame->version=XVID_VERSION;

 frame->vop_flags|=XVID_VOP_HALFPEL;
 frame->vop_flags|=XVID_VOP_HQACPRED;

 if (coCfg->trellisquant) frame->vop_flags|=XVID_VOP_TRELLISQUANT;

 if (coCfg->me_gmc) frame->vol_flags|=XVID_VOL_GMC;
 if (coCfg->interlacing)
  {
   frame->vol_flags|=XVID_VOL_INTERLACING;
   if (coCfg->interlacing_tff)
    frame->vop_flags|=XVID_VOP_TOPFIELDFIRST;
  }
 if (coCfg->xvid_chromaopt && !coCfg->gray) frame->vop_flags|=XVID_VOP_CHROMAOPT;

 if (coCfg->is_xvid_me_custom)
  {
   frame->motion=me_(coCfg->xvid_me_custom);
   if (coCfg->xvid_me_inter4v) frame->vop_flags|=XVID_VOP_INTER4V;
  }
 else
  {
   frame->motion=me_(meXviDpresets[coCfg->xvid_motion_search].preset);
   if (coCfg->xvid_motion_search>4) frame->vop_flags|=XVID_VOP_INTER4V;
  }

 if (coCfg->is_xvid_vhq_custom)
  {
   frame->motion|=me_hq(coCfg->xvid_vhq_custom);
   if (coCfg->xvid_vhq_modedecisionbits) frame->vop_flags|=XVID_VOP_MODEDECISION_RD;
  }
 else
  {
   frame->motion|=me_hq(vhqXviDpresets[coCfg->xvid_vhq].preset);
   if (coCfg->xvid_vhq>0) frame->vop_flags|=XVID_VOP_MODEDECISION_RD;
  }

 if (coCfg->me_qpel)
  {
   frame->vol_flags|=XVID_VOL_QUARTERPEL;
   frame->motion|=XVID_ME_QUARTERPELREFINE16|XVID_ME_QUARTERPELREFINE8;
  }
 if (coCfg->me_gmc)
  {
   frame->vol_flags|=XVID_VOL_GMC;
   frame->motion|=XVID_ME_GME_REFINE;
  }
 if (coCfg->me_cmp_chroma && !coCfg->gray) frame->motion|=XVID_ME_CHROMA_PVOP|XVID_ME_CHROMA_BVOP;

 frame->par=XVID_PAR_EXT;
 Rational sar=coCfg->sar(r.dx,r.dy).reduce(255);
 frame->par_width=sar.num;frame->par_height=sar.den;

 if (psnr) frame->vol_flags|=XVID_VOL_EXTRASTATS;

 frame->input.csp=XVID4_CSP_PLANAR;

 if (coCfg->quant_type==QUANT::MPEG)
  frame->quant_intra_matrix=frame->quant_inter_matrix=NULL;
 else if (coCfg->quant_type==QUANT::CUSTOM)
  {
   frame->quant_intra_matrix=(unsigned char*)&coCfg->qmatrix_intra_custom0;
   frame->quant_inter_matrix=(unsigned char*)&coCfg->qmatrix_inter_custom0;
  }

 return ICERR_OK;
}

HRESULT TvideoCodecXviD4::compress(const TffPict &srcpict,TencFrameParams &params)
{
 if (!srcpict.data[0])
  {
   frame->input.csp=XVID4_CSP_NULL;
   frame->input.plane[0]=frame->input.plane[1]=frame->input.plane[2]=NULL;
  }
 else
  {
   frame->input.plane[0]=srcpict.data[0];frame->input.plane[1]=srcpict.data[1];frame->input.plane[2]=srcpict.data[2];
   frame->input.stride[0]=(int)srcpict.stride[0];frame->input.stride[1]=(int)srcpict.stride[1];frame->input.stride[2]=(int)srcpict.stride[2];
  }

 if (params.quant==-1)
  frame->quant=0;
 else
  frame->quant=coCfg->limitq(params.quant);

 if (params.quanttype==QUANT::MPEG || params.quanttype==QUANT::CUSTOM)
  frame->vol_flags|=XVID_VOL_MPEGQUANT;
 else
  frame->vol_flags&=~XVID_VOL_MPEGQUANT;

 switch (params.frametype)
  {
   case FRAME_TYPE::I:frame->type=XVID_TYPE_IVOP;break;
   case FRAME_TYPE::P:frame->type=XVID_TYPE_PVOP;break;
   case FRAME_TYPE::B:frame->type=XVID_TYPE_BVOP;break;
   //case FRAME::SKIP:frame->type=XVID_TYPE_NOTHING;break;
   //case FRAME::PAD:frame->type=XVID_TYPE_;break;
   case FRAME_TYPE::DELAY:frame->type=XVID_TYPE_NOTHING;break;
   default:frame->type=XVID_TYPE_AUTO;
  }

 if (params.gray)
  frame->vop_flags|=XVID_VOP_GREYSCALE;
 else
  frame->vop_flags&=~XVID_VOP_GREYSCALE;

 HRESULT hr=S_OK;
again:
 TmediaSample sample;
 if (FAILED(hr=sinkE->getDstBuffer(&sample,srcpict)))
  return hr;
 frame->bitstream=sample;frame->length=sample.size();

 xvid_enc_stats_t stats;
 memset(&stats,0,sizeof(stats));
 stats.version=XVID_VERSION;
 int length=xvid_encore(enchandle,XVID_ENC_ENCODE,frame,&stats);
 if ((length==0 || length==XVID_ERR_END) && !srcpict.data[0])
  return S_OK;
 else if (length<0)
  return sinkE->deliverError();

 params.quant=stats.quant;
 params.keyframe=frame->out_flags&XVID_KEYFRAME?true:false;
 switch (stats.type)
  {
   case XVID_TYPE_PVOP:params.frametype=FRAME_TYPE::P;break;
   case XVID_TYPE_IVOP:params.frametype=FRAME_TYPE::I;break;
   case XVID_TYPE_BVOP:params.frametype=FRAME_TYPE::B;break;
   case XVID_TYPE_NOTHING:params.frametype=FRAME_TYPE::DELAY;break;
   default:params.frametype=FRAME_TYPE::UNKNOWN;break;
  }

 params.kblks=stats.kblks;
 params.mblks=stats.mblks;
 params.ublks=stats.ublks;

 if (length==0)
  {
   frame->length=1;
   *(uint8_t*)frame->bitstream=0x7f;
  }

 if (psnr)
  {
   params.psnrY=stats.sse_y;
   params.psnrU=stats.sse_u;
   params.psnrV=stats.sse_v;
  }
 params.length=length;
 if (FAILED(hr=sinkE->deliverEncodedSample(sample,params)))
  return hr;
 if (!srcpict.data[0])
  goto again;
 return hr;
}
void TvideoCodecXviD4::end(void)
{
 if (enchandle) xvid_encore(enchandle,XVID_ENC_DESTROY,NULL,NULL);enchandle=NULL;
 if (dechandle) xvid_decore(dechandle,XVID_DEC_DESTROY,NULL,NULL);dechandle=NULL;
 pictbuf.clear();
 if (extradata) delete extradata;extradata=NULL;
}

⌨️ 快捷键说明

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