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

📄 2pass.cpp.svn-base

📁 ffshow源码
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
	}	// Foxer: make sure overflow doesn't run away	if (overflow > bytes2 * config.twopass_max_overflow_improvement / 100)	{		bytes2 += (overflow <= bytes2) ? bytes2 * config.twopass_max_overflow_improvement / 100 :			overflow * config.twopass_max_overflow_improvement / 100;	}	else if (overflow < bytes2 * config.twopass_max_overflow_degradation / -100)	{		bytes2 += bytes2 * config.twopass_max_overflow_degradation / -100;	}	else	{		bytes2 += overflow;	}	if (bytes2 > twopass.max_framesize)	{		capped_to_max_framesize = 1;		bytes2 = twopass.max_framesize;	}	// make sure to not scale below the minimum framesize	if (twopass.nns1.quant & NNSTATS_KEYFRAME)	{		if (bytes2 < twopass.minisize)			bytes2 = twopass.minisize;	}	else if (twopass.nns1.dd_v & NNSTATS_BFRAME)	{		if (bytes2 < twopass.minbsize)			bytes2 = twopass.minbsize;	}	else	{		if (bytes2 < twopass.minpsize)			bytes2 = twopass.minpsize;	}	twopass.bytes1 = bytes1;	twopass.bytes2 = bytes2;	// very 'simple' quant<->filesize relationship	frame->quant = ((twopass.nns1.quant & ~NNSTATS_KEYFRAME) * bytes1) / bytes2;	if (frame->quant < 1)	{		frame->quant = 1;	}	else if (frame->quant > 31)	{		frame->quant = 31;	}	else if (!(frame->frametype==FRAME_TYPE::I))	{		// Foxer: aid desired quantizer precision by accumulating decision error		if (twopass.nns1.dd_v & NNSTATS_BFRAME)		{			bquant_error[frame->quant] += ((double)((twopass.nns1.quant & ~NNSTATS_KEYFRAME) * 				bytes1) / bytes2) - frame->quant;			if (bquant_error[frame->quant] >= 1.0)			{				bquant_error[frame->quant] -= 1.0;				++frame->quant;			}		}		else		{			pquant_error[frame->quant] += ((double)((twopass.nns1.quant & ~NNSTATS_KEYFRAME) * 				bytes1) / bytes2) - frame->quant;			if (pquant_error[frame->quant] >= 1.0)			{				pquant_error[frame->quant] -= 1.0;				++frame->quant;			}		}	}	// we're done with credits	if (codec_is_in_credits( framenum))	{		return ICERR_OK;	}	if ((frame->frametype==FRAME_TYPE::I))	{		if (frame->quant < config.q_i_min)		{			frame->quant = config.q_i_min;			DEBUG2P(_l("I-frame quantizer raised"));		}		if (frame->quant > config.q_i_max)		{			frame->quant = config.q_i_max;			DEBUG2P(_l("I-frame quantizer lowered"));		}	}	else	{		if (frame->quant > config.q_p_max)		{			frame->quant = config.q_p_max;		}		if (frame->quant < config.q_p_min)		{			frame->quant = config.q_p_min;		}		// subsequent frame quants can only be +- 2		if ((last_pquant || last_bquant) && capped_to_max_framesize == 0)		{			if (twopass.nns1.dd_v & NNSTATS_BFRAME)			{				// this bframe quantizer variation				// restriction needs to be redone.				if (frame->quant > last_bquant + 2)				{					frame->quant = last_bquant + 2;					DEBUG2P(_l("B-frame quantizer prevented from rising too steeply"));				}				if (frame->quant < last_bquant - 2)				{					frame->quant = last_bquant - 2;					DEBUG2P(_l("B-frame quantizer prevented from falling too steeply"));				}			}			else			{				if (frame->quant > last_pquant + 2)				{					frame->quant = last_pquant + 2;					DEBUG2P(_l("P-frame quantizer prevented from rising too steeply"));				}				if (frame->quant < last_pquant - 2)				{					frame->quant = last_pquant - 2;					DEBUG2P(_l("P-frame quantizer prevented from falling too steeply"));				}			}		}	}	if (capped_to_max_framesize == 0)	{		if (twopass.nns1.quant & NNSTATS_KEYFRAME)		{			last_bquant = frame->quant;			last_pquant = frame->quant;		}		else if (twopass.nns1.dd_v & NNSTATS_BFRAME)			last_bquant = frame->quant;		else			last_pquant = frame->quant;	}	return ICERR_OK;}int Txvid_2pass::codec_2pass_update(const TencFrameParams *frame){	int credits_pos, tempdiv;	char_t* frame_type;	if (framenum == 0)	{		total_size = 0;	}        if (statsWrite)        {        	NNSTATS nns1;		nns1.bytes = frame->length;	// total bytes		nns1.dd_v = 0;		nns1.dd_u = nns1.dd_y = 0;		nns1.dk_v = nns1.dk_u = nns1.dk_y = 0;		nns1.md_u = nns1.md_y = 0;		nns1.mk_u = nns1.mk_y = 0;		nns1.quant = frame->quant;				// 2 ugly fix for lumi masking in 1st pass returning new quant		nns1.lum_noise[0] = nns1.lum_noise[1] = 1;		frame_type=_l("inter");		if (frame->frametype ==FRAME_TYPE::I) {			nns1.quant |= NNSTATS_KEYFRAME;			frame_type=_l("intra");		}		else if (frame->frametype==FRAME_TYPE::B) {			nns1.dd_v |= NNSTATS_BFRAME;			frame_type=_l("bframe");		}		else if (frame->frametype==FRAME_TYPE::SKIP) {			nns1.dd_v |= NNSTATS_SKIPFRAME;			frame_type=_l("skiped");		}		else if (frame->frametype==FRAME_TYPE::PAD) {			nns1.dd_v |= NNSTATS_PADFRAME;			frame_type=_l("padded");		}		else if (frame->frametype==FRAME_TYPE::DELAY) {			nns1.dd_v |= NNSTATS_DELAYFRAME;			frame_type=_l("delayed");		}                if (frame->kblks+frame->mblks+frame->ublks==0)                 {		  nns1.kblk = 1;		  nns1.mblk = 1;		  nns1.ublk = 1;                 }                else                 {		  nns1.kblk = frame->kblks;		  nns1.mblk = frame->mblks;		  nns1.ublk = frame->ublks;                 }		total_size += frame->length;		DEBUG1ST(frame->length, (int)total_size/1024, frame_type, frame->quant, _l(""), 1, 1);		if (statsWrite->write(&nns1)!=sizeof(NNSTATS))		{			DEBUGERR(_l("stats1: WriteFile error"));			return ICERR_ERROR;			}        }		        if (config.mode==DLG_MODE_2PASS_2_INT || config.mode==DLG_MODE_2PASS_2_EXT)        {		credits_pos = codec_is_in_credits(framenum);		if (!(twopass.nns1.dd_v & NNSTATS_SKIPFRAME) &&			!(twopass.nns1.dd_v & NNSTATS_PADFRAME) &&			!(twopass.nns1.dd_v & NNSTATS_DELAYFRAME))		{			if (!credits_pos)			{				if ((twopass.nns1.quant & NNSTATS_KEYFRAME))				{					// calculate how much to distribute per frame in					// order to make up for this keyframe's overflow					twopass.overflow += twopass.KFoverflow;					twopass.KFoverflow = twopass.desired_bytes2 - frame->length;					tempdiv = (twopass.keyframe_locations[twopass.KF_idx] -						twopass.keyframe_locations[twopass.KF_idx - 1]);					if (tempdiv > 1)					{						// non-consecutive keyframes						twopass.KFoverflow_partial = twopass.KFoverflow / (tempdiv - 1);					}					else					{						// consecutive keyframes						twopass.overflow += twopass.KFoverflow;						twopass.KFoverflow = 0;						twopass.KFoverflow_partial = 0;					}					twopass.KF_idx++;				}				else				{					// distribute part of the keyframe overflow					twopass.overflow += twopass.desired_bytes2 - frame->length +						twopass.KFoverflow_partial;					twopass.KFoverflow -= twopass.KFoverflow_partial;				}			}			else			{				twopass.overflow += twopass.desired_bytes2 - frame->length;				// ugly fix for credits..				twopass.overflow += twopass.KFoverflow;				twopass.KFoverflow = 0;				twopass.KFoverflow_partial = 0;				// end of ugly fix.			}		}		frame_type=_l("inter");		if (frame->frametype==FRAME_TYPE::I) {			frame_type=_l("intra");		}		else if (twopass.nns1.dd_v & NNSTATS_BFRAME) {			frame_type=_l("bframe");		}		else if (twopass.nns1.dd_v & NNSTATS_SKIPFRAME) {			frame_type=_l("skipped");			//frame->quant = 2;			twopass.bytes1 = 1;			twopass.desired_bytes2 = 1;			//frame->length = 1;		}		else if (twopass.nns1.dd_v & NNSTATS_PADFRAME) {			frame_type=_l("padded");			//frame->quant = 2;			twopass.bytes1 = 7;			twopass.desired_bytes2 = 7;			//frame->length = 7;		}		else if (twopass.nns1.dd_v & NNSTATS_DELAYFRAME) {			frame_type=_l("delayed");			//frame->quant = 2;			twopass.bytes1 = 1;			twopass.desired_bytes2 = 1;			//frame->length = 1;		}		DEBUG2ND(frame->quant, _l(""), frame_type, twopass.bytes1, twopass.desired_bytes2, frame->length, twopass.overflow, credits_pos);	}	return ICERR_OK;}void Txvid_2pass::codec_2pass_finish(void){	twopass.nns_array_length = 0;	twopass.nns_array_pos = 0;}Txvid_2pass::Txvid_2pass(void){ statsRead=statsRead2=statsWrite=NULL; ownStatsRead=ownStatsRead2=ownStatsWrite=NULL;}Txvid_2pass::~Txvid_2pass(){ if (ownStatsRead ) delete ownStatsRead ; if (ownStatsRead2) delete ownStatsRead2; if (ownStatsWrite) delete ownStatsWrite;}//================================= T2passFirst ==================================T2passFirst::T2passFirst(const TcoSettings &Iconfig){ config=Iconfig; codec_2pass_init();}T2passFirst::~T2passFirst(){ codec_2pass_finish();}bool T2passFirst::update(const TencFrameParams &frame){ return codec_2pass_update(&frame)==ICERR_OK;}//================================= T2passSecond =================================T2passSecond::T2passSecond(IffdshowEnc *IdeciE,bool Iquiet):quiet(Iquiet),deciE(IdeciE),deci(IdeciE){ start();}T2passSecond::T2passSecond(IffdshowEnc *IdeciE,TxvidStats *IstatsRead,TxvidStats *IstatsRead2,TxvidStats *IstatsWrite,bool Iquiet):quiet(Iquiet),deciE(IdeciE),deci(IdeciE){ statsRead =IstatsRead; statsRead2=IstatsRead2; statsWrite=IstatsWrite; start();}T2passSecond::~T2passSecond(){ codec_2pass_finish();}void T2passSecond::start(void){ const TcoSettings *Iconfig;deciE->getCoSettingsPtr(&Iconfig); config=*Iconfig; twopass.max_framesize=int((double)config.twopass_max_bitrate/8.0/((double)deci->getParam2(IDFF_enc_fpsRate)/(double)deci->getParam2(IDFF_enc_fpsScale))); framenum=0; memset(quant_threshs,0,sizeof(quant_threshs));  codec_2pass_init();}void T2passSecond::DEBUG2P(const char_t*s){ if (!quiet) deci->dbgWrite(_l("%s"),s);}bool T2passSecond::getQuantSecond(TencFrameParams &params){ framenum=params.framenum; int ret=codec_2pass_get_quant(&params); return ret==ICERR_OK;}int T2passSecond::getQuantFirst(void){ return twopass.nns1.quant&NNSTATS_QUANTMASK;}unsigned int T2passSecond::getBytesFirst(void){ return twopass.bytes1;}void  T2passSecond::writeInfo(const TencFrameParams &params){ deci->dbgWrite(_l("2nd-pass: quant:%d %s %s stats1:%d scaled:%d actual:%d overflow:%d %s\n"),params.quant,encQuantTypes[params.quanttype],FRAME_TYPE::name(params.frametype),twopass.bytes1,twopass.bytes2,params.length,twopass.overflow,config.isInCredits(params.framenum)?_l("credits"):_l("movie"));}bool T2passSecond::update(const TencFrameParams &frame){ codec_2pass_update(&frame); return true;}int T2passSecond::codec_is_in_credits(int framenum){ return config.isInCredits(framenum);}

⌨️ 快捷键说明

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