📄 tvideocodecxvid4.cpp
字号:
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 ¶ms)
{
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 + -