Beispiel #1
0
func (this *TEncRCPic) getLCUEstQP(lambda float64, clipPicQP int) int {
	LCUIdx := int(this.getLCUCoded())
	estQP := int(4.2005*math.Log(lambda) + 13.7122 + 0.5)

	//for Lambda clip, LCU level clip
	clipNeighbourQP := g_RCInvalidQPValue
	//#if L0033_RC_BUGFIX
	for i := LCUIdx - 1; i >= 0; i-- {
		//#else
		//  for  i:=LCUIdx; i>=0; i-- {
		//#endif
		if (this.getLCU(i)).m_QP > g_RCInvalidQPValue {
			clipNeighbourQP = this.getLCU(i).m_QP
			break
		}
	}

	if clipNeighbourQP > g_RCInvalidQPValue {
		estQP = TLibCommon.CLIP3(clipNeighbourQP-1, clipNeighbourQP+1, estQP).(int)
	}

	estQP = TLibCommon.CLIP3(clipPicQP-2, clipPicQP+2, estQP).(int)

	return estQP
}
Beispiel #2
0
func (this *TEncRCPic) estimatePicQP(lambda float64, listPreviousPictures *list.List) int {
	QP := int(4.2005*math.Log(lambda) + 13.7122 + 0.5)

	lastLevelQP := g_RCInvalidQPValue
	lastPicQP := g_RCInvalidQPValue
	lastValidQP := g_RCInvalidQPValue
	//list<TEncRCPic*>::iterator it;
	for it := listPreviousPictures.Front(); it != nil; it = it.Next() {
		v := it.Value.(*TEncRCPic)
		if v.getFrameLevel() == this.m_frameLevel {
			lastLevelQP = v.getPicActualQP()
		}
		lastPicQP = v.getPicActualQP()
		if lastPicQP > g_RCInvalidQPValue {
			lastValidQP = lastPicQP
		}
	}

	if lastLevelQP > g_RCInvalidQPValue {
		QP = TLibCommon.CLIP3(lastLevelQP-3, lastLevelQP+3, QP).(int)
	}

	if lastPicQP > g_RCInvalidQPValue {
		QP = TLibCommon.CLIP3(lastPicQP-10, lastPicQP+10, QP).(int)
	} else if lastValidQP > g_RCInvalidQPValue {
		QP = TLibCommon.CLIP3(lastValidQP-10, lastValidQP+10, QP).(int)
	}

	return QP
}
Beispiel #3
0
func (this *TEncRCPic) getLCUEstLambda(bpp float64) float64 {
	LCUIdx := this.getLCUCoded()
	var alpha, beta float64
	if this.m_encRCSeq.getUseLCUSeparateModel() {
		alpha = this.m_encRCSeq.getLCUPara2(this.m_frameLevel, LCUIdx).m_alpha
		beta = this.m_encRCSeq.getLCUPara2(this.m_frameLevel, LCUIdx).m_beta
	} else {
		alpha = this.m_encRCSeq.getPicPara1(this.m_frameLevel).m_alpha
		beta = this.m_encRCSeq.getPicPara1(this.m_frameLevel).m_beta
	}

	estLambda := alpha * math.Pow(bpp, beta)
	//for Lambda clip, picture level clip
	clipPicLambda := this.m_estPicLambda

	//for Lambda clip, LCU level clip
	clipNeighbourLambda := float64(-1.0)
	for i := LCUIdx - 1; i >= 0; i-- {
		if this.m_LCUs[i].m_lambda > 0 {
			clipNeighbourLambda = this.m_LCUs[i].m_lambda
			break
		}
	}

	if clipNeighbourLambda > 0.0 {
		estLambda = TLibCommon.CLIP3(clipNeighbourLambda*math.Pow(2.0, -1.0/3.0), clipNeighbourLambda*math.Pow(2.0, 1.0/3.0), estLambda).(float64)
	}

	if clipPicLambda > 0.0 {
		estLambda = TLibCommon.CLIP3(clipPicLambda*math.Pow(2.0, -2.0/3.0), clipPicLambda*math.Pow(2.0, 2.0/3.0), estLambda).(float64)
	} else {
		estLambda = TLibCommon.CLIP3(10.0, 1000.0, estLambda).(float64)
	}

	if estLambda < 0.1 {
		estLambda = 0.1
	}

	return estLambda
}
Beispiel #4
0
func (this *TEncRCPic) updateAfterLCU(LCUIdx, bits, QP int, lambda float64, updateLCUParameter bool) {
	this.m_LCUs[LCUIdx].m_actualBits = bits
	this.m_LCUs[LCUIdx].m_QP = QP
	this.m_LCUs[LCUIdx].m_lambda = lambda

	this.m_LCULeft--
	this.m_bitsLeft -= bits
	this.m_pixelsLeft -= this.m_LCUs[LCUIdx].m_numberOfPixel

	if !updateLCUParameter {
		return
	}

	if !this.m_encRCSeq.getUseLCUSeparateModel() {
		return
	}

	alpha := this.m_encRCSeq.getLCUPara2(this.m_frameLevel, LCUIdx).m_alpha
	beta := this.m_encRCSeq.getLCUPara2(this.m_frameLevel, LCUIdx).m_beta

	LCUActualBits := this.m_LCUs[LCUIdx].m_actualBits
	LCUTotalPixels := this.m_LCUs[LCUIdx].m_numberOfPixel
	bpp := float64(LCUActualBits) / float64(LCUTotalPixels)
	calLambda := alpha * math.Pow(bpp, beta)
	inputLambda := this.m_LCUs[LCUIdx].m_lambda

	if inputLambda < 0.01 || calLambda < 0.01 || bpp < 0.0001 {
		alpha *= (1.0 - this.m_encRCSeq.getAlphaUpdate()/2.0)
		beta *= (1.0 - this.m_encRCSeq.getBetaUpdate()/2.0)

		alpha = TLibCommon.CLIP3(0.05, 20.0, alpha).(float64)
		beta = TLibCommon.CLIP3(-3.0, -0.1, beta).(float64)

		var rcPara TRCParameter
		rcPara.m_alpha = alpha
		rcPara.m_beta = beta
		this.m_encRCSeq.setLCUPara3(this.m_frameLevel, LCUIdx, rcPara)

		return
	}

	calLambda = TLibCommon.CLIP3(inputLambda/10.0, inputLambda*10.0, calLambda).(float64)
	alpha += this.m_encRCSeq.getAlphaUpdate() * (math.Log(inputLambda) - math.Log(calLambda)) * alpha
	lnbpp := math.Log(bpp)
	lnbpp = TLibCommon.CLIP3(-5.0, 1.0, lnbpp).(float64)
	beta += this.m_encRCSeq.getBetaUpdate() * (math.Log(inputLambda) - math.Log(calLambda)) * lnbpp

	alpha = TLibCommon.CLIP3(0.05, 20.0, alpha).(float64)
	beta = TLibCommon.CLIP3(-3.0, -0.1, beta).(float64)
	var rcPara TRCParameter
	rcPara.m_alpha = alpha
	rcPara.m_beta = beta
	this.m_encRCSeq.setLCUPara3(this.m_frameLevel, LCUIdx, rcPara)
}
Beispiel #5
0
func (this *TEncRCPic) updateAfterPicture(actualHeaderBits, actualTotalBits int, averageQP, averageLambda, effectivePercentage float64) {
	this.m_picActualHeaderBits = actualHeaderBits
	this.m_picActualBits = actualTotalBits
	if averageQP > 0.0 {
		this.m_picQP = int(averageQP + 0.5)
	} else {
		this.m_picQP = g_RCInvalidQPValue
	}
	this.m_picLambda = averageLambda
	for i := 0; i < this.m_numberOfLCU; i++ {
		this.m_totalMAD += this.m_LCUs[i].m_MAD
	}

	alpha := this.m_encRCSeq.getPicPara1(this.m_frameLevel).m_alpha
	beta := this.m_encRCSeq.getPicPara1(this.m_frameLevel).m_beta

	// update parameters
	picActualBits := float64(this.m_picActualBits)
	picActualBpp := picActualBits / float64(this.m_numberOfPixel)
	calLambda := alpha * math.Pow(picActualBpp, beta)
	inputLambda := this.m_picLambda

	if inputLambda < 0.01 || calLambda < 0.01 || picActualBpp < 0.0001 || effectivePercentage < 0.05 {
		alpha *= (1.0 - this.m_encRCSeq.getAlphaUpdate()/2.0)
		beta *= (1.0 - this.m_encRCSeq.getBetaUpdate()/2.0)

		alpha = TLibCommon.CLIP3(0.05, 20.0, alpha).(float64)
		beta = TLibCommon.CLIP3(-3.0, -0.1, beta).(float64)
		var rcPara TRCParameter
		rcPara.m_alpha = alpha
		rcPara.m_beta = beta
		this.m_encRCSeq.setPicPara2(this.m_frameLevel, rcPara)

		return
	}

	calLambda = TLibCommon.CLIP3(inputLambda/10.0, inputLambda*10.0, calLambda).(float64)
	alpha += this.m_encRCSeq.getAlphaUpdate() * (math.Log(inputLambda) - math.Log(calLambda)) * alpha
	lnbpp := math.Log(picActualBpp)
	lnbpp = TLibCommon.CLIP3(-5.0, 1.0, lnbpp).(float64)
	beta += this.m_encRCSeq.getBetaUpdate() * (math.Log(inputLambda) - math.Log(calLambda)) * lnbpp

	alpha = TLibCommon.CLIP3(0.05, 20.0, alpha).(float64)
	beta = TLibCommon.CLIP3(-3.0, -0.1, beta).(float64)

	var rcPara TRCParameter
	rcPara.m_alpha = alpha
	rcPara.m_beta = beta

	this.m_encRCSeq.setPicPara2(this.m_frameLevel, rcPara)
}
Beispiel #6
0
func (this *TEncRCPic) estimatePicLambda(listPreviousPictures *list.List) float64 {
	alpha := this.m_encRCSeq.getPicPara1(this.m_frameLevel).m_alpha
	beta := this.m_encRCSeq.getPicPara1(this.m_frameLevel).m_beta
	bpp := float64(this.m_targetBits) / float64(this.m_numberOfPixel)
	estLambda := alpha * math.Pow(bpp, beta)
	lastLevelLambda := float64(-1.0)
	lastPicLambda := float64(-1.0)
	lastValidLambda := float64(-1.0)
	//list<TEncRCPic*>::iterator it;
	for it := listPreviousPictures.Front(); it != nil; it = it.Next() {
		v := it.Value.(*TEncRCPic)
		if v.getFrameLevel() == this.m_frameLevel {
			lastLevelLambda = v.getPicActualLambda()
		}
		lastPicLambda = v.getPicActualLambda()

		if lastPicLambda > 0.0 {
			lastValidLambda = lastPicLambda
		}
	}

	if lastLevelLambda > 0.0 {
		lastLevelLambda = TLibCommon.CLIP3(float64(0.1), float64(10000.0), lastLevelLambda).(float64)
		estLambda = TLibCommon.CLIP3(lastLevelLambda*math.Pow(2.0, -3.0/3.0), lastLevelLambda*math.Pow(2.0, 3.0/3.0), estLambda).(float64)
	}

	if lastPicLambda > 0.0 {
		lastPicLambda = TLibCommon.CLIP3(0.1, 2000.0, lastPicLambda).(float64)
		estLambda = TLibCommon.CLIP3(lastPicLambda*math.Pow(2.0, -10.0/3.0), lastPicLambda*math.Pow(2.0, 10.0/3.0), estLambda).(float64)
	} else if lastValidLambda > 0.0 {
		lastValidLambda = TLibCommon.CLIP3(0.1, 2000.0, lastValidLambda).(float64)
		estLambda = TLibCommon.CLIP3(lastValidLambda*math.Pow(2.0, -10.0/3.0), lastValidLambda*math.Pow(2.0, 10.0/3.0), estLambda).(float64)
	} else {
		estLambda = TLibCommon.CLIP3(0.1, 10000.0, estLambda).(float64)
	}

	if estLambda < 0.1 {
		estLambda = 0.1
	}

	this.m_estPicLambda = estLambda
	return estLambda
}