vop_code.c
上传用户:hxb_1234
上传日期:2010-03-30
资源大小:8328k
文件大小:6k
源码类别:

VC书籍

开发平台:

Visual C++

  1. #include "vop_code.h"
  2. #include "mot_est_comp.h"
  3. #include "bitstream.h"
  4. #include "rate_ctl.h"
  5. #define SCENE_CHANGE_THREADHOLD 50
  6. #define MB_RATIO_THREADHOLD 0.40
  7. extern FILE *ftrace;
  8. UInt   BitstreamPutVopHeader ( Vop *vop,
  9. Float time,
  10. VolConfig *vol_config
  11. );
  12. Void ImageRepetitivePadding(Image *image, Int edge);
  13. Double compute_MAD(Vop *vop);
  14. Void VopCode(Vop *curr,
  15. Vop *reference,
  16. Vop *reconstruct,
  17. Vop *error,
  18. Int enable_8x8_mv,
  19. Float time,
  20. VolConfig *vol_config)
  21. {
  22. ImageF    *mot_x=NULL, *mot_y=NULL;
  23. Image     *MB_decisions=NULL;
  24. Int       edge,f_code_for=1;
  25. Vop       *error_vop=NULL;
  26. Int       vop_quantizer;
  27. Float   mad_P = 0., mad_I = 0.;
  28. Float   IntraMBRatio = 1.;
  29. Int   numberMB, i, IntraMB;
  30. edge = 0;
  31. f_code_for = curr->fcode_for;
  32. if (curr->prediction_type == P_VOP) 
  33. {
  34. MotionEstimationCompensation(curr, reference,
  35. enable_8x8_mv, edge ,f_code_for,
  36. reconstruct, &mad_P, &mot_x,&mot_y,&MB_decisions);
  37. IntraMB = 0;
  38. numberMB = MB_decisions->x * MB_decisions->y;
  39. for (i = 0; i < numberMB; i ++)
  40. if (MB_decisions->f[i] == MBM_INTRA) IntraMB ++;
  41. IntraMBRatio = (float)IntraMB / (float)numberMB;
  42. #ifdef _RC_
  43. fprintf(ftrace, "ME with MAD : %fn", mad_P);
  44. fprintf(ftrace, "%4.2f of the MBs are I-MBs.n", IntraMBRatio);
  45. #endif
  46. }
  47. else
  48. mad_P = SCENE_CHANGE_THREADHOLD * 2;
  49. if ((mad_P < SCENE_CHANGE_THREADHOLD / 3) || 
  50. ((mad_P < SCENE_CHANGE_THREADHOLD) && (IntraMBRatio < MB_RATIO_THREADHOLD)))
  51. {
  52. curr->prediction_type = P_VOP;
  53. error->prediction_type = P_VOP;
  54. #ifdef _RC_
  55. fprintf(ftrace, "Coding mode : INTERn");
  56. #endif
  57. vop_quantizer = RateCtlGetQ(mad_P);
  58. curr->quantizer = vop_quantizer;
  59. error->quantizer = vop_quantizer;
  60. #ifdef _RC_DEBUG_
  61. fprintf(stdout, "RC: >>>>> New quantizer= %dn", vop_quantizer);
  62. #endif
  63. SubImage(curr->y_chan, reconstruct->y_chan, error->y_chan);
  64. SubImage(curr->u_chan, reconstruct->u_chan, error->u_chan);
  65. SubImage(curr->v_chan, reconstruct->v_chan, error->v_chan); 
  66. BitstreamPutVopHeader(curr,time,vol_config);
  67. VopShapeMotText(error, reconstruct, MB_decisions,
  68. mot_x, mot_y, f_code_for, 
  69. GetVopIntraACDCPredDisable(curr), reference,
  70. NULL);
  71. } else {
  72. curr->prediction_type = I_VOP;
  73. curr->rounding_type = 1;
  74. #ifdef _RC_
  75. fprintf(ftrace, "Coding mode : INTRAn");
  76. #endif
  77. if (mad_I == 0.) mad_I = (Float) compute_MAD(curr);
  78. vop_quantizer = RateCtlGetQ(mad_I);
  79. curr->intra_quantizer = vop_quantizer;
  80. curr->rounding_type = 1;
  81. BitstreamPutVopHeader(curr,time,vol_config);
  82. VopCodeShapeTextIntraCom(curr,
  83. reference,
  84. NULL
  85. );
  86. if (MB_decisions) FreeImage(MB_decisions);
  87. if (mot_x) FreeImage(mot_x);
  88. if (mot_y) FreeImage(mot_y);
  89. ImageRepetitivePadding(reference->y_chan, 16);
  90. ImageRepetitivePadding(reference->u_chan, 8);
  91. ImageRepetitivePadding(reference->v_chan, 8);
  92. Bitstream_NextStartCode();   
  93. return;
  94. }   
  95. UInt
  96. BitstreamPutVopHeader(Vop *vop,
  97. Float time, 
  98. VolConfig *vol_config)
  99. {
  100. Image *buffer = NULL;
  101. Int bits;
  102. Int   time_modulo;
  103. Float time_inc;
  104. Int   index;
  105. UInt  num_bits_header=0;
  106. BitstreamPutBits(buffer,VOP_START_CODE,VOP_START_CODE_LENGTH);
  107. BitstreamPutBits(buffer,GetVopPredictionType(vop),2);
  108. index = GetVolConfigModTimeBase(vol_config, 1);
  109. time_modulo = (int)time - index*1000;
  110. while(time_modulo >= 1000)
  111. {
  112. BitstreamPutBits(buffer,1,1);
  113. time_modulo = time_modulo - 1000;
  114. index++;
  115. printf("time modulo : 1n");
  116. }
  117. BitstreamPutBits(buffer,0,1);
  118. PutVolConfigModTimeBase(index,vol_config);
  119. time_inc = (time - index*1000);
  120. bits = (int)ceil(log((double)GetVopTimeIncrementResolution(vop))/log(2.0));
  121. if (bits<1) bits=1;
  122. time_inc=time_inc*GetVopTimeIncrementResolution(vop)/1000.0f;
  123. BitstreamPutBits(buffer,1,1);
  124. BitstreamPutBits(buffer,(Int)(time_inc+0.001),bits);
  125. BitstreamPutBits(buffer,1,1);
  126. if (GetVopWidth(vop)==0)
  127. {
  128. printf("Empty VOP at %.2fn",time);   
  129. BitstreamPutBits(buffer,0L,1L);
  130. num_bits_header += Bitstream_NextStartCode();
  131. return(num_bits_header);
  132. }
  133. else
  134. BitstreamPutBits(buffer,1L,1L);
  135. if( GetVopPredictionType(vop) == P_VOP )
  136. BitstreamPutBits(buffer,GetVopRoundingType(vop),1);
  137. BitstreamPutBits(buffer,GetVopIntraDCVlcThr(vop),3);
  138. if (GetVopPredictionType(vop) == I_VOP)   
  139. BitstreamPutBits(buffer,GetVopIntraQuantizer(vop),GetVopQuantPrecision(vop));
  140. else   
  141. BitstreamPutBits(buffer,GetVopQuantizer(vop),GetVopQuantPrecision(vop));
  142. if (GetVopPredictionType(vop)!=I_VOP)
  143. {
  144. BitstreamPutBits(buffer,GetVopFCodeFor(vop),3);
  145. }
  146. return(num_bits_header);
  147. }
  148. Void ImageRepetitivePadding(Image *image, Int edge)
  149. {
  150. SInt *p, left, right;
  151. Int width, height, x, y;
  152. p = image->f;
  153. width = image->x;
  154. height = image->y;
  155. for( y=edge; y<height-edge; y++)
  156.     {
  157. left = p[y*width+edge];
  158. right = p[y*width+width-edge-1];
  159. for(x=0; x<edge; x++)
  160. {
  161. p[y*width+x] = left;
  162. p[y*width+width-edge+x] = right;
  163. }
  164.     }
  165.     for(y=0; y<edge; y++)
  166.         for(x=0; x<width; x++)
  167.             p[y*width+x] = p[edge*width+x];
  168. for(y=height-edge; y<height; y++)
  169. for(x=0; x<width; x++)
  170. p[y*width+x] = p[(height-1-edge)*width+x];
  171. return;
  172. }
  173. Double compute_MAD(
  174. Vop  *error_vop
  175. )
  176. {
  177. SInt  *curr_in,
  178. *curr_end;
  179. Float *curr_fin,
  180. *curr_fend;
  181. UInt   sxy_in;
  182. Double mad=0.0, dc = 0.0;
  183. Int    cnt=0;
  184. switch (GetImageType(error_vop->y_chan))
  185. {
  186. case SHORT_TYPE:
  187. curr_in = (SInt*)GetImageData(error_vop->y_chan);
  188. sxy_in = GetImageSize(error_vop->y_chan);
  189. curr_end = curr_in + sxy_in;
  190. cnt = 0;
  191. while (curr_in != curr_end)
  192. {
  193. dc += *curr_in; 
  194. cnt++;
  195. curr_in++;
  196. }
  197. dc /= cnt;
  198. curr_in = (SInt*)GetImageData(error_vop->y_chan);
  199. sxy_in = GetImageSize(error_vop->y_chan);
  200. curr_end = curr_in + sxy_in;
  201. cnt = 0;
  202. while (curr_in != curr_end)
  203. {
  204. mad += fabs(*curr_in - dc);
  205. cnt++;
  206. curr_in++;
  207. }
  208. mad /= cnt;
  209. break;
  210. case FLOAT_TYPE:
  211. curr_fin = (Float*)GetImageData(error_vop->y_chan);
  212. sxy_in = GetImageSize(error_vop->y_chan);
  213. curr_fend = curr_fin + sxy_in;
  214. cnt = 0;
  215. while (curr_fin != curr_fend)
  216. {
  217. mad += fabs(*curr_fin);
  218. cnt++;
  219. curr_fin++;
  220. }
  221. mad /= cnt;
  222. break;
  223. default: break;
  224. }
  225. #ifdef _RC_
  226. fprintf(ftrace, "The MAD of the VOP to be coded is %f.n", mad);
  227. #endif
  228. return mad;
  229. }