text_code_mb.c
上传用户:enenge
上传日期:2007-01-08
资源大小:96k
文件大小:13k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /**************************************************************************
  2.  *                                                                        *
  3.  * This code is developed by Adam Li.  This software is an                *
  4.  * implementation of a part of one or more MPEG-4 Video tools as          *
  5.  * specified in ISO/IEC 14496-2 standard.  Those intending to use this    *
  6.  * software module in hardware or software products are advised that its  *
  7.  * use may infringe existing patents or copyrights, and any such use      *
  8.  * would be at such party's own risk.  The original developer of this     *
  9.  * software module and his/her company, and subsequent editors and their  *
  10.  * companies (including Project Mayo), will have no liability for use of  *
  11.  * this software or modifications or derivatives thereof.                 *
  12.  *                                                                        *
  13.  * Project Mayo gives users of the Codec a license to this software       *
  14.  * module or modifications thereof for use in hardware or software        *
  15.  * products claiming conformance to the MPEG-4 Video Standard as          *
  16.  * described in the Open DivX license.                                    *
  17.  *                                                                        *
  18.  * The complete Open DivX license can be found at                         *
  19.  * http://www.projectmayo.com/opendivx/license.php .                      *
  20.  *                                                                        *
  21.  **************************************************************************/
  22. /**************************************************************************
  23.  *
  24.  *  text_code_mb.c
  25.  *
  26.  *  Copyright (C) 2001  Project Mayo
  27.  *
  28.  *  Adam Li
  29.  *  Juice
  30.  *
  31.  *  DivX Advance Research Center <darc@projectmayo.com>
  32.  *
  33.  **************************************************************************/
  34. /* This file contains some functions for text coding of MacroBlocks.      */
  35. /* Some codes of this project come from MoMuSys MPEG-4 implementation.    */
  36. /* Please see seperate acknowledgement file for a list of contributors.   */
  37. #include "text_code.h"
  38. #include "text_dct.h"
  39. #define BLOCK_SIZE 8
  40. Void   BlockPredict (SInt *curr, /*SInt *rec_curr,*/
  41. Int x_pos, Int y_pos, UInt width, Int fblock[][8]);
  42. Void   BlockRebuild (SInt *rec_curr, SInt *comp, Int pred_type, Int max,
  43. Int x_pos, Int y_pos, UInt width, UInt edge, Int fblock[][8]);
  44. Void   BlockQuantH263 (Int *coeff, Int QP, Int mode, Int type,
  45. Int *qcoeff, Int maxDC, Int image_type);
  46. Void   BlockDequantH263 (Int *qcoeff, Int QP, Int mode, Int type,
  47. Int *rcoeff, Int image_type, Int short_video_header, Int bits_per_pixel);
  48. /***********************************************************CommentBegin******
  49.  *
  50.  * -- CodeMB -- Code, decode and reconstruct Macroblock 
  51.  *              combined with substraction and addition operation
  52.  *
  53.  * Arguments in :
  54.  * Int x_pos x_position of Macroblock
  55.  * Int y_pos y_position of Macroblock
  56.  * UInt width width of Vop bounding box (unpadded size)
  57.  * Int QP Quantization parameter
  58.  * Int Mode Macroblock coding mode
  59.  *
  60.  * Arguments in/out :
  61.  * Vop *curr current Vop, uncoded
  62.  * Vop *rec_curr current Vop, decoded and reconstructed
  63.  *  Vop *comp   current Vop, motion compensated
  64.  *  Int *qcoeff coefficient block (384 * sizeof(Int))
  65.  *
  66.  ***********************************************************CommentEnd********/
  67. Void CodeMB(Vop *curr, Vop *rec_curr, Vop *comp, Int x_pos, Int y_pos, UInt width,
  68. Int QP, Int Mode, Int *qcoeff)
  69. {
  70. Int k;
  71. Int fblock[6][8][8];
  72. Int coeff[384];
  73. Int *coeff_ind;
  74. Int *qcoeff_ind;
  75. Int* rcoeff_ind;
  76. Int x, y;
  77. SInt *current, *recon, *compensated = NULL;
  78. UInt xwidth;
  79. Int iblock[6][8][8];
  80. Int rcoeff[6*64];
  81. Int i, j;
  82. Int type;   /* luma = 1, chroma = 2 */
  83. // Int *qmat;
  84. SInt tmp[64];
  85. Int s;
  86. int operation = curr->prediction_type;
  87. /* This variable is for combined operation.
  88. If it is an I_VOP, then MB in curr is reconstruct into rec_curr,
  89. and comp is not used at all (i.e., it can be set to NULL).
  90. If it is a P_VOP, then MB in curr is reconstructed, and the result
  91. added with MB_comp is written into rec_curr. 
  92. - adamli 11/19/2000 */
  93. Int max = GetVopBrightWhite(curr);
  94. /* This variable is the max value for the clipping of the reconstructed image. */
  95. coeff_ind = coeff;
  96. qcoeff_ind = qcoeff;
  97. rcoeff_ind = rcoeff;
  98. for (k = 0; k < 6; k++)
  99. {
  100. switch (k)
  101. {
  102. case 0:
  103. x = x_pos;
  104. y = y_pos;
  105. xwidth = width;
  106. current = (SInt *) GetImageData (GetVopY (curr));
  107. break;
  108. case 1:
  109. x = x_pos + 8;
  110. y = y_pos;
  111. xwidth = width;
  112. current = (SInt *) GetImageData (GetVopY (curr));
  113. break;
  114. case 2:
  115. x = x_pos;
  116. y = y_pos + 8;
  117. xwidth = width;
  118. current = (SInt *) GetImageData (GetVopY (curr));
  119. break;
  120. case 3:
  121. x = x_pos + 8;
  122. y = y_pos + 8;
  123. xwidth = width;
  124. current = (SInt *) GetImageData (GetVopY (curr));
  125. break;
  126. case 4:
  127. x = x_pos / 2;
  128. y = y_pos / 2;
  129. xwidth = width / 2;
  130. current = (SInt *) GetImageData (GetVopU (curr));
  131. break;
  132. case 5:
  133. x = x_pos / 2;
  134. y = y_pos / 2;
  135. xwidth = width / 2;
  136. current = (SInt *) GetImageData (GetVopV (curr));
  137. break;
  138. default:
  139. break;
  140. }
  141. BlockPredict (current, x, y, xwidth, fblock[k]);
  142. }
  143. for (k = 0; k < 6; k++)
  144. {
  145. s = 0;
  146. for (i = 0; i < 8; i++)
  147. for (j = 0; j < 8; j++)
  148. tmp[s++] = (SInt) fblock[k][i][j];
  149. #ifndef _MMX_
  150. fdct_enc(tmp);
  151. #else
  152. fdct_mm32(tmp);
  153. #endif
  154. for (s = 0; s < 64; s++)
  155. coeff_ind[s] = (Int) tmp[s];
  156. if (k < 4) type = 1;
  157. else type = 2;
  158. /* For this release, only H263 quantization is supported. - adamli */
  159. BlockQuantH263(coeff_ind,QP,Mode,type,qcoeff_ind,
  160. GetVopBrightWhite(curr),1);
  161. BlockDequantH263(qcoeff_ind,QP,Mode,type,rcoeff_ind,1, 0, GetVopBitsPerPixel(curr));
  162. for (s = 0; s < 64; s++)
  163. tmp[s] = (SInt) rcoeff_ind[s];
  164. #ifndef _MMX_
  165. idct_enc(tmp);
  166. #else
  167. Fast_IDCT(tmp);
  168. #endif
  169. s = 0;
  170. for (i = 0; i < 8; i++)
  171. for (j = 0; j < 8; j++)
  172. iblock[k][i][j] = (Int)tmp[s++];
  173. coeff_ind += 64;
  174. qcoeff_ind += 64;
  175. rcoeff_ind += 64;
  176. if (Mode == MODE_INTRA||Mode==MODE_INTRA_Q)
  177. for (i = 0; i < 8; i++)
  178. for (j = 0; j < 8; j ++)
  179. iblock[k][i][j] = MIN (GetVopBrightWhite(curr), MAX (0, iblock[k][i][j]));
  180. switch (k)
  181. {
  182. case 0:
  183. case 1:
  184. case 2:
  185. continue;
  186. case 3:
  187. recon = (SInt *) GetImageData (GetVopY (rec_curr));
  188. if (operation == P_VOP) compensated = (SInt *) GetImageData (GetVopY (comp));
  189. BlockRebuild (recon, compensated, operation, max, x_pos,     y_pos,     width, 16, iblock[0]);
  190. BlockRebuild (recon, compensated, operation, max, x_pos + 8, y_pos,     width, 16, iblock[1]);
  191. BlockRebuild (recon, compensated, operation, max, x_pos,     y_pos + 8, width, 16, iblock[2]);
  192. BlockRebuild (recon, compensated, operation, max, x_pos + 8, y_pos + 8, width, 16, iblock[3]);
  193. continue;
  194. case 4:
  195. recon = (SInt *) GetImageData (GetVopU (rec_curr));
  196. if (operation == P_VOP) compensated = (SInt *) GetImageData (GetVopU (comp));
  197. BlockRebuild (recon, compensated, operation, max,
  198. x_pos/2, y_pos/2, width/2, 8, iblock[4]);
  199. continue;
  200. case 5:
  201. recon = (SInt *) GetImageData (GetVopV (rec_curr));
  202. if (operation == P_VOP) compensated = (SInt *) GetImageData (GetVopV (comp));
  203. BlockRebuild (recon, compensated, operation, max,
  204. x_pos/2, y_pos/2, width/2, 8, iblock[5]);
  205. continue;
  206. }
  207. }
  208. return;
  209. }
  210. /***********************************************************CommentBegin******
  211.  *
  212.  * -- BlockPredict -- Get prediction for an Intra block
  213.  *
  214.  * Purpose :
  215.  * Get prediction for an Intra block
  216.  *
  217.  * Arguments in :
  218.  * Int x_pos x_position of Macroblock
  219.  * Int y_pos y_position of Macroblock
  220.  * UInt width width of Vop bounding box
  221.  *
  222.  * Arguments in/out :
  223.  * SInt *curr current uncoded Vop data
  224.  * SInt *rec_curr reconstructed Vop data area
  225.  *
  226.  * Arguments out :
  227.  * Int fblock[][8] the prediction block to be coded for bitstream
  228.  *
  229.  ***********************************************************CommentEnd********/
  230. Void
  231. BlockPredict (SInt *curr, /*SInt *rec_curr,*/ Int x_pos, Int y_pos,
  232. UInt width, Int fblock[][8])
  233. {
  234. Int i, j;
  235. for (i = 0; i < 8; i++)
  236. {
  237. for (j = 0; j < 8; j++)
  238. {
  239. fblock[i][j] = curr[(y_pos+i)*width + x_pos+j];
  240. }
  241. }
  242. }
  243. /***********************************************************CommentBegin******
  244.  *
  245.  * -- BlockRebuild -- Reconstructs a block into data area of Vop
  246.  *
  247.  * Purpose :
  248.  * Reconstructs a block into data area of Vop
  249.  *
  250.  * Arguments in :
  251.  * Int x_pos x_position of Macroblock
  252.  * Int y_pos y_position of Macroblock
  253.  * UInt width width of Vop bounding box
  254.  *
  255.  * Arguments in/out :
  256.  * SInt *rec_curr current Vop data area to be reconstructed
  257.  *
  258.  * Description :
  259.  * Does reconstruction for Intra predicted blocks also
  260.  *
  261.  ***********************************************************CommentEnd********/
  262. Void
  263. BlockRebuild (SInt *rec_curr, SInt *comp, Int pred_type, Int max,
  264. Int x_pos, Int y_pos, UInt width, UInt edge, Int fblock[][8])
  265. {
  266. /* this function now does rebuild and generating error at the same time */
  267. Int i, j;
  268. SInt *rec;
  269. Int padded_width;
  270. padded_width = width + 2 * edge;
  271. rec = rec_curr + edge * padded_width + edge;
  272. if (pred_type == I_VOP)
  273. {
  274. SInt *p;
  275. p  = rec + y_pos * padded_width + x_pos;
  276. for (i = 0; i < 8; i++) 
  277. {
  278. for (j = 0; j < 8; j++)
  279. {
  280. SInt temp = fblock[i][j];
  281. *(p++) = CLIP(temp, 0, max);
  282. }
  283. p += padded_width - 8;
  284. }
  285. }
  286. else if (pred_type == P_VOP)
  287. {
  288. SInt *p, *pc; 
  289. p  = rec + y_pos * padded_width + x_pos;
  290. pc = comp     + y_pos * width + x_pos;
  291. for (i = 0; i < 8; i++)
  292. {
  293. for (j = 0; j < 8; j++)
  294. {
  295. SInt temp = *(pc++) + fblock[i][j];
  296. *(p++) = CLIP(temp, 0, max);
  297. }
  298. p += padded_width - 8;
  299. pc += width - 8;
  300. }
  301. }
  302. }
  303. /***********************************************************CommentBegin******
  304.  *
  305.  * -- BlockQuantH263 -- 8x8 block level quantization
  306.  *
  307.  * Purpose :
  308.  * 8x8 block level quantization
  309.  *
  310.  * Arguments in :
  311.  * Int *coeff non-quantized coefficients
  312.  * Int QP quantization parameter
  313.  * Int Mode Macroblock coding mode
  314.  *
  315.  * Arguments out :
  316.  * Int *qcoeff quantized coefficients
  317.  *
  318.  ***********************************************************CommentEnd********/
  319. Void
  320. BlockQuantH263 (Int *coeff, Int QP, Int mode, Int type, Int *qcoeff, Int maxDC, Int image_type)
  321. {
  322. Int i;
  323. Int level, result;
  324. Int step, offset;
  325. Int dc_scaler;
  326. if (!(QP > 0 && (QP < 32*image_type))) return;
  327. if (!(type == 1 || type == 2)) return;
  328. if (mode == MODE_INTRA || mode == MODE_INTRA_Q)
  329. {   /* Intra */
  330. dc_scaler = cal_dc_scaler(QP,type);
  331. qcoeff[0] = MAX(1,MIN(maxDC-1, (coeff[0] + dc_scaler/2)/dc_scaler));
  332. step = 2 * QP;
  333. for (i = 1; i < 64; i++)
  334. {
  335. level = (abs(coeff[i]))  / step;
  336. result = (coeff[i] >= 0) ? level : -level;
  337. qcoeff[i] =  MIN(2047, MAX(-2048, result));
  338. }
  339. }
  340. else
  341. {   /* non Intra */
  342. step = 2 * QP;
  343. offset = QP / 2;
  344. for (i = 0; i < 64; i++)
  345. {
  346. level = (abs(coeff[i]) - offset)  / step;
  347. result = (coeff[i] >= 0) ? level : -level;
  348. qcoeff[i] =  MIN(2047, MAX(-2048, result));
  349. }
  350. }
  351. return;
  352. }
  353. /***********************************************************CommentBegin******
  354.  *
  355.  * -- BlockDequantH263 -- 8x8 block dequantization
  356.  *
  357.  * Purpose :
  358.  * 8x8 block dequantization
  359.  *
  360.  * Arguments in :
  361.  * Int *qcoeff         quantized coefficients
  362.  * Int QP         quantization parameter
  363.  * Int mode         Macroblock coding mode
  364.  *      Int short_video_header  Flag to signal short video header bitstreams (H.263)
  365.  *
  366.  * Arguments out :
  367.  * Int *rcoeff reconstructed (dequantized) coefficients
  368.  *
  369.  ***********************************************************CommentEnd********/
  370. Void
  371. BlockDequantH263 (Int *qcoeff, Int QP, Int mode, Int type, Int *rcoeff,
  372. Int image_type, Int short_video_header, Int bits_per_pixel)
  373. {
  374. Int i;
  375. Int dc_scaler;
  376. Int lim;
  377. lim = (1 << (bits_per_pixel + 3));
  378. if (QP)
  379. {
  380. for (i = 0; i < 64; i++)
  381. {
  382. if (qcoeff[i])
  383. {
  384. /* 16.11.98 Sven Brandau: "correct saturation" due to N2470, Clause 2.1.6 */
  385. qcoeff[i] =  MIN(2047, MAX(-2048, qcoeff[i] ));
  386. if ((QP % 2) == 1)
  387. rcoeff[i] = QP * (2*ABS(qcoeff[i]) + 1);
  388. else
  389. rcoeff[i] = QP * (2*ABS(qcoeff[i]) + 1) - 1;
  390. rcoeff[i] = SIGN(qcoeff[i]) * rcoeff[i];
  391. }
  392. else
  393. rcoeff[i] = 0;
  394. }
  395. if (mode == MODE_INTRA || mode == MODE_INTRA_Q)
  396. {   /* Intra */
  397. MOMCHECK(QP > 0 && (QP < 32*image_type));
  398. MOMCHECK(type == 1 || type == 2);
  399. if (short_video_header)
  400. dc_scaler = 8;
  401. else
  402. dc_scaler = cal_dc_scaler(QP,type);
  403. rcoeff[0] = qcoeff[0] * dc_scaler;
  404. }
  405. }
  406. else
  407. {
  408. /* No quantizing at all */
  409. for (i = 0; i < 64; i++)
  410. {
  411. rcoeff[i] = qcoeff[i];
  412. }
  413. if (mode == MODE_INTRA || mode == MODE_INTRA_Q)
  414. {   /* Intra */
  415. rcoeff[0] = qcoeff[0]*8;
  416. }
  417. }
  418. for (i=0;i<64;i++)
  419. if (rcoeff[i]>(lim-1)) rcoeff[i]=(lim-1);
  420. else if (rcoeff[i]<(-lim)) rcoeff[i]=(-lim);
  421. return;
  422. }