📄 rate.c
字号:
VBV_buffer -= frameBits; VBV_buffer += bufferFillRate; if (VBV_buffer < 0 && wantVbvUnderflowWarning) pm_message("WARNING - VBV buffer underflow (%d)", VBV_buffer); if (VBV_buffer > buffer_size && wantVbvOverflowWarning) pm_message("WARNING - VBV buffer overflow (%d > %d)", VBV_buffer, buffer_size);}/*===========================================================================* * * updateRateControl * * Update the statistics kept, after end of frame. Resets * various global variables * * RETURNS: nothing * * SIDE EFFECTS: many global variables * *===========================================================================*/voidupdateRateControl(int const type) { int totalBits, frameComplexity, pctAllocUsed, pctGOPUsed; float avgQuant; const char *strPtr; totalBits = rc_totalFrameBits; avgQuant = ((float) rc_totalQuant / (float) rc_numBlocks); frameComplexity = totalBits * avgQuant; pctAllocUsed = (totalBits *100 / current_Tx); rc_R -= totalBits; pctGOPUsed = (rc_R *100/ rc_G); avg_act = (total_act_j / MB_cnt); updateVBVBuffer(totalBits); switch (type) { case TYPE_IFRAME: Ti = current_Tx; d0_i = currentVirtBuf; Ni--; Si = totalBits; Qi = avgQuant; Xi = frameComplexity; break; case TYPE_PFRAME: Tp = current_Tx; d0_p = currentVirtBuf; Np--; Sp = totalBits; Qp = avgQuant; Xp = frameComplexity; break; case TYPE_BFRAME: Tb = current_Tx; d0_b = currentVirtBuf; Nb--; Sb = totalBits; Qb = avgQuant; Xb = frameComplexity; break; } /* Print Frame info */ strPtr = Frame_trailer1; DBG_PRINT(("%s\n",strPtr)); strPtr = Frame_trailer2; DBG_PRINT(("%s\n",strPtr)); strPtr = Frame_trailer3; DBG_PRINT(("%s\n",strPtr)); sprintf(rc_buffer, "%6d %2.2f %6d %3d %2.2f %7d " "%3d %7d %3d %6d %6d", totalBits, avgQuant, frameComplexity, avg_act, N_act, currentVirtBuf, pctAllocUsed, rc_R, pctGOPUsed, VBV_buffer, VBV_remainingDelay);#ifdef RC_STATS_FILE fprintf(RC_FILE,"%s\n", rc_buffer); fflush(RC_FILE);#endif DBG_PRINT(("%s\n",rc_buffer)); Nx--; rc_totalMBBits= rc_bitsThisMB= rc_totalFrameBits=rc_totalOverheadBits = 0; rc_numBlocks = rc_totalQuant = total_act_j = currentVirtBuf = 0; DBG_PRINT(("GOP now has %d bits remaining (%3d%%) for %d frames .. , " "Ni= %d, Np= %d, Nb= %d\n", rc_R, (rc_R*100/rc_G), (Ni+Np+Nb), Ni, Np, Nb)); }/*===========================================================================* * * MB_RateOut * * Prints out sampling of MB rate control data. Every "nth" block * stats are printed, with "n" controled by global RC_MB_SAMPLE_RATE * (NB. "skipped" blocks do not go through this function and thus do not * show up in the sample ) * * RETURNS: nothing * * SIDE EFFECTS: none * * NOTES: * *===========================================================================*/void MB_RateOut(type)int type;{ int totalBits; int pctUsed, pctDone; int bitsThisMB; int bitsPerMB; bitsThisMB = rc_bitsThisMB; totalBits = rc_totalFrameBits; bitsPerMB = (totalBits / rc_numBlocks); pctDone = (rc_numBlocks * 100/ MB_cnt); pctUsed = (totalBits *100/current_Tx); sprintf(rc_buffer, "%3d %5d %2d %3d %6d %3d %6d %2.2f %6d %4d %3d %3d\n", (rc_numBlocks - 1), bitsThisMB, Qscale, mquant, currentVirtBuf, rc_Q, act_j, N_act, totalBits, bitsPerMB, pctUsed, pctDone);#ifdef RC_STATS_FILE fprintf(RC_FILE, "%s", rc_buffer); fflush(RC_FILE);#endif if ( (RC_MB_SAMPLE_RATE) && ((rc_numBlocks -1) % RC_MB_SAMPLE_RATE)) { DBG_PRINT(("%s\n", rc_buffer)); } else { return; }}/*===========================================================================* * * incNumBlocks() * * * RETURNS: nothing * * SIDE EFFECTS: rc_numBlocks * * NOTES: * *===========================================================================*/void incNumBlocks(num) int num;{ rc_numBlocks += num;}/*===========================================================================* * * incMacroBlockBits() * * Increments the number of Macro Block bits and the total of Frame * bits by the number passed. * * RETURNS: nothing * * SIDE EFFECTS: rc_totalMBBits * * NOTES: * *===========================================================================*/void incMacroBlockBits(num) int num;{ rc_bitsThisMB = num; rc_totalMBBits += num; rc_totalFrameBits += num;}/*===========================================================================* * * needQScaleChange(current Q scale, 4 luminance blocks) * * * RETURNS: new Qscale * * SIDE EFFECTS: * *===========================================================================*/int needQScaleChange(oldQScale, blk0, blk1, blk2, blk3) int oldQScale; Block blk0; Block blk1; Block blk2; Block blk3;{ /* One more MacroBlock seen */ rc_numBlocks++; /* this notes each block num in MB */ checkBufferFullness(oldQScale); checkSpatialActivity(blk0, blk1, blk2, blk3); mquant = rc_Q * N_act; Qscale = (mquant > 31 ? 31 : mquant); Qscale = (Qscale < 1 ? 1 : Qscale); rc_totalQuant += Qscale; if (oldQScale == Qscale) return -1; else return Qscale;}/*===========================================================================* * * determineMBCount() * * Determines number of Macro Blocks in frame from the frame sizes * passed. * * RETURNS: nothing * * SIDE EFFECTS: sets the count passed * *===========================================================================*/int determineMBCount (){ int y,x; x = (Fsize_x +15)/16; y = (Fsize_y +15)/16; return (x * y);}/*===========================================================================* * * void checkBufferFullness () * * Calculates the fullness of the virtual buffer for each * frame type. Called before encoding each macro block. Along * with the normalisec spatial activity measure (N_act), it * determine the quantization factor for the next macroblock. * * RETURNS: nothing * * SIDE EFFECTS: the "currentVirtBuf" variable * * NOTES: * *===========================================================================*/void checkBufferFullness (oldQScale) int oldQScale;{ int temp; temp = lastFrameVirtBuf + rc_totalFrameBits; temp -= (current_Tx * rc_numBlocks / MB_cnt); currentVirtBuf = temp; rc_Q = (currentVirtBuf * 31 / reactionParameter); return;}/*===========================================================================* * * void checkSpatialActivity() * * Calcualtes the spatial activity for the four luminance blocks of the * macroblock. Along with the normalised reference quantization parameter * (rc_Q) , it determines the quantization factor for the next macroblock. * * RETURNS: nothing * * SIDE EFFECTS: the Adaptive quantization variables- act_j, N_act. * * NOTES: * *===========================================================================*/void checkSpatialActivity(blk0, blk1, blk2, blk3) Block blk0; Block blk1; Block blk2; Block blk3;{ int temp; int16 *blkArray[4]; int16 *curBlock; int16 *blk_ptr; int var[4]; int i, j; blkArray[0] = (int16 *) blk0; blkArray[1] = (int16 *) blk1; blkArray[2] = (int16 *) blk2; blkArray[3] = (int16 *) blk3; for (i =0; i < 4; i++) { /* Compute the activity in each block */ curBlock = blkArray[i]; blk_ptr = curBlock; P_mean = 0; /* Find the mean pixel value */ for (j=0; j < DCTSIZE_SQ; j ++) { P_mean += *(blk_ptr++); /* P_mean += curBlock[j]; if (curBlock[j] != *(blk_ptr++)) { printf("ARRAY ERROR: block %d\n", j); } */ } P_mean /= DCTSIZE_SQ; /* Now find the variance */ curBlock = blkArray[i]; blk_ptr = curBlock; var[i] = 0; for (j=0; j < DCTSIZE_SQ; j++) {#ifdef notdef if (curBlock[j] != *(blk_ptr++)) { printf("ARRAY ERROR: block %d\n", j); } temp = curBlock[j] - P_mean;#endif temp = *(blk_ptr++) - P_mean; var[i] += (temp * temp); } var[i] /= DCTSIZE_SQ; } /* Choose the minimum variance from the 4 blocks and use as the activity */ var_sblk = var[0]; for (i=1; i < 4; i++) { var_sblk = (var_sblk < var[i] ? var_sblk : var[i]); } act_j = 1 + var_sblk; total_act_j += act_j; temp = (2 * act_j + avg_act); N_act = ( (float) temp / (float) (act_j + 2*avg_act) ); return;}/*============================================================================* * * getRateMode () * * Returns the rate mode- interpreted as either Fixed or Variable * * RETURNS: integer * * SIDE EFFECTS: none * * *==========================================================================*/int getRateMode(){ return RateControlMode;}/*===========================================================================* * * setBitRate () * * Checks the string parsed from the parameter file. Verifies * number and sets global values. MPEG standard specifies that bit rate * be rounded up to nearest 400 bits/sec. * * RETURNS: nothing * * SIDE EFFECTS: global variables * * NOTES: Should this be in the 400-bit units used in sequence header? * *===========================================================================*/void setBitRate (const char * const charPtr){ int rate, rnd; rate = atoi(charPtr); if (rate > 0) { RateControlMode = FIXED_RATE; } else { printf("Parameter File Error: invalid BIT_RATE: \"%s\", defaults to Variable ratemode\n", charPtr); RateControlMode = VARIABLE_RATE; bit_rate = -1; } rnd = (rate % 400); rate += (rnd ? 400 -rnd : 0); /* round UP to nearest 400 bps */ rate = (rate > MAX_BIT_RATE ? MAX_BIT_RATE : rate); bit_rate = rate; DBG_PRINT(("Bit rate is: %d\n", bit_rate));} /*===========================================================================* * * getBitRate () * * Returns the bit rate read from the parameter file. This is the * real rate in bits per second, not in 400 bit units as is written to * the sequence header. * * RETURNS: int (-1 if Variable mode operation) * * SIDE EFFECTS: none * *===========================================================================*/int getBitRate (){ return bit_rate;}/*===========================================================================* * * setBufferSize () * * Checks the string parsed from the parameter file. Verifies * number and sets global values. * * RETURNS: nothing * * SIDE EFFECTS: buffer_size global variable. * * NOTES: The global is in bits, NOT the 16kb units used in sequence header * *===========================================================================*/void setBufferSize (const char * const charPtr){ int size; size = atoi(charPtr); size = (size > MAX_BUFFER_SIZE ? MAX_BUFFER_SIZE : size); if (size > 0) { size = (16*1024) * ((size + (16*1024 - 1)) / (16*1024)); buffer_size = size; } else { buffer_size = DEFAULT_BUFFER_SIZE; printf("Parameter File Error: invalid BUFFER_SIZE: \"%s\", defaults to : %d\n", charPtr, buffer_size); } DBG_PRINT(("Buffer size is: %d\n", buffer_size));}/*===========================================================================* * * getBufferSize () * * returns the buffer size read from the parameter file. Size is * in bits- not in units of 16k as written to the sequence header. * * RETURNS: int (or -1 if invalid) * * SIDE EFFECTS: none * *===========================================================================*/int getBufferSize (){ return buffer_size;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -