Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/mpc-hc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/rate_control.cpp')
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/rate_control.cpp280
1 files changed, 138 insertions, 142 deletions
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/rate_control.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/rate_control.cpp
index da4b4bab8..bd5b62346 100644
--- a/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/rate_control.cpp
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/rate_control.cpp
@@ -89,30 +89,30 @@ FrameComplexity::FrameComplexity():
//Default constructor
RateController::RateController(int trate, SourceParams& srcp, EncoderParams& encp):
- m_qf(encp.Qf()),
- m_I_qf(encp.Qf()),
+ m_qf (encp.Qf()),
+ m_I_qf (encp.Qf()),
m_I_qf_long_term(encp.Qf()),
m_target_rate(trate),
- m_buffer_size(5000 * trate), // for the moment, set buffer size to 5 seconds
- m_buffer_bits((m_buffer_size * 9) / 10), // initial occupancy of 90%
+ m_buffer_size(5000*trate),// for the moment, set buffer size to 5 seconds
+ m_buffer_bits((m_buffer_size*9)/10),// initial occupancy of 90%
m_encparams(encp),
- m_fcount(encp.L1Sep()),
+ m_fcount(encp.L1Sep() ),
m_intra_only(false),
m_L2_complexity_sum(0)
{
SetFrameDistribution();
CalcTotalBits(srcp);
- if(m_intra_only)
+ if (m_intra_only)
m_Iframe_bits = m_total_GOP_bits;
else
{
- m_Iframe_bits = m_total_GOP_bits / 10;
- m_L1frame_bits = (m_Iframe_bits * 3) / m_num_L1frame;
- if(m_encparams.L1Sep() > 1)
- m_L2frame_bits = (m_total_GOP_bits - m_Iframe_bits -
- m_L1frame_bits * m_num_L1frame) /
- (m_encparams.GOPLength() - 1 - m_num_L1frame);
+ m_Iframe_bits = m_total_GOP_bits/10;
+ m_L1frame_bits = (m_Iframe_bits*3)/m_num_L1frame;
+ if (m_encparams.L1Sep()>1)
+ m_L2frame_bits = ( m_total_GOP_bits - m_Iframe_bits -
+ m_L1frame_bits*m_num_L1frame )/
+ (m_encparams.GOPLength()-1-m_num_L1frame);
else
m_L2frame_bits = 0;
@@ -124,7 +124,7 @@ void RateController::SetFrameDistribution()
m_num_L1frame = m_encparams.NumL1();
m_num_Iframe = 1;
- if(m_num_L1frame == 0)
+ if (m_num_L1frame == 0)
{
m_num_Iframe = m_encparams.GOPLength();
m_intra_only = true;
@@ -136,60 +136,60 @@ void RateController::SetFrameDistribution()
void RateController::CalcTotalBits(const SourceParams& sourceparams)
{
const Rational& frame_rate = sourceparams.FrameRate();
- double f_rate = double(frame_rate.m_num) / double(frame_rate.m_denom);
+ double f_rate = double(frame_rate.m_num)/double(frame_rate.m_denom);
int GOP_length = m_encparams.GOPLength();
- m_GOP_duration = GOP_length / f_rate;
- m_total_GOP_bits = (long int)(m_GOP_duration * 1000.0) * m_target_rate; //Unit in bits
+ m_GOP_duration = GOP_length/f_rate;
+ m_total_GOP_bits = (long int)(m_GOP_duration*1000.0)*m_target_rate; //Unit in bits
m_GOP_target = m_total_GOP_bits;
- m_picture_bits = m_total_GOP_bits / GOP_length;
+ m_picture_bits = m_total_GOP_bits/GOP_length;
- if(m_encparams.Verbose())
+ if (m_encparams.Verbose())
{
- std::cout << "\nRate Control Encoding with target bit rate = ";
- std::cout << m_target_rate << " kbps" << std::endl;
+ std::cout<<"\nRate Control Encoding with target bit rate = ";
+ std::cout<<m_target_rate<<" kbps"<< std::endl;
- std::cout << "GOP Length = " << GOP_length << std::endl;
+ std::cout<<"GOP Length = "<<GOP_length<< std::endl;
- std::cout << "Frame Rate = " << f_rate << std::endl;
+ std::cout<<"Frame Rate = "<<f_rate<< std::endl;
- std::cout << "GOP Duration = " << m_GOP_duration << std::endl;
+ std::cout<<"GOP Duration = "<<m_GOP_duration<< std::endl;
- std::cout << "Total Allocated Num. of bits for each GOP = ";
- std::cout << m_total_GOP_bits << " (" << m_picture_bits << " per frame)";
- std::cout << std::endl;
+ std::cout<<"Total Allocated Num. of bits for each GOP = ";
+ std::cout<<m_total_GOP_bits<<" ("<<m_picture_bits<<" per frame)";
+ std::cout<<std::endl;
}
}
void RateController::Report()
{
- std::cout << std::endl;
- std::cout << std::endl << "GOP target is " << m_GOP_target;
- std::cout << std::endl << "Allocated frame bits by type: ";
- std::cout << "I frames - " << m_Iframe_bits;
- std::cout << "; L1/P frames - " << m_L1frame_bits;
- std::cout << "; L2/B frames - " << m_L2frame_bits;
- std::cout << std::endl;
+ std::cout<<std::endl;
+ std::cout<<std::endl<<"GOP target is "<<m_GOP_target;
+ std::cout<<std::endl<<"Allocated frame bits by type: ";
+ std::cout<<"I frames - "<<m_Iframe_bits;
+ std::cout<<"; L1/P frames - "<<m_L1frame_bits;
+ std::cout<<"; L2/B frames - "<<m_L2frame_bits;
+ std::cout<<std::endl;
}
double RateController::TargetSubgroupRate()
{
- long int bits = (m_encparams.L1Sep() - 1) * m_L2frame_bits +
- m_L1frame_bits;
- return (double)(bits) / (1000.0 * m_GOP_duration);
+ long int bits = (m_encparams.L1Sep()-1)*m_L2frame_bits+
+ m_L1frame_bits;
+ return (double)(bits)/(1000.0*m_GOP_duration);
}
double RateController::ProjectedSubgroupRate()
{
- int bits = (m_encparams.L1Sep() - 1) * m_frame_complexity.L2Complexity() +
+ int bits = (m_encparams.L1Sep()-1)*m_frame_complexity.L2Complexity()+
m_frame_complexity.L1Complexity();
- return (double)(bits) / (1000.0 * m_GOP_duration);
+ return (double)(bits)/(1000.0*m_GOP_duration);
}
void RateController::CalcNextQualFactor(const PictureParams& pparams, int num_bits)
{
@@ -198,54 +198,53 @@ void RateController::CalcNextQualFactor(const PictureParams& pparams, int num_bi
// L2 frame before the next L1 frame i.e. before the start of an L1L2L2
// subgroup
m_fcount--;
- UpdateBuffer(num_bits);
+ UpdateBuffer( num_bits );
// filter tap for adjusting the QF
double target_ratio = 0.9;
int field_factor = m_encparams.FieldCoding() ? 2 : 1;
- double top_size = (1.0 - target_ratio) - 0.5;
- double bottom_size = target_ratio - 0.1;
- double actual_ratio = double(m_buffer_bits) / double(m_buffer_size);
+ double top_size = (1.0 - target_ratio)-0.5;
+ double bottom_size = target_ratio-0.1;
+ double actual_ratio = double(m_buffer_bits)/double(m_buffer_size);
double tap;
- if((pparams.PictureNum() / field_factor) <= 3 * m_encparams.L1Sep())
+ if ((pparams.PictureNum()/field_factor)<=3*m_encparams.L1Sep() )
tap = 1.0;
- else
- {
- if(actual_ratio > target_ratio)
- tap = (actual_ratio - target_ratio) / top_size;
+ else{
+ if (actual_ratio>target_ratio)
+ tap = (actual_ratio-target_ratio)/top_size;
else
- tap = (target_ratio - actual_ratio) / bottom_size;
+ tap = (target_ratio-actual_ratio)/bottom_size;
- tap = std::min(1.0, std::max(tap, 0.25));
+ tap = std::min( 1.0, std::max(tap, 0.25 ));
}
- if(!m_intra_only)
+ if (!m_intra_only)
{
bool emergency_realloc = false;
int target;
// First, do normal coding
- if(pparams.PicSort().IsIntra() == true)
+ if ( pparams.PicSort().IsIntra() == true )
{
target = m_Iframe_bits;
- if(num_bits < target / 2)
+ if (num_bits < target/2 )
emergency_realloc = true;
// Update the statistics
- m_frame_complexity.SetIComplexity(num_bits);
+ m_frame_complexity.SetIComplexity( num_bits );
// We've just coded an intra frame so we need to set qf for
// the next group of L2(B) frames
- m_qf = std::max(tap * m_qf + (1.0 - tap) * m_encparams.Qf(), m_encparams.Qf() - 1.0);
- m_encparams.SetQf(m_qf);
+ m_qf = std::max(tap*m_qf+(1.0-tap)*m_encparams.Qf(), m_encparams.Qf()-1.0);
+ m_encparams.SetQf( m_qf );
- if(pparams.PictureNum() / field_factor == 0)
+ if (pparams.PictureNum()/field_factor==0)
{
// We've just coded the very first frame, which is a special
// case as the two L2 frames which normally follow are missing
@@ -255,47 +254,45 @@ void RateController::CalcNextQualFactor(const PictureParams& pparams, int num_bi
}
//Update complexities
- if((pparams.PictureNum() / field_factor) % m_encparams.L1Sep() != 0)
+ if ( (pparams.PictureNum()/field_factor) % m_encparams.L1Sep() !=0 )
{
// Scheduled B/L2 picture
target = m_L2frame_bits;
- if(num_bits < target / 2)
- {
+ if (num_bits < target/2 ){
emergency_realloc = true;
}
m_L2_complexity_sum += num_bits;
}
- else if(pparams.PicSort().IsIntra() == false)
+ else if ( pparams.PicSort().IsIntra() == false )
{
// Scheduled P/L1 picture (if inserted I picture, don't change the complexity)
target = m_L1frame_bits;
- if(num_bits < target / 2 || num_bits > target * 3)
- {
+ if (num_bits < target/2 || num_bits > target*3 ){
emergency_realloc = true;
}
m_frame_complexity.SetL1Complexity(num_bits);
}
- if(m_fcount == 0 || emergency_realloc == true)
+ if ( m_fcount==0 || emergency_realloc==true)
{
- if(emergency_realloc == true && m_encparams.Verbose() == true)
- std::cout << std::endl << "Major mis-prediction of frame bit rate: re-allocating";
+ if (emergency_realloc==true && m_encparams.Verbose()==true )
+ std::cout<<std::endl<<"Major mis-prediction of frame bit rate: re-allocating";
/* We recompute allocations for the next subgroup */
- if(m_encparams.L1Sep() > 1 && m_fcount < m_encparams.L1Sep() - 1)
+ if ( m_encparams.L1Sep()>1 && m_fcount<m_encparams.L1Sep()-1)
{
- m_frame_complexity.SetL2Complexity(m_L2_complexity_sum /
- (m_encparams.L1Sep() - 1 - m_fcount));
+ m_frame_complexity.SetL2Complexity(m_L2_complexity_sum/
+ (m_encparams.L1Sep()-1-m_fcount));
}
- Allocate((pparams.PictureNum() / field_factor));
+ Allocate( (pparams.PictureNum()/field_factor) );
/* We work out what this means for the quality factor and set it*/
@@ -307,29 +304,28 @@ void RateController::CalcNextQualFactor(const PictureParams& pparams, int num_bi
// from measured values (complexities)
double prate = ProjectedSubgroupRate();
- if(m_encparams.Verbose() == true)
+ if (m_encparams.Verbose()==true )
{
- std::cout << std::endl << "Target subgroup rate = " << trate;
- std::cout << ", projected subgroup rate = " << prate;
+ std::cout<<std::endl<<"Target subgroup rate = "<<trate;
+ std::cout<<", projected subgroup rate = "<<prate;
}
// Determine K value
- double K = std::pow(prate, 2) * std::pow(10.0, ((double)2 / 5 * (10 - m_qf))) / 16;
+ double K = std::pow(prate, 2)*std::pow(10.0, ((double)2/5*(10-m_qf)))/16;
// Determine a new QF
- double new_qf = 10 - (double)5 / 2 * log10(16 * K / std::pow(trate, 2));
- if((std::abs(m_qf - new_qf) < 0.25 && new_qf > 4.0) || new_qf > 8.0)
+ double new_qf = 10 - (double)5/2*log10(16*K/std::pow(trate, 2));
+ if ( ( std::abs(m_qf-new_qf)<0.25 && new_qf > 4.0 ) || new_qf>8.0)
m_qf = new_qf;
else
- m_qf = tap * new_qf + (1.0 - tap) * m_qf;
+ m_qf = tap*new_qf+(1.0-tap)*m_qf;
- m_qf = ReviewQualityFactor(m_qf , num_bits);
+ m_qf = ReviewQualityFactor( m_qf , num_bits );
- if(m_qf < 8.0)
- {
- if(prate < 2 * trate)
- m_qf = std::max(m_qf, m_encparams.Qf() - 1.0);
+ if ( m_qf<8.0 ){
+ if (prate<2*trate)
+ m_qf = std::max(m_qf,m_encparams.Qf()-1.0);
else
- m_qf = std::max(m_qf, m_encparams.Qf() - 2.0);
+ m_qf = std::max(m_qf,m_encparams.Qf()-2.0);
}
m_encparams.SetQf(m_qf);
@@ -338,7 +334,7 @@ void RateController::CalcNextQualFactor(const PictureParams& pparams, int num_bi
/* Resetting */
// Reset the frame counter
- if(m_fcount == 0)
+ if (m_fcount==0)
m_fcount = m_encparams.L1Sep();
// Reset the count of L2 bits
@@ -352,22 +348,22 @@ void RateController::CalcNextQualFactor(const PictureParams& pparams, int num_bi
// Target rate
- double trate = double(m_total_GOP_bits) / (1000.0 * m_num_Iframe);
+ double trate = double(m_total_GOP_bits)/(1000.0*m_num_Iframe);
// Projected rate with current QF
- double prate = double(num_bits) / 1000.0;
+ double prate = double(num_bits)/1000.0;
// Determine K value
- double K = std::pow(prate, 2) * std::pow(10.0, ((double)2 / 5 * (10 - m_qf))) / 16;
+ double K = std::pow(prate, 2)*std::pow(10.0, ((double)2/5*(10-m_qf)))/16;
// Determine a new QF
- double new_qf = 10 - (double)5 / 2 * log10(16 * K / std::pow(trate, 2));
+ double new_qf = 10 - (double)5/2*log10(16*K/std::pow(trate, 2));
// Adjust the QF to meet the target
- double abs_delta = std::abs(new_qf - m_qf);
- if(abs_delta > 0.01)
+ double abs_delta = std::abs( new_qf - m_qf );
+ if ( abs_delta>0.01)
{
// Rate of convergence to new QF
double r;
@@ -386,16 +382,16 @@ void RateController::CalcNextQualFactor(const PictureParams& pparams, int num_bi
Actual parameters may be adjusted later. Some applications may
require instant lock.
*/
- double lg_diff = std::log(abs_delta / 2.0);
- if(lg_diff < 0.0)
- r = 0.5 * std::exp(-lg_diff * lg_diff / 2.0);
+ double lg_diff = std::log( abs_delta/2.0 );
+ if ( lg_diff< 0.0 )
+ r = 0.5*std::exp(-lg_diff*lg_diff/2.0);
else
- r = 1.0 - 0.5 * std::exp(-lg_diff * lg_diff / 2.0);
+ r = 1.0-0.5*std::exp(-lg_diff*lg_diff/2.0);
r *= 0.75;
- m_qf = r * m_qf + (1.0 - r) * new_qf;
- m_qf = ReviewQualityFactor(m_qf , num_bits);
+ m_qf = r*m_qf + (1.0-r)*new_qf;
+ m_qf = ReviewQualityFactor( m_qf , num_bits );
m_encparams.SetQf(m_qf);
}
@@ -406,31 +402,31 @@ void RateController::CalcNextQualFactor(const PictureParams& pparams, int num_bi
}
-void RateController::UpdateBuffer(const long int num_bits)
+void RateController::UpdateBuffer( const long int num_bits )
{
m_buffer_bits -= num_bits;
m_buffer_bits += m_picture_bits;
- if(m_encparams.Verbose())
+ if (m_encparams.Verbose())
{
- std::cout << std::endl << "Buffer occupancy = " << ((double)m_buffer_bits * 100.0)
- / ((double)m_buffer_size) << "%";
+ std::cout<<std::endl<<"Buffer occupancy = "<<((double)m_buffer_bits*100.0)
+ /((double)m_buffer_size)<<"%";
}
- if(m_buffer_bits < 0)
+ if (m_buffer_bits<0)
{
- if(m_encparams.Verbose())
+ if (m_encparams.Verbose())
{
- std::cout << std::endl << "WARNING: decoder buffer is out of bits - bit rate is too high";
+ std::cout<<std::endl<<"WARNING: decoder buffer is out of bits - bit rate is too high";
}
// m_buffer_bits = 0;
}
- if(m_buffer_bits > m_buffer_size)
+ if (m_buffer_bits>m_buffer_size)
{
- if(m_encparams.Verbose())
+ if (m_encparams.Verbose())
{
- std::cout << std::endl << "WARNING: decoder buffer has overflowed - bit rate is too low. Assuming bit-stuffing.";
+ std::cout<<std::endl<<"WARNING: decoder buffer has overflowed - bit rate is too low. Assuming bit-stuffing.";
}
m_buffer_bits = m_buffer_size;
}
@@ -438,97 +434,97 @@ void RateController::UpdateBuffer(const long int num_bits)
}
-void RateController::Allocate(const int fnum)
+void RateController::Allocate (const int fnum)
{
const int XI = m_frame_complexity.IComplexity();
const int XL1 = m_frame_complexity.L1Complexity();
const int XL2 = m_frame_complexity.L2Complexity();
- double buffer_occ = ((double)m_buffer_bits) / ((double)m_buffer_size);
+ double buffer_occ = ( (double)m_buffer_bits)/((double)m_buffer_size);
- if(!m_intra_only)
+ if ( !m_intra_only)
{
double correction;
- if(buffer_occ < 0.9 && ((fnum + 1) % 4 * m_encparams.L1Sep()) == 0)
+ if (buffer_occ<0.9 && ( (fnum+1) % 4*m_encparams.L1Sep())==0 )
{
// If we're undershooting buffer target, correct slowly
- correction = std::min(0.25, 0.25 * (0.9 - buffer_occ) / 0.9);
- m_GOP_target = (long int)(double(m_total_GOP_bits) * (1.0 - correction));
+ correction = std::min( 0.25, 0.25*(0.9 - buffer_occ )/0.9 );
+ m_GOP_target = ( long int)(double(m_total_GOP_bits)*( 1.0-correction) );
}
- else if(buffer_occ > 0.9 && ((fnum + 1) % m_encparams.L1Sep()) == 0)
+ else if (buffer_occ>0.9 && ((fnum+1) % m_encparams.L1Sep())==0)
{
// If we're overshooting buffer target, correct quickly
- correction = std::min(0.5, 0.5 * (buffer_occ - 0.9) / 0.9);
- m_GOP_target = (long int)(double(m_total_GOP_bits) * (1.0 + correction));
+ correction = std::min( 0.5, 0.5*( buffer_occ - 0.9 )/0.9 );
+ m_GOP_target = ( long int)(double(m_total_GOP_bits)*( 1.0+correction) );
}
}
- const long int min_bits = m_total_GOP_bits / (100 * m_encparams.GOPLength());
+ const long int min_bits = m_total_GOP_bits/(100*m_encparams.GOPLength());
// Allocate intra bits
- m_Iframe_bits = (long int)(m_GOP_target
- / (m_num_Iframe
- + (double)(m_num_L1frame * XL1) / XI
- + (double)(m_num_L2frame * XL2) / XI));
+ m_Iframe_bits = (long int) (m_GOP_target
+ / (m_num_Iframe
+ +(double)(m_num_L1frame*XL1)/XI
+ +(double)(m_num_L2frame*XL2)/XI));
- m_Iframe_bits = std::max(min_bits, m_Iframe_bits);
+ m_Iframe_bits = std::max( min_bits, m_Iframe_bits );
// Allocate L1 bits
- m_L1frame_bits = (long int)(m_GOP_target
- / (m_num_L1frame
- + (double)(m_num_Iframe * XI) / XL1
- + (double)(m_num_L2frame * XL2) / XL1));
+ m_L1frame_bits = (long int) (m_GOP_target
+ / (m_num_L1frame
+ +(double)(m_num_Iframe*XI)/XL1
+ +(double)(m_num_L2frame*XL2)/XL1));
- m_L1frame_bits = std::max(min_bits, m_L1frame_bits);
+ m_L1frame_bits = std::max( min_bits, m_L1frame_bits );
// Allocate L2 bits
- m_L2frame_bits = (long int)(m_GOP_target
- / (m_num_L2frame
- + (double)(m_num_Iframe * XI) / XL2
- + (double)(m_num_L1frame * XL1) / XL2));
+ m_L2frame_bits = (long int) (m_GOP_target
+ / (m_num_L2frame
+ +(double)(m_num_Iframe*XI)/XL2
+ +(double)(m_num_L1frame*XL1)/XL2));
- m_L2frame_bits = std::max(min_bits, m_L2frame_bits);
+ m_L2frame_bits = std::max( min_bits, m_L2frame_bits );
}
-float RateController::ReviewQualityFactor(const float qfac, const long int num_bits)
+float RateController::ReviewQualityFactor( const float qfac, const long int num_bits )
{
- if(num_bits > m_total_GOP_bits / 2)
+ if (num_bits>m_total_GOP_bits/2)
{
// The frame is too big, so reset to a smaller quality factor
- return ClipQualityFactor(qfac - 2);
+ return ClipQualityFactor(qfac-2);
}
else
{
// Keep the quality factor in a sensible range
- return ClipQualityFactor(qfac);
+ return ClipQualityFactor( qfac );
}
}
-float RateController::ClipQualityFactor(const float qfac)
+float RateController::ClipQualityFactor( const float qfac )
{
// Keep the quality factor in a sensible range
- if(!m_intra_only)
- return std::min(std::max(qfac, 0.0f), 16.0f);
+ if ( !m_intra_only )
+ return std::min( std::max(qfac, 0.0f), 16.0f);
else
return std::max(qfac, 0.0f);
}
void RateController::CalcNextIntraQualFactor()
{
- m_I_qf = (m_I_qf + m_qf) / 2.0;
- m_I_qf = ClipQualityFactor(m_I_qf);
+ m_I_qf = (m_I_qf + m_qf)/2.0;
+ m_I_qf = ClipQualityFactor( m_I_qf );
m_encparams.SetQf(m_I_qf);
const double ff = 0.95;
m_I_qf_long_term *= ff;
- m_I_qf_long_term += (1.0 - ff) * m_I_qf;
+ m_I_qf_long_term += ( 1.0 - ff )*m_I_qf;
}
void RateController::SetCutPictureQualFactor()
{
- m_qf = std::min(m_qf , m_I_qf_long_term);
- m_encparams.SetQf(m_qf);
+ m_qf = std::min( m_qf , m_I_qf_long_term );
+ m_encparams.SetQf( m_qf );
}