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

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. #include "../portab.h"
  2. #include "adapt_quant.h"
  3. #include <stdlib.h> /* free, malloc */
  4. #define MAX(a,b)      (((a) > (b)) ? (a) : (b))
  5. #define RDIFF(a,b)    ((int)(a+0.5)-(int)(b+0.5))
  6. int normalize_quantizer_field(float *in, int *out, int num, int min_quant, int max_quant)
  7. {
  8. int i;
  9. int finished;
  10. do
  11. {    
  12. finished = 1;
  13. for(i = 1; i < num; i++)
  14. {
  15. if(RDIFF(in[i], in[i-1]) > 2)
  16. {
  17. in[i] -= (float) 0.5;
  18. finished = 0;
  19. }
  20. else if(RDIFF(in[i], in[i-1]) < -2)
  21. {
  22. in[i-1] -= (float) 0.5;
  23. finished = 0;
  24. }
  25.         
  26. if(in[i] > max_quant)
  27. {
  28. in[i] = (float) max_quant;
  29. finished = 0;
  30. }
  31. if(in[i] < min_quant)
  32. in[i] = (float) min_quant;
  33. finished = 0;
  34. }
  35. if(in[i-1] > max_quant)
  36. in[i-1] = (float) max_quant;
  37. finished = 0;
  38. }
  39. if(in[i-1] < min_quant) 
  40. in[i-1] = (float) min_quant;
  41. finished = 0;
  42. }
  43. }
  44. } while(!finished);
  45. out[0] = 0;
  46. for (i = 1; i < num; i++)
  47. out[i] = RDIFF(in[i], in[i-1]);
  48. return (int) (in[0] + 0.5);
  49. }
  50. int adaptive_quantization(unsigned char* buf, int stride, int* intquant, 
  51.   int framequant, int min_quant, int max_quant,
  52.   int mb_width, int mb_height)  // no qstride because normalization
  53. {
  54. int i,j,k,l;
  55. static float *quant;
  56. unsigned char *ptr;
  57. float *val;
  58. float global = 0.;
  59. uint32_t mid_range = 0;
  60. const float DarkAmpl    = 14 / 2;
  61. const float BrightAmpl  = 10 / 2;
  62. const float DarkThres   = 70;
  63. const float BrightThres = 200;
  64. const float GlobalDarkThres = 60;
  65. const float GlobalBrightThres = 170;
  66. const float MidRangeThres = 20;
  67. const float UpperLimit = 200;
  68. const float LowerLimit = 25;
  69. if(!quant)
  70. if(!(quant = (float *) malloc(mb_width*mb_height * sizeof(float))))
  71. return -1;
  72. val = (float *) malloc(mb_width*mb_height * sizeof(float));
  73. for(k = 0; k < mb_height; k++)
  74. {
  75. for(l = 0;l < mb_width; l++)        // do this for all macroblocks individually 
  76. {
  77. quant[k*mb_width+l] = (float) framequant;
  78. // calculate luminance-masking
  79. ptr = &buf[16*k*stride+16*l]; // address of MB
  80. val[k*mb_width+l] = 0.;
  81. for(i = 0; i < 16; i++)
  82. for(j = 0; j < 16; j++)
  83. val[k*mb_width+l] += ptr[i*stride+j];
  84. val[k*mb_width+l] /= 256.;
  85. global += val[k*mb_width+l];
  86. if((val[k*mb_width+l] > LowerLimit) && (val[k*mb_width+l] < UpperLimit))
  87. mid_range++;
  88. }
  89. }
  90. global /= mb_width*mb_height;
  91. if(((global < GlobalBrightThres) && (global > GlobalDarkThres))
  92.    || (mid_range < MidRangeThres)) {
  93. for(k = 0; k < mb_height; k++)
  94. {
  95. for(l = 0;l < mb_width; l++)        // do this for all macroblocks individually 
  96. {
  97. if(val[k*mb_width+l] < DarkThres)
  98. quant[k*mb_width+l] += DarkAmpl*(DarkThres-val[k*mb_width+l])/DarkThres;
  99. else if (val[k*mb_width+l]>BrightThres)
  100. quant[k*mb_width+l] += BrightAmpl*(val[k*mb_width+l]-BrightThres)/(255-BrightThres);
  101. }
  102. }
  103. }
  104. free(val);
  105. return normalize_quantizer_field(quant, intquant, mb_width*mb_height, min_quant, max_quant);
  106. }