leaky_bucket.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:10k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2. ***********************************************************************
  3. * COPYRIGHT AND WARRANTY INFORMATION
  4. *
  5. * Copyright 2001, International Telecommunications Union, Geneva
  6. *
  7. * DISCLAIMER OF WARRANTY
  8. *
  9. * These software programs are available to the user without any
  10. * license fee or royalty on an "as is" basis. The ITU disclaims
  11. * any and all warranties, whether express, implied, or
  12. * statutory, including any implied warranties of merchantability
  13. * or of fitness for a particular purpose.  In no event shall the
  14. * contributor or the ITU be liable for any incidental, punitive, or
  15. * consequential damages of any kind whatsoever arising from the
  16. * use of these programs.
  17. *
  18. * This disclaimer of warranty extends to the user of these programs
  19. * and user's customers, employees, agents, transferees, successors,
  20. * and assigns.
  21. *
  22. * The ITU does not represent or warrant that the programs furnished
  23. * hereunder are free of infringement of any third-party patents.
  24. * Commercial implementations of ITU-T Recommendations, including
  25. * shareware, may be subject to royalty fees to patent holders.
  26. * Information regarding the ITU-T patent policy is available from
  27. * the ITU Web site at http://www.itu.int.
  28. *
  29. * THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE ITU-T PATENT POLICY.
  30. ************************************************************************
  31. */
  32. /*!
  33.  ***************************************************************************
  34.  * file leaky_bucket.c
  35.  *
  36.  * brief
  37.  *    calculate Leaky Buffer parameters
  38.  *
  39.  * author
  40.  *    Main contributors (see contributors.h for copyright, address and affiliation details)
  41.  *    - Shankar Regunathan                   <shanre@microsoft.com>
  42.  ***************************************************************************
  43.  */
  44. #include <stdlib.h>
  45. #include <assert.h>
  46. #include "contributors.h"
  47. #include "global.h"
  48. #ifdef _LEAKYBUCKET_
  49. long Bit_Buffer[10000];
  50. unsigned long total_frame_buffer = 0;
  51. /*!
  52.  ***********************************************************************
  53.  * brief
  54.  *   Function to get Leaky Bucket rates from rate file
  55.  * param NumberLeakyBuckets
  56.  *    Number of Leaky Bucket Parameters
  57.  * param Rmin
  58.  *    Rate values for each Bucket.
  59.  * return
  60.  *    returns 1 if successful; else returns zero.
  61.  * para SideEffects
  62.  *     None.
  63.  * para Notes
  64.  *     Failure if LeakyBucketRate is missing or if it does not have
  65.  *     the correct number of entries.
  66.  * author
  67.  *    Shankar Regunathan                   shanre@microsoft.com
  68.  *  date 
  69.  *      December 06, 2001.
  70.  ***********************************************************************
  71.  */
  72. int get_LeakyBucketRate(unsigned long NumberLeakyBuckets, unsigned long *Rmin)
  73. {
  74.   FILE *f;
  75.   unsigned long i, buf;
  76.   
  77.   if((f = fopen(input->LeakyBucketRateFile, "r")) == NULL)
  78.   {
  79.     printf(" LeakyBucketRate File does not exist; using rate calculated from avg. rate n");
  80.     return 0;
  81.   }
  82.   
  83.   for(i=0; i<NumberLeakyBuckets; i++) 
  84.   {
  85.     if(1 != fscanf(f, "%ld", &buf)) 
  86.     {
  87.       printf(" Leaky BucketRateFile does not have valid entries;n using rate calculated from avg. rate n");
  88.       return 0;
  89.     }
  90.     Rmin[i] = buf;
  91.   }
  92.   return 1;
  93. }
  94. /*!
  95.  ***********************************************************************
  96.  * brief
  97.  *   Writes one unsigned long word in big endian order to a file. 
  98.  * param dw
  99.  *    Value to be written
  100.  * param fp
  101.  *    File pointer
  102.  * return
  103.  *    None.
  104.  * para SideEffects
  105.  *     None.
  106.  * author
  107.  *    Shankar Regunathan                   shanre@microsoft.com
  108.  *  date 
  109.  *      December 06, 2001.
  110.  ***********************************************************************
  111.  */
  112. void PutBigDoubleWord(unsigned long dw, FILE *fp)
  113. {
  114.   fputc((dw >> 0x18) & 0xFF, fp);
  115.   fputc((dw >> 0x10) & 0xFF, fp);
  116.   fputc((dw >> 0x08) & 0xFF, fp);
  117.   fputc(dw & 0xFF, fp);
  118. }
  119. /*!
  120.  ***********************************************************************
  121.  * brief
  122.  *   Stores the Leaky BucketParameters in file input->LeakyBucketParamFile.
  123.  * param NumberLeakyBuckets
  124.  *    Number of LeakyBuckets.
  125.  * param Rmin
  126.  *    Rate values of the buckets.
  127.  * param Bmin
  128.  *    Minimum buffer values of the buckets.
  129.  *  param Fmin
  130.  *     Minimum initial buffer fullness of the buckets
  131.  * return
  132.  *    None.
  133.  * para
  134.  *    Returns error if LeakyBucketParamFile cannot be opened.
  135.  * para SideEffects
  136.  *     Prints the LeakyBucket Parameters in standard output.
  137.  * author
  138.  *    Shankar Regunathan                   shanre@microsoft.com
  139.  *  date 
  140.  *      December 06, 2001.
  141.  ***********************************************************************
  142.  */
  143. void write_buffer(unsigned long NumberLeakyBuckets, unsigned long Rmin[], unsigned long Bmin[], unsigned long Fmin[])
  144. {
  145. #ifndef H26L_LIB
  146.   FILE *outf;
  147.   unsigned long iBucket;
  148.         
  149.   if ((outf=fopen(input->LeakyBucketParamFile,"wb"))==NULL)
  150.   {
  151.     snprintf(errortext, ET_SIZE, "Error open file %s  n",input->outfile);
  152.     error(errortext,1);
  153.   }
  154.   PutBigDoubleWord(NumberLeakyBuckets, outf);
  155.   printf(" Number Leaky Buckets: %ld n     Rmin     Bmin     Fmin n", NumberLeakyBuckets);
  156.   for(iBucket =0; iBucket < NumberLeakyBuckets; iBucket++) 
  157.   {
  158.     assert(Rmin[iBucket]<4294967296); //Overflow should be corrected already.
  159.     assert(Bmin[iBucket]<4294967296);
  160.     assert(Fmin[iBucket]<4294967296);
  161.     PutBigDoubleWord(Rmin[iBucket], outf);
  162.     PutBigDoubleWord(Bmin[iBucket], outf);
  163.     PutBigDoubleWord(Fmin[iBucket], outf);
  164.     printf(" %8ld %8ld %8ld n", Rmin[iBucket], Bmin[iBucket], Fmin[iBucket]);
  165.   }
  166.   fclose(outf);
  167. #endif
  168. }
  169. /*!
  170.  ***********************************************************************
  171.  * brief
  172.  *    Sorts the rate array in ascending order. 
  173.  * param NumberLeakyBuckets
  174.  *    Number of LeakyBuckets.
  175.  * param Rmin
  176.  *    Rate values of the buckets.
  177.  * return
  178.  *    None.
  179.  * author
  180.  *    Shankar Regunathan                   shanre@microsoft.com
  181.  *  date 
  182.  *      December 06, 2001.
  183.  ***********************************************************************
  184.  */
  185. void Sort(unsigned long NumberLeakyBuckets, unsigned long *Rmin)
  186. {
  187.   unsigned long i, j;
  188.   unsigned long temp;
  189.   for(i=0; i< NumberLeakyBuckets-1; i++) 
  190.   {
  191.     for(j=i+1; j<NumberLeakyBuckets; j++) 
  192.     {
  193.       if(Rmin[i] > Rmin[j]) {
  194.         temp = Rmin[i];
  195.         Rmin[i] = Rmin[j];
  196.         Rmin[j] = temp;
  197.       }
  198.     }
  199.   }
  200. }
  201. /*!
  202.  ***********************************************************************
  203.  * brief
  204.  *    Main Routine to calculate Leaky Buffer parameters
  205.  * param NumberLeakyBuckets
  206.  *    None.
  207.  * return
  208.  *    None.
  209.  * author
  210.  *    Shankar Regunathan                   shanre@microsoft.com
  211.  *  date 
  212.  *      December 06, 2001.
  213.  ***********************************************************************
  214.  */
  215. void calc_buffer()
  216. {    
  217.   unsigned long AvgRate, TotalRate, NumberLeakyBuckets;
  218.   long *buffer_frame, minB;
  219.   unsigned long iBucket, iFrame,  FrameIndex;
  220.   long maxBuffer, actualBuffer, InitFullness, iChannelRate;
  221.   unsigned long *Rmin, *Bmin, *Fmin;
  222.    
  223.   fprintf(stdout,"--------------------------------------------------------------------------n");
  224.   printf(" Total Frames:  %ld (%d) n", total_frame_buffer, input->no_frames);
  225.   NumberLeakyBuckets = (unsigned long) input->NumberLeakyBuckets;
  226.   buffer_frame = calloc(total_frame_buffer, sizeof(long));
  227.   if(!buffer_frame)
  228.     no_mem_exit("init_buffer: buffer_frame");
  229.   Rmin = calloc(NumberLeakyBuckets, sizeof(unsigned long));
  230.   if(!Rmin)
  231.     no_mem_exit("init_buffer: Rmin");    
  232.   Bmin = calloc(NumberLeakyBuckets, sizeof(unsigned long));
  233.   if(!Bmin)
  234.     no_mem_exit("init_buffer: Bmin");
  235.   Fmin = calloc(NumberLeakyBuckets, sizeof(unsigned long));
  236.   if(!Fmin)
  237.     no_mem_exit("init_buffer: Fmin");
  238.   TotalRate = 0;
  239.   for(iFrame=0; iFrame < total_frame_buffer; iFrame++) 
  240.   {
  241.     TotalRate += (unsigned long) Bit_Buffer[iFrame];
  242.   }
  243.   AvgRate = (unsigned long) ((float) TotalRate/ total_frame_buffer);
  244.   
  245.   if(1 != get_LeakyBucketRate(NumberLeakyBuckets, Rmin))
  246.   { /* if rate file is not present, use default calculated from avg.rate */
  247.     for(iBucket=0; iBucket < NumberLeakyBuckets; iBucket++) 
  248.     {
  249.       if(iBucket == 0)
  250.         Rmin[iBucket] = (AvgRate * img->framerate)/(input->jumpd+1); /* convert bits/frame to bits/second */
  251.       else
  252.         Rmin[iBucket] = Rmin[iBucket-1] + (AvgRate/4) * (img->framerate) / (input->jumpd+1);    
  253.     }
  254.   }
  255.   Sort(NumberLeakyBuckets, Rmin);   
  256.   maxBuffer = AvgRate * 20; /* any initialization is good. */        
  257.   for(iBucket=0; iBucket< NumberLeakyBuckets; iBucket++) 
  258.   {           
  259.     iChannelRate = (long) Rmin[iBucket] * (input->jumpd+1)/(img->framerate); /* converts bits/second to bits/frame */
  260.     /* To calculate initial buffer size */
  261.     InitFullness = maxBuffer; /* set Initial Fullness to be buffer size */
  262.     buffer_frame[0] = InitFullness;
  263.     minB = maxBuffer; 
  264.     
  265.     for(iFrame=0; iFrame<total_frame_buffer ; iFrame++) 
  266.     {        
  267.       buffer_frame[iFrame] = buffer_frame[iFrame] - Bit_Buffer[iFrame];
  268.       if(buffer_frame[iFrame] < minB) 
  269.       {
  270.         minB = buffer_frame[iFrame];
  271.         FrameIndex = iFrame;
  272.       }
  273.       
  274.       buffer_frame[iFrame+1] = buffer_frame[iFrame] + iChannelRate;
  275.       if(buffer_frame[iFrame+1] > maxBuffer)
  276.         buffer_frame[iFrame+1] = maxBuffer;
  277.     }
  278.     actualBuffer = (maxBuffer - minB);
  279.     /* To calculate initial buffer Fullness */
  280.     InitFullness = Bit_Buffer[0];
  281.     buffer_frame[0] = InitFullness;
  282.     for(iFrame=0; iFrame < FrameIndex+1; iFrame++) 
  283.     {
  284.       buffer_frame[iFrame] = buffer_frame[iFrame] - Bit_Buffer[iFrame];
  285.       if(buffer_frame[iFrame] < 0) {
  286.         InitFullness -= buffer_frame[iFrame];
  287.         buffer_frame[iFrame] = 0;
  288.       }
  289.       buffer_frame[iFrame+1] = buffer_frame[iFrame] + iChannelRate;
  290.       if(buffer_frame[iFrame+1] > actualBuffer)
  291.         break;
  292.     }       
  293.     Bmin[iBucket] = (unsigned long) actualBuffer;
  294.     Fmin[iBucket] = (unsigned long) InitFullness;
  295.   }
  296.   write_buffer(NumberLeakyBuckets, Rmin, Bmin, Fmin);
  297.   free(Rmin);
  298.   free(Bmin);
  299.   free(Fmin);
  300.   return;
  301. }
  302. #endif