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

多媒体编程

开发平台:

Visual C++

  1. #include <math.h>
  2. #include "mp4_vars.h"
  3. #include "mp4_predict.h"
  4. /**
  5.  *
  6. **/
  7. static void rescue_predict();
  8. void dc_recon(int block_num, short * dc_value)
  9. {
  10. if (mp4_state->hdr.prediction_type == P_VOP) {
  11. rescue_predict();
  12. }
  13. if (block_num < 4)
  14. {
  15. int b_xpos = (mp4_state->hdr.mb_xpos << 1) + (block_num & 1);
  16. int b_ypos = (mp4_state->hdr.mb_ypos << 1) + ((block_num & 2) >> 1);
  17. int dc_pred;
  18. if (abs(mp4_state->coeff_pred.dc_store_lum[b_ypos+1-1][b_xpos+1-1] -
  19. mp4_state->coeff_pred.dc_store_lum[b_ypos+1][b_xpos+1-1]) < // Fa - Fb
  20. abs(mp4_state->coeff_pred.dc_store_lum[b_ypos+1-1][b_xpos+1-1] -
  21. mp4_state->coeff_pred.dc_store_lum[b_ypos+1-1][b_xpos+1])) // Fb - Fc
  22. {
  23. mp4_state->coeff_pred.predict_dir = TOP;
  24. dc_pred = mp4_state->coeff_pred.dc_store_lum[b_ypos+1-1][b_xpos+1];
  25. }
  26. else
  27. {
  28. mp4_state->coeff_pred.predict_dir = LEFT;
  29. dc_pred = mp4_state->coeff_pred.dc_store_lum[b_ypos+1][b_xpos+1-1];
  30. }
  31. (* dc_value) += _div_div(dc_pred, mp4_state->hdr.dc_scaler);
  32. (* dc_value) *= mp4_state->hdr.dc_scaler;
  33. mp4_state->coeff_pred.dc_store_lum[b_ypos+1][b_xpos+1] = (* dc_value);
  34. }
  35. else 
  36. {
  37. int b_xpos = mp4_state->hdr.mb_xpos;
  38. int b_ypos = mp4_state->hdr.mb_ypos;
  39. int chr_num = block_num - 4;
  40. int dc_pred;
  41. if (abs(mp4_state->coeff_pred.dc_store_chr[chr_num][b_ypos+1-1][b_xpos+1-1] -
  42. mp4_state->coeff_pred.dc_store_chr[chr_num][b_ypos+1][b_xpos+1-1]) < // Fa - Fb
  43. abs(mp4_state->coeff_pred.dc_store_chr[chr_num][b_ypos+1-1][b_xpos+1-1] -
  44. mp4_state->coeff_pred.dc_store_chr[chr_num][b_ypos+1-1][b_xpos+1])) // Fb - Fc
  45. {
  46. mp4_state->coeff_pred.predict_dir = TOP;
  47. dc_pred = mp4_state->coeff_pred.dc_store_chr[chr_num][b_ypos+1-1][b_xpos+1];
  48. }
  49. else
  50. {
  51. mp4_state->coeff_pred.predict_dir = LEFT;
  52. dc_pred = mp4_state->coeff_pred.dc_store_chr[chr_num][b_ypos+1][b_xpos+1-1];
  53. }
  54. (* dc_value) += _div_div(dc_pred, mp4_state->hdr.dc_scaler);
  55. (* dc_value) *= mp4_state->hdr.dc_scaler;
  56. mp4_state->coeff_pred.dc_store_chr[chr_num][b_ypos+1][b_xpos+1] = (* dc_value);
  57. }
  58. }
  59. /***/
  60. static int saiAcLeftIndex[8] = 
  61. {
  62. 0, 8,16,24,32,40,48,56
  63. };
  64. void ac_recon(int block_num, short * psBlock)
  65. {
  66. int b_xpos, b_ypos;
  67. int i;
  68. if (block_num < 4) {
  69. b_xpos = (mp4_state->hdr.mb_xpos << 1) + (block_num & 1);
  70. b_ypos = (mp4_state->hdr.mb_ypos << 1) + ((block_num & 2) >> 1);
  71. }
  72. else {
  73. b_xpos = mp4_state->hdr.mb_xpos;
  74. b_ypos = mp4_state->hdr.mb_ypos;
  75. }
  76. if (mp4_state->hdr.ac_pred_flag) 
  77. {
  78. if (block_num < 4) 
  79. {
  80. if (mp4_state->coeff_pred.predict_dir == TOP)
  81. {
  82. for (i = 1; i < 8; i++) 
  83. psBlock[i] += mp4_state->coeff_pred.ac_top_lum[b_ypos+1-1][b_xpos+1][i-1];
  84. }
  85. else 
  86. {
  87. for (i = 1; i < 8; i++)
  88. psBlock[mp4_tables->saiAcLeftIndex[i]] += mp4_state->coeff_pred.ac_left_lum[b_ypos+1][b_xpos+1-1][i-1];
  89. }
  90. }
  91. else
  92. {
  93. int chr_num = block_num - 4;
  94. if (mp4_state->coeff_pred.predict_dir == TOP)
  95. {
  96. for (i = 1; i < 8; i++)
  97. psBlock[i] += mp4_state->coeff_pred.ac_top_chr[chr_num][b_ypos+1-1][b_xpos+1][i-1];
  98. }
  99. else 
  100. {
  101. for (i = 1; i < 8; i++)
  102. psBlock[mp4_tables->saiAcLeftIndex[i]] += mp4_state->coeff_pred.ac_left_chr[chr_num][b_ypos+1][b_xpos+1-1][i-1];
  103. }
  104. }
  105. }
  106. }
  107. /***/
  108. void ac_store(int block_num, short * psBlock)
  109. {
  110. int b_xpos, b_ypos;
  111. int i;
  112. if (block_num < 4) { 
  113. b_xpos = (mp4_state->hdr.mb_xpos << 1) + (block_num & 1);
  114. b_ypos = (mp4_state->hdr.mb_ypos << 1) + ((block_num & 2) >> 1);
  115. }
  116. else {
  117. b_xpos = mp4_state->hdr.mb_xpos;
  118. b_ypos = mp4_state->hdr.mb_ypos;
  119. }
  120. if (block_num < 4)
  121. {
  122. for (i = 1; i < 8; i++) {
  123. mp4_state->coeff_pred.ac_top_lum[b_ypos+1][b_xpos+1][i-1] = psBlock[i];
  124. mp4_state->coeff_pred.ac_left_lum[b_ypos+1][b_xpos+1][i-1] = psBlock[mp4_tables->saiAcLeftIndex[i]];
  125. }
  126. }
  127. else 
  128. {
  129. int chr_num = block_num - 4;
  130. for (i = 1; i < 8; i++) {
  131. mp4_state->coeff_pred.ac_top_chr[chr_num][b_ypos+1][b_xpos+1][i-1] = psBlock[i];
  132. mp4_state->coeff_pred.ac_left_chr[chr_num][b_ypos+1][b_xpos+1][i-1] = psBlock[mp4_tables->saiAcLeftIndex[i]];
  133. }
  134. }
  135. }
  136. /***/
  137. #define _rescale(predict_quant, current_quant, coeff) (coeff != 0) ?
  138. _div_div((coeff) * (predict_quant), (current_quant)) : 0
  139. int ac_rescaling(int block_num, short * psBlock)
  140. {
  141. int mb_xpos = mp4_state->hdr.mb_xpos;
  142. int mb_ypos = mp4_state->hdr.mb_ypos;
  143. int current_quant = mp4_state->hdr.quantizer;
  144. int predict_quant = (mp4_state->coeff_pred.predict_dir == TOP) ?
  145. mp4_state->quant_store[mb_ypos][mb_xpos+1] : mp4_state->quant_store[mb_ypos+1][mb_xpos];
  146. int b_xpos, b_ypos; 
  147. int i;
  148. if ((! mp4_state->hdr.ac_pred_flag) || (current_quant == predict_quant) || (block_num == 3))
  149. return 0;
  150. if ((mb_ypos == 0) && (mp4_state->coeff_pred.predict_dir == TOP))
  151. return 0;
  152. if ((mb_xpos == 0) && (mp4_state->coeff_pred.predict_dir == LEFT))
  153. return 0;
  154. if ((mb_xpos == 0) && (mb_ypos == 0))
  155. return 0;
  156. if (block_num < 4) {
  157. b_xpos = (mp4_state->hdr.mb_xpos << 1) + (block_num & 1);
  158. b_ypos = (mp4_state->hdr.mb_ypos << 1) + ((block_num & 2) >> 1);
  159. }
  160. else {
  161. b_xpos = mp4_state->hdr.mb_xpos;
  162. b_ypos = mp4_state->hdr.mb_ypos;
  163. }
  164. if (mp4_state->coeff_pred.predict_dir == TOP) 
  165. switch (block_num)
  166. {
  167. case 0: case 1:
  168. for (i = 1; i < 8; i++)
  169. psBlock[i] += _rescale(predict_quant, current_quant, mp4_state->coeff_pred.ac_top_lum[b_ypos][b_xpos+1][i-1]);
  170. return 1;
  171. break;
  172. case 4:
  173. for (i = 1; i < 8; i++)
  174. psBlock[i] += _rescale(predict_quant, current_quant, mp4_state->coeff_pred.ac_top_chr[0][b_ypos][b_xpos+1][i-1]);
  175. return 1;
  176. break;
  177. case 5:
  178. for (i = 1; i < 8; i++)
  179. psBlock[i] += _rescale(predict_quant, current_quant, mp4_state->coeff_pred.ac_top_chr[1][b_ypos][b_xpos+1][i-1]);
  180. return 1;
  181. break;
  182. }
  183. else 
  184. {
  185. switch (block_num)
  186. {
  187. case 0: case 2:
  188. for (i = 1; i < 8; i++)
  189. psBlock[mp4_tables->saiAcLeftIndex[i]] += _rescale(predict_quant, current_quant, mp4_state->coeff_pred.ac_left_lum[b_ypos+1][b_xpos][i-1]);
  190. return 1;
  191. break;
  192. case 4:
  193. for (i = 1; i < 8; i++)
  194. psBlock[mp4_tables->saiAcLeftIndex[i]] += _rescale(predict_quant, current_quant, mp4_state->coeff_pred.ac_left_chr[0][b_ypos+1][b_xpos][i-1]);
  195. return 1;
  196. break;
  197. case 5:
  198. for (i = 1; i < 8; i++)
  199. psBlock[mp4_tables->saiAcLeftIndex[i]] += _rescale(predict_quant, current_quant, mp4_state->coeff_pred.ac_left_chr[1][b_ypos+1][b_xpos][i-1]);
  200. return 1;
  201. break;
  202. }
  203. }
  204. return 0;
  205. }
  206. /***/
  207. #define _IsIntra(mb_y, mb_x) ((mp4_state->modemap[(mb_y)+1][(mb_x)+1] == INTRA) || 
  208. (mp4_state->modemap[(mb_y)+1][(mb_x)+1] == INTRA_Q))
  209. static void rescue_predict() 
  210. {
  211. int mb_xpos = mp4_state->hdr.mb_xpos;
  212. int mb_ypos = mp4_state->hdr.mb_ypos;
  213. int i;
  214. if (! _IsIntra(mb_ypos-1, mb_xpos-1)) {
  215. mp4_state->coeff_pred.dc_store_lum[2*mb_ypos+1-1][2*mb_xpos+1-1] = 1024;
  216. mp4_state->coeff_pred.dc_store_chr[0][mb_ypos+1-1][mb_xpos+1-1] = 1024;
  217. mp4_state->coeff_pred.dc_store_chr[1][mb_ypos+1-1][mb_xpos+1-1] = 1024;
  218. }
  219. if (! _IsIntra(mb_ypos, mb_xpos-1)) {
  220. mp4_state->coeff_pred.dc_store_lum[2*mb_ypos+1][2*mb_xpos+1-1] = 1024;
  221. mp4_state->coeff_pred.dc_store_lum[2*mb_ypos+1+1][2*mb_xpos+1-1] = 1024;
  222. mp4_state->coeff_pred.dc_store_chr[0][mb_ypos+1][mb_xpos+1-1] = 1024;
  223. mp4_state->coeff_pred.dc_store_chr[1][mb_ypos+1][mb_xpos+1-1] = 1024;
  224. for(i = 0; i < 7; i++) {
  225. mp4_state->coeff_pred.ac_left_lum[2*mb_ypos+1][2*mb_xpos+1-1][i] = 0;
  226. mp4_state->coeff_pred.ac_left_lum[2*mb_ypos+1+1][2*mb_xpos+1-1][i] = 0;
  227. mp4_state->coeff_pred.ac_left_chr[0][mb_ypos+1][mb_xpos+1-1][i] = 0;
  228. mp4_state->coeff_pred.ac_left_chr[1][mb_ypos+1][mb_xpos+1-1][i] = 0;
  229. }
  230. }
  231. if (! _IsIntra(mb_ypos-1, mb_xpos)) {
  232. mp4_state->coeff_pred.dc_store_lum[2*mb_ypos+1-1][2*mb_xpos+1] = 1024;
  233. mp4_state->coeff_pred.dc_store_lum[2*mb_ypos+1-1][2*mb_xpos+1+1] = 1024;
  234. mp4_state->coeff_pred.dc_store_chr[0][mb_ypos+1-1][mb_xpos+1] = 1024;
  235. mp4_state->coeff_pred.dc_store_chr[1][mb_ypos+1-1][mb_xpos+1] = 1024;
  236. for(i = 0; i < 7; i++) {
  237. mp4_state->coeff_pred.ac_top_lum[2*mb_ypos+1-1][2*mb_xpos+1][i] = 0;
  238. mp4_state->coeff_pred.ac_top_lum[2*mb_ypos+1-1][2*mb_xpos+1+1][i] = 0;
  239. mp4_state->coeff_pred.ac_top_chr[0][mb_ypos+1-1][mb_xpos+1][i] = 0;
  240. mp4_state->coeff_pred.ac_top_chr[1][mb_ypos+1-1][mb_xpos+1][i] = 0;
  241. }
  242. }
  243. }