⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rate.c

📁 linux下将各类格式图片转换工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/*============================================================================* * rate.c								      * *									      *  *	Procedures concerned with rate control                                * *									      * * EXPORTED PROCEDURES:							      * *      initRatecontrol()                                                     * *      targetRateControl()                                                   * *      updateRateControl()                                                   * *      MB_RateOut()                                                          * *      needQScaleChange()                                                    * *      incNumBlocks()                                                        * *      incQuant()                                                            * *	incMacroBlockBits()                                                   * *      setPictureRate()                                                      * *      setBitRate()                                                          * *      getBitRate()                                                          * *      setBufferSize()                                                       * *      getBufferSize()                                                       * *                                                                            * * NOTES:                                                                     * *	Naming conventions follow those of MPEG-2 draft algorithm (chap. 10)  * *============================================================================*//* * Copyright (c) 1995 The Regents of the University of California. * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without written agreement is * hereby granted, provided that the above copyright notice and the following * two paragraphs appear in all copies of this software. * * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. *//*==============* * HEADER FILES * *==============*/#include <assert.h>#include <sys/types.h>#include <sys/times.h>#include "ppm.h"#include "nstring.h"#include "all.h"#include "mtypes.h"#include "bitio.h"#include "frames.h"#include "prototypes.h"#include "param.h"#include "mheaders.h"#include "fsize.h"#include "postdct.h"#include "mpeg.h"#include "parallel.h"#include "dct.h"#include "rate.h"/*==================* * GLOBAL VARIABLES * *==================*/#define MAX_BIT_RATE 104857600		/* 18 digit number in units of 400 */#define MAX_BUFFER_SIZE 16760832        /* 10 digit number in units of 16k */#define DEFAULT_BUFFER_SIZE 327680      /* maximun for "constrained" bitstream */#define DEFAULT_VBV_FULLNESS 3          /* wait till 1/3 full */#define DEFAULT_PICT_RATE_CODE 5        /* code for 30 Frames/sec */#define DEFAULT_PICT_RATE 30            /* 30 frames per second */#define MAX_VBV_DELAY 32768             /* 16 digits *//*	  Variables from Parameter File */static int	RateControlMode = VARIABLE_RATE;static int32 buffer_size = DEFAULT_BUFFER_SIZE;static int32 bit_rate = -1;static bool wantVbvUnderflowWarning;static bool wantVbvOverflowWarning;/*   Variables for the VBV buffer defined in MPEG specs */static unsigned int VBV_remainingDelay;     /* delay in units of 1/90000 seconds */static int32 VBV_buffer = 0;	  /* fullness of the theoretical VBV buffer */static int32 bufferFillRate = 0;    /* constant rate at which buffer filled */static int32 frameDelayIncrement = 0;	/* number of "delay" units/Frame *//*  Global complexity measure variables */static int Xi, Xp, Xb;  /*  Global complexity measure  */static int Si, Sp, Sb;  /*  Total # bits for last pict of type (Overhead?) */static float Qi, Qp, Qb; /* avg quantizaton for last picture of type  */     /*  Target bit allocations for each type of picture*/int Ti, Tp, Tb;int current_Tx;	/* allocation for current frame *//*  Count of number of pictures of each type remaining */int GOP_X;int GOP_I;int GOP_P;int GOP_B;int Nx = 0;int Ni = 0;int Np = 0;int Nb = 0;/*   Counters used while encoding frames   */int rc_numBlocks = 0;int rc_totalQuant = 0;int rc_bitsThisMB;int rc_totalMBBits;int rc_totalFrameBits;int rc_totalOverheadBits = 0;/*	Want to print out Macroblock info every Nth MB */int RC_MB_SAMPLE_RATE = 0;static float Ki = .7;static float Kp = 1;static float Kb = 1.4;static int rc_R;static int rc_G;/*   Rate Control variables   *//*   Virtual buffers for each frame type */static int d0_i;   /* Initial fullnesses */static int d0_p;static int d0_b;static int lastFrameVirtBuf;   /* fullness after last frame of this type */static int currentVirtBuf;     /* fullness during current encoding*/static int MB_cnt = -1;	       /* Number of MB's in picture */static int rc_Q;               /* reference quantization parameter */static int reactionParameter;  /*  Reaction parameter *//*	Adaptive Quantization variables */static int act_j;              /*  spatial activity measure */static float N_act;            /*  Normalised spacial activity */static int avg_act;	   /*  average activity value in last picture encoded */static int total_act_j;	       /*  Sum of activity values in current frame */static int var_sblk;	       /* sub-block activity */static int P_mean;	       /* Mean value of pixels in 8x8 sub-block */static int mquant;	       /* Raw Quantization value */static int Qscale;	       /* Clipped, truncated quantization value *//*  Output-related variables */#ifdef RC_STATS_FILEstatic FILE *RC_FILE;#endifstatic const char * const Frame_header1 = "  Fm         #     Bit      GOP                    V                ";static const char * const Frame_header2 = "   #  type   MBs   Alloc    left  Ni Np Nb  N_act  buff   Q_rc Qscale";static const char * const Frame_header3 = "----     -  ----  ------ -------  -- -- --  -----  ------ ----   ----";static const char * const Frame_trailer1 = "                      avg          virt     %    GOP      %     VBV";static const char * const Frame_trailer2 = "    Sx    Qx      Xx  act N_act  buffer alloc    left  left     buf  delay";static const char * const Frame_trailer3 = "------ --.-- -------  --- --.-- -------   --- -------   --- ------- ------";static const char * const MB_header1 = "MB#  #bits  Q mqt     Dj  Q_j   actj  N_act  totbits b/MB %alloc %done";static const char * const MB_header2 = "---  ----- -- --- ------  ---  -----  --.--   ------ ----    ---   ---";static char rc_buffer[101];/*	EXTERNAL Variables  */extern char *framePattern;extern int framePatternLen;/*===============================* * INTERNAL PROCEDURE prototypes * *===============================*/int initGOPRateControl _ANSI_ARGS_((void));int determineMBCount _ANSI_ARGS_((void));void checkBufferFullness _ANSI_ARGS_((int count));void checkSpatialActivity _ANSI_ARGS_((Block blk0, Block blk1, Block blk2, Block blk3));void incNumBlocks _ANSI_ARGS_((int num));void calculateVBVDelay _ANSI_ARGS_((int num));int BlockExperiments  _ANSI_ARGS_((int16 *OrigBlock, int16 *NewBlock, int control));          static voidanalyzePattern(const char *  const framePattern,               int           const framePatternLen,               int *         const gop_xP,               int *         const gop_iP,               int *         const gop_pP,               int *         const gop_bP,               const char ** const errorP) {    unsigned int i;    /*  Initialize Pattern info */    *gop_xP = framePatternLen;        for (i = 0, *gop_iP = 0, *gop_pP = 0, *gop_bP = 0, *errorP = NULL;         i < framePatternLen && !*errorP;          ++i) {        switch(framePattern[i]) {        case 'i': ++*gop_iP; break;        case 'p': ++*gop_pP; break;        case 'b': ++*gop_bP; break;        default:            asprintfN(errorP, "Bad pattern - not composed of i, p, and b");        }    }    assert(*gop_xP == *gop_iP + *gop_pP + *gop_bP);}  /*===========================================================================* * * initRateControl * *	initialize the allocation parameters. * * RETURNS:	nothing * * SIDE EFFECTS:   many global variables  * * NOTES:  Get rid of the redundant pattern stuff!! *===========================================================================*/intinitRateControl(bool const wantUnderflowWarning,                bool const wantOverflowWarning) {    int result;    const char * error;    wantVbvUnderflowWarning = wantUnderflowWarning;    wantVbvOverflowWarning  = wantOverflowWarning;    DBG_PRINT(("Initializing Allocation Data\n"));  #ifdef RC_STATS_FILE    RC_FILE = fopen("RC_STATS_FILE", "w");    if ( RC_FILE  == NULL) {        DBG_PRINT(("Open of RC file failed, using stderr\n"));        RC_FILE = stderr;        fprintf(RC_FILE, "Open of RC file failed, using stderr\n");        fflush(RC_FILE);    }#endif    VBV_remainingDelay = 0;      analyzePattern(framePattern, framePatternLen,                   &GOP_X, &GOP_I, &GOP_P, &GOP_B, &error);    if (error) {        pm_message("Unable to set up rate control.  Switching to variable.  "                   "%s", error);        strfree(error);        RateControlMode = VARIABLE_RATE;        return -1;    }    /* Initializing GOP bit allocation */	    rc_R = 0;    rc_G = (bit_rate * GOP_X/frameRateRounded);      /*   Initialize the "global complexity measures" */    Xi = (160 * bit_rate/115);    Xp = (60 * bit_rate/115);    Xb = (42 * bit_rate/115);      /*   Initialize MB counters */    rc_totalMBBits= rc_bitsThisMB= rc_totalFrameBits=rc_totalOverheadBits = 0;    rc_numBlocks = rc_totalQuant = 0;      /*   init virtual buffers  */    reactionParameter = (2 * bit_rate / frameRateRounded);    d0_i = (10 * reactionParameter / 31);    d0_p = (Kp * d0_i);    d0_b = (Kb * d0_i);      lastFrameVirtBuf = d0_i;	/*  start with I Frame */    rc_Q = lastFrameVirtBuf  * 31 / reactionParameter;      /*   init spatial activity measures */    avg_act = 400;		/* Suggested initial value */    N_act = 1;      mquant = rc_Q * N_act;      frameDelayIncrement = (90000 / frameRateRounded);        /* num of "delay" units per frame */    bufferFillRate = bit_rate / frameRateRounded;         /* VBV buf fills at constant rate */    VBV_buffer = buffer_size;    DBG_PRINT(("VBV- delay: %d, fill rate: %d, delay/Frame: %d units, "               "buffer size: %d\n",               VBV_remainginDelay, bufferFillRate, frameDelayIncrement,                buffer_size));      result = initGOPRateControl();      return result;}/*===========================================================================* * * initGOPRateControl * *		(re)-initialize the RC for the a new Group of Pictures. *	New bit allocation, but carry over complexity measures. * * RETURNS:	nothing * * SIDE EFFECTS:   many global variables  * *===========================================================================*/intinitGOPRateControl(){    DBG_PRINT(("Initializing new GOP\n"));      Nx = GOP_X;    Ni = GOP_I;    Np = GOP_P;    Nb = GOP_B;      rc_R += rc_G;      DBG_PRINT(("bufsize: %d, bitrate: %d, pictrate: %d, GOP bits: %d\n",               buffer_size, bit_rate, frameRateRounded, rc_R));    DBG_PRINT(("Xi: %d, Xp: %d, Xb: %d Nx: %d, Ni: %d, Np: %d, Nb: %d\n",               Xi, Xp, Xb, Nx,Ni,Np,Nb));    DBG_PRINT(("d0_i: %d, d0_p: %d, d0_b: %d, avg_act: %d, rc_Q: %d, "               "mquant: %d\n",               d0_i, d0_p, d0_b, avg_act, rc_Q, mquant));    return 1;}/*===========================================================================* * * targetRateControl * *      Determine the target allocation for given picture type, initiates *  variables for rate control process. * * RETURNS:     nothing. * * SIDE EFFECTS:   many global variables * *===========================================================================*/voidtargetRateControl(MpegFrame * const frame) {    float temp1, minimumBits;    float tempX, tempY, tempZ;    int result;    int frameType;    const char *strPtr;      minimumBits = (bit_rate / (8 * frameRateRounded));      /*   Check if new GOP */    if (Nx == 0) {        initGOPRateControl();    }      if (MB_cnt < 0) {MB_cnt = determineMBCount();}      switch (frame->type) {    case TYPE_IFRAME:        frameType = 'I';            tempX = ( (Np * Ki * Xp) / (Xi * Kp) );        tempY = ( (Nb * Ki * Xb) / (Xi*Kb) );        tempZ = Ni + tempX + tempY;        temp1 = (rc_R / tempZ);        result = (int) (temp1 > minimumBits ? temp1 :  minimumBits);        current_Tx = Ti = result;        lastFrameVirtBuf = d0_i;        break;        case TYPE_PFRAME:        frameType = 'P';        tempX =  ( (Ni * Kp * Xi) / (Ki * Xp) );        tempY =  ( (Nb * Kp * Xb) / (Kb * Xp) );        tempZ = Np + tempX + tempY;        temp1 = (rc_R/ tempZ);        result = (int) (temp1 > minimumBits ? temp1 :  minimumBits);        current_Tx = Tp = result;        lastFrameVirtBuf = d0_p;        break;        case TYPE_BFRAME:        frameType = 'B';        tempX =  ( (Ni * Kb * Xi) / (Ki * Xb) );        tempY =  ( (Np * Kb * Xp) / (Kp * Xb) );        tempZ = Nb + tempX + tempY;        temp1 = (rc_R/ tempZ);        result = (int) (temp1 > minimumBits ? temp1 :  minimumBits);        current_Tx = Tb = result;        lastFrameVirtBuf = d0_b;        break;        default:        frameType = 'X';    }      N_act = 1;    rc_Q = lastFrameVirtBuf  * 31 / reactionParameter;    mquant = rc_Q * N_act;    Qscale = (mquant > 31 ? 31 : mquant);    Qscale = (Qscale < 1 ? 1 : Qscale);      /*   Print headers for Frame info */    strPtr = Frame_header1;    DBG_PRINT(("%s\n",strPtr));    strPtr = Frame_header2;    DBG_PRINT(("%s\n",strPtr));    strPtr = Frame_header3;    DBG_PRINT(("%s\n",strPtr));      /*   Print Frame info */    sprintf(rc_buffer, "%4d     %1c  %4d  %6d %7d  "            "%2d %2d %2d   %2.2f  %6d %4d    %3d",            frame->id,frameType,MB_cnt,current_Tx,rc_R,Ni,Np,Nb,             N_act, lastFrameVirtBuf, rc_Q, Qscale);  #ifdef RC_STATS_FILE    fprintf(RC_FILE,"%s\n", rc_buffer);    fflush(RC_FILE);#endif    DBG_PRINT(("%s\n",rc_buffer));      /*  Print headers for Macroblock info */    if (RC_MB_SAMPLE_RATE) {        strPtr = MB_header1;        DBG_PRINT(("%s\n",strPtr));        strPtr = MB_header2;        DBG_PRINT(("%s\n",strPtr));    }}static void updateVBVBuffer(int const frameBits) {/*----------------------------------------------------------------------------  Update the VBV buffer after each frame.  This theoretical buffer is  being filled at constant rate 'bufferFillRate' from an mpeg stream.  It is emptied as each frame is grabbed by the decoder.  Exception is  that the decoder will wait until the "delay" is over.  We mark the passing of one unit of time, in which 'frameBits' bits of  mpeg data were grabbed from the buffer by the decoder.-----------------------------------------------------------------------------*/    if (VBV_remainingDelay)        VBV_remainingDelay -= MIN(frameDelayIncrement, VBV_remainingDelay);    else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -