leaky_bucket.c
上传用户:hjq518
上传日期:2021-12-09
资源大小:5084k
文件大小:9k
源码类别:

Audio

开发平台:

Visual C++

  1. /*!
  2.  ***************************************************************************
  3.  * file leaky_bucket.c
  4.  *
  5.  * brief
  6.  *    calculate Leaky Buffer parameters
  7.  *
  8.  * author
  9.  *    Main contributors (see contributors.h for copyright, address and affiliation details)
  10.  *    - Shankar Regunathan                   <shanre@microsoft.com>
  11.  ***************************************************************************
  12.  */
  13. #include "contributors.h"
  14. #include "global.h"
  15. #ifdef _LEAKYBUCKET_
  16. //long Bit_Buffer[20000];
  17. unsigned long total_frame_buffer = 0;
  18. /*!
  19.  ***********************************************************************
  20.  * brief
  21.  *   Function to get Leaky Bucket rates from rate file
  22.  * param NumberLeakyBuckets
  23.  *    Number of Leaky Bucket Parameters
  24.  * param Rmin
  25.  *    Rate values for each Bucket.
  26.  * return
  27.  *    returns 1 if successful; else returns zero.
  28.  * para SideEffects
  29.  *     None.
  30.  * para Notes
  31.  *     Failure if LeakyBucketRate is missing or if it does not have
  32.  *     the correct number of entries.
  33.  * author
  34.  *    Shankar Regunathan                   shanre@microsoft.com
  35.  *  date
  36.  *      December 06, 2001.
  37.  ***********************************************************************
  38.  */
  39. int get_LeakyBucketRate(unsigned long NumberLeakyBuckets, unsigned long *Rmin)
  40. {
  41.   FILE *f;
  42.   unsigned long i, buf;
  43.   if((f = fopen(params->LeakyBucketRateFile, "r")) == NULL)
  44.   {
  45.     printf(" LeakyBucketRate File does not exist. Using rate calculated from avg. rate n");
  46.     return 0;
  47.   }
  48.   for(i=0; i<NumberLeakyBuckets; i++)
  49.   {
  50.     if(1 != fscanf(f, "%lu", &buf))
  51.     {
  52.       printf(" Leaky BucketRateFile does not have valid entries.n Using rate calculated from avg. rate n");
  53.       fclose (f);
  54.       return 0;
  55.     }
  56.     Rmin[i] = buf;
  57.   }
  58.   fclose (f);
  59.   return 1;
  60. }
  61. /*!
  62.  ***********************************************************************
  63.  * brief
  64.  *   Writes one unsigned long word in big endian order to a file.
  65.  * param dw
  66.  *    Value to be written
  67.  * param fp
  68.  *    File pointer
  69.  * return
  70.  *    None.
  71.  * para SideEffects
  72.  *     None.
  73.  * author
  74.  *    Shankar Regunathan                   shanre@microsoft.com
  75.  *  date
  76.  *      December 06, 2001.
  77.  ***********************************************************************
  78.  */
  79. void PutBigDoubleWord(unsigned long dw, FILE *fp)
  80. {
  81.   fputc((dw >> 0x18) & 0xFF, fp);
  82.   fputc((dw >> 0x10) & 0xFF, fp);
  83.   fputc((dw >> 0x08) & 0xFF, fp);
  84.   fputc(dw & 0xFF, fp);
  85. }
  86. /*!
  87.  ***********************************************************************
  88.  * brief
  89.  *   Stores the Leaky BucketParameters in file params->LeakyBucketParamFile.
  90.  * param NumberLeakyBuckets
  91.  *    Number of LeakyBuckets.
  92.  * param Rmin
  93.  *    Rate values of the buckets.
  94.  * param Bmin
  95.  *    Minimum buffer values of the buckets.
  96.  *  param Fmin
  97.  *     Minimum initial buffer fullness of the buckets
  98.  * return
  99.  *    None.
  100.  * para
  101.  *    Returns error if LeakyBucketParamFile cannot be opened.
  102.  * para SideEffects
  103.  *     Prints the LeakyBucket Parameters in standard output.
  104.  * author
  105.  *    Shankar Regunathan                   shanre@microsoft.com
  106.  *  date
  107.  *      December 06, 2001.
  108.  ***********************************************************************
  109.  */
  110. void write_buffer(unsigned long NumberLeakyBuckets, unsigned long Rmin[], unsigned long Bmin[], unsigned long Fmin[])
  111. {
  112.   FILE *outf;
  113.   unsigned long iBucket;
  114.   if ((outf=fopen(params->LeakyBucketParamFile,"wb"))==NULL)
  115.   {
  116.     snprintf(errortext, ET_SIZE, "Error open file lk %s  n",params->LeakyBucketParamFile);
  117.     error(errortext,1);
  118.   }
  119.   PutBigDoubleWord(NumberLeakyBuckets, outf);
  120.   if (params->Verbose != 0)
  121.     printf(" Number Leaky Buckets: %ld n     Rmin     Bmin     Fmin n", NumberLeakyBuckets);
  122.   for(iBucket =0; iBucket < NumberLeakyBuckets; iBucket++)
  123.   {
  124.     //assert(Rmin[iBucket]<4294967296); //Overflow should be corrected already.
  125.     //assert(Bmin[iBucket]<4294967296);
  126.     //assert(Fmin[iBucket]<4294967296);
  127.     PutBigDoubleWord(Rmin[iBucket], outf);
  128.     PutBigDoubleWord(Bmin[iBucket], outf);
  129.     PutBigDoubleWord(Fmin[iBucket], outf);
  130.     if (params->Verbose != 0)
  131.       printf(" %8ld %8ld %8ld n", Rmin[iBucket], Bmin[iBucket], Fmin[iBucket]);
  132.   }
  133.   fclose(outf);
  134. }
  135. /*!
  136.  ***********************************************************************
  137.  * brief
  138.  *    Sorts the rate array in ascending order.
  139.  * param NumberLeakyBuckets
  140.  *    Number of LeakyBuckets.
  141.  * param Rmin
  142.  *    Rate values of the buckets.
  143.  * return
  144.  *    None.
  145.  * author
  146.  *    Shankar Regunathan                   shanre@microsoft.com
  147.  *  date
  148.  *      December 06, 2001.
  149.  ***********************************************************************
  150.  */
  151. void Sort(unsigned long NumberLeakyBuckets, unsigned long *Rmin)
  152. {
  153.   unsigned long i, j;
  154.   unsigned long temp;
  155.   for(i=0; i< NumberLeakyBuckets-1; i++)
  156.   {
  157.     for(j=i+1; j<NumberLeakyBuckets; j++)
  158.     {
  159.       if(Rmin[i] > Rmin[j]) 
  160.       {
  161.         temp = Rmin[i];
  162.         Rmin[i] = Rmin[j];
  163.         Rmin[j] = temp;
  164.       }
  165.     }
  166.   }
  167. }
  168. /*!
  169.  ***********************************************************************
  170.  * brief
  171.  *    Main Routine to calculate Leaky Buffer parameters
  172.  * param NumberLeakyBuckets
  173.  *    None.
  174.  * return
  175.  *    None.
  176.  * author
  177.  *    Shankar Regunathan                   shanre@microsoft.com
  178.  *  date
  179.  *      December 06, 2001.
  180.  ***********************************************************************
  181.  */
  182. void calc_buffer()
  183. {
  184.   unsigned long AvgRate, TotalRate, NumberLeakyBuckets;
  185.   long *buffer_frame, minB;
  186.   unsigned long iBucket, iFrame,  FrameIndex = 0;
  187.   long maxBuffer, actualBuffer, InitFullness, iChannelRate;
  188.   unsigned long *Rmin, *Bmin, *Fmin;
  189.   switch (params->Verbose)
  190.   {
  191.     case 1:
  192.       fprintf(stdout,"-------------------------------------------------------------------------------n");
  193.       break;
  194.     case 2:
  195.       fprintf(stdout,"------------------------------------------------------------------------------------------------n");
  196.       break;
  197.     case 3:
  198.       fprintf(stdout,"-------------------------------------------------------------------------------------------------------n");
  199.       break;
  200.     case 0:
  201.     default:
  202.       fprintf(stdout,"-------------------------------------------------------------------------------n");
  203.       printf("nEncoding. Please Wait.nn");
  204.       break;
  205.   }
  206.   printf(" Total Frames:  %ld (%d) n", total_frame_buffer, params->no_frames);
  207.   NumberLeakyBuckets = (unsigned long) params->NumberLeakyBuckets;
  208.   buffer_frame = calloc(total_frame_buffer+1, sizeof(long));
  209.   if(!buffer_frame)
  210.     no_mem_exit("init_buffer: buffer_frame");
  211.   Rmin = calloc(NumberLeakyBuckets, sizeof(unsigned long));
  212.   if(!Rmin)
  213.     no_mem_exit("init_buffer: Rmin");
  214.   Bmin = calloc(NumberLeakyBuckets, sizeof(unsigned long));
  215.   if(!Bmin)
  216.     no_mem_exit("init_buffer: Bmin");
  217.   Fmin = calloc(NumberLeakyBuckets, sizeof(unsigned long));
  218.   if(!Fmin)
  219.     no_mem_exit("init_buffer: Fmin");
  220.   TotalRate = 0;
  221.   for(iFrame=0; iFrame < total_frame_buffer; iFrame++)
  222.   {
  223.     TotalRate += (unsigned long) Bit_Buffer[iFrame];
  224.   }
  225.   AvgRate = (unsigned long) ((float) TotalRate/ total_frame_buffer);
  226.   if(1 != get_LeakyBucketRate(NumberLeakyBuckets, Rmin))
  227.   { /* if rate file is not present, use default calculated from avg.rate */
  228.     for(iBucket=0; iBucket < NumberLeakyBuckets; iBucket++)
  229.     {
  230.       if(iBucket == 0)
  231.         Rmin[iBucket] = (unsigned long)((float) AvgRate * img->framerate)/(params->jumpd+1); /* convert bits/frame to bits/second */
  232.       else
  233.         Rmin[iBucket] = (unsigned long) ((float) Rmin[iBucket-1] + (AvgRate/4) * (img->framerate) / (params->jumpd+1));
  234.     }
  235.   }
  236.   Sort(NumberLeakyBuckets, Rmin);
  237.   maxBuffer = AvgRate * 20; /* any initialization is good. */
  238.   for(iBucket=0; iBucket< NumberLeakyBuckets; iBucket++)
  239.   {
  240.     iChannelRate = (long) (Rmin[iBucket] * (params->jumpd+1)/(img->framerate)); /* converts bits/second to bits/frame */
  241.     /* To calculate initial buffer size */
  242.     InitFullness = maxBuffer; /* set Initial Fullness to be buffer size */
  243.     buffer_frame[0] = InitFullness;
  244.     minB = maxBuffer;
  245.     for(iFrame=0; iFrame<total_frame_buffer ; iFrame++)
  246.     {
  247.       buffer_frame[iFrame] = buffer_frame[iFrame] - Bit_Buffer[iFrame];
  248.       if(buffer_frame[iFrame] < minB)
  249.       {
  250.         minB = buffer_frame[iFrame];
  251.         FrameIndex = iFrame;
  252.       }
  253.       buffer_frame[iFrame+1] = buffer_frame[iFrame] + iChannelRate;
  254.       if(buffer_frame[iFrame+1] > maxBuffer)
  255.         buffer_frame[iFrame+1] = maxBuffer;
  256.     }
  257.     actualBuffer = (maxBuffer - minB);
  258.     /* To calculate initial buffer Fullness */
  259.     InitFullness = Bit_Buffer[0];
  260.     buffer_frame[0] = InitFullness;
  261.     for(iFrame=0; iFrame < FrameIndex+1; iFrame++)
  262.     {
  263.       buffer_frame[iFrame] = buffer_frame[iFrame] - Bit_Buffer[iFrame];
  264.       if(buffer_frame[iFrame] < 0) 
  265.       {
  266.         InitFullness -= buffer_frame[iFrame];
  267.         buffer_frame[iFrame] = 0;
  268.       }
  269.       buffer_frame[iFrame+1] = buffer_frame[iFrame] + iChannelRate;
  270.       if(buffer_frame[iFrame+1] > actualBuffer)
  271.         break;
  272.     }
  273.     Bmin[iBucket] = (unsigned long) actualBuffer;
  274.     Fmin[iBucket] = (unsigned long) InitFullness;
  275.   }
  276.   write_buffer(NumberLeakyBuckets, Rmin, Bmin, Fmin);
  277.   free(buffer_frame);
  278.   free(Rmin);
  279.   free(Bmin);
  280.   free(Fmin);
  281.   return;
  282. }
  283. #endif