00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "vm_common_defs.h"
00041 #include "bitstream.h"
00042
00043 #include "putvlc.h"
00044
00045
00046
00047
00048
00049
00050 #define MBV_H(h,v) (ph[2*(v)*2*hdim+2*(h)])
00051 #define MBV_V(h,v) (pv[2*(v)*2*hdim+2*(h)])
00052
00053
00054 #define BV_H(h,v,h2,v2) (ph[(2*(v)+(v2))*2*hdim+2*(h)+(h2)])
00055 #define BV_V(h,v,h2,v2) (pv[(2*(v)+(v2))*2*hdim+2*(h)+(h2)])
00056
00057
00058 #define MB_MODE(h,v) ( ((h)<0||(h)>=hdim||(v)<0||(v)>=vdim ? MBM_OUT : (pm[(v)*hdim+(h)])) )
00059
00060
00061 #define BV(p,xdim,h,v,h2,v2) (p[(2*(v)+(v2))*(xdim)+2*(h)+(h2)])
00062
00063
00064
00065
00066
00067 Int WriteMVcomponent(Int f_code, Int dmv, Image *bs);
00068 Void ScaleMVD (Int f_code, Int diff_vector, Int *residual, Int *vlc_code_mag);
00069 Void find_pmvs (Image *mot_x, Image *mot_y, Image *MB_decisions, Image *B_decisions,
00070 Int x, Int y, Int block, Int transparent_value, Int quarter_pel, Int *error_flag,
00071 Int *mvx, Int *mvy, Int newgob);
00072 SInt ModeMB (Image *MB_decision, Int i, Int j);
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 Int
00099 Bits_CountMB_Motion(
00100 Image *mot_h,
00101 Image *mot_v,
00102 Image *alpha,
00103 Image *modes,
00104 Int h,
00105 Int v,
00106 Int f_code,
00107
00108 Int quarter_pel,
00109 Image *bs,
00110 Int error_res_disable,
00111 Int after_marker,
00112 Int **slice_nb,
00113 Int arbitrary_shape
00114 )
00115 {
00116 Int vdim, hdim;
00117 Float *ph, *pv;
00118 SInt *pm;
00119 SInt *pa;
00120 Int mode;
00121 Int bits_mot = 0;
00122
00123
00124 Int i, error_flag=0,mvx=0,mvy=0;
00125 Float pred_h, pred_v;
00126 Float diff_h, diff_v;
00127 Int bh, bv;
00128 Int local_f_code;
00129 Float subdim;
00130
00131 vdim = (Int)modes->y;
00132 hdim = (Int)modes->x;
00133 ph=(Float*)GetImageData(mot_h);
00134 pv=(Float*)GetImageData(mot_v);
00135 pm=(SInt*)GetImageData(modes);
00136 pa=NULL;
00137
00138
00139
00140
00141 if (quarter_pel)
00142 {
00143 local_f_code = f_code+1;
00144 subdim = 4.0;
00145 }
00146 else
00147 {
00148 local_f_code = f_code;
00149 subdim = 2.0;
00150 }
00151
00152
00153 switch (mode=MB_MODE(h,v))
00154 {
00155 case MBM_INTRA:
00156 break;
00157
00158 case MBM_INTER16:
00159
00160 find_pmvs(mot_h,mot_v,modes,alpha,h,v,0,MBM_TRANSPARENT,
00161
00162 quarter_pel,&error_flag,&mvx,&mvy,0);
00163
00164 pred_h=((Float)mvx)/subdim;
00165 pred_v=((Float)mvy)/subdim;
00166
00167
00168 bits_mot += WriteMVcomponent(local_f_code, (Int)(subdim*(MBV_H(h,v) - pred_h)), bs);
00169
00170 bits_mot += WriteMVcomponent(local_f_code, (Int)(subdim*(MBV_V(h,v) - pred_v)), bs);
00171
00172 break;
00173
00174 case MBM_INTER8:
00175 i=1;
00176 for (bv=0; bv<=1; bv++)
00177 for (bh=0; bh<=1; bh++)
00178 {
00179 find_pmvs(mot_h,mot_v,modes,alpha,h,v,i,MBM_TRANSPARENT,
00180
00181 quarter_pel,&error_flag,&mvx,&mvy,0);
00182
00183 pred_h=((Float)mvx)/subdim;
00184 pred_v=((Float)mvy)/subdim;
00185
00186 i++;
00187
00188 diff_h=BV_H(h,v,bh,bv)-pred_h;
00189 diff_v=BV_V(h,v,bh,bv)-pred_v;
00190
00191
00192 bits_mot += WriteMVcomponent(local_f_code, (Int)(subdim*diff_h), bs);
00193
00194 bits_mot += WriteMVcomponent(local_f_code, (Int)(subdim*diff_v), bs);
00195 }
00196 break;
00197 }
00198
00199 return bits_mot;
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 Int
00225 WriteMVcomponent(
00226 Int f_code,
00227 Int dmv,
00228 Image *bs
00229 )
00230 {
00231 Int residual, vlc_code_mag, bits, entry;
00232
00233 ScaleMVD(f_code, dmv, &residual, &vlc_code_mag);
00234
00235 if (vlc_code_mag < 0)
00236 entry = vlc_code_mag + 65;
00237 else
00238 entry = vlc_code_mag;
00239
00240 bits = PutMV (entry, bs);
00241
00242 if ((f_code != 1) && (vlc_code_mag != 0))
00243 {
00244 BitstreamPutBits(bs, residual, f_code-1);
00245 bits += f_code - 1;
00246 }
00247 return(bits);
00248 }
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 Void
00272 ScaleMVD (
00273 Int f_code,
00274 Int diff_vector,
00275 Int *residual,
00276 Int *vlc_code_mag
00277 )
00278 {
00279 Int range;
00280 Int scale_factor;
00281 Int r_size;
00282 Int low;
00283 Int high;
00284 Int aux;
00285
00286 r_size = f_code-1;
00287 scale_factor = 1<<r_size;
00288 range = 32*scale_factor;
00289 low = -range;
00290 high = range-1;
00291 if (diff_vector < low)
00292 {
00293 diff_vector += 2*range;
00294 }
00295 else if (diff_vector > high)
00296 {
00297 diff_vector -= 2*range;
00298 }
00299
00300 if (diff_vector==0)
00301 {
00302 *vlc_code_mag = 0;
00303 *residual = 0;
00304 }
00305 else if (scale_factor==1)
00306 {
00307 *vlc_code_mag = diff_vector;
00308 *residual = 0;
00309 }
00310 else
00311 {
00312 aux = ABS(diff_vector) + scale_factor - 1;
00313 *vlc_code_mag = aux>>r_size;
00314
00315 if (diff_vector<0)
00316 *vlc_code_mag = -*vlc_code_mag;
00317
00318 *residual = aux & (scale_factor-1);
00319 }
00320 }
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332 Void
00333 find_pmvs(
00334 Image *mot_x,
00335 Image *mot_y,
00336 Image *MB_decisions,
00337 Image *B_decisions,
00338 Int x,
00339 Int y,
00340 Int block,
00341 Int transparent_value,
00342 Int quarter_pel,
00343 Int *error_flag,
00344 Int *mvx,
00345 Int *mvy,
00346 Int newgob
00347 )
00348 {
00349 Float p1x,p2x,p3x;
00350 Float p1y,p2y,p3y;
00351 Int xin1, xin2, xin3;
00352 Int yin1, yin2, yin3;
00353 Int vec1, vec2, vec3;
00354 Int rule1, rule2, rule3;
00355 Int subdim;
00356 Float *motxdata = (Float *) GetImageData(mot_x);
00357 Float *motydata = (Float *) GetImageData(mot_y);
00358 Int xM = GetImageSizeX(mot_x);
00359 Int xB = xM;
00360 Int mb_mode, sum;
00361
00362
00363 if (quarter_pel)
00364 {
00365 subdim=4;
00366 }
00367 else
00368 {
00369 subdim=2;
00370 }
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 switch (block)
00388 {
00389 case 0:
00390 vec1 = 1 ; yin1 = y ; xin1 = x-1;
00391 vec2 = 2 ; yin2 = y-1; xin2 = x;
00392 vec3 = 2 ; yin3 = y-1; xin3 = x+1;
00393 break;
00394 case 1:
00395 vec1 = 1 ; yin1 = y ; xin1 = x-1;
00396 vec2 = 2 ; yin2 = y-1; xin2 = x;
00397 vec3 = 2 ; yin3 = y-1; xin3 = x+1;
00398 break;
00399 case 2:
00400 vec1 = 0 ; yin1 = y ; xin1 = x;
00401 vec2 = 3 ; yin2 = y-1; xin2 = x;
00402 vec3 = 2 ; yin3 = y-1; xin3 = x+1;
00403 break;
00404 case 3:
00405 vec1 = 3 ; yin1 = y ; xin1 = x-1;
00406 vec2 = 0 ; yin2 = y ; xin2 = x;
00407 vec3 = 1 ; yin3 = y ; xin3 = x;
00408 break;
00409 case 4:
00410 vec1 = 2 ; yin1 = y ; xin1 = x;
00411 vec2 = 0 ; yin2 = y ; xin2 = x;
00412 vec3 = 1 ; yin3 = y ; xin3 = x;
00413 break;
00414 default:
00415 printf("Illegal block number in find_pmv (mot_decode.c)");
00416 *error_flag = 1;
00417 *mvx=*mvy=0;
00418 return ;
00419 }
00420
00421 if (block==0)
00422 {
00423
00424
00425
00426
00427 if (x>0
00428 )
00429 rule1 = 0;
00430 else
00431 rule1 = 1;
00432
00433 if ((y>0 && newgob==0)
00434 )
00435 rule2 = 0;
00436 else
00437 rule2 = 1;
00438
00439 if ((x != xB/2 -1) &&
00440 ((y>0 && newgob==0))
00441 )
00442 rule3 = 0;
00443 else
00444 rule3 = 1;
00445 }
00446
00447 else
00448 {
00449
00450
00451
00452 if (((block == 1 || block == 3) && (x == 0))
00453
00454
00455 )
00456 rule1 = 1;
00457 else
00458 rule1 = 0;
00459
00460
00461
00462 if (((block == 1 || block == 2) && (y == 0))
00463
00464
00465 )
00466 rule2 = 1;
00467 else
00468 rule2 = 0;
00469
00470
00471 if (((block == 1 || block == 2) && (x == xB/2 -1 || y == 0))
00472
00473
00474
00475 )
00476 rule3 = 1;
00477 else
00478 rule3 = 0;
00479
00480 }
00481
00482 if (rule1 )
00483 {
00484 p1x = p1y = 0;
00485 }
00486 else if (((mb_mode = ModeMB(MB_decisions,xin1,yin1)) >= MBM_FIELD00) && (mb_mode <= MBM_FIELD11))
00487 {
00488
00489 sum = subdim*(BV(motxdata, xM, xin1, yin1, 0, 0) + BV(motxdata, xM, xin1, yin1, 1, 0));
00490 p1x = (Float)((sum & 3) ? ((sum | 2) >> 1) : (sum >> 1))/(Float)subdim;
00491 sum = subdim*(BV(motydata, xM, xin1, yin1, 0, 0) + BV(motydata, xM, xin1, yin1, 1, 0));
00492 p1y = (Float)((sum & 3) ? ((sum | 2) >> 1) : (sum >> 1))/(Float)subdim;
00493 }
00494 else
00495 {
00496 p1x = BV(motxdata, xM, xin1, yin1, vec1&0x1, vec1>>1 );
00497 p1y = BV(motydata, xM, xin1, yin1, vec1&0x1, vec1>>1 );
00498 }
00499
00500 if (rule2)
00501 {
00502 p2x = p2y = 0 ;
00503 }
00504 else if (((mb_mode = ModeMB(MB_decisions,xin2,yin2)) >= MBM_FIELD00) && (mb_mode <= MBM_FIELD11))
00505 {
00506
00507 sum = subdim*(BV(motxdata, xM, xin2, yin2, 0, 0) + BV(motxdata, xM, xin2, yin2, 1, 0));
00508 p2x = (Float)((sum & 3) ? ((sum | 2) >> 1) : (sum >> 1))/(Float)subdim;
00509 sum = subdim*(BV(motydata, xM, xin2, yin2, 0, 0) + BV(motydata, xM, xin2, yin2, 1, 0));
00510 p2y = (Float)((sum & 3) ? ((sum | 2) >> 1) : (sum >> 1))/(Float)subdim;
00511 }
00512 else
00513 {
00514 p2x = BV(motxdata, xM, xin2, yin2, vec2&0x1, vec2>>1 );
00515 p2y = BV(motydata, xM, xin2, yin2, vec2&0x1, vec2>>1 );
00516 }
00517
00518 if (rule3 )
00519 {
00520 p3x = p3y =0;
00521 }
00522 else if (((mb_mode = ModeMB(MB_decisions,xin3,yin3)) >= MBM_FIELD00) && (mb_mode <= MBM_FIELD11))
00523 {
00524
00525 sum = subdim*(BV(motxdata, xM, xin3, yin3, 0, 0) + BV(motxdata, xM, xin3, yin3, 1, 0));
00526 p3x = (Float)((sum & 3) ? ((sum | 2) >> 1) : (sum >> 1))/(Float)subdim;
00527 sum = subdim*(BV(motydata, xM, xin3, yin3, 0, 0) + BV(motydata, xM, xin3, yin3, 1, 0));
00528 p3y = (Float)((sum & 3) ? ((sum | 2) >> 1) : (sum >> 1))/(Float)subdim;
00529 }
00530 else
00531 {
00532 p3x = BV(motxdata, xM, xin3, yin3, vec3&0x1, vec3>>1 );
00533 p3y = BV(motydata, xM, xin3, yin3, vec3&0x1, vec3>>1 );
00534 }
00535
00536 if (rule1 && rule2 && rule3 )
00537 {
00538
00539 *mvx=*mvy=0;
00540 }
00541 else if (rule1+rule2+rule3 == 2)
00542 {
00543
00544
00545 *mvx=(Int) subdim*(p1x+p2x+p3x);
00546 *mvy=(Int) subdim*(p1y+p2y+p3y);
00547 }
00548 else
00549 {
00550
00551
00552 *mvx=(Int)(subdim*(p1x+p2x+p3x-MAX(p1x,MAX(p2x,p3x))-MIN(p1x,MIN(p2x,p3x))));
00553
00554 *mvy=(Int)(subdim*(p1y+p2y+p3y-MAX(p1y,MAX(p2y,p3y))-MIN(p1y,MIN(p2y,p3y))));
00555 }
00556
00557 #ifdef _DEBUG_PMVS_
00558 fprintf(stdout,"find_pmvs (%2d,%2d, rule %1d%1d%1d) :\np1 %6.2f / %6.2f\np2 %6.2f / %6.2f\np3 %6.2f / %6.2f\n",x,y,rule1,rule2,rule3,p1x,p1y,p2x,p2y,p3x,p3y);
00559 #endif
00560
00561 return;
00562 }
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574 SInt ModeMB (Image *MB_decision, Int i, Int j)
00575 {
00576 Int width = MB_decision->x;
00577 SInt *p = (SInt *)GetImageData(MB_decision);
00578
00579 return p[width*j+i];
00580 }
00581