📄 umc_vc1_enc_brc_gop.cpp
字号:
#ifdef VC1_GOP_DEBUG
printf("\n\n I:P = %f\n", m_IP_size);
printf(" I:B = %f\n\n", m_IB_size);
#endif
}
///---------------------------
m_needISize = (Ipp32s)(m_nextGOPSize/(1 + m_IP_size*m_PNum + m_IB_size*m_BNum));
ratioI = ((Ipp32f)prefINeedSize/(Ipp32f)m_needISize);
QuantForNewGOP(VC1_I_FRAME, ratioI);
m_currFrameInGOP = 0;
m_poorRefFrame = 0;
m_currGOPSize = 0;
m_GOPHalfFlag = 1;
m_I_GOPSize = 0;
m_P_GOPSize = 0;
m_B_GOPSize = 0;
m_CurrINum = 0;
m_CurrPNum = 0;
m_CurrBNum = 0;
m_failGOP = 0;
m_AveragePQuant = 0;
m_AverageBQuant = 0;
}
m_recoding = 0;
m_failPQuant = 0;
m_failBQuant = 0;
#ifdef VC1_BRC_DEBUG
printf("\n\n\n");
#endif
};
void VC1BRC_IPB::CheckFrame_QualityMode(Ipp32u picType, Ipp32f ratio, UMC::Status UMCSts)
{
Ipp32s curQuant = 0;
Ipp32s Sts = VC1_BRC_OK;
bool HalfQP = 0;
//new quant calculation
curQuant = (Ipp32s)(ratio * m_CurQuant.PQIndex + 0.5);
VC1_QUANT_CLIP(curQuant, 0);
//check compression
if((ratio <= m_buffer_overflow) && (ratio >= VC1_GOOD_COMPRESSION))
Sts = VC1_BRC_OK; //good frame
else if(ratio > m_buffer_overflow)
Sts |= VC1_BRC_NOT_ENOUGH_BUFFER; //could be critical situation, if HRD buffer small
else if(ratio <= m_ratio_min)
{
//very small frame
Sts |= VC1_BRC_ERR_SMALL_FRAME;
if(m_CurQuant.PQIndex > 1)
HalfQP = 1;
}
else if(ratio >= VC1_MIN_RATIO_HALF)
{
if((m_CurQuant.PQIndex > 1) && ((Ipp32u)curQuant > m_CurQuant.PQIndex))
HalfQP = 1;
Sts |= VC1_BRC_SMALL_FRAME;
}
else
Sts |= VC1_BRC_SMALL_FRAME;
//check HRD status
if(UMCSts == UMC::UMC_ERR_NOT_ENOUGH_BUFFER)
{
Sts |= VC1_BRC_NOT_ENOUGH_BUFFER;
HalfQP = 0;
}
if(Sts != VC1_BRC_OK)
switch (picType)
{
case(VC1_I_FRAME):
{
#ifdef VC1_BRC_DEBUG
printf("m_LimIQuant %d\n", m_Quant.LimIQuant);
#endif
m_Quant.IQuant = (m_Quant.IQuant + curQuant)/2;
if(Sts & VC1_BRC_NOT_ENOUGH_BUFFER)
{
if(ratio > VC1_RATIO_ILIM)
{
m_Quant.IQuant++;
m_Quant.LimIQuant = m_CurQuant.PQIndex + 2;
}
else
{
if(m_CurQuant.PQIndex > 9)
m_Quant.LimIQuant = m_CurQuant.PQIndex + 1;
else if(m_Quant.IQuant <= m_CurQuant.PQIndex)
HalfQP = 1;
}
}
else if(Sts & VC1_BRC_ERR_SMALL_FRAME)
{
m_Quant.LimIQuant--;
if(m_Quant.IQuant >= m_CurQuant.PQIndex)
m_Quant.IQuant--;
if((ratio > VC1_MIN_RATIO_HALF) && (m_CurQuant.PQIndex > 1))
HalfQP = 1;
}
else if(Sts & VC1_BRC_SMALL_FRAME)
{
m_Quant.LimIQuant--;
if((m_Quant.IQuant < m_CurQuant.PQIndex) && m_Quant.IQuant && (m_CurQuant.PQIndex > 1))
HalfQP = 1;
}
VC1_QUANT_CLIP(m_Quant.LimIQuant,0);
VC1_QUANT_CLIP(m_Quant.IQuant, m_Quant.LimIQuant);
m_Quant.IHalf = HalfQP;
}
break;
case(VC1_P_FRAME):
{
#ifdef VC1_BRC_DEBUG
printf("m_LimPQuant %d\n", m_Quant.LimPQuant);
#endif
if(Sts & VC1_BRC_NOT_ENOUGH_BUFFER)
{
if(ratio > VC1_RATIO_ILIM)
{
m_failPQuant = (m_Quant.PQuant + curQuant + 1)/2 - m_Quant.PQuant;
m_Quant.PQuant++;
m_Quant.LimPQuant = m_CurQuant.PQIndex + 1;
}
else
{
m_Quant.PQuant = (m_Quant.PQuant + curQuant + 1)/2;
if(m_Quant.PQuant <= m_CurQuant.PQIndex)
if(m_CurQuant.PQIndex > 9)
{
if(m_Quant.PQuant <= m_CurQuant.PQIndex)
m_Quant.PQuant++;
}
else
{
if(!m_CurQuant.HalfPQ)
HalfQP = 1;
else
{
HalfQP = 0;
if(m_Quant.PQuant <= m_CurQuant.PQIndex)
m_Quant.PQuant++;
}
}
}
}
else if(Sts & VC1_BRC_ERR_SMALL_FRAME)
{
m_Quant.PQuant = (m_Quant.PQuant + curQuant + 1)/2;
m_Quant.LimPQuant--;
if(m_CurQuant.PQIndex > 9)
{
if(m_Quant.PQuant >= m_CurQuant.PQIndex)
m_Quant.PQuant--;
}
else
{
if(m_CurQuant.HalfPQ)
HalfQP = 0;
else
{
if(m_Quant.PQuant >= m_CurQuant.PQIndex)
m_Quant.PQuant--;
}
}
}
else if(Sts & VC1_BRC_SMALL_FRAME)
{
m_Quant.PQuant = (m_Quant.PQuant + curQuant + 1)/2;
m_Quant.LimPQuant--;
if(m_CurQuant.HalfPQ)
HalfQP = 0;
else
{
if(m_Quant.PQuant >= m_CurQuant.PQIndex)
{
m_Quant.PQuant--;
if((m_CurQuant.PQIndex != VC1_MIN_QUANT) && (ratio > VC1_MIN_RATIO_HALF))
HalfQP = 1;
}
}
}
VC1_QUANT_CLIP(m_Quant.LimPQuant,0);
VC1_QUANT_CLIP(m_Quant.PQuant, m_Quant.LimPQuant);
m_Quant.PHalf = HalfQP;
}
break;
case(VC1_B_FRAME):
{
#ifdef VC1_BRC_DEBUG
printf("m_LimBQuant %d\n", m_Quant.LimBQuant);
#endif
if(Sts & VC1_BRC_NOT_ENOUGH_BUFFER)
{
if(ratio > VC1_RATIO_ILIM)
{
m_failBQuant = (m_Quant.BQuant + curQuant + 1)/2 - m_Quant.BQuant;
m_Quant.BQuant++;
m_Quant.LimBQuant = m_CurQuant.PQIndex + 1;
}
else
{
m_Quant.BQuant = (m_Quant.BQuant + curQuant + 1)/2;
if(m_Quant.BQuant <= m_CurQuant.PQIndex)
if(m_CurQuant.PQIndex > 9)
{
if(m_Quant.BQuant <= m_CurQuant.PQIndex)
m_Quant.BQuant++;
}
else
{
if(!m_CurQuant.HalfPQ)
HalfQP = 1;
else
{
HalfQP = 0;
if(m_Quant.BQuant <= m_CurQuant.PQIndex)
m_Quant.BQuant++;
}
}
}
}
else if(Sts & VC1_BRC_ERR_SMALL_FRAME)
{
m_Quant.BQuant = (m_Quant.BQuant + curQuant + 1)/2;
m_Quant.LimBQuant--;
if(m_CurQuant.PQIndex > 9)
{
if(m_Quant.BQuant >= m_CurQuant.PQIndex)
m_Quant.BQuant--;
}
else
{
if(m_CurQuant.HalfPQ)
HalfQP = 0;
else
{
if(m_Quant.BQuant >= m_CurQuant.PQIndex)
m_Quant.BQuant--;
}
}
}
else if(Sts & VC1_BRC_SMALL_FRAME)
{
m_Quant.BQuant = (m_Quant.BQuant + curQuant + 1)/2;
m_Quant.LimBQuant--;
if(m_CurQuant.HalfPQ)
HalfQP = 0;
else
{
if(m_Quant.BQuant >= m_CurQuant.PQIndex)
{
m_Quant.BQuant--;
if((m_CurQuant.PQIndex != VC1_MIN_QUANT) && (ratio > VC1_MIN_RATIO_HALF))
HalfQP = 1;
}
}
}
VC1_QUANT_CLIP(m_Quant.LimBQuant,0);
VC1_QUANT_CLIP(m_Quant.BQuant, m_Quant.LimBQuant);
m_Quant.BHalf = HalfQP;
}
break;
}
};
void VC1BRC_IPB::QuantForNewGOP(Ipp32u picType, Ipp32f ratio)
{
Ipp32s curQuant = 0;
if(ratio == 1)
return;
switch (picType)
{
case(VC1_I_FRAME):
{
//new quant calculation
curQuant = (Ipp32s)(ratio * m_Quant.IQuant + 0.5);
VC1_QUANT_CLIP(curQuant, 0);
if(curQuant != m_Quant.IQuant)
m_Quant.IHalf = 0;
m_Quant.IQuant = (m_Quant.IQuant + curQuant + 1)/2;
// m_Quant.LimIQuant = (m_Quant.LimIQuant + m_Quant.IQuant)/2;
//VC1_QUANT_CLIP(m_Quant.LimIQuant,0);
VC1_QUANT_CLIP(m_Quant.IQuant, m_Quant.LimIQuant);
}
break;
case(VC1_P_FRAME):
{
//new quant calculation
curQuant = (Ipp32s)(ratio * m_Quant.PQuant - 0.5);
VC1_QUANT_CLIP(curQuant, 0);
if(curQuant != m_Quant.PQuant)
m_Quant.PHalf = 0;
m_Quant.PQuant = (m_Quant.PQuant + curQuant + 1)/2;
m_Quant.LimPQuant = (m_Quant.LimPQuant + m_Quant.PQuant)/2;
VC1_QUANT_CLIP(m_Quant.LimPQuant,0);
VC1_QUANT_CLIP(m_Quant.PQuant, m_Quant.LimPQuant);
}
break;
case(VC1_B_FRAME):
{
//new quant calculation
curQuant = (Ipp32s)(ratio * m_Quant.BQuant - 0.5);
VC1_QUANT_CLIP(curQuant, 0);
if(curQuant != m_Quant.BQuant)
m_Quant.BHalf = 0;
m_Quant.BQuant = (m_Quant.BQuant + curQuant + 1)/2;
m_Quant.LimBQuant = (m_Quant.LimBQuant + m_Quant.BQuant)/2;
VC1_QUANT_CLIP(m_Quant.LimBQuant,0);
VC1_QUANT_CLIP(m_Quant.BQuant, m_Quant.LimBQuant);
}
break;
}
};
void VC1BRC_IPB::GetQuant(Ipp32u picType, Ipp8u* PQuant, bool* Half)
{
m_picType = picType;
switch (picType)
{
case(VC1_I_FRAME):
m_CurQuant.PQIndex = m_Quant.IQuant;
m_CurQuant.HalfPQ = m_Quant.IHalf;
break;
case(VC1_P_FRAME):
m_CurQuant.PQIndex = m_Quant.PQuant + m_failPQuant;
m_CurQuant.HalfPQ = m_Quant.PHalf;
if(m_encMode != VC1_BRC_CONST_QUANT_MODE)
if(m_poorRefFrame&0x1)
{//correct quant for next B frame
if(m_CurQuant.PQIndex > 9)
{
m_CurQuant.PQIndex--;
m_CurQuant.HalfPQ = 1;
m_Quant.PQuant--;
m_Quant.PHalf = 0;
}
else
{
m_CurQuant.HalfPQ = 0;
m_Quant.PHalf = 0;
}
}
VC1_QUANT_CLIP(m_CurQuant.PQIndex,0);
VC1_QUANT_CLIP(m_CurQuant.PQIndex, m_Quant.LimPQuant);
break;
case(VC1_B_FRAME):
m_CurQuant.PQIndex = m_Quant.BQuant + m_failBQuant;
m_CurQuant.HalfPQ = m_Quant.BHalf;
if(m_encMode != VC1_BRC_CONST_QUANT_MODE)
if(m_poorRefFrame)
{//correct quant for next B frame
if(m_CurQuant.PQIndex > 9)
{
m_CurQuant.PQIndex--;
m_CurQuant.HalfPQ = 1;
m_Quant.BQuant--;
m_Quant.BHalf = 0;
}
else
{
m_CurQuant.HalfPQ = 0;
m_Quant.BHalf = 0;
}
}
VC1_QUANT_CLIP(m_CurQuant.PQIndex,0);
VC1_QUANT_CLIP(m_CurQuant.PQIndex, m_Quant.LimBQuant);
break;
default:
break;
}
if(m_CurQuant.PQIndex > 8)
m_CurQuant.HalfPQ = 0;
#ifdef VC1_BRC_DEBUG
printf("cur quant %d\n", m_CurQuant.PQIndex);
printf("half quant %d\n", m_CurQuant.HalfPQ);
#endif
*PQuant = m_CurQuant.PQIndex;
*Half = m_CurQuant.HalfPQ;
}
}
#endif // defined (UMC_ENABLE_VC1_VIDEO_ENCODER)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -