📄 ratectrl.c
字号:
} mean_MB= 0; for (l= 0; l < 16; l++) for (m=0; m < 16; m++) mean_MB += (float) diff->lum[l][m]; for (l= 0; l < 8; l++) for (m=0; m < 8; m++) { mean_MB += (float) diff->Cr[l][m]; mean_MB += (float) diff->Cb[l][m]; } mean_MB /= 384.0; var_MB= 0; for (l= 0; l < 16; l++) for (m=0; m < 16; m++) var_MB += (((float)diff->lum[l][m])-mean_MB)*(((float)diff->lum[l][m])-mean_MB); for (l= 0; l < 8; l++) for (m=0; m < 8; m++) { var_MB += (((float)diff->Cr[l][m])-mean_MB)*(((float)diff->Cr[l][m])-mean_MB); var_MB += (((float)diff->Cb[l][m])-mean_MB)*(((float)diff->Cb[l][m])-mean_MB); } var_MB /= 384.0; free(diff); /* divide variance by 3.0 if intra block */ if (MV[0][j+1][i+1]->Mode == MODE_INTRA) var_MB /= 3.0; var[i+j*(pels>>4)] = var_MB; dev[i+j*(pels>>4)] = (float) sqrt((double) var_MB); alpha[i+j*(pels>>4)] = ((B_target/256)/N_frame < 0.5) ? B_target/(128*N_frame) * (1-dev[i+j*(pels>>4)]) + dev[i+j*(pels>>4)] : 1; /* compute parameter S */ S += alpha[i+j*(pels>>4)] * dev[i+j*(pels>>4)]; } }}/********************************************************************** * * Name: Compute_QP * Description: compute quantizer of a macroblock * * Returns: Optimized quantizer for the macroblock * Side effects: * * Date: 970922 Author: Guy Cote <guyc@ee.ubc.ca> * ***********************************************************************/int Compute_QP(int xpos,int ypos){ int newQP; if ((L=(B_target - 256 * N * C))<=0) newQP = 31; else { newQP = (int) (sqrt( (256 * K * (float) dev[xpos+ypos * (pels>>4)] * S) / (L * alpha[xpos+ypos * (pels>>4)]) ) + 1)/2; newQP = mmax (1, mmin (31, newQP)); }#if 0 fprintf(stdout,"\nQP(%3d): %3d K: %5.4f B_target: %6.0f dev: %5.2f alpha: %4.3f L: %5.0f C: %5.4f, S: %5.0f", xpos+ypos * (pels>>4), newQP, K, B_target, dev[xpos+ypos * (pels>>4)], alpha[xpos+ypos * (pels>>4)], L, C, S );#endif return newQP;}/********************************************************************** * * Name: UpdateRateControlMB * Description: update counters and rate control parameters for the * macroblock * * Returns: * Side effects: * * Date: 970922 Author: Guy Cote <guyc@ee.ubc.ca> * ***********************************************************************/void UpdateRateControlMB(int bitsMB, int bitsCoeff, int xpos, int ypos, int QP){ /* Update counters */ B_target -= bitsMB; S -= alpha[xpos+ypos*(pels>>4)] * (float) dev[xpos+ypos*(pels>>4)]; N--; parameter_count++; /* Update model parameters */ K_est = ((float) bitsCoeff * (2*QP)*(2*QP)) / (var[xpos+ypos*(pels>>4)] * 256); C_est = ((float) bitsMB - (float) bitsCoeff) / 256; if (K_est>0 && K_est <= 4.53236014) { K_count++; K_avg = K_avg*((float) K_count-1)/K_count + K_est/K_count; } C_avg = C_avg*((float) MBN-1)/(MBN) + C_est/(MBN); /* The updates are a weighted average of the initial estimates * * and the current averages */ K = K_avg*((float) MBN/N_frame) + K_prev*(N_frame - MBN)/N_frame; C = C_avg*((float) MBN/N_frame) + C_prev*(N_frame - MBN)/N_frame; MBN++;}int InitializeQuantizer (int pict_type, float bit_rate, float target_frame_rate, float QP_mean)/* QP_mean = mean quantizer parameter for the previous picture *//* bitcount = current total bit count *//* To calculate bitcount in coder.c, do something like this : *//* int bitcount; *//* AddBitsPicture(bits); *//* bitcount = bits->total; */{ int newQP; if (pict_type == PCT_INTER || pict_type == PCT_IPB) { B_target = bit_rate / target_frame_rate; /* compute picture buffer descrepency as of the previous picture */ if (B_prev != 0.0) { global_adj = (B_prev - B_target) / (2 * B_target); } else { global_adj = (float) 0.0; } newQP = (int) (QP_mean * (1 + global_adj) + (float) 0.5); newQP = mmax (1, mmin (31, newQP)); } else if (pict_type == PCT_INTRA) { fprintf (stderr, "No need to call InititializeQuantizer() for Intra picture\n"); exit (-1); } else { fprintf (stderr, "Error (InitializePictureRate): picture type unkown.\n"); exit (-1); }#if 1 printf ("Global adj = %.2f\n", global_adj); printf ("meanQP = %.2f newQP = %d\n", QP_mean, newQP);#endif fprintf (stdout, "Target no. of bits: %.2f\n", B_target); return newQP;}/********************************************************************** Name: UpdateQuantizer*** Description: This function generates a new quantizer step size based* on bits spent up until current macroblock and bits* spent from the previous picture. Note: this* routine should be called at the beginning of each* macroblock line as specified by TMN4. However, this* can be done at any macroblock if so desired.** Input: current macroblock number (raster scan), mean quantizer* paramter for previous picture, bit rate, source frame rate,* hor. number of macroblocks, vertical number of macroblocks, total #* of bits used until now in the current picture.** Returns: Returns a new quantizer step size for the use of current* macroblock Note: adjustment to fit with 2-bit DQUANT should be done* in the calling program (unless Annex T is used)** Side Effects:** Date: 1/5/95 Author: Anurag Bist* ***********************************************************************/int UpdateQuantizer (int mb, float QP_mean, int pict_type, float bit_rate, int mb_width, int mb_height, int bitcount)/* mb = macroblock index number *//* QP_mean = mean quantizer parameter for the previous picture *//* bitcount = total # of bits used until now in the current picture */{ int newQP = 16; float local_adj, descrepency, projection; if (pict_type == PCT_INTRA) { newQP = 16; } else if (pict_type == PCT_INTER || pict_type == PCT_IPB) { /* compute expected buffer fullness */ projection = mb * (B_target / (mb_width * mb_height)); /* measure descrepency between current fullness and projection */ descrepency = (bitcount - projection); /* scale */ local_adj = 12 * descrepency / bit_rate;#if 0 printf ("mb = %d\n", mb); printf ("bit_count = %d projection = %.2f \n", bitcount, projection); printf ("B_target = %.2f local_adj = %.2f \n", B_target, local_adj);#endif newQP = (int) (QP_mean * (1 + global_adj + local_adj) + 0.5); /* the update equation for newQP in TMN4 document section 3.7 */ } else { fprintf (stderr, "Error (UpdateQuantizer): picture type unkown.\n"); }#if 0 printf ("mb = %d newQP = %d \n", mb, newQP);#endif newQP = mmax (1, mmin (31, newQP)); return newQP;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -