Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

rate.c

Go to the documentation of this file.
00001 /*============================================================================*
00002  * rate.c                                                                     *
00003  *                                                                            * 
00004  *      Procedures concerned with rate control                                *
00005  *                                                                            *
00006  * EXPORTED PROCEDURES:                                                       *
00007  *      initRatecontrol()                                                     *
00008  *      targetRateControl()                                                   *
00009  *      updateRateControl()                                                   *
00010  *      MB_RateOut()                                                          *
00011  *      needQScaleChange()                                                    *
00012  *      incNumBlocks()                                                        *
00013  *      incQuant()                                                            *
00014  *      incMacroBlockBits()                                                   *
00015  *      setPictureRate()                                                      *
00016  *      setBitRate()                                                          *
00017  *      getBitRate()                                                          *
00018  *      setBufferSize()                                                       *
00019  *      getBufferSize()                                                       *
00020  *                                                                            *
00021  * NOTES:                                                                     *
00022  *      Naming conventions follow those of MPEG-2 draft algorithm (chap. 10)  *
00023  *============================================================================*/
00024 
00025 
00026 /*
00027  * Copyright (c) 1995 The Regents of the University of California.
00028  * All rights reserved.
00029  *
00030  * Permission to use, copy, modify, and distribute this software and its
00031  * documentation for any purpose, without fee, and without written agreement is
00032  * hereby granted, provided that the above copyright notice and the following
00033  * two paragraphs appear in all copies of this software.
00034  *
00035  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
00036  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
00037  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
00038  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00039  *
00040  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
00041  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
00042  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
00043  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
00044  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
00045  */
00046 
00047 /*==============*
00048  * HEADER FILES *
00049  *==============*/
00050 
00051 #include <sys/times.h>
00052 #include "all.h"
00053 #include "mtypes.h"
00054 #include "bitio.h"
00055 #include "frames.h"
00056 #include "prototypes.h"
00057 #include "param.h"
00058 #include "mheaders.h"
00059 #include "fsize.h"
00060 #include "postdct.h"
00061 #include "mpeg.h"
00062 #include "parallel.h"
00063 #include "dct.h"
00064 #include "rate.h"
00065 
00066 
00067 /*==================*
00068  * GLOBAL VARIABLES *
00069  *==================*/
00070 
00071 #define MAX_BIT_RATE 104857600          /* 18 digit number in units of 400 */
00072 #define MAX_BUFFER_SIZE 16760832        /* 10 digit number in units of 16k */
00073 #define DEFAULT_BUFFER_SIZE 327680      /* maximun for "constrained" bitstream */
00074 #define DEFAULT_VBV_FULLNESS 3          /* wait till 1/3 full */
00075 #define DEFAULT_PICT_RATE_CODE 5        /* code for 30 Frames/sec */
00076 #define DEFAULT_PICT_RATE 30            /* 30 frames per second */
00077 #define MAX_VBV_DELAY 32768             /* 16 digits */
00078 
00079 
00080 /*        Variables from Parameter File */
00081 
00082 static int      RateControlMode = VARIABLE_RATE;
00083 static int32 buffer_size = DEFAULT_BUFFER_SIZE;
00084 static int32 bit_rate = -1;
00085 
00086 
00087 /*   Variables for the VBV buffer defined in MPEG specs */
00088 static int32 VBV_delay =0;          /* delay in units of 1/90000 seconds */
00089 static int32 VBV_buffer = 0;        /* fullness of the theoretical VBV buffer */
00090 static int32 bufferFillRate = 0;    /* constant rate at which buffer filled */
00091 static int32 frameDelayIncrement = 0;   /* number of "delay" units/Frame */
00092 
00093 /*  Global complexity measure variables */
00094 static int Xi, Xp, Xb;  /*  Global complexity measure  */
00095 
00096 static int Si, Sp, Sb;  /*  Total # bits for last pict of type (Overhead?) */
00097 
00098 static float Qi, Qp, Qb; /* avg quantizaton for last picture of type  */
00099      
00100 /*  Target bit allocations for each type of picture*/
00101 int Ti, Tp, Tb;
00102 
00103 int current_Tx; /* allocation for current frame */
00104 
00105 /*  Count of number of pictures of each type remaining */
00106 int GOP_X = 0;
00107 int GOP_I = 0;
00108 int GOP_P = 0;
00109 int GOP_B = 0;
00110 
00111 int Nx = 0;
00112 int Ni = 0;
00113 int Np = 0;
00114 int Nb = 0;
00115 
00116 /*   Counters used while encoding frames   */
00117 
00118 int rc_numBlocks = 0;
00119 int rc_totalQuant = 0;
00120 int rc_bitsThisMB;
00121 int rc_totalMBBits;
00122 int rc_totalFrameBits;
00123 int rc_totalOverheadBits = 0;
00124 
00125 
00126 /*      Want to print out Macroblock info every Nth MB */
00127 int RC_MB_SAMPLE_RATE = 0;
00128 
00129 static float Ki = .7;
00130 static float Kp = 1;
00131 static float Kb = 1.4;
00132 static int rc_R;
00133 static int rc_G;
00134 
00135 /*   Rate Control variables   */
00136 
00137 /*   Virtual buffers for each frame type */
00138 static int d0_i;   /* Initial fullnesses */
00139 static int d0_p;
00140 static int d0_b;
00141 
00142 static int lastFrameVirtBuf;   /* fullness after last frame of this type */
00143 static int currentVirtBuf;     /* fullness during current encoding*/
00144 
00145 static int MB_cnt = -1;        /* Number of MB's in picture */
00146 
00147 static int rc_Q;               /* reference quantization parameter */
00148 
00149 static int reactionParameter;  /*  Reaction parameter */
00150 
00151 /*      Adaptive Quantization variables */
00152 static int act_j;              /*  spatial activity measure */
00153 static float N_act;            /*  Normalised spacial activity */
00154 static int avg_act;        /*  average activity value in last picture encoded */
00155 static int total_act_j;        /*  Sum of activity values in current frame */
00156 
00157 static int var_sblk;           /* sub-block activity */
00158 static int P_mean;             /* Mean value of pixels in 8x8 sub-block */
00159 
00160 static int mquant;             /* Raw Quantization value */
00161 static int Qscale;             /* Clipped, truncated quantization value */
00162 
00163 
00164 
00165 /*  Output-related variables */
00166 #ifdef RC_STATS_FILE
00167 static FILE *RC_FILE;
00168 #endif
00169 
00170 static char *Frame_header1 = "  Fm         #     Bit      GOP                    V                ";
00171 static char *Frame_header2 = "   #  type   MBs   Alloc    left  Ni Np Nb  N_act  buff   Q_rc Qscale";
00172 static char *Frame_header3 = "----     -  ----  ------ -------  -- -- --  -----  ------ ----   ----";
00173 static char *Frame_trailer1 = "                      avg          virt     %    GOP      %     VBV";
00174 static char *Frame_trailer2 = "    Sx    Qx      Xx  act N_act  buffer alloc    left  left     buf  delay";
00175 static char *Frame_trailer3 = "------ --.-- -------  --- --.-- -------   --- -------   --- ------- ------";
00176 
00177 static char *MB_header1 = "MB#  #bits  Q mqt     Dj  Q_j   actj  N_act  totbits b/MB %alloc %done";
00178 static char *MB_header2 = "---  ----- -- --- ------  ---  -----  --.--   ------ ----    ---   ---";
00179 
00180 static char rc_buffer[101];
00181 
00182 /*      EXTERNAL Variables  */
00183 extern char *framePattern;
00184 extern int framePatternLen;
00185 
00186 
00187 /*===============================*
00188  * INTERNAL PROCEDURE prototypes *
00189  *===============================*/
00190 
00191 int initGOPRateControl _ANSI_ARGS_((void));
00192      int determineMBCount _ANSI_ARGS_((void));
00193      void checkBufferFullness _ANSI_ARGS_((int count));
00194      void checkSpatialActivity _ANSI_ARGS_((Block blk0, Block blk1, Block blk2, Block blk3));
00195      void incNumBlocks _ANSI_ARGS_((int num));
00196      void calculateVBVDelay _ANSI_ARGS_((int num));
00197      void updateVBVBuffer _ANSI_ARGS_((int frameBits));
00198      int BlockExperiments  _ANSI_ARGS_((int16 *OrigBlock, int16 *NewBlock, int control));
00199      
00200      
00201      /*=====================*
00202       * EXPORTED PROCEDURES *
00203       *=====================*/
00204      
00205      /*===========================================================================*
00206       *
00207       * initRateControl
00208       *
00209       * initialize the allocation parameters.
00210       *
00211       * RETURNS:        nothing
00212       *
00213       * SIDE EFFECTS:   many global variables 
00214       *
00215       * NOTES:  Get rid of the redundant pattern stuff!!
00216       *===========================================================================*/
00217      int
00218        initRateControl()
00219 {
00220   int index;
00221   int result;
00222   
00223   DBG_PRINT(("\tInitializing Allocation Data\n"));
00224   
00225 #ifdef RC_STATS_FILE
00226   RC_FILE = fopen("RC_STATS_FILE", "w");
00227   if ( RC_FILE  == NULL) {
00228     DBG_PRINT(("\tOpen of RC file failed, using stderr\n"));
00229     RC_FILE = stderr;
00230     fprintf(RC_FILE, "\tOpen of RC file failed, using stderr\n");
00231     fflush(RC_FILE);
00232   }
00233 #endif
00234   
00235   /*  Initialize Pattern info */
00236   GOP_X = framePatternLen;
00237   for ( index = 0; index < framePatternLen; index++ ) {
00238     switch( framePattern[index] ) {
00239     case 'i':
00240       GOP_I++;
00241       break;
00242     case 'p':
00243       GOP_P++;
00244       break;
00245     case 'b':
00246       GOP_B++;
00247       break;
00248     default:
00249       printf("\n\tERROR rate.c - BAD PATTERN!\n");
00250       RateControlMode = VARIABLE_RATE;
00251       return (0);
00252     }
00253   }
00254   if (GOP_X != (GOP_I + GOP_P + GOP_B )) {
00255     printf("\n\tERROR rate.c - Pattern Length Mismatch\n");
00256     RateControlMode = VARIABLE_RATE;
00257     return (-1);
00258   }
00259   
00260   /* Initializing GOP bit allocation */ 
00261   rc_R = 0;
00262   rc_G = (bit_rate * GOP_X/frameRateRounded);
00263   
00264   /*   Initialize the "global complexity measures" */
00265   Xi = (160 * bit_rate/115);
00266   Xp = (60 * bit_rate/115);
00267   Xb = (42 * bit_rate/115);
00268   
00269   /*   Initialize MB counters */
00270   rc_totalMBBits= rc_bitsThisMB= rc_totalFrameBits=rc_totalOverheadBits = 0;
00271   rc_numBlocks = rc_totalQuant = 0;
00272   
00273   /*   init virtual buffers  */
00274   reactionParameter = (2 * bit_rate / frameRateRounded);
00275   d0_i = (10 * reactionParameter / 31);
00276   d0_p = (Kp * d0_i);
00277   d0_b = (Kb * d0_i);
00278   
00279   lastFrameVirtBuf = d0_i;      /*  start with I Frame */
00280   rc_Q = lastFrameVirtBuf  * 31 / reactionParameter;
00281   
00282   /*   init spatial activity measures */
00283   avg_act = 400;                /* Suggested initial value */
00284   N_act = 1;
00285   
00286   mquant = rc_Q * N_act;
00287   
00288   frameDelayIncrement = (90000 / frameRateRounded); /* num of "delay" units per frame */
00289   bufferFillRate = bit_rate / frameRateRounded; /* VBV buf fills at constant rate */
00290   VBV_buffer = buffer_size;
00291   DBG_PRINT(("\tVBV- delay: %d, fill rate: %d, delay/Frame: %d units, buffer size: %d\n",
00292              VBV_delay, bufferFillRate, frameDelayIncrement, buffer_size));
00293   
00294   result = initGOPRateControl();
00295   
00296   return result;
00297 }
00298 
00299 /*===========================================================================*
00300  *
00301  * initGOPRateControl
00302  *
00303  *              (re)-initialize the RC for the a new Group of Pictures.
00304  *      New bit allocation, but carry over complexity measures.
00305  *
00306  * RETURNS:     nothing
00307  *
00308  * SIDE EFFECTS:   many global variables 
00309  *
00310  *===========================================================================*/
00311 int
00312   initGOPRateControl()
00313 {
00314   DBG_PRINT(("\tInitializing new GOP\n"));
00315   
00316   Nx = GOP_X;
00317   Ni = GOP_I;
00318   Np = GOP_P;
00319   Nb = GOP_B;
00320   
00321   rc_R += rc_G;
00322   
00323   DBG_PRINT(("\tbufsize: %d, bitrate: %d, pictrate: %d, GOP bits: %d\n",
00324              buffer_size, bit_rate, frameRateRounded, rc_R));
00325   DBG_PRINT(("\tXi: %d, Xp: %d, Xb: %d Nx: %d, Ni: %d, Np: %d, Nb: %d\n",
00326              Xi, Xp, Xb, Nx,Ni,Np,Nb));
00327   DBG_PRINT(("\td0_i: %d, d0_p: %d, d0_b: %d, avg_act: %d, rc_Q: %d, mquant: %d\n",
00328              d0_i, d0_p, d0_b, avg_act, rc_Q, mquant));
00329   return 1;
00330 }
00331 
00332 
00333 /*===========================================================================*
00334  *
00335  * targetRateControl
00336  *
00337  *      Determine the target allocation for given picture type, initiates
00338  *  variables for rate control process.
00339  *
00340  * RETURNS:     nothing.
00341  *
00342  * SIDE EFFECTS:   many global variables
00343  *
00344  *===========================================================================*/
00345 void
00346   targetRateControl(frame)
00347 MpegFrame   *frame;
00348 {
00349   float temp1, minimumBits;
00350   float tempX, tempY, tempZ;
00351   int result;
00352   int frameType;
00353   char *strPtr;
00354   
00355   minimumBits = (bit_rate / (8 * frameRateRounded));
00356   
00357   /*   Check if new GOP */
00358   if (Nx == 0) {
00359     initGOPRateControl();
00360   }
00361   
00362   if (MB_cnt < 0) {MB_cnt = determineMBCount();}
00363   
00364   switch (frame->type) {
00365   case TYPE_IFRAME:
00366     frameType = 'I';
00367     
00368     /*          temp1 = ( rc_R / ( 1+ ((Np * Xp) / (Xi * Kp)) + ((Nb*Xb) / (Xi*Kb))))); */
00369     
00370     tempX = ( (Np * Ki * Xp) / (Xi * Kp) );
00371     tempY = ( (Nb * Ki * Xb) / (Xi*Kb) );
00372     tempZ = Ni + tempX + tempY;
00373     temp1 = (rc_R / tempZ);
00374     result = (int) (temp1 > minimumBits ? temp1 :  minimumBits);
00375     current_Tx = Ti = result;
00376     lastFrameVirtBuf = d0_i;
00377     break;
00378     
00379   case TYPE_PFRAME:
00380     frameType = 'P';
00381     tempX =  ( (Ni * Kp * Xi) / (Ki * Xp) );
00382     tempY =  ( (Nb * Kp * Xb) / (Kb * Xp) );
00383     tempZ = Np + tempX + tempY;
00384     temp1 = (rc_R/ tempZ);
00385     result = (int) (temp1 > minimumBits ? temp1 :  minimumBits);
00386     current_Tx = Tp = result;
00387     lastFrameVirtBuf = d0_p;
00388     break;
00389     
00390   case TYPE_BFRAME:
00391     frameType = 'B';
00392     tempX =  ( (Ni * Kb * Xi) / (Ki * Xb) );
00393     tempY =  ( (Np * Kb * Xp) / (Kp * Xb) );
00394     tempZ = Nb + tempX + tempY;
00395     temp1 = (rc_R/ tempZ);
00396     result = (int) (temp1 > minimumBits ? temp1 :  minimumBits);
00397     current_Tx = Tb = result;
00398     lastFrameVirtBuf = d0_b;
00399     break;
00400     
00401   default:
00402     frameType = 'X';
00403   }
00404   
00405   N_act = 1;
00406   rc_Q = lastFrameVirtBuf  * 31 / reactionParameter;
00407   mquant = rc_Q * N_act;
00408   Qscale = (mquant > 31 ? 31 : mquant);
00409   Qscale = (Qscale < 1 ? 1 : Qscale);
00410   
00411   /*   Print headers for Frame info */
00412   strPtr = Frame_header1;
00413   DBG_PRINT(("%s\n",strPtr));
00414   strPtr = Frame_header2;
00415   DBG_PRINT(("%s\n",strPtr));
00416   strPtr = Frame_header3;
00417   DBG_PRINT(("%s\n",strPtr));
00418   
00419   /*   Print Frame info */
00420   sprintf(rc_buffer, "%4d     %1c  %4d  %6d %7d  %2d %2d %2d   %2.2f  %6d %4d    %3d",
00421           frame->id,frameType,MB_cnt,current_Tx,rc_R,Ni,Np,Nb, N_act, lastFrameVirtBuf, rc_Q, Qscale);
00422   
00423 #ifdef RC_STATS_FILE
00424   fprintf(RC_FILE,"%s\n", rc_buffer);
00425   fflush(RC_FILE);
00426 #endif
00427   DBG_PRINT(("%s\n",rc_buffer));
00428   
00429   /*  Print headers for Macroblock info */
00430   if (RC_MB_SAMPLE_RATE) {
00431     strPtr = MB_header1;
00432     DBG_PRINT(("%s\n",strPtr));
00433     strPtr = MB_header2;
00434     DBG_PRINT(("%s\n",strPtr));
00435   } else {
00436     return;
00437   }
00438   
00439   return;
00440 }
00441 
00442 
00443 
00444 /*===========================================================================*
00445  *
00446  * updateRateControl
00447  *
00448  *      Update the statistics kept, after end of frame.  Resets
00449  *  various global variables
00450  *
00451  * RETURNS:     nothing
00452  *
00453  * SIDE EFFECTS:   many global variables
00454  *
00455  *===========================================================================*/
00456 void
00457   updateRateControl(type)
00458 int type; 
00459 {
00460   int totalBits, frameComplexity, pctAllocUsed, pctGOPUsed;
00461   float avgQuant;
00462   char *strPtr;
00463   
00464   totalBits = rc_totalFrameBits;
00465   avgQuant = ((float) rc_totalQuant / (float) rc_numBlocks);
00466   frameComplexity = totalBits * avgQuant;
00467   pctAllocUsed = (totalBits *100 / current_Tx);
00468   rc_R -= totalBits;
00469   pctGOPUsed = (rc_R *100/ rc_G);
00470   
00471   avg_act = (total_act_j / MB_cnt);
00472   
00473   updateVBVBuffer(totalBits);
00474   
00475   switch (type) {
00476   case TYPE_IFRAME:
00477     Ti = current_Tx;
00478     d0_i = currentVirtBuf;
00479     Ni--;
00480     Si = totalBits;
00481     Qi = avgQuant;
00482     Xi = frameComplexity;
00483     break;
00484   case TYPE_PFRAME:
00485     Tp = current_Tx;
00486     d0_p = currentVirtBuf;
00487     Np--;
00488     Sp = totalBits;
00489     Qp = avgQuant;
00490     Xp = frameComplexity;
00491     break;
00492   case TYPE_BFRAME:
00493     Tb = current_Tx;
00494     d0_b = currentVirtBuf;
00495     Nb--;
00496     Sb = totalBits;
00497     Qb = avgQuant;
00498     Xb = frameComplexity;
00499     break;
00500   }
00501   
00502   
00503   /*  Print Frame info */
00504   strPtr = Frame_trailer1;
00505   DBG_PRINT(("%s\n",strPtr));
00506   strPtr = Frame_trailer2;
00507   DBG_PRINT(("%s\n",strPtr));
00508   strPtr = Frame_trailer3;
00509   DBG_PRINT(("%s\n",strPtr));
00510   
00511   sprintf(rc_buffer, "%6d  %2.2f  %6d  %3d  %2.2f %7d   %3d %7d   %3d  %6d %6d",
00512           totalBits, avgQuant, frameComplexity, avg_act, N_act, currentVirtBuf, pctAllocUsed, rc_R, pctGOPUsed, VBV_buffer, VBV_delay);
00513 #ifdef RC_STATS_FILE
00514   fprintf(RC_FILE,"%s\n", rc_buffer);
00515   fflush(RC_FILE);
00516 #endif
00517   DBG_PRINT(("%s\n",rc_buffer));
00518   
00519   Nx--;
00520   rc_totalMBBits= rc_bitsThisMB= rc_totalFrameBits=rc_totalOverheadBits = 0;
00521   rc_numBlocks = rc_totalQuant = total_act_j = currentVirtBuf = 0;
00522   
00523   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));
00524   
00525 }
00526 
00527 
00528 /*===========================================================================*
00529  *
00530  * MB_RateOut
00531  *
00532  *      Prints out sampling of MB rate control data.  Every "nth" block
00533  *      stats are printed, with "n" controled by global RC_MB_SAMPLE_RATE
00534  *      (NB. "skipped" blocks do not go through this function and thus do not
00535  *              show up in the sample )
00536  *
00537  * RETURNS:     nothing
00538  *
00539  * SIDE EFFECTS:   none
00540  *
00541  * NOTES:
00542  *
00543  *===========================================================================*/
00544 void
00545   MB_RateOut(type)
00546 int type;
00547 {
00548   int totalBits;
00549   int pctUsed, pctDone;
00550   int bitsThisMB;
00551   int bitsPerMB;
00552   
00553   bitsThisMB = rc_bitsThisMB;
00554   totalBits = rc_totalFrameBits;
00555   bitsPerMB = (totalBits / rc_numBlocks); 
00556   pctDone = (rc_numBlocks * 100/ MB_cnt); 
00557   pctUsed = (totalBits *100/current_Tx);
00558   
00559   sprintf(rc_buffer, "%3d  %5d %2d %3d %6d  %3d %6d   %2.2f   %6d %4d    %3d   %3d\n",
00560           (rc_numBlocks - 1), bitsThisMB, Qscale, mquant, currentVirtBuf, 
00561           rc_Q, act_j, N_act, totalBits, bitsPerMB, pctUsed, pctDone);
00562 #ifdef RC_STATS_FILE
00563   fprintf(RC_FILE, "%s", rc_buffer);
00564   fflush(RC_FILE);
00565 #endif
00566   
00567   if ( (RC_MB_SAMPLE_RATE) && ((rc_numBlocks -1) % RC_MB_SAMPLE_RATE)) {
00568     DBG_PRINT(("%s\n", rc_buffer));
00569   } else {
00570     return;
00571   }
00572 }
00573 
00574 
00575 
00576 /*===========================================================================*
00577  *
00578  * incNumBlocks()
00579  *
00580  *
00581  * RETURNS:   nothing
00582  *
00583  * SIDE EFFECTS:  rc_numBlocks
00584  *
00585  * NOTES:
00586  *
00587  *===========================================================================*/
00588 void incNumBlocks(num)
00589      int num;
00590 {
00591   rc_numBlocks += num;
00592 }
00593 
00594 
00595 /*===========================================================================*
00596  *
00597  * incMacroBlockBits()
00598  *
00599  *      Increments the number of Macro Block bits and the total of Frame
00600  *  bits by the number passed.
00601  *
00602  * RETURNS:   nothing
00603  *
00604  * SIDE EFFECTS:  rc_totalMBBits
00605  *
00606  * NOTES:
00607  *
00608  *===========================================================================*/
00609 void incMacroBlockBits(num)
00610      int num;
00611 {
00612   rc_bitsThisMB = num;
00613   rc_totalMBBits += num;
00614   rc_totalFrameBits += num;
00615 }
00616 
00617 
00618 /*===========================================================================*
00619  *
00620  *      needQScaleChange(current Q scale, 4 luminance blocks)
00621  *
00622  *
00623  * RETURNS:     new Qscale
00624  *
00625  * SIDE EFFECTS:   
00626  *
00627  *===========================================================================*/
00628 int needQScaleChange(oldQScale, blk0, blk1, blk2, blk3)
00629      int oldQScale;
00630      Block blk0;
00631      Block blk1;
00632      Block blk2;
00633      Block blk3;
00634 {
00635   
00636   /*   One more MacroBlock seen */
00637   rc_numBlocks++;               /* this notes each block num in MB */
00638   
00639   checkBufferFullness(oldQScale);
00640   
00641   checkSpatialActivity(blk0, blk1, blk2, blk3);
00642   
00643   mquant = rc_Q * N_act;
00644   Qscale = (mquant > 31 ? 31 : mquant);
00645   Qscale = (Qscale < 1 ? 1 : Qscale);
00646   rc_totalQuant += Qscale;
00647   
00648   if (oldQScale == Qscale)
00649     return -1;
00650   else
00651     return Qscale;
00652 }
00653 
00654 
00655 /*===========================================================================*
00656  *
00657  * determineMBCount() 
00658  *
00659  *      Determines number of Macro Blocks in frame from the frame sizes
00660  *      passed.
00661  *
00662  * RETURNS:     nothing
00663  *
00664  * SIDE EFFECTS:   sets the count passed
00665  *
00666  *===========================================================================*/
00667 int
00668   determineMBCount ()
00669 {
00670   int y,x;
00671   
00672   x = (Fsize_x +15)/16;
00673   y = (Fsize_y +15)/16;
00674   return  (x * y);
00675 }
00676 
00677 
00678 
00679 /*===========================================================================*
00680  *
00681  * void checkBufferFullness ()
00682  *
00683  *      Calculates the fullness of the virtual buffer for each
00684  *  frame type.  Called before encoding each macro block.  Along
00685  *  with the normalisec spatial activity measure (N_act), it
00686  *  determine the quantization factor for the next macroblock.
00687  *
00688  * RETURNS:     nothing
00689  *
00690  * SIDE EFFECTS:   the "currentVirtBuf" variable
00691  *
00692  * NOTES:
00693  *
00694  *===========================================================================*/
00695 void checkBufferFullness (oldQScale)
00696      int oldQScale;
00697 {
00698   int temp;
00699   
00700   temp = lastFrameVirtBuf + rc_totalFrameBits;
00701   temp -=  (current_Tx * rc_numBlocks / MB_cnt);
00702   currentVirtBuf = temp;
00703   
00704   rc_Q = (currentVirtBuf * 31 / reactionParameter);
00705   return;
00706 }
00707 
00708 
00709 /*===========================================================================*
00710  *
00711  * void checkSpatialActivity()
00712  *
00713  *      Calcualtes the spatial activity for the four luminance blocks of the
00714  *      macroblock.  Along with the normalised reference quantization parameter 
00715  *  (rc_Q) , it determines the quantization factor for the next macroblock.
00716  *
00717  * RETURNS:     nothing
00718  *
00719  * SIDE EFFECTS:   the Adaptive quantization variables- act_j, N_act.
00720  *
00721  * NOTES:
00722  *
00723  *===========================================================================*/
00724 void checkSpatialActivity(blk0, blk1, blk2, blk3)
00725      Block blk0;
00726      Block blk1;
00727      Block blk2;
00728      Block blk3;
00729 {
00730   int temp;
00731   int16 *blkArray[4]; 
00732   int16 *curBlock;
00733   int16 *blk_ptr;
00734   int var[4];
00735   int i, j;
00736   
00737   
00738   blkArray[0] = (int16 *) blk0;
00739   blkArray[1] = (int16 *) blk1;
00740   blkArray[2] = (int16 *) blk2;
00741   blkArray[3] = (int16 *) blk3;
00742   
00743   
00744   for (i =0; i < 4; i++) {      /* Compute the activity in each block */
00745     curBlock = blkArray[i];
00746     blk_ptr = curBlock;
00747     P_mean = 0;
00748     /*  Find the mean pixel value */
00749     for (j=0; j < DCTSIZE_SQ; j ++) {
00750       P_mean += *(blk_ptr++);
00751       /*                        P_mean += curBlock[j]; 
00752                                 if (curBlock[j] != *(blk_ptr++)) {
00753                                 printf("\n\tARRAY ERROR: block %d\n", j);
00754                                 }
00755                                 */
00756     }
00757     P_mean /= DCTSIZE_SQ;
00758     
00759     /*  Now find the variance  */
00760     curBlock = blkArray[i];
00761     blk_ptr = curBlock;
00762     var[i] = 0;
00763     for (j=0; j < DCTSIZE_SQ; j++) {
00764 #ifdef notdef
00765       if (curBlock[j] != *(blk_ptr++)) {
00766         printf("\n\tARRAY ERROR: block %d\n", j);
00767       }
00768       temp = curBlock[j] - P_mean;
00769 #endif      
00770       temp = *(blk_ptr++) - P_mean;
00771       var[i] += (temp * temp);
00772     }
00773     var[i] /= DCTSIZE_SQ;
00774   }
00775   
00776   /*  Choose the minimum variance from the 4 blocks and use as the activity */
00777   var_sblk  = var[0];
00778   for (i=1; i < 4; i++) {
00779     var_sblk = (var_sblk < var[i] ? var_sblk : var[i]);
00780   }
00781   
00782   
00783   act_j = 1 + var_sblk;
00784   total_act_j += act_j;
00785   temp = (2 * act_j + avg_act);
00786   N_act = ( (float) temp / (float) (act_j + 2*avg_act) );
00787   
00788   return;
00789 }
00790 
00791 
00792 
00793 
00794 /*============================================================================*
00795  *
00796  * getRateMode ()
00797  *
00798  *      Returns the rate mode- interpreted as either Fixed or Variable
00799  *
00800  * RETURNS:     integer
00801  *
00802  * SIDE EFFECTS:   none
00803  *
00804  *
00805  *==========================================================================*/
00806 int getRateMode()
00807 {
00808   return RateControlMode;
00809 }
00810 
00811 
00812 /*===========================================================================*
00813  *
00814  * setBitRate ()
00815  *
00816  *      Checks the string parsed from the parameter file.  Verifies
00817  *  number and sets global values. MPEG standard specifies that bit rate
00818  *      be rounded up to nearest 400 bits/sec.
00819  *
00820  * RETURNS:     nothing
00821  *
00822  * SIDE EFFECTS:   global variables
00823  *
00824  * NOTES:       Should this be in the 400-bit units used in sequence header?
00825  *
00826  *===========================================================================*/
00827 void setBitRate (charPtr)
00828      char * charPtr;
00829 {
00830   int rate, rnd;
00831   
00832   rate = atoi(charPtr);
00833   if (rate > 0) {
00834     RateControlMode = FIXED_RATE;
00835   } else {
00836     printf("Parameter File Error:  invalid BIT_RATE: \"%s\", defaults to Variable ratemode\n",
00837            charPtr);
00838     RateControlMode = VARIABLE_RATE;
00839     bit_rate = -1;
00840   }
00841   rnd = (rate % 400);
00842   rate += (rnd ? 400 -rnd : 0); /* round UP to nearest 400 bps */
00843   rate = (rate > MAX_BIT_RATE ? MAX_BIT_RATE : rate);
00844   bit_rate = rate;
00845   DBG_PRINT(("Bit rate is: %d\n", bit_rate));
00846 } 
00847 
00848 
00849 
00850 /*===========================================================================*
00851  *
00852  * getBitRate ()
00853  *
00854  *      Returns the bit rate read from the parameter file.  This is the
00855  *  real rate in bits per second, not in 400 bit units as is written to
00856  *  the sequence header.
00857  *
00858  * RETURNS:     int (-1 if Variable mode operation)
00859  *
00860  * SIDE EFFECTS:   none
00861  *
00862  *===========================================================================*/
00863 int getBitRate ()
00864 {
00865   return bit_rate;
00866 }
00867 
00868 
00869 
00870 
00871 /*===========================================================================*
00872  *
00873  * setBufferSize ()
00874  *
00875  *      Checks the string parsed from the parameter file.  Verifies
00876  *  number and sets global values.
00877  *
00878  * RETURNS:     nothing
00879  *
00880  * SIDE EFFECTS:   buffer_size global variable.
00881  *
00882  * NOTES:       The global is in bits, NOT the 16kb units used in sequence header
00883  *
00884  *===========================================================================*/
00885 void setBufferSize (charPtr)
00886      char * charPtr;
00887 {
00888   int size;
00889   
00890   size = atoi(charPtr);
00891   size = (size > MAX_BUFFER_SIZE ? MAX_BUFFER_SIZE : size);
00892   if (size > 0) {
00893     size = (16*1024) * ((size + (16*1024 - 1)) / (16*1024));
00894     buffer_size = size;
00895   } else {
00896     buffer_size = DEFAULT_BUFFER_SIZE;
00897     printf("Parameter File Error:  invalid BUFFER_SIZE: \"%s\", defaults to : %d\n",
00898            charPtr, buffer_size);
00899   }
00900   DBG_PRINT(("Buffer size is: %d\n", buffer_size));
00901 }
00902 
00903 
00904 /*===========================================================================*
00905  *
00906  * getBufferSize ()
00907  *
00908  *      returns the buffer size read from the parameter file.  Size is
00909  *  in bits- not in units of 16k as written to the sequence header.
00910  *
00911  * RETURNS:     int (or -1 if invalid)
00912  *
00913  * SIDE EFFECTS:   none
00914  *
00915  *===========================================================================*/
00916 int getBufferSize ()
00917 {
00918   return buffer_size;
00919 }
00920 
00921 
00922 /*===========================================================================*
00923  *
00924  * updateVBVBuffer ()
00925  *
00926  *      Update the VBV buffer after each frame.  This theoretical 
00927  * buffer is being filled at constant rate, given by the bit rate.
00928  * It is emptied as each frame is grabbed by the decoder.  Exception 
00929  * is that the deocder will wait until the "delay" is over.
00930  *
00931  * RETURNS:     nothing
00932  *
00933  * SIDE EFFECTS:   VBV_buffer
00934  *
00935  * NOTES:       
00936  *
00937  *===========================================================================*/
00938 void updateVBVBuffer (frameBits)
00939      int frameBits;
00940 {
00941   if (VBV_delay) {
00942     VBV_delay -= frameDelayIncrement;
00943     if (VBV_delay < 0) {
00944       VBV_delay = 0;
00945     }
00946     
00947   } else {
00948     VBV_buffer -= frameBits;
00949   }
00950   VBV_buffer += bufferFillRate;
00951   if (VBV_buffer < 0) {
00952     fprintf(stderr, "\tWARNING - VBV buffer underflow (%d)\n", VBV_buffer);
00953   }
00954   if (VBV_buffer > buffer_size) {
00955     fprintf(stderr, "WARNING - VBV buffer overflow (%d > %d)\n",
00956             VBV_buffer, buffer_size);
00957   }
00958 }
 

Powered by Plone

This site conforms to the following standards: