ratectl.cc
来自「Motion JPEG编解码器源代码」· CC 代码 · 共 1,089 行 · 第 1/3 页
CC
1,089 行
int available_bits; double Xsum,varsum; /* TODO: A.Stevens Nov 2000 - This modification needs testing visually. Weird. The original code used the average activity of the *previous* frame as the basis for quantisation calculations for rather than the activity in the *current* frame. That *has* to be a bad idea..., surely, here we try to be smarter by using the current values and keeping track of how much of the frames activitity has been covered as we go along. We also guesstimate the relationship between (sum of DCT coefficients) and actual quantisation weighted activty. We use this to try to predict the activity of each frame. */ picture.ActivityMeasures( actsum, varsum ); avg_act = actsum/(double)(encparams.mb_per_pict); avg_var = varsum/(double)(encparams.mb_per_pict); sum_avg_act += avg_act; sum_avg_var += avg_var; actcovered = 0.0; sum_vbuf_Q = 0.0; /* Allocate target bits for frame based on frames numbers in GOP weighted by: - global complexity averages - predicted activity measures T = available_bits * (Nx * Xx) / Sigma_j (Nj * Xj) N.b. B frames are an exception as there is *no* predictive element in their bit-allocations. The reason this is done is that highly active B frames are inevitably the result of transients and/or scene changes. Psycho-visual considerations suggest there's no point rendering sudden transients terribly well as they're not percieved accurately anyway. In the case of scene changes similar considerations apply. In this case also we want to save bits for the next I or P frame where they will help improve other frames too. Note that we have to calulate per-frame bits by scaling the one-second bit-pool a one-GOP bit-pool. */ if( encparams.still_size > 0 ) available_bits = per_pict_bits; else { int feedback_correction = static_cast<int>( fast_tune ? buffer_variation * overshoot_gain : (buffer_variation+gop_buffer_correction) * overshoot_gain ); available_bits = static_cast<int>( (encparams.bit_rate+feedback_correction) * fields_in_gop/field_rate ); } Xsum = 0.0; int i; for( i = FIRST_PICT_TYPE; i <= LAST_PICT_TYPE; ++i ) Xsum += N[i]*Xhi[i]; vbuf_fullness = ratectl_vbuf[picture.pict_type]; double first_weight[NUM_PICT_TYPES]; first_weight[I_TYPE] = 1.0; first_weight[P_TYPE] = 1.7; first_weight[B_TYPE] = 1.7*2.0; double gop_frac = 0.0; if( first_encountered[picture.pict_type] ) { for( i = FIRST_PICT_TYPE; i <= LAST_PICT_TYPE; ++i ) gop_frac += N[i]/first_weight[i]; target_bits = static_cast<int32_t>(fields_per_pict*available_bits / (gop_frac * first_weight[picture.pict_type])); } else target_bits = static_cast<int32_t>(fields_per_pict*available_bits*Xhi[picture.pict_type]/Xsum); /* If we're fed a sequences of identical or near-identical images we can get actually get allocations for frames that exceed the video buffer size! This of course won't work so we arbitrarily limit any individual frame to 3/4's of the buffer. */ target_bits = min( target_bits, encparams.video_buffer_size*3/4 ); mjpeg_debug( "Frame %c T=%05d A=%06d Xi=%.2f Xp=%.2f Xb=%.2f", pict_type_char[picture.pict_type], (int)target_bits/8, (int)available_bits/8, Xhi[I_TYPE], Xhi[P_TYPE],Xhi[B_TYPE] ); /* To account for the wildly different sizes of frames we compute a correction to the current instantaneous buffer state that accounts for the fact that all other thing being equal buffer will go down a lot after the I-frame decode but fill up again through the B and P frames. For this we use the base bit allocations of the picture's "pict_base_bits" which will pretty accurately add up to a GOP-length's of bits not the more dynamic predictive T target bit-allocation (which *won't* add up very well). */ gop_buffer_correction += (pict_base_bits[picture.pict_type]-per_pict_bits); /* Undershot bits have been "returned" via R */ vbuf_fullness = max( vbuf_fullness, 0 ); /* We don't let the target volume get absurdly low as it makes some of the prediction maths ill-condtioned. At these levels quantisation is always minimum anyway */ target_bits = max( target_bits, 4000 ); if( encparams.still_size > 0 && encparams.vbv_buffer_still_size ) { /* If stills size must match then target low to ensure no overshoot. */ mjpeg_info( "Setting VCD HR still overshoot margin to %d bytes", target_bits/(16*8) ); frame_overshoot_margin = target_bits/16; target_bits -= frame_overshoot_margin; } picture.avg_act = avg_act; picture.sum_avg_act = sum_avg_act; mquant_change_ctr = encparams.mb_width; cur_mquant = ScaleQuant( picture.q_scale_type, fmax( vbuf_fullness*62.0/fb_gain, encparams.quant_floor) ); mquant_change_ctr = encparams.mb_width;}/* Step 1b: compute target bits for current picture being coded, based * on an actual encoding */void OnTheFlyRateCtl::InitKnownPict( Picture &picture ){ double target_Q; int available_bits; double Xsum,varsum; actcovered = 0.0; sum_vbuf_Q = 0.0; /* Allocate target bits for frame based on frames numbers in GOP weighted by: - global complexity averages - predicted activity measures T = (Nx * Xx) / Sigma_j (Nj * Xj) */ if( encparams.still_size > 0 ) available_bits = per_pict_bits; else { int feedback_correction = static_cast<int>( fast_tune ? buffer_variation * overshoot_gain : (buffer_variation+gop_buffer_correction) * overshoot_gain ); available_bits = static_cast<int>( (encparams.bit_rate+feedback_correction) * fields_in_gop/field_rate ); } Xsum = 0.0; int i; double rawquant = InvScaleQuant( picture.q_scale_type, static_cast<int>(actual_avg_Q) ); vbuf_fullness = static_cast<int>(rawquant*fb_gain/62.0); for( i = FIRST_PICT_TYPE; i <= LAST_PICT_TYPE; ++i ) Xsum += N[i]*Xhi[i]; target_bits = static_cast<int32_t>(fields_per_pict*available_bits*actual_Xhi/Xsum); /* If we're fed a sequences of identical or near-identical images we can get actually get allocations for frames that exceed the video buffer size! This of course won't work so we arbitrarily limit any individual frame to 3/4's of the buffer. */ target_bits = min( target_bits, encparams.video_buffer_size*3/4 ); mjpeg_debug( "Frame %c T=%05d A=%06d Xi=%.2f Xp=%.2f Xb=%.2f", pict_type_char[picture.pict_type], (int)target_bits/8, (int)available_bits/8, Xhi[I_TYPE], Xhi[P_TYPE],Xhi[B_TYPE] ); /* To account for the wildly different sizes of frames we compute a correction to the current instantaneous buffer state that accounts for the fact that all other thing being equal buffer will go down a lot after the I-frame decode but fill up again through the B and P frames. For this we use the base bit allocations of the picture's "pict_base_bits" which will pretty accurately add up to a GOP-length's of bits not the more dynamic predictive T target bit-allocation (which *won't* add up very well). */ gop_buffer_correction += (pict_base_bits[picture.pict_type]-per_pict_bits); /* We don't let the target volume get absurdly low as it makes some of the prediction maths ill-condtioned. At these levels quantisation is always minimum anyway */ target_bits = max( target_bits, 4000 ); if( encparams.still_size > 0 && encparams.vbv_buffer_still_size ) { /* If stills size must match then target low to ensure no overshoot. */ mjpeg_info( "Setting VCD HR still overshoot margin to %d bytes", target_bits/(16*8) ); frame_overshoot_margin = target_bits/16; target_bits -= frame_overshoot_margin; } printf( "vbuf = %d\n", vbuf_fullness ); cur_mquant = ScaleQuant( picture.q_scale_type, fmax( vbuf_fullness*62.0/fb_gain, encparams.quant_floor) ); printf( "MQ = %d\n", cur_mquant ); mquant_change_ctr = encparams.mb_width;}/* * Update rate-controls statistics after pictures has ended.. * * RETURN: The amount of padding necessary for picture to meet syntax or * rate constraints... */void OnTheFlyRateCtl::UpdatePict( Picture &picture, int &padding_needed){ double K; int32_t actual_bits; /* Actual (inc. padding) picture bit counts */ int i; int Qsum; int frame_overshoot; actual_bits = picture.SizeCodedMacroBlocks(); frame_overshoot = (int)actual_bits-(int)target_bits; /* For the virtual buffers for quantisation feedback it is the actual under/overshoot *including* padding. Otherwise the buffers go zero. BUGBUGBUG should'nt this go after the padding calculation? */ vbuf_fullness += frame_overshoot; /* Warn if it looks like we've busted the safety margins in stills size specification. Adjust padding to account for safety margin if we're padding to suit stills whose size has to be specified in advance in vbv_buffer_size. */ picture.pad = 0; int padding_bits = 0; if( encparams.still_size > 0 && encparams.vbv_buffer_still_size) { if( frame_overshoot > frame_overshoot_margin ) { mjpeg_warn( "Rate overshoot: VCD hi-res still %d bytes too large! ", ((int)actual_bits)/8-encparams.still_size); } // // Aim for an actual size squarely in the middle of the 2048 // byte granuality of the still_size coding. This gives a // safety margin for headers etc. // frame_overshoot = frame_overshoot - frame_overshoot_margin; if( frame_overshoot < -2048*8 ) frame_overshoot += 1024*8; // Make sure we pad nicely to byte alignment if( frame_overshoot < 0 ) { padding_bits = (((actual_bits-frame_overshoot)>>3)<<3)-actual_bits; picture.pad = 1; } } /* Adjust the various bit counting parameters for the padding bytes that * will be added */ actual_bits += padding_bits ; frame_overshoot += padding_bits; /* Compute the estimate of the current decoder buffer state. We use this to feedback-correct the available bit-pool with a fraction of the current buffer state estimate. If we're ahead of the game we allow a small increase in the pool. If we dropping towards a dangerously low buffer we decrease the pool (rather more vigorously). Note that since we cannot hold more than a buffer-full if we have a positive buffer_variation in CBR we assume it was padded away and in VBR we assume we only sent until the buffer was full. */ bits_used += actual_bits; bits_transported += per_pict_bits; //mjpeg_debug( "TR=%" PRId64 " USD=%" PRId64 "", bits_transported/8, bits_used/8); buffer_variation = static_cast<int32_t>(bits_transported - bits_used); if( buffer_variation > 0 ) { if( encparams.quant_floor > 0 ) { bits_transported = bits_used; buffer_variation = 0; } else if( buffer_variation > undershoot_carry ) { bits_used = bits_transported + undershoot_carry; buffer_variation = undershoot_carry; } } Qsum = 0; for( i = 0; i < encparams.mb_per_pict; ++i ) { Qsum += picture.mbinfo[i].mquant; } /* actual_Q is the average Quantisation of the block. Its only used for stats display as the integerisation of the quantisation value makes it rather coarse for use in estimating bit-demand */ actual_avg_Q = static_cast<double>(Qsum)/encparams.mb_per_pict; sum_avg_quant += actual_avg_Q; /* X (Chi - Complexity!) is an estimate of "bit-demand" for the frame. I.e. how many bits it would need to be encoded without quantisation. It is used in adaptively allocating bits to busy frames. It is simply calculated as bits actually used times average target (not rounded!) quantisation.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?