text_code_mb.c
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:7k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. #include "text_code.h"
  2. #include "text_dct.h"
  3. #define BLOCK_SIZE 8
  4. Void   BlockPredict (SInt *curr, 
  5. Int x_pos, Int y_pos, UInt width, Int fblock[][8]);
  6. Void   BlockRebuild (SInt *rec_curr, SInt *comp, Int pred_type, Int max,
  7. Int x_pos, Int y_pos, UInt width, UInt edge, Int fblock[][8]);
  8. Void   BlockQuantH263 (Int *coeff, Int QP, Int mode, Int type,
  9. Int *qcoeff, Int maxDC, Int image_type);
  10. Void   BlockDequantH263 (Int *qcoeff, Int QP, Int mode, Int type,
  11. Int *rcoeff, Int image_type, Int short_video_header, Int bits_per_pixel);
  12. Void CodeMB(Vop *curr, Vop *rec_curr, Vop *comp, Int x_pos, Int y_pos, UInt width,
  13. Int QP, Int Mode, Int *qcoeff)
  14. {
  15. Int k;
  16. Int fblock[6][8][8];
  17. Int coeff[384];
  18. Int *coeff_ind;
  19. Int *qcoeff_ind;
  20. Int* rcoeff_ind;
  21. Int x, y;
  22. SInt *current, *recon, *compensated = NULL;
  23. UInt xwidth;
  24. Int iblock[6][8][8];
  25. Int rcoeff[6*64];
  26. Int i, j;
  27. Int type;   
  28. SInt tmp[64];
  29. Int s;
  30. int operation = curr->prediction_type;
  31. Int max = GetVopBrightWhite(curr);
  32. coeff_ind = coeff;
  33. qcoeff_ind = qcoeff;
  34. rcoeff_ind = rcoeff;
  35. for (k = 0; k < 6; k++)
  36. {
  37. switch (k)
  38. {
  39. case 0:
  40. x = x_pos;
  41. y = y_pos;
  42. xwidth = width;
  43. current = (SInt *) GetImageData (GetVopY (curr));
  44. break;
  45. case 1:
  46. x = x_pos + 8;
  47. y = y_pos;
  48. xwidth = width;
  49. current = (SInt *) GetImageData (GetVopY (curr));
  50. break;
  51. case 2:
  52. x = x_pos;
  53. y = y_pos + 8;
  54. xwidth = width;
  55. current = (SInt *) GetImageData (GetVopY (curr));
  56. break;
  57. case 3:
  58. x = x_pos + 8;
  59. y = y_pos + 8;
  60. xwidth = width;
  61. current = (SInt *) GetImageData (GetVopY (curr));
  62. break;
  63. case 4:
  64. x = x_pos / 2;
  65. y = y_pos / 2;
  66. xwidth = width / 2;
  67. current = (SInt *) GetImageData (GetVopU (curr));
  68. break;
  69. case 5:
  70. x = x_pos / 2;
  71. y = y_pos / 2;
  72. xwidth = width / 2;
  73. current = (SInt *) GetImageData (GetVopV (curr));
  74. break;
  75. default:
  76. break;
  77. }
  78. BlockPredict (current, x, y, xwidth, fblock[k]);
  79. }
  80. for (k = 0; k < 6; k++)
  81. {
  82. s = 0;
  83. for (i = 0; i < 8; i++)
  84. for (j = 0; j < 8; j++)
  85. tmp[s++] = (SInt) fblock[k][i][j];
  86. #ifndef _MMX_
  87. fdct_enc(tmp);
  88. #else
  89. fdct_mm32(tmp);
  90. #endif
  91. for (s = 0; s < 64; s++)
  92. coeff_ind[s] = (Int) tmp[s];
  93. if (k < 4) type = 1;
  94. else type = 2;
  95. BlockQuantH263(coeff_ind,QP,Mode,type,qcoeff_ind,
  96. GetVopBrightWhite(curr),1);
  97. BlockDequantH263(qcoeff_ind,QP,Mode,type,rcoeff_ind,1, 0, GetVopBitsPerPixel(curr));
  98. for (s = 0; s < 64; s++)
  99. tmp[s] = (SInt) rcoeff_ind[s];
  100. #ifndef _MMX_
  101. idct_enc(tmp);
  102. #else
  103. Fast_IDCT(tmp);
  104. #endif
  105. s = 0;
  106. for (i = 0; i < 8; i++)
  107. for (j = 0; j < 8; j++)
  108. iblock[k][i][j] = (Int)tmp[s++];
  109. coeff_ind += 64;
  110. qcoeff_ind += 64;
  111. rcoeff_ind += 64;
  112. if (Mode == MODE_INTRA||Mode==MODE_INTRA_Q)
  113. for (i = 0; i < 8; i++)
  114. for (j = 0; j < 8; j ++)
  115. iblock[k][i][j] = MIN (GetVopBrightWhite(curr), MAX (0, iblock[k][i][j]));
  116. switch (k)
  117. {
  118. case 0:
  119. case 1:
  120. case 2:
  121. continue;
  122. case 3:
  123. recon = (SInt *) GetImageData (GetVopY (rec_curr));
  124. if (operation == P_VOP) compensated = (SInt *) GetImageData (GetVopY (comp));
  125. BlockRebuild (recon, compensated, operation, max, x_pos,     y_pos,     width, 16, iblock[0]);
  126. BlockRebuild (recon, compensated, operation, max, x_pos + 8, y_pos,     width, 16, iblock[1]);
  127. BlockRebuild (recon, compensated, operation, max, x_pos,     y_pos + 8, width, 16, iblock[2]);
  128. BlockRebuild (recon, compensated, operation, max, x_pos + 8, y_pos + 8, width, 16, iblock[3]);
  129. continue;
  130. case 4:
  131. recon = (SInt *) GetImageData (GetVopU (rec_curr));
  132. if (operation == P_VOP) compensated = (SInt *) GetImageData (GetVopU (comp));
  133. BlockRebuild (recon, compensated, operation, max,
  134. x_pos/2, y_pos/2, width/2, 8, iblock[4]);
  135. continue;
  136. case 5:
  137. recon = (SInt *) GetImageData (GetVopV (rec_curr));
  138. if (operation == P_VOP) compensated = (SInt *) GetImageData (GetVopV (comp));
  139. BlockRebuild (recon, compensated, operation, max,
  140. x_pos/2, y_pos/2, width/2, 8, iblock[5]);
  141. continue;
  142. }
  143. }
  144. return;
  145. }
  146. Void
  147. BlockPredict (SInt *curr,  Int x_pos, Int y_pos,
  148. UInt width, Int fblock[][8])
  149. {
  150. Int i, j;
  151. for (i = 0; i < 8; i++)
  152. {
  153. for (j = 0; j < 8; j++)
  154. {
  155. fblock[i][j] = curr[(y_pos+i)*width + x_pos+j];
  156. }
  157. }
  158. }
  159. Void
  160. BlockRebuild (SInt *rec_curr, SInt *comp, Int pred_type, Int max,
  161. Int x_pos, Int y_pos, UInt width, UInt edge, Int fblock[][8])
  162. {
  163. Int i, j;
  164. SInt *rec;
  165. Int padded_width;
  166. padded_width = width + 2 * edge;
  167. rec = rec_curr + edge * padded_width + edge;
  168. if (pred_type == I_VOP)
  169. {
  170. SInt *p;
  171. p  = rec + y_pos * padded_width + x_pos;
  172. for (i = 0; i < 8; i++) 
  173. {
  174. for (j = 0; j < 8; j++)
  175. {
  176. SInt temp = fblock[i][j];
  177. *(p++) = CLIP(temp, 0, max);
  178. }
  179. p += padded_width - 8;
  180. }
  181. }
  182. else if (pred_type == P_VOP)
  183. {
  184. SInt *p, *pc; 
  185. p  = rec + y_pos * padded_width + x_pos;
  186. pc = comp     + y_pos * width + x_pos;
  187. for (i = 0; i < 8; i++)
  188. {
  189. for (j = 0; j < 8; j++)
  190. {
  191. SInt temp = *(pc++) + fblock[i][j];
  192. *(p++) = CLIP(temp, 0, max);
  193. }
  194. p += padded_width - 8;
  195. pc += width - 8;
  196. }
  197. }
  198. }
  199. Void
  200. BlockQuantH263 (Int *coeff, Int QP, Int mode, Int type, Int *qcoeff, Int maxDC, Int image_type)
  201. {
  202. Int i;
  203. Int level, result;
  204. Int step, offset;
  205. Int dc_scaler;
  206. if (!(QP > 0 && (QP < 32*image_type))) return;
  207. if (!(type == 1 || type == 2)) return;
  208. if (mode == MODE_INTRA || mode == MODE_INTRA_Q)
  209. {   
  210. dc_scaler = cal_dc_scaler(QP,type);
  211. qcoeff[0] = MAX(1,MIN(maxDC-1, (coeff[0] + dc_scaler/2)/dc_scaler));
  212. step = 2 * QP;
  213. for (i = 1; i < 64; i++)
  214. {
  215. level = (abs(coeff[i]))  / step;
  216. result = (coeff[i] >= 0) ? level : -level;
  217. qcoeff[i] =  MIN(2047, MAX(-2048, result));
  218. }
  219. }
  220. else
  221. {   
  222. step = 2 * QP;
  223. offset = QP / 2;
  224. for (i = 0; i < 64; i++)
  225. {
  226. level = (abs(coeff[i]) - offset)  / step;
  227. result = (coeff[i] >= 0) ? level : -level;
  228. qcoeff[i] =  MIN(2047, MAX(-2048, result));
  229. }
  230. }
  231. return;
  232. }
  233. Void
  234. BlockDequantH263 (Int *qcoeff, Int QP, Int mode, Int type, Int *rcoeff,
  235. Int image_type, Int short_video_header, Int bits_per_pixel)
  236. {
  237. Int i;
  238. Int dc_scaler;
  239. Int lim;
  240. lim = (1 << (bits_per_pixel + 3));
  241. if (QP)
  242. {
  243. for (i = 0; i < 64; i++)
  244. {
  245. if (qcoeff[i])
  246. {
  247. qcoeff[i] =  MIN(2047, MAX(-2048, qcoeff[i] ));
  248. if ((QP % 2) == 1)
  249. rcoeff[i] = QP * (2*ABS(qcoeff[i]) + 1);
  250. else
  251. rcoeff[i] = QP * (2*ABS(qcoeff[i]) + 1) - 1;
  252. rcoeff[i] = SIGN(qcoeff[i]) * rcoeff[i];
  253. }
  254. else
  255. rcoeff[i] = 0;
  256. }
  257. if (mode == MODE_INTRA || mode == MODE_INTRA_Q)
  258. {   
  259. MOMCHECK(QP > 0 && (QP < 32*image_type));
  260. MOMCHECK(type == 1 || type == 2);
  261. if (short_video_header)
  262. dc_scaler = 8;
  263. else
  264. dc_scaler = cal_dc_scaler(QP,type);
  265. rcoeff[0] = qcoeff[0] * dc_scaler;
  266. }
  267. }
  268. else
  269. {
  270. for (i = 0; i < 64; i++)
  271. {
  272. rcoeff[i] = qcoeff[i];
  273. }
  274. if (mode == MODE_INTRA || mode == MODE_INTRA_Q)
  275. {   
  276. rcoeff[0] = qcoeff[0]*8;
  277. }
  278. }
  279. for (i=0;i<64;i++)
  280. if (rcoeff[i]>(lim-1)) rcoeff[i]=(lim-1);
  281. else if (rcoeff[i]<(-lim)) rcoeff[i]=(-lim);
  282. return;
  283. }