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

多媒体编程

开发平台:

Visual C++

  1. #include "vm_common_defs.h"
  2. #include "bitstream.h"
  3. #include "putvlc.h"
  4. #define MBV_H(h,v)      (ph[2*(v)*2*hdim+2*(h)])
  5. #define MBV_V(h,v)      (pv[2*(v)*2*hdim+2*(h)])
  6. #define BV_H(h,v,h2,v2) (ph[(2*(v)+(v2))*2*hdim+2*(h)+(h2)])
  7. #define BV_V(h,v,h2,v2) (pv[(2*(v)+(v2))*2*hdim+2*(h)+(h2)])
  8. #define MB_MODE(h,v)    ( ((h)<0||(h)>=hdim||(v)<0||(v)>=vdim ? MBM_OUT : (pm[(v)*hdim+(h)])) )
  9. #define BV(p,xdim,h,v,h2,v2) (p[(2*(v)+(v2))*(xdim)+2*(h)+(h2)])
  10. Int WriteMVcomponent(Int f_code, Int dmv, Image *bs);
  11. Void ScaleMVD (Int f_code, Int diff_vector, Int *residual, Int *vlc_code_mag);
  12. Void   find_pmvs (Image *mot_x, Image *mot_y, Image *MB_decisions, Image *B_decisions,
  13. Int x, Int y, Int block, Int transparent_value, Int quarter_pel, Int *error_flag,
  14. Int *mvx, Int *mvy, Int newgob);
  15. SInt ModeMB (Image *MB_decision, Int i, Int j);
  16. Int
  17. Bits_CountMB_Motion(
  18. Image   *mot_h,   
  19. Image   *mot_v,   
  20. Image   *alpha,   
  21. Image   *modes,   
  22. Int     h,   
  23. Int     v,   
  24. Int     f_code,   
  25.   
  26. Int     quarter_pel,       
  27. Image   *bs,   
  28. Int     error_res_disable,
  29. Int     after_marker,
  30. Int     **slice_nb,
  31. Int arbitrary_shape
  32. )
  33. {
  34. Int     vdim, hdim;   
  35. Float   *ph, *pv;   
  36. SInt    *pm;   
  37. SInt    *pa;   
  38. Int     mode;
  39. Int     bits_mot = 0;
  40. Int     i, error_flag=0,mvx=0,mvy=0;
  41. Float   pred_h, pred_v;
  42. Float   diff_h, diff_v;
  43. Int     bh, bv;
  44. Int     local_f_code;   
  45. Float   subdim;   
  46. vdim = (Int)modes->y;
  47. hdim = (Int)modes->x;
  48. ph=(Float*)GetImageData(mot_h);
  49. pv=(Float*)GetImageData(mot_v);
  50. pm=(SInt*)GetImageData(modes);
  51. pa=NULL;
  52. if (quarter_pel)
  53. {
  54. local_f_code = f_code+1;
  55. subdim = 4.0;
  56. }
  57. else
  58. {
  59. local_f_code = f_code;
  60. subdim = 2.0;
  61. }
  62. switch (mode=MB_MODE(h,v))
  63. {
  64. case MBM_INTRA:
  65. break;
  66. case MBM_INTER16:
  67. find_pmvs(mot_h,mot_v,modes,alpha,h,v,0,MBM_TRANSPARENT,
  68.   
  69. quarter_pel,&error_flag,&mvx,&mvy,0);
  70. pred_h=((Float)mvx)/subdim;   
  71. pred_v=((Float)mvy)/subdim;   
  72.   
  73. bits_mot += WriteMVcomponent(local_f_code, (Int)(subdim*(MBV_H(h,v) - pred_h)), bs);
  74.   
  75. bits_mot += WriteMVcomponent(local_f_code, (Int)(subdim*(MBV_V(h,v) - pred_v)), bs);
  76. break;
  77. case MBM_INTER8:
  78. i=1;
  79. for (bv=0; bv<=1; bv++)
  80. for (bh=0; bh<=1; bh++)
  81. {
  82. find_pmvs(mot_h,mot_v,modes,alpha,h,v,i,MBM_TRANSPARENT,
  83.   
  84. quarter_pel,&error_flag,&mvx,&mvy,0);
  85. pred_h=((Float)mvx)/subdim;   
  86. pred_v=((Float)mvy)/subdim;   
  87. i++;
  88. diff_h=BV_H(h,v,bh,bv)-pred_h;
  89. diff_v=BV_V(h,v,bh,bv)-pred_v;
  90.   
  91. bits_mot += WriteMVcomponent(local_f_code, (Int)(subdim*diff_h), bs);
  92.   
  93. bits_mot += WriteMVcomponent(local_f_code, (Int)(subdim*diff_v), bs);
  94. }
  95. break;
  96. }
  97. return bits_mot;
  98. }
  99. Int
  100. WriteMVcomponent(
  101. Int     f_code,
  102. Int     dmv,
  103. Image   *bs
  104. )
  105. {
  106. Int   residual, vlc_code_mag, bits, entry;
  107. ScaleMVD(f_code, dmv, &residual, &vlc_code_mag);
  108. if (vlc_code_mag < 0)
  109. entry = vlc_code_mag + 65;
  110. else
  111. entry = vlc_code_mag;
  112. bits = PutMV (entry, bs);
  113. if ((f_code != 1) && (vlc_code_mag != 0))
  114. {
  115. BitstreamPutBits(bs, residual, f_code-1);
  116. bits += f_code - 1;
  117. }
  118. return(bits);
  119. }
  120. Void
  121. ScaleMVD (
  122. Int  f_code,   
  123. Int  diff_vector,   
  124. Int  *residual,   
  125. Int  *vlc_code_mag   
  126. )
  127. {
  128. Int   range;
  129. Int   scale_factor;
  130. Int   r_size;
  131. Int   low;
  132. Int   high;
  133. Int   aux;
  134. r_size = f_code-1;
  135. scale_factor = 1<<r_size;
  136. range = 32*scale_factor;
  137. low   = -range;
  138. high  =  range-1;
  139. if (diff_vector < low)
  140. {
  141. diff_vector += 2*range;
  142. }
  143. else if (diff_vector > high)
  144. {
  145. diff_vector -= 2*range;
  146. }
  147. if (diff_vector==0)
  148. {
  149. *vlc_code_mag = 0;
  150. *residual = 0;
  151. }
  152. else if (scale_factor==1)
  153. {
  154. *vlc_code_mag = diff_vector;
  155. *residual = 0;
  156. }
  157. else
  158. {
  159. aux = ABS(diff_vector) + scale_factor - 1;
  160. *vlc_code_mag = aux>>r_size;
  161. if (diff_vector<0)
  162. *vlc_code_mag = -*vlc_code_mag;
  163. *residual = aux & (scale_factor-1);
  164. }
  165. }
  166. Void   
  167. find_pmvs(
  168. Image  *mot_x,   
  169. Image  *mot_y,   
  170. Image  *MB_decisions,   
  171. Image  *B_decisions,   
  172. Int    x,   
  173. Int    y,   
  174. Int    block,   
  175. Int    transparent_value,   
  176. Int    quarter_pel,      
  177. Int    *error_flag,   
  178. Int    *mvx,   
  179. Int    *mvy,   
  180. Int    newgob
  181. )
  182. {
  183. Float   p1x,p2x,p3x;
  184. Float   p1y,p2y,p3y;
  185. Int     xin1, xin2, xin3;
  186. Int     yin1, yin2, yin3;
  187. Int     vec1, vec2, vec3;
  188. Int     rule1, rule2, rule3;
  189. Int     subdim;   
  190. Float   *motxdata = (Float *) GetImageData(mot_x);
  191. Float   *motydata = (Float *) GetImageData(mot_y);
  192. Int     xM = GetImageSizeX(mot_x);
  193. Int xB = xM;
  194. Int     mb_mode, sum;
  195. if (quarter_pel)
  196. {
  197. subdim=4;
  198. }
  199. else
  200. {
  201. subdim=2;
  202. }
  203. switch (block)
  204. {
  205. case 0:
  206. vec1 = 1 ; yin1 = y  ; xin1 = x-1;
  207. vec2 = 2 ; yin2 = y-1; xin2 = x;
  208. vec3 = 2 ; yin3 = y-1; xin3 = x+1;
  209. break;
  210. case 1:
  211. vec1 = 1 ; yin1 = y  ; xin1 = x-1;
  212. vec2 = 2 ; yin2 = y-1; xin2 = x;
  213. vec3 = 2 ; yin3 = y-1; xin3 = x+1;
  214. break;
  215. case 2:
  216. vec1 = 0 ; yin1 = y  ; xin1 = x;
  217. vec2 = 3 ; yin2 = y-1; xin2 = x;
  218. vec3 = 2 ; yin3 = y-1; xin3 = x+1;
  219. break;
  220. case 3:
  221. vec1 = 3 ; yin1 = y  ; xin1 = x-1;
  222. vec2 = 0 ; yin2 = y  ; xin2 = x;
  223. vec3 = 1 ; yin3 = y  ; xin3 = x;
  224. break;
  225. case 4:
  226. vec1 = 2 ; yin1 = y  ; xin1 = x;
  227. vec2 = 0 ; yin2 = y  ; xin2 = x;
  228. vec3 = 1 ; yin3 = y  ; xin3 = x;
  229. break;
  230. default:
  231. printf("Illegal block number in find_pmv (mot_decode.c)");
  232. *error_flag = 1;
  233. *mvx=*mvy=0;
  234. return ;
  235. }
  236. if (block==0)
  237. {
  238. if (x>0 )
  239. rule1 = 0;
  240. else
  241. rule1 = 1;
  242. if ((y>0 && newgob==0) )
  243. rule2 = 0;
  244. else
  245. rule2 = 1;
  246. if ((x != xB/2 -1) &&
  247. ((y>0 && newgob==0)) )
  248. rule3 = 0;
  249. else
  250. rule3 = 1;
  251. }
  252. else
  253. {
  254.   
  255. if (((block == 1 || block == 3) && (x == 0))  )
  256. rule1 = 1;
  257. else
  258. rule1 = 0;
  259.   
  260. if (((block == 1 || block == 2) && (y == 0))  )
  261. rule2 = 1;
  262. else
  263. rule2 = 0;
  264. if (((block == 1 || block == 2) && (x == xB/2 -1 || y == 0)) )
  265. rule3 = 1;
  266. else
  267. rule3 = 0;
  268. }
  269. if (rule1 )
  270. {
  271. p1x = p1y = 0;
  272. }
  273. else if (((mb_mode = ModeMB(MB_decisions,xin1,yin1)) >= MBM_FIELD00) && (mb_mode <= MBM_FIELD11))
  274. {
  275. sum = subdim*(BV(motxdata, xM, xin1, yin1, 0, 0) + BV(motxdata, xM, xin1, yin1, 1, 0));
  276. p1x = (Float)((sum & 3) ? ((sum | 2) >> 1) : (sum >> 1))/(Float)subdim;
  277. sum = subdim*(BV(motydata, xM, xin1, yin1, 0, 0) + BV(motydata, xM, xin1, yin1, 1, 0));
  278. p1y = (Float)((sum & 3) ? ((sum | 2) >> 1) : (sum >> 1))/(Float)subdim;
  279. }
  280. else
  281. {
  282. p1x = BV(motxdata, xM, xin1, yin1, vec1&0x1, vec1>>1 );
  283. p1y = BV(motydata, xM, xin1, yin1, vec1&0x1, vec1>>1 );
  284. }
  285. if (rule2)
  286. {
  287. p2x = p2y = 0 ;
  288. }
  289. else if (((mb_mode = ModeMB(MB_decisions,xin2,yin2)) >= MBM_FIELD00) && (mb_mode <= MBM_FIELD11))
  290. {
  291. sum = subdim*(BV(motxdata, xM, xin2, yin2, 0, 0) + BV(motxdata, xM, xin2, yin2, 1, 0));
  292. p2x = (Float)((sum & 3) ? ((sum | 2) >> 1) : (sum >> 1))/(Float)subdim;
  293. sum = subdim*(BV(motydata, xM, xin2, yin2, 0, 0) + BV(motydata, xM, xin2, yin2, 1, 0));
  294. p2y = (Float)((sum & 3) ? ((sum | 2) >> 1) : (sum >> 1))/(Float)subdim;
  295. }
  296. else
  297. {
  298. p2x = BV(motxdata, xM, xin2, yin2, vec2&0x1, vec2>>1 );
  299. p2y = BV(motydata, xM, xin2, yin2, vec2&0x1, vec2>>1 );
  300. }
  301. if (rule3 )
  302. {
  303. p3x = p3y =0;
  304. }
  305. else if (((mb_mode = ModeMB(MB_decisions,xin3,yin3)) >= MBM_FIELD00) && (mb_mode <= MBM_FIELD11))
  306. {
  307. sum = subdim*(BV(motxdata, xM, xin3, yin3, 0, 0) + BV(motxdata, xM, xin3, yin3, 1, 0));
  308. p3x = (Float)((sum & 3) ? ((sum | 2) >> 1) : (sum >> 1))/(Float)subdim;
  309. sum = subdim*(BV(motydata, xM, xin3, yin3, 0, 0) + BV(motydata, xM, xin3, yin3, 1, 0));
  310. p3y = (Float)((sum & 3) ? ((sum | 2) >> 1) : (sum >> 1))/(Float)subdim;
  311. }
  312. else
  313. {
  314. p3x = BV(motxdata, xM, xin3, yin3, vec3&0x1, vec3>>1 );
  315. p3y = BV(motydata, xM, xin3, yin3, vec3&0x1, vec3>>1 );
  316. }
  317. if (rule1 && rule2 && rule3 )
  318. {
  319. *mvx=*mvy=0;
  320. }
  321. else if (rule1+rule2+rule3 == 2)
  322. {
  323. *mvx=(Int) subdim*(p1x+p2x+p3x);   
  324. *mvy=(Int) subdim*(p1y+p2y+p3y);   
  325. }
  326. else
  327. {
  328.   
  329. *mvx=(Int)(subdim*(p1x+p2x+p3x-MAX(p1x,MAX(p2x,p3x))-MIN(p1x,MIN(p2x,p3x))));
  330.   
  331. *mvy=(Int)(subdim*(p1y+p2y+p3y-MAX(p1y,MAX(p2y,p3y))-MIN(p1y,MIN(p2y,p3y))));
  332. }
  333. #ifdef _DEBUG_PMVS_
  334. fprintf(stdout,"find_pmvs (%2d,%2d, rule %1d%1d%1d) :np1 %6.2f / %6.2fnp2 %6.2f / %6.2fnp3 %6.2f / %6.2fn",x,y,rule1,rule2,rule3,p1x,p1y,p2x,p2y,p3x,p3y);
  335. #endif
  336. return;
  337. }
  338. SInt ModeMB (Image *MB_decision, Int i, Int j)
  339. {
  340. Int   width = MB_decision->x;
  341. SInt  *p = (SInt *)GetImageData(MB_decision);
  342. return p[width*j+i];
  343. }