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

多媒体编程

开发平台:

Visual C++

  1. #include "vm_common_defs.h"
  2. #include "mom_util.h"
  3. #include "mot_util.h"
  4. #include "mot_est_mb.h"
  5. extern FILE *ftrace;
  6. static Int roundtab16[] = {0,0,0,1,1,1,1,1,1,1,1,1,1,1,2,2};
  7. Void   MotionEstCompPicture (
  8. SInt *curr,
  9. SInt *prev,
  10. SInt *prev_ipol_y,
  11. SInt *prev_ipol_u,
  12. SInt *prev_ipol_v,
  13. Int prev_x,
  14. Int prev_y,
  15. Int vop_width,
  16. Int vop_height,
  17. Int enable_8x8_mv,
  18. Int edge,
  19. Int sr_for,
  20. Int f_code,
  21. Int rounding_type,
  22. Int br_x,
  23. Int br_y,
  24. Int br_width,
  25. Int br_height,
  26. SInt *curr_comp_y,
  27. SInt *curr_comp_u,
  28. SInt *curr_comp_v,
  29. Float *mad,
  30. Float *mv16_w,
  31. Float *mv16_h,
  32. Float *mv8_w,
  33. Float *mv8_h,
  34. SInt *mode16
  35. );
  36. Void GetPred_Chroma (
  37. Int x_curr,
  38. Int y_curr,
  39. Int dx,
  40. Int dy,
  41. SInt *prev_u,
  42. SInt *prev_v,
  43. SInt *comp_u,
  44. SInt *comp_v,
  45. Int width,
  46. Int width_prev,
  47. Int prev_x_min,
  48. Int prev_y_min,
  49. Int prev_x_max,
  50. Int prev_y_max,
  51. Int rounding_control
  52. );
  53. Void
  54. MotionEstimationCompensation (
  55. Vop    *curr_vop,   
  56. Vop    *prev_rec_vop,   
  57. Int    enable_8x8_mv,   
  58. Int    edge,   
  59. Int    f_code,   
  60. Vop    *curr_comp_vop,   
  61. Float  *mad,   
  62. Image  **mot_x,   
  63. Image  **mot_y,   
  64. Image  **mode   
  65. )
  66. {
  67. Image   *pr_rec_y;   
  68. Image   *pi_y;   
  69. Image   *mode16;
  70. Image   *mv16_w;
  71. Image   *mv16_h;
  72. Image   *mv8_w;
  73. Image   *mv8_h;
  74. SInt    *prev_ipol_y,   
  75. *prev_orig_y;   
  76. Int     vop_width, vop_height;
  77. Int     br_x;
  78. Int     br_y;
  79. Int     br_height;
  80. Int     br_width;
  81. Int     mv_h, mv_w;
  82. br_y=curr_vop->ver_spat_ref;
  83. br_x=curr_vop->hor_spat_ref;
  84. br_height=curr_vop->height;
  85. br_width=curr_vop->width;
  86. mv_h=br_height/MB_SIZE;
  87. mv_w=br_width/MB_SIZE;
  88. vop_width=prev_rec_vop->width;
  89. vop_height=prev_rec_vop->height;
  90. pr_rec_y = prev_rec_vop->y_chan;
  91. prev_orig_y = (SInt*)GetImageData(pr_rec_y);
  92. pi_y = AllocImage (2*vop_width, 2*vop_height, SHORT_TYPE);
  93. InterpolateImage(pr_rec_y, pi_y, GetVopRoundingType(curr_vop));
  94. prev_ipol_y = (SInt*)GetImageData(pi_y);
  95. mode16=AllocImage (mv_w,mv_h,SHORT_TYPE);
  96. SetConstantImage (mode16,(Float)MBM_INTRA);
  97. mv16_w=AllocImage (mv_w*2,mv_h*2,FLOAT_TYPE);
  98. mv16_h=AllocImage (mv_w*2,mv_h*2,FLOAT_TYPE);
  99. mv8_w =AllocImage (mv_w*2,mv_h*2,FLOAT_TYPE);
  100. mv8_h =AllocImage (mv_w*2,mv_h*2,FLOAT_TYPE);
  101. SetConstantImage (mv16_h,+0.0);
  102. SetConstantImage (mv16_w,+0.0);
  103. SetConstantImage (mv8_h,+0.0);
  104. SetConstantImage (mv8_w,+0.0);
  105. SetConstantImage (curr_comp_vop->u_chan, 0);
  106. SetConstantImage (curr_comp_vop->v_chan, 0);
  107. MotionEstCompPicture(
  108. (SInt *)GetImageData(GetVopY(curr_vop)), 
  109. prev_orig_y,   
  110. prev_ipol_y,   
  111. (SInt*)GetImageData(prev_rec_vop->u_chan) + (vop_width/2) * (16/2) + (16/2),
  112. (SInt*)GetImageData(prev_rec_vop->v_chan) + (vop_width/2) * (16/2) + (16/2),
  113. prev_rec_vop->hor_spat_ref,
  114. prev_rec_vop->ver_spat_ref,
  115. vop_width,vop_height,
  116. enable_8x8_mv,
  117. edge,
  118. GetVopSearchRangeFor(curr_vop), 
  119. f_code,
  120. GetVopRoundingType(curr_vop),
  121. br_x,br_y,   
  122. br_width,br_height,   
  123. (SInt*)GetImageData(curr_comp_vop->y_chan),
  124. (SInt*)GetImageData(curr_comp_vop->u_chan),
  125. (SInt*)GetImageData(curr_comp_vop->v_chan),
  126. mad,
  127. (Float*)GetImageData(mv16_w),
  128. (Float*)GetImageData(mv16_h),
  129. (Float*)GetImageData(mv8_w),
  130. (Float*)GetImageData(mv8_h),
  131. (SInt*) GetImageData(mode16)
  132. );
  133. GetMotionImages(mv16_w, mv16_h, mv8_w, mv8_h, mode16, mot_x, mot_y, mode);
  134. FreeImage(mv16_w); FreeImage(mv16_h);
  135. FreeImage(mv8_w);  FreeImage(mv8_h);
  136. FreeImage(mode16);
  137. FreeImage(pi_y);
  138. }
  139. Void
  140. MotionEstCompPicture(
  141. SInt    *curr,   
  142. SInt    *prev,   
  143. SInt    *prev_ipol,   
  144. SInt    *prev_u,   
  145. SInt    *prev_v,   
  146. Int     prev_x,   
  147. Int     prev_y,   
  148. Int     vop_width,   
  149. Int     vop_height,   
  150. Int     enable_8x8_mv,   
  151. Int     edge,   
  152. Int sr_for,   
  153. Int     f_code,          /* <-- MV search range 1/2 or 1/4 pel: 1=32,2=64,...,7=2048*/
  154. Int rounding_type,   
  155. Int     br_x,   
  156. Int     br_y,   
  157. Int     br_width,   
  158. Int     br_height,   
  159. SInt *curr_comp_y,   
  160. SInt *curr_comp_u,   
  161. SInt *curr_comp_v,   
  162. Float *mad,   
  163. Float   *mv16_w,   
  164. Float   *mv16_h,   
  165. Float   *mv8_w,   
  166. Float   *mv8_h,   
  167. SInt    *mode16   
  168. )
  169. {
  170. Int i, j, k;
  171. SInt curr_mb[MB_SIZE][MB_SIZE];
  172. SInt curr_comp_mb_16[MB_SIZE][MB_SIZE];
  173. SInt curr_comp_mb_8[MB_SIZE][MB_SIZE];
  174. Int sad8 = MV_MAX_ERROR, sad16, sad;
  175. Int imas_w, imas_h, Mode;
  176. Int posmode, pos16, pos8;
  177. Int min_error16,
  178. min_error8_0, min_error8_1, min_error8_2, min_error8_3;
  179. SInt *halfpelflags;
  180. Float hint_mv_w, hint_mv_h;
  181. Int xsum,ysum,dx,dy;
  182. Int prev_x_min,prev_x_max,prev_y_min,prev_y_max;
  183. prev_x_min = 2 * prev_x + 2 * 16;
  184. prev_y_min = 2 * prev_y + 2 * 16;
  185. prev_x_max = prev_x_min + 2 * vop_width - 4 * 16;
  186. prev_y_max = prev_y_min + 2 * vop_height - 4 * 16; 
  187. imas_w=br_width/MB_SIZE;
  188. imas_h=br_height/MB_SIZE;
  189. halfpelflags=(SInt*)malloc(5*4*sizeof(SInt));
  190. sad = 0;
  191. for ( j=0; j< (br_height/MB_SIZE); j++)
  192. {
  193. hint_mv_w = hint_mv_h = 0.f;
  194. for ( i=0; i< (br_width/MB_SIZE); i++)
  195. {
  196. Int min_error;
  197. posmode =          j * imas_w +   i;
  198. pos16   = pos8 = 2*j*2*imas_w + 2*i;
  199. MBMotionEstimation(curr,
  200. prev, br_x, br_y,
  201. br_width, i, j, prev_x, prev_y,
  202. vop_width, vop_height, enable_8x8_mv, edge,
  203. f_code, sr_for, 
  204. hint_mv_w, hint_mv_h, 
  205. mv16_w, mv16_h,
  206. mv8_w, mv8_h, &min_error, halfpelflags);
  207. Mode = ChooseMode(curr, 
  208. i*MB_SIZE,j*MB_SIZE, min_error, br_width);
  209. hint_mv_w = mv16_w[pos16];
  210. hint_mv_h = mv16_h[pos16];
  211. LoadArea(curr, i*MB_SIZE, j*MB_SIZE, 16, 16, br_width, (SInt *)curr_mb);
  212. if ( Mode != 0)
  213. {
  214. FindSubPel (i*MB_SIZE,j*MB_SIZE, prev_ipol,
  215. &curr_mb[0][0], 16, 16 , 0,
  216. br_x-prev_x,br_y-prev_y,vop_width, vop_height,
  217. edge, halfpelflags, &curr_comp_mb_16[0][0],
  218. &mv16_w[pos16], &mv16_h[pos16], &min_error16);
  219. sad16 = min_error16;
  220. mode16[posmode] = MBM_INTER16;
  221. if (enable_8x8_mv)
  222. {
  223. xsum = 0; ysum = 0;
  224. FindSubPel(i*MB_SIZE, j*MB_SIZE, prev_ipol,
  225. &curr_mb[0][0], 8, 8 , 0,
  226. br_x-prev_x,br_y-prev_y, vop_width, vop_height,
  227. edge, halfpelflags, &curr_comp_mb_8[0][0],
  228. &mv8_w[pos8], &mv8_h[pos8], &min_error8_0);
  229. xsum += (Int)(2*(mv8_w[pos8]));
  230. ysum += (Int)(2*(mv8_h[pos8]));
  231. FindSubPel(i*MB_SIZE, j*MB_SIZE, prev_ipol,
  232. &curr_mb[0][8], 8, 8 , 1,
  233. br_x-prev_x,br_y-prev_y, vop_width,vop_height,
  234. edge, halfpelflags, &curr_comp_mb_8[0][8],
  235. &mv8_w[pos8+1], &mv8_h[pos8+1], &min_error8_1);
  236. xsum += (Int)(2*(mv8_w[pos8+1]));
  237. ysum += (Int)(2*(mv8_h[pos8+1]));
  238. pos8+=2*imas_w;
  239. FindSubPel(i*MB_SIZE, j*MB_SIZE, prev_ipol,
  240. &curr_mb[8][0], 8, 8 , 2,
  241. br_x-prev_x,br_y-prev_y, vop_width,vop_height,
  242. edge, halfpelflags, &curr_comp_mb_8[8][0], 
  243. &mv8_w[pos8], &mv8_h[pos8], &min_error8_2);
  244. xsum += (Int)(2*(mv8_w[pos8]));
  245. ysum += (Int)(2*(mv8_h[pos8]));
  246. FindSubPel(i*MB_SIZE, j*MB_SIZE, prev_ipol, 
  247. &curr_mb[8][8], 8, 8 , 3,
  248. br_x-prev_x,br_y-prev_y, vop_width,vop_height,
  249. edge, halfpelflags, &curr_comp_mb_8[8][8], 
  250. &mv8_w[pos8+1], &mv8_h[pos8+1], &min_error8_3);
  251. xsum += (Int)(2*(mv8_w[pos8+1]));
  252. ysum += (Int)(2*(mv8_h[pos8+1]));
  253. sad8 = min_error8_0+min_error8_1+min_error8_2+min_error8_3;
  254. if (sad8 < (sad16 -(128+1)))
  255. mode16[posmode] = MBM_INTER8;
  256. }   
  257. if ((mv16_w[pos16]==0.0) && (mv16_h[pos16]==0.0) && (mode16[posmode]==MBM_INTER16))
  258. sad16 += 128+1;
  259. if(mode16[posmode] == MBM_INTER8)
  260. {
  261. dx = SIGN (xsum) * (roundtab16[ABS (xsum) % 16] + (ABS (xsum) / 16) * 2);
  262. dy = SIGN (ysum) * (roundtab16[ABS (ysum) % 16] + (ABS (ysum) / 16) * 2);
  263. sad += sad8;
  264. }
  265. else 
  266. {
  267. dx = (Int)(2 * mv16_w[pos16]);
  268. dy = (Int)(2 * mv16_h[pos16]);
  269. dx = ( dx % 4 == 0 ? dx >> 1 : (dx>>1)|1 );
  270. dy = ( dy % 4 == 0 ? dy >> 1 : (dy>>1)|1 );
  271. sad += sad16;
  272. }
  273. GetPred_Chroma (i*MB_SIZE, j*MB_SIZE, dx, dy, 
  274. prev_u, prev_v, curr_comp_u, curr_comp_v,
  275. br_width, vop_width,
  276. prev_x_min/4,prev_y_min/4,prev_x_max/4,prev_y_max/4, rounding_type);
  277. }   
  278. else   
  279. {
  280. mode16[posmode] = MBM_INTRA;
  281. for (k = 0; k < MB_SIZE*MB_SIZE; k++) 
  282. {
  283. curr_comp_mb_16[k/MB_SIZE][k%MB_SIZE] = 0;
  284. sad += curr_mb[k/MB_SIZE][k%MB_SIZE];
  285. }
  286. }
  287. if (mode16[posmode] == MBM_INTER8)
  288. SetArea((SInt*)curr_comp_mb_8, i*MB_SIZE, j*MB_SIZE, 16, 16, br_width, curr_comp_y);
  289. else
  290. SetArea((SInt*)curr_comp_mb_16, i*MB_SIZE, j*MB_SIZE, 16, 16, br_width, curr_comp_y);
  291. }   
  292. }
  293. *mad = (float)sad/(br_width*br_height);
  294. free((Char*)halfpelflags);
  295. return;
  296. }
  297. #define unrestricted_MC_chro(x,y,npix,prev_x_min,prev_y_min,prev_x_max,prev_y_max) ((x)+(y)*(npix))
  298. Void GetPred_Chroma (
  299. Int x_curr,
  300. Int y_curr,
  301. Int dx,
  302. Int dy,
  303. SInt *prev_u,
  304. SInt *prev_v,
  305. SInt *comp_u,
  306. SInt *comp_v,
  307. Int width,
  308. Int width_prev,
  309. Int prev_x_min,
  310. Int prev_y_min,
  311. Int prev_x_max,
  312. Int prev_y_max,
  313. Int rounding_control)
  314. {
  315. Int m,n;
  316. Int x, y, ofx, ofy, lx;
  317. Int xint, yint;
  318. Int xh, yh;
  319. Int index1,index2,index3,index4;
  320. lx = width_prev/2;
  321. x = x_curr>>1;
  322. y = y_curr>>1;
  323. xint = dx>>1;
  324. xh = dx & 1;
  325. yint = dy>>1;
  326. yh = dy & 1;
  327. if (!xh && !yh)
  328. {
  329. for (n = 0; n < 8; n++)
  330. {
  331. for (m = 0; m < 8; m++)
  332. {
  333. ofx = x + xint + m;
  334. ofy = y + yint + n;
  335. index1 = unrestricted_MC_chro(ofx,ofy,lx,prev_x_min,
  336. prev_y_min,prev_x_max,prev_y_max);
  337. comp_u[(y+n)*width/2+x+m]
  338. = *(prev_u+index1);
  339. comp_v[(y+n)*width/2+x+m]
  340. = *(prev_v+index1);
  341. }
  342. }
  343. }
  344. else if (!xh && yh)
  345. {
  346. for (n = 0; n < 8; n++)
  347. {
  348. for (m = 0; m < 8; m++)
  349. {
  350. ofx = x + xint + m;
  351. ofy = y + yint + n;
  352. index1 =  unrestricted_MC_chro(ofx,ofy,lx,prev_x_min,
  353. prev_y_min,prev_x_max,prev_y_max);
  354. index2 =  unrestricted_MC_chro(ofx,ofy+yh,lx,prev_x_min,
  355. prev_y_min,prev_x_max,prev_y_max);
  356. comp_u[(y+n)*width/2+x+m]
  357. = (*(prev_u+index1) +
  358. *(prev_u+index2) + 1- rounding_control)>>1;
  359. comp_v[(y+n)*width/2+x+m]
  360. = (*(prev_v+index1) +
  361. *(prev_v+index2) + 1- rounding_control)>>1;
  362. }
  363. }
  364. }
  365. else if (xh && !yh)
  366. {
  367. for (n = 0; n < 8; n++)
  368. {
  369. for (m = 0; m < 8; m++)
  370. {
  371. ofx = x + xint + m;
  372. ofy = y + yint + n;
  373. index1 =  unrestricted_MC_chro(ofx,ofy,lx,prev_x_min,
  374. prev_y_min,prev_x_max,prev_y_max);
  375. index2 =  unrestricted_MC_chro(ofx+xh,ofy,lx,prev_x_min,
  376. prev_y_min,prev_x_max,prev_y_max);
  377. comp_u[(y+n)*width/2+x+m]
  378. = (*(prev_u+index1) +
  379. *(prev_u+index2) + 1- rounding_control)>>1;
  380. comp_v[(y+n)*width/2+x+m]
  381. = (*(prev_v+index1) +
  382. *(prev_v+index2) + 1- rounding_control)>>1;
  383. }
  384. }
  385. }
  386. else
  387. {   
  388. for (n = 0; n < 8; n++)
  389. {
  390. for (m = 0; m < 8; m++)
  391. {
  392. ofx = x + xint + m;
  393. ofy = y + yint + n;
  394. index1 =  unrestricted_MC_chro(ofx,ofy,lx,prev_x_min,
  395. prev_y_min,prev_x_max,prev_y_max);
  396. index2 =  unrestricted_MC_chro(ofx+xh,ofy,lx,prev_x_min,
  397. prev_y_min,prev_x_max,prev_y_max);
  398. index3 =  unrestricted_MC_chro(ofx,ofy+yh,lx,prev_x_min,
  399. prev_y_min,prev_x_max,prev_y_max);
  400. index4 =  unrestricted_MC_chro(ofx+xh,ofy+yh,lx,prev_x_min,
  401. prev_y_min,prev_x_max,prev_y_max);
  402. comp_u[(y+n)*width/2+x+m]
  403. = (*(prev_u+index1)+
  404. *(prev_u+index2)+
  405. *(prev_u+index3)+
  406. *(prev_u+index4)+
  407. 2- rounding_control)>>2;
  408. comp_v[(y+n)*width/2+x+m]
  409. = (*(prev_v+index1)+
  410. *(prev_v+index2)+
  411. *(prev_v+index3)+
  412. *(prev_v+index4)+
  413. 2- rounding_control)>>2;
  414. }
  415. }
  416. }
  417. return;
  418. }