PageRenderTime 68ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/lencod/src/leaky_bucket.c

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