mot_util.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.  *  mot_util.c
  25.  *
  26.  *  Copyright (C) 2001  Project Mayo
  27.  *
  28.  *  Adam Li
  29.  *
  30.  *  DivX Advance Research Center <darc@projectmayo.com>
  31.  *
  32.  **************************************************************************/
  33. /* This file contains some utility functions to for motion estimation and */
  34. /* compensation.                                                          */
  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 "mom_structs.h"
  38. #include "vm_common_defs.h"
  39. #include "mot_util.h"
  40. /* ------------------------------------------------------------------------- */
  41. /* Macro to compute the MB absolute error difference of the inside the shape */
  42. //static Int P_diff;
  43. #define DIFF1(v1,v2,idx) (P_diff = (v1[idx]-v2[idx]), ABS(P_diff))
  44. /***********************************************************CommentBegin******
  45.  *
  46.  * -- InterpolateImage -- Interpolates a complete  (SInt)image
  47.  *
  48.  * Purpose :
  49.  *      Interpolates a complete  (SInt) image for easier half pel prediction
  50.  *
  51.  ***********************************************************CommentEnd********/
  52. Void
  53. InterpolateImage(
  54. Image   *input_image,   /* <-- image to interpolate (SInt) */
  55. Image   *output_image,   /* --> interpolated image (SInt)  */
  56. Int     rounding_control
  57. )
  58. {
  59. SInt   *ii, *oo;
  60. UInt    i, j;
  61. UInt   width, height;
  62. width = input_image->x;
  63. height = input_image->y;
  64. ii = (SInt*)GetImageData(output_image);
  65. oo = (SInt*)GetImageData(input_image);
  66. /* main image */
  67. for (j = 0; j < height-1; j++)
  68. {
  69. for (i = 0; i  < width-1; i++)
  70. {
  71. *(ii + (i<<1)) = *(oo + i);
  72. *(ii + (i<<1)+1) = (*(oo + i) + *(oo + i + 1) + 1- rounding_control)>>1;
  73. *(ii + (i<<1)+(width<<1)) = (*(oo + i) + *(oo + i + width) + 1-
  74. rounding_control)>>1;
  75. *(ii + (i<<1)+1+(width<<1)) = (*(oo+i) + *(oo+i+1) +
  76. *(oo+i+width) + *(oo+i+1+width) + 2-
  77. rounding_control)>>2;
  78. }
  79. /* last pels on each line */
  80. *(ii+ (width<<1) - 2) = *(oo + width - 1);
  81. *(ii+ (width<<1) - 1) = *(oo + width - 1);
  82. *(ii+ (width<<1)+ (width<<1)-2) = (*(oo+width-1)+*(oo+width+width-1)+1-
  83. rounding_control)>>1;
  84. *(ii+ (width<<1)+ (width<<1)-1) = (*(oo+width-1)+*(oo+width+width-1)+1-
  85. rounding_control)>>1;
  86. ii += (width<<2);
  87. oo += width;
  88. }
  89. /* last lines */
  90. for (i = 0; i < width-1; i++)
  91. {
  92. *(ii+ (i<<1)) = *(oo + i);
  93. *(ii+ (i<<1)+1) = (*(oo + i) + *(oo + i + 1) + 1- rounding_control)>>1;
  94. *(ii+ (width<<1)+ (i<<1)) = *(oo + i);
  95. *(ii+ (width<<1)+ (i<<1)+1) = (*(oo + i) + *(oo + i + 1) + 1-
  96. rounding_control)>>1;
  97. }
  98. /* bottom right corner pels */
  99. *(ii + (width<<1) - 2) = *(oo + width -1);
  100. *(ii + (width<<1) - 1) = *(oo + width -1);
  101. *(ii + (width<<2) - 2) = *(oo + width -1);
  102. *(ii + (width<<2) - 1) = *(oo + width -1);
  103. return;
  104. }
  105. /***********************************************************CommentBegin******
  106.  *
  107.  * -- GetMotionImages --
  108.  *
  109.  * Purpose :
  110.  *      Translate the MVs data from the resulting separated four
  111.  *      (Float) Images (16x16/8x8, X,Y) of the motion estimation process
  112.  *      into two Images, which contain the 16x16 and 8x8 MVs
  113.  *      values acording to the modes (MBM_INTRA, MBM_INTER16,
  114.  *      MBM_INTER8). It also
  115.  *      makes a copy of imode16 (SInt-Image of modes).
  116.  *
  117.  * Return values :
  118.  *      1 on success, -1 on error
  119.  *
  120.  ***********************************************************CommentEnd********/
  121. Int
  122. GetMotionImages(
  123. Image   *imv16_w,   /* <-- 16x16 horiz. MV Float-Image (MxN) (cuad.)   */
  124. Image   *imv16_h,   /* <-- 16x16 verti. MV Float-Image   (MxN) (cuad.) */
  125. Image   *imv8_w,   /* <-- 8x8  horizontal MV Float-Image  (MxN)       */
  126. Image   *imv8_h,   /* <-- 8x8  vertical MV Float-Image    (MxN)       */
  127. Image   *imode16,   /* <-- SInt-Image of modes            (M/2xN/2)    */
  128. Image   **mv_x,   /* --> horizontal MV Float-Image      (MxN)        */
  129. Image   **mv_y,   /* --> vertical   MV Float-Image      (MxN)        */
  130. Image   **mode   /* --> SInt-Image of modes           (M/2xN/2)     */
  131. )
  132. {
  133. Int     i, j;
  134. Int     width, height, base;
  135. Float   val_x, val_y;
  136. Float   *data_x, *data_y,
  137. *mv16_w, *mv16_h,
  138. *mv8_w,  *mv8_h;
  139. SInt    *mode16, *data_mode;
  140. SInt    modo;
  141. width = imode16->x; height = imode16->y;
  142. (*mode)=AllocImage(width,height,SHORT_TYPE);
  143. (*mv_x)=AllocImage(width*2,height*2,FLOAT_TYPE);
  144. (*mv_y)=AllocImage(width*2,height*2,FLOAT_TYPE);
  145. data_x = (Float*)GetImageData((*mv_x));
  146. data_y = (Float*)GetImageData((*mv_y));
  147. data_mode = (SInt*)GetImageData((*mode));
  148. mode16=(SInt*)GetImageData(imode16);
  149. mv16_w=(Float*)GetImageData(imv16_w);
  150. mv16_h=(Float*)GetImageData(imv16_h);
  151. mv8_w=(Float*)GetImageData(imv8_w);
  152. mv8_h=(Float*)GetImageData(imv8_h);
  153. for(j=0;j<height;j++)
  154. {
  155. for(i=0;i< width;i++)
  156. {
  157. modo=data_mode[j*width+i]=mode16[j*width+i];
  158. if ( modo==MBM_INTRA)   /*INTRA*/
  159. {
  160. base=2*j*2*width+2*i;
  161. data_x[base]=0.0;  data_x[base+1]=0.0;
  162. data_y[base]=0.0;  data_y[base+1]=0.0;
  163. base+=width*2;
  164. data_x[base]=0.0;  data_x[base+1]=0.0;
  165. data_y[base]=0.0;  data_y[base+1]=0.0;
  166. }
  167. else if(modo==MBM_INTER16)   /*INTER 16*/
  168. {
  169. base=2*j*2*width+2*i;
  170. val_x=mv16_w[base];val_y=mv16_h[base];
  171. data_x[base]=val_x; data_x[base+1]=val_x;
  172. data_y[base]=val_y; data_y[base+1]=val_y;
  173. base+=width*2;
  174. data_x[base]=val_x; data_x[base+1]=val_x;
  175. data_y[base]=val_y; data_y[base+1]=val_y;
  176. }
  177. else if (modo==MBM_INTER8)   /*INTER4*8*/
  178. {
  179. base=2*j*2*width+2*i;
  180. data_x[base]   = mv8_w[base];
  181. data_y[base]   = mv8_h[base];
  182. data_x[base+1] = mv8_w[base+1];
  183. data_y[base+1] = mv8_h[base+1];
  184. base+=width*2;
  185. data_x[base]   = mv8_w[base];
  186. data_y[base]   = mv8_h[base];
  187. data_x[base+1] = mv8_w[base+1];
  188. data_y[base+1] = mv8_h[base+1];
  189. }
  190. }   /* end for*/
  191. }   /* end for*/
  192. return(1);
  193. }
  194. /***********************************************************CommentBegin******
  195.  *
  196.  * -- ChooseMode -- chooses coding mode INTRA/INTER dependig on the SAD values
  197.  *
  198.  * Purpose :
  199.  *      chooses coding mode INTRA/INTER dependig on the SAD values
  200.  *
  201.  * Return values :
  202.  *      1 for INTER, 0 for INTRA
  203.  *
  204.  ***********************************************************CommentEnd********/
  205. Int
  206. ChooseMode(
  207. SInt   *curr,   /* <-- current Y values (not extended)          */
  208. Int    x_pos,   /* <-- upper-left MB corner hor. coor.          */
  209. Int    y_pos,   /* <-- upper-left MB corner ver. coor.          */
  210. Int    min_SAD,   /* <-- min SAD (from integer pel search)        */
  211. UInt   width   /* <-- current Y picture width                  */
  212. )
  213. {
  214. Int   i, j;
  215. Int   MB_mean = 0, A = 0;
  216. Int   y_off;
  217. for (j = 0; j < MB_SIZE; j++)
  218. {
  219. y_off = (y_pos + j) * width;
  220. for (i = 0; i < MB_SIZE; i++)
  221. {
  222. MB_mean += *(curr + x_pos + i + y_off);
  223. }
  224. }
  225. MB_mean /= 256;
  226. for (j = 0; j < MB_SIZE; j++)
  227. {
  228. y_off = (y_pos + j) * width;
  229. for (i = 0; i < MB_SIZE; i++)
  230. {
  231. A += abs( *(curr + x_pos + i + y_off) - MB_mean );
  232. }
  233. }
  234. if (A < (min_SAD - 2*256))
  235. return 0;
  236. else
  237. return 1;
  238. }
  239. /***********************************************************CommentBegin******
  240.  *
  241.  * -- SAD_Macroblock -- obtains the SAD for a Macroblock
  242.  *
  243.  * Purpose :
  244.  *      obtains the SAD for a Macroblock
  245.  *
  246.  * Return values :
  247.  *      sad of the MB
  248.  *
  249.  ***********************************************************CommentEnd********/
  250. Int
  251. SAD_Macroblock(
  252. SInt   *ii,   /* <-- Pointer to the upper-left pel of first MB */
  253. SInt   *act_block,   /* <-- Id, second MB (width=16)                  */
  254. UInt   h_length,   /* <-- Width of first area                       */
  255. Int    Min_FRAME   /* <-- Minimum prediction error so far           */
  256. )
  257. {
  258. /* Int    i;
  259. Int    sad = 0;
  260. SInt   *kk;
  261. register Int P_diff;
  262. kk = act_block;
  263. i = 16;
  264. while (i--)
  265. {
  266. sad += (DIFF1(ii,kk,0)+DIFF1(ii,kk,1)
  267. +DIFF1(ii,kk,2)+DIFF1(ii,kk,3)
  268. +DIFF1(ii,kk,4)+DIFF1(ii,kk,5)
  269. +DIFF1(ii,kk,6)+DIFF1(ii,kk,7)
  270. +DIFF1(ii,kk,8)+DIFF1(ii,kk,9)
  271. +DIFF1(ii,kk,10)+DIFF1(ii,kk,11)
  272. +DIFF1(ii,kk,12)+DIFF1(ii,kk,13)
  273. +DIFF1(ii,kk,14)+DIFF1(ii,kk,15)
  274. );
  275. ii += h_length;
  276. kk += 16;
  277. if (sad > Min_FRAME)
  278. return MV_MAX_ERROR;
  279. }
  280. return sad;
  281. */
  282. int i, j;
  283. int sad = 0;
  284. SInt *p1 = ii, *p2 = act_block;
  285. i = 16;
  286. while (i--) {
  287. j = 16;
  288. while (j --)
  289. sad += abs((int)*(p1++) - (int)*(p2++));
  290. if (sad > Min_FRAME)
  291. return MV_MAX_ERROR;
  292. p1 += h_length - 16;
  293. }
  294. return sad;
  295. }
  296. /***********************************************************CommentBegin******
  297.  *
  298.  * -- SAD_Block -- obtains the SAD for a Block
  299.  *
  300.  * Purpose :
  301.  *      obtains the SAD for a Block
  302.  *
  303.  * Return values :
  304.  *      sad of the Block
  305.  *
  306.  ***********************************************************CommentEnd********/
  307. Int
  308. SAD_Block(
  309. SInt   *ii,   /* <-- First area                      */
  310. SInt   *act_block,   /* <-- Id. second MB (width=16)        */
  311. UInt   h_length,   /* <-- Width of first area             */
  312. Int    min_sofar   /* <-- Minimum prediction error so far */
  313. )
  314. {
  315. /* Int    i;
  316. Int    sad = 0;
  317. SInt   *kk;
  318. register Int P_diff;
  319. kk = act_block;
  320. i = 8;
  321. while (i--)
  322. {
  323. sad += (DIFF1(ii,kk,0)+DIFF1(ii,kk,1)
  324. +DIFF1(ii,kk,2)+DIFF1(ii,kk,3)
  325. +DIFF1(ii,kk,4)+DIFF1(ii,kk,5)
  326. +DIFF1(ii,kk,6)+DIFF1(ii,kk,7)
  327. );
  328. ii += h_length;
  329. kk += 16;
  330. if (sad > min_sofar)
  331. return INT_MAX;
  332. }
  333. return sad;
  334. */
  335. int i, j;
  336. int sad = 0;
  337. SInt *p1 = ii, *p2 = act_block;
  338. i = 8;
  339. while (i--) {
  340. j = 8;
  341. while (j --)
  342. sad += abs((int)*(p1++) - (int)*(p2++));
  343. if (sad > min_sofar)
  344. return INT_MAX;
  345. p1 += h_length - 8;
  346. p2 += 16 - 8;
  347. }
  348. return sad;
  349. }
  350. /***********************************************************CommentBegin******
  351.  *
  352.  * -- LoadArea -- fills array with a image-data
  353.  *
  354.  * Purpose :
  355.  *      fills array with a image-data
  356.  *
  357.  * Return values :
  358.  *      Pointer to the filled array
  359.  *
  360.  ***********************************************************CommentEnd********/
  361. Void
  362. LoadArea(
  363. SInt *im,   /* <-- pointer to image         */
  364. Int x,   /* <-- horizontal pos           */
  365. Int y,   /* <-- vertical  pos            */
  366. Int x_size,   /* <-- width of array           */
  367. Int y_size,   /* <-- height of array          */
  368. Int lx,   /* <-- width of the image data  */
  369. SInt *block   /* <-> pointer to the array     */
  370. )
  371. {
  372. SInt   *in;
  373. SInt   *out;
  374. Int    i = x_size;
  375. Int    j = y_size;
  376. in = im + (y*lx) + x;
  377. out = block;
  378. while (j--)
  379. {
  380. while (i--)
  381. *out++ = *in++;
  382. i = x_size;
  383. in += lx - x_size;
  384. }
  385. return;
  386. }
  387. /***********************************************************CommentBegin******
  388.  *
  389.  * -- SetArea -- fills a image-data with an array
  390.  *
  391.  * Purpose :
  392.  *      fills a image-data with an array
  393.  *
  394.  ***********************************************************CommentEnd********/
  395. Void
  396. SetArea(
  397. SInt   *block,   /* <-- pointer to array         */
  398. Int    x,   /* <-- horizontal pos in image  */
  399. Int    y,   /* <-- vertical  pos in image   */
  400. Int    x_size,   /* <-- width of array           */
  401. Int    y_size,   /* <-- height of array          */
  402. Int    lx,   /* <-- width of the image data  */
  403. SInt   *im   /* --> pointer to image         */
  404. )
  405. {
  406. SInt   *in;
  407. SInt   *out;
  408. Int    i = x_size;
  409. Int    j = y_size;
  410. in  = block;
  411. out = im + (y*lx) + x;
  412. while (j--)
  413. {
  414. while (i--)
  415. *out++ = *in++;
  416. i = x_size;
  417. out += lx - x_size;
  418. }
  419. }