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
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
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
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 #include "all.h"
00118 #include "mtypes.h"
00119 #include "frames.h"
00120 #include "bitio.h"
00121 #include "prototypes.h"
00122 #include "fsize.h"
00123 #include "opts.h"
00124 #include "postdct.h"
00125
00126 #undef ABS
00127 #define ABS(x) ((x < 0) ? (-x) : x)
00128
00129 #define TRUNCATE_UINT8(x) ((x < 0) ? 0 : ((x > 255) ? 255 : x))
00130
00131
00132
00133
00134
00135
00136 extern Block **dct, **dctb, **dctr;
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 boolean
00155 ComputeDiffDCTBlock(current, dest, motionBlock)
00156 Block current, dest, motionBlock;
00157 {
00158 register int x, y, diff = 0;
00159
00160 for ( y = 0; y < 8; y++ ) {
00161 for ( x = 0; x < 8; x++ ) {
00162 current[y][x] -= motionBlock[y][x];
00163 diff += ABS(current[y][x]);
00164 }
00165 }
00166
00167
00168 if (diff < block_bound) return FALSE;
00169
00170 mp_fwd_dct_block2(current, dest);
00171
00172 return TRUE;
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 void
00191 ComputeDiffDCTs(current, prev, by, bx, my, mx, pattern)
00192 MpegFrame *current;
00193 MpegFrame *prev;
00194 int by;
00195 int bx;
00196 int my;
00197 int mx;
00198 int *pattern;
00199 {
00200 Block motionBlock;
00201
00202 if (collect_quant && (collect_quant_detailed & 1)) fprintf(collect_quant_fp, "l\n");
00203 if ( *pattern & 0x20 ) {
00204 ComputeMotionBlock(prev->ref_y, by, bx, my, mx, motionBlock);
00205 if (!ComputeDiffDCTBlock(current->y_blocks[by][bx], dct[by][bx], motionBlock))
00206 *pattern^=0x20;
00207 }
00208
00209 if ( *pattern & 0x10 ) {
00210 ComputeMotionBlock(prev->ref_y, by, bx+1, my, mx, motionBlock);
00211 if (!ComputeDiffDCTBlock(current->y_blocks[by][bx+1], dct[by][bx+1], motionBlock))
00212 *pattern^=0x10;
00213 }
00214
00215 if ( *pattern & 0x8 ) {
00216 ComputeMotionBlock(prev->ref_y, by+1, bx, my, mx, motionBlock);
00217 if (!ComputeDiffDCTBlock(current->y_blocks[by+1][bx], dct[by+1][bx], motionBlock))
00218 *pattern^=0x8;
00219 }
00220
00221 if ( *pattern & 0x4 ) {
00222 ComputeMotionBlock(prev->ref_y, by+1, bx+1, my, mx, motionBlock);
00223 if (!ComputeDiffDCTBlock(current->y_blocks[by+1][bx+1], dct[by+1][bx+1], motionBlock))
00224 *pattern^=0x4;
00225 }
00226
00227 if (collect_quant && (collect_quant_detailed & 1)) fprintf(collect_quant_fp, "c\n");
00228 if ( *pattern & 0x2 ) {
00229 ComputeMotionBlock(prev->ref_cb, by >> 1, bx >> 1, my/2, mx/2, motionBlock);
00230 if (!ComputeDiffDCTBlock(current->cb_blocks[by >> 1][bx >> 1], dctb[by >> 1][bx >> 1], motionBlock))
00231 *pattern^=0x2;
00232 }
00233
00234 if ( *pattern & 0x1 ) {
00235 ComputeMotionBlock(prev->ref_cr, by >> 1, bx >> 1, my/2, mx/2, motionBlock);
00236 if (!ComputeDiffDCTBlock(current->cr_blocks[by >> 1][bx >> 1], dctr[by >> 1][bx >> 1], motionBlock))
00237 *pattern^=0x1;
00238 }
00239 }
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264 void
00265 ComputeMotionBlock(prev, by, bx, my, mx, motionBlock)
00266 uint8 **prev;
00267 int by;
00268 int bx;
00269 int my;
00270 int mx;
00271 Block motionBlock;
00272 {
00273 register int fy, fx;
00274 register int y;
00275 register int16 *destPtr;
00276 register uint8 *srcPtr;
00277 register uint8 *srcPtr2;
00278 boolean xHalf, yHalf;
00279
00280 xHalf = (ABS(mx) % 2 == 1);
00281 yHalf = (ABS(my) % 2 == 1);
00282
00283 MOTION_TO_FRAME_COORD(by, bx, (my/2), (mx/2), fy, fx);
00284
00285 if ( xHalf && yHalf ) {
00286
00287
00288
00289 if ( my < 0 ) {
00290 fy--;
00291 }
00292 if ( mx < 0 ) {
00293 fx--;
00294 }
00295
00296 for ( y = 0; y < 8; y++ ) {
00297 destPtr = motionBlock[y];
00298 srcPtr = &(prev[fy+y][fx]);
00299 srcPtr2 = &(prev[fy+y+1][fx]);
00300
00301 destPtr[0] = (srcPtr[0]+srcPtr[1]+srcPtr2[0]+srcPtr2[1]+2)>>2;
00302 destPtr[1] = (srcPtr[1]+srcPtr[2]+srcPtr2[1]+srcPtr2[2]+2)>>2;
00303 destPtr[2] = (srcPtr[2]+srcPtr[3]+srcPtr2[2]+srcPtr2[3]+2)>>2;
00304 destPtr[3] = (srcPtr[3]+srcPtr[4]+srcPtr2[3]+srcPtr2[4]+2)>>2;
00305 destPtr[4] = (srcPtr[4]+srcPtr[5]+srcPtr2[4]+srcPtr2[5]+2)>>2;
00306 destPtr[5] = (srcPtr[5]+srcPtr[6]+srcPtr2[5]+srcPtr2[6]+2)>>2;
00307 destPtr[6] = (srcPtr[6]+srcPtr[7]+srcPtr2[6]+srcPtr2[7]+2)>>2;
00308 destPtr[7] = (srcPtr[7]+srcPtr[8]+srcPtr2[7]+srcPtr2[8]+2)>>2;
00309 }
00310 } else if ( xHalf ) {
00311 if ( mx < 0 ) {
00312 fx--;
00313 }
00314
00315 for ( y = 0; y < 8; y++ ) {
00316 destPtr = motionBlock[y];
00317 srcPtr = &(prev[fy+y][fx]);
00318
00319 destPtr[0] = (srcPtr[0]+srcPtr[1]+1)>>1;
00320 destPtr[1] = (srcPtr[1]+srcPtr[2]+1)>>1;
00321 destPtr[2] = (srcPtr[2]+srcPtr[3]+1)>>1;
00322 destPtr[3] = (srcPtr[3]+srcPtr[4]+1)>>1;
00323 destPtr[4] = (srcPtr[4]+srcPtr[5]+1)>>1;
00324 destPtr[5] = (srcPtr[5]+srcPtr[6]+1)>>1;
00325 destPtr[6] = (srcPtr[6]+srcPtr[7]+1)>>1;
00326 destPtr[7] = (srcPtr[7]+srcPtr[8]+1)>>1;
00327 }
00328 } else if ( yHalf ) {
00329 if ( my < 0 ) {
00330 fy--;
00331 }
00332
00333 for ( y = 0; y < 8; y++ ) {
00334 destPtr = motionBlock[y];
00335 srcPtr = &(prev[fy+y][fx]);
00336 srcPtr2 = &(prev[fy+y+1][fx]);
00337
00338 destPtr[0] = (srcPtr[0]+srcPtr2[0]+1)>>1;
00339 destPtr[1] = (srcPtr[1]+srcPtr2[1]+1)>>1;
00340 destPtr[2] = (srcPtr[2]+srcPtr2[2]+1)>>1;
00341 destPtr[3] = (srcPtr[3]+srcPtr2[3]+1)>>1;
00342 destPtr[4] = (srcPtr[4]+srcPtr2[4]+1)>>1;
00343 destPtr[5] = (srcPtr[5]+srcPtr2[5]+1)>>1;
00344 destPtr[6] = (srcPtr[6]+srcPtr2[6]+1)>>1;
00345 destPtr[7] = (srcPtr[7]+srcPtr2[7]+1)>>1;
00346 }
00347 } else {
00348 for ( y = 0; y < 8; y++ ) {
00349 destPtr = motionBlock[y];
00350 srcPtr = &(prev[fy+y][fx]);
00351
00352 destPtr[0] = (uint8) srcPtr[0];
00353 destPtr[1] = (uint8) srcPtr[1];
00354 destPtr[2] = (uint8) srcPtr[2];
00355 destPtr[3] = (uint8) srcPtr[3];
00356 destPtr[4] = (uint8) srcPtr[4];
00357 destPtr[5] = (uint8) srcPtr[5];
00358 destPtr[6] = (uint8) srcPtr[6];
00359 destPtr[7] = (uint8) srcPtr[7];
00360 }
00361 }
00362 }
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 void
00381 ComputeMotionLumBlock(prevFrame, by, bx, my, mx, motionBlock)
00382 MpegFrame *prevFrame;
00383 int by;
00384 int bx;
00385 int my;
00386 int mx;
00387 LumBlock motionBlock;
00388 {
00389 register uint8 *across;
00390 register int32 *macross;
00391 register int y;
00392 uint8 **prev;
00393 int fy, fx;
00394 boolean xHalf, yHalf;
00395
00396 xHalf = (ABS(mx) % 2 == 1);
00397 yHalf = (ABS(my) % 2 == 1);
00398
00399 MOTION_TO_FRAME_COORD(by, bx, my/2, mx/2, fy, fx);
00400
00401 if ( xHalf ) {
00402 if ( mx < 0 ) {
00403 fx--;
00404 }
00405
00406 if ( yHalf ) {
00407 if ( my < 0 ) {
00408 fy--;
00409 }
00410
00411 prev = prevFrame->halfBoth;
00412 } else {
00413 prev = prevFrame->halfX;
00414 }
00415 } else if ( yHalf ) {
00416 if ( my < 0 ) {
00417 fy--;
00418 }
00419
00420 prev = prevFrame->halfY;
00421 } else {
00422 prev = prevFrame->ref_y;
00423 }
00424
00425 for ( y = 0; y < 16; y++ ) {
00426 across = &(prev[fy+y][fx]);
00427 macross = motionBlock[y];
00428
00429 macross[0] = across[0];
00430 macross[1] = across[1];
00431 macross[2] = across[2];
00432 macross[3] = across[3];
00433 macross[4] = across[4];
00434 macross[5] = across[5];
00435 macross[6] = across[6];
00436 macross[7] = across[7];
00437 macross[8] = across[8];
00438 macross[9] = across[9];
00439 macross[10] = across[10];
00440 macross[11] = across[11];
00441 macross[12] = across[12];
00442 macross[13]= across[13];
00443 macross[14] = across[14];
00444 macross[15] = across[15];
00445 }
00446
00447
00448
00449
00450
00451
00452
00453
00454 }
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474 int32
00475 LumBlockMAD(currentBlock, motionBlock, bestSoFar)
00476 LumBlock currentBlock;
00477 LumBlock motionBlock;
00478 int32 bestSoFar;
00479 {
00480 register int32 diff = 0;
00481 register int32 localDiff;
00482 register int y, x;
00483
00484 for ( y = 0; y < 16; y++ ) {
00485 for ( x = 0; x < 16; x++ ) {
00486 localDiff = currentBlock[y][x] - motionBlock[y][x];
00487 diff += ABS(localDiff);
00488 }
00489
00490 if ( diff > bestSoFar ) {
00491 return diff;
00492 }
00493 }
00494
00495 return (int32)diff;
00496 }
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517 int32
00518 LumMotionError(currentBlock, prevFrame, by, bx, my, mx, bestSoFar)
00519 LumBlock currentBlock;
00520 MpegFrame *prevFrame;
00521 int by;
00522 int bx;
00523 int my;
00524 int mx;
00525 int32 bestSoFar;
00526 {
00527 register int32 adiff = 0, diff = 0;
00528 register int32 localDiff;
00529 register uint8 *across;
00530 register int32 *cacross;
00531 register int y;
00532 uint8 **prev;
00533 int fy, fx;
00534 boolean xHalf, yHalf;
00535
00536 xHalf = (ABS(mx) % 2 == 1);
00537 yHalf = (ABS(my) % 2 == 1);
00538
00539 MOTION_TO_FRAME_COORD(by, bx, my/2, mx/2, fy, fx);
00540
00541 if ( xHalf ) {
00542 if ( mx < 0 ) {
00543 fx--;
00544 }
00545
00546 if ( yHalf ) {
00547 if ( my < 0 ) {
00548 fy--;
00549 }
00550
00551 prev = prevFrame->halfBoth;
00552 } else {
00553 prev = prevFrame->halfX;
00554 }
00555 } else if ( yHalf ) {
00556 if ( my < 0 ) {
00557 fy--;
00558 }
00559
00560 prev = prevFrame->halfY;
00561 } else {
00562 prev = prevFrame->ref_y;
00563 }
00564
00565 switch (SearchCompareMode) {
00566 case DEFAULT_SEARCH:
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576 for ( y = 0; y < 16; y++ ) {
00577 across = &(prev[fy+y][fx]);
00578 cacross = currentBlock[y];
00579
00580 localDiff = across[0]-cacross[0]; diff += ABS(localDiff);
00581 localDiff = across[1]-cacross[1]; diff += ABS(localDiff);
00582 localDiff = across[2]-cacross[2]; diff += ABS(localDiff);
00583 localDiff = across[3]-cacross[3]; diff += ABS(localDiff);
00584 localDiff = across[4]-cacross[4]; diff += ABS(localDiff);
00585 localDiff = across[5]-cacross[5]; diff += ABS(localDiff);
00586 localDiff = across[6]-cacross[6]; diff += ABS(localDiff);
00587 localDiff = across[7]-cacross[7]; diff += ABS(localDiff);
00588 localDiff = across[8]-cacross[8]; diff += ABS(localDiff);
00589 localDiff = across[9]-cacross[9]; diff += ABS(localDiff);
00590 localDiff = across[10]-cacross[10]; diff += ABS(localDiff);
00591 localDiff = across[11]-cacross[11]; diff += ABS(localDiff);
00592 localDiff = across[12]-cacross[12]; diff += ABS(localDiff);
00593 localDiff = across[13]-cacross[13]; diff += ABS(localDiff);
00594 localDiff = across[14]-cacross[14]; diff += ABS(localDiff);
00595 localDiff = across[15]-cacross[15]; diff += ABS(localDiff);
00596
00597 if ( diff > bestSoFar ) {
00598 return diff;
00599 }
00600 }
00601 break;
00602
00603 case LOCAL_DCT: {
00604 Block dctdiff[4], dctquant[4];
00605 FlatBlock quant;
00606 int x, i, tmp;
00607 int distortion=0, datarate=0;
00608 int pq = GetPQScale();
00609
00610 for (y = 0; y < 16; y++) {
00611 across = &(prev[fy+y][fx]);
00612 cacross = currentBlock[y];
00613 for (x = 0; x < 16; x++) {
00614 dctdiff[(x>7)+2*(y>7)][y%8][x%8] = cacross[x]-across[x];
00615 }}
00616
00617
00618 for (i = 0; i < 4; i++) {
00619 mp_fwd_dct_block2(dctdiff[i], dctdiff[i]);
00620 if (Mpost_QuantZigBlock(dctdiff[i], quant, pq, FALSE) == MPOST_ZERO) {
00621
00622 memset((char *)dctquant[i], 0, sizeof(Block));
00623 } else {
00624 Mpost_UnQuantZigBlock(quant, dctquant[i], pq, FALSE);
00625 mpeg_jrevdct((int16 *)dctquant[i]);
00626 datarate += CalcRLEHuffLength(quant);
00627 }
00628 }
00629
00630
00631 for (y = 0; y < 16; y++) {
00632 across = &(prev[fy+y][fx]);
00633 cacross = currentBlock[y];
00634 for (x = 0; x < 16; x++) {
00635 tmp = across[x] - cacross[x] + dctquant[(x>7)+2*(y>7)][y%8][x%8];
00636 distortion += tmp*tmp;
00637 }}
00638 distortion /= 256;
00639 distortion *= LocalDCTDistortScale;
00640 datarate *= LocalDCTRateScale;
00641 diff = (int) sqrt(distortion*distortion + datarate*datarate);
00642 break;
00643 }
00644
00645 case NO_DC_SEARCH: {
00646 extern int32 niqtable[];
00647 int pq = niqtable[0]*GetPQScale();
00648
00649 for ( y = 0; y < 16; y++ ) {
00650 across = &(prev[fy+y][fx]);
00651 cacross = currentBlock[y];
00652
00653 localDiff = across[0]-cacross[0]; diff += localDiff; adiff += ABS(localDiff);
00654 localDiff = across[1]-cacross[1]; diff += localDiff; adiff += ABS(localDiff);
00655 localDiff = across[2]-cacross[2]; diff += localDiff; adiff += ABS(localDiff);
00656 localDiff = across[3]-cacross[3]; diff += localDiff; adiff += ABS(localDiff);
00657 localDiff = across[4]-cacross[4]; diff += localDiff; adiff += ABS(localDiff);
00658 localDiff = across[5]-cacross[5]; diff += localDiff; adiff += ABS(localDiff);
00659 localDiff = across[6]-cacross[6]; diff += localDiff; adiff += ABS(localDiff);
00660 localDiff = across[7]-cacross[7]; diff += localDiff; adiff += ABS(localDiff);
00661 localDiff = across[8]-cacross[8]; diff += localDiff; adiff += ABS(localDiff);
00662 localDiff = across[9]-cacross[9]; diff += localDiff; adiff += ABS(localDiff);
00663 localDiff = across[10]-cacross[10]; diff += localDiff; adiff += ABS(localDiff);
00664 localDiff = across[11]-cacross[11]; diff += localDiff; adiff += ABS(localDiff);
00665 localDiff = across[12]-cacross[12]; diff += localDiff; adiff += ABS(localDiff);
00666 localDiff = across[13]-cacross[13]; diff += localDiff; adiff += ABS(localDiff);
00667 localDiff = across[14]-cacross[14]; diff += localDiff; adiff += ABS(localDiff);
00668 localDiff = across[15]-cacross[15]; diff += localDiff; adiff += ABS(localDiff);
00669
00670 }
00671
00672 diff /= 64*pq;
00673 adiff -= 64*pq*ABS(diff);
00674 diff = adiff;
00675 }
00676 break;
00677
00678 case DO_Mean_Squared_Distortion:
00679 for ( y = 0; y < 16; y++ ) {
00680 across = &(prev[fy+y][fx]);
00681 cacross = currentBlock[y];
00682
00683 localDiff = across[0]-cacross[0]; diff += localDiff*localDiff;
00684 localDiff = across[1]-cacross[1]; diff += localDiff*localDiff;
00685 localDiff = across[2]-cacross[2]; diff += localDiff*localDiff;
00686 localDiff = across[3]-cacross[3]; diff += localDiff*localDiff;
00687 localDiff = across[4]-cacross[4]; diff += localDiff*localDiff;
00688 localDiff = across[5]-cacross[5]; diff += localDiff*localDiff;
00689 localDiff = across[6]-cacross[6]; diff += localDiff*localDiff;
00690 localDiff = across[7]-cacross[7]; diff += localDiff*localDiff;
00691 localDiff = across[8]-cacross[8]; diff += localDiff*localDiff;
00692 localDiff = across[9]-cacross[9]; diff += localDiff*localDiff;
00693 localDiff = across[10]-cacross[10]; diff += localDiff*localDiff;
00694 localDiff = across[11]-cacross[11]; diff += localDiff*localDiff;
00695 localDiff = across[12]-cacross[12]; diff += localDiff*localDiff;
00696 localDiff = across[13]-cacross[13]; diff += localDiff*localDiff;
00697 localDiff = across[14]-cacross[14]; diff += localDiff*localDiff;
00698 localDiff = across[15]-cacross[15]; diff += localDiff*localDiff;
00699
00700 if ( diff > bestSoFar ) {
00701 return diff;
00702 }
00703 }
00704 break;
00705 }
00706
00707 return diff;
00708 }
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726 int32
00727 LumAddMotionError(currentBlock, blockSoFar, prevFrame, by, bx, my, mx,
00728 bestSoFar)
00729 LumBlock currentBlock;
00730 LumBlock blockSoFar;
00731 MpegFrame *prevFrame;
00732 int by;
00733 int bx;
00734 int my;
00735 int mx;
00736 int32 bestSoFar;
00737 {
00738 register int32 diff = 0;
00739 register int32 localDiff;
00740 register uint8 *across;
00741 register int32 *bacross;
00742 register int32 *cacross;
00743 register int y;
00744 uint8 **prev;
00745 int fy, fx;
00746 boolean xHalf, yHalf;
00747
00748 xHalf = (ABS(mx) % 2 == 1);
00749 yHalf = (ABS(my) % 2 == 1);
00750
00751 MOTION_TO_FRAME_COORD(by, bx, my/2, mx/2, fy, fx);
00752
00753 if ( xHalf ) {
00754 if ( mx < 0 ) {
00755 fx--;
00756 }
00757
00758 if ( yHalf ) {
00759 if ( my < 0 ) {
00760 fy--;
00761 }
00762
00763 prev = prevFrame->halfBoth;
00764 } else {
00765 prev = prevFrame->halfX;
00766 }
00767 } else if ( yHalf ) {
00768 if ( my < 0 ) {
00769 fy--;
00770 }
00771
00772 prev = prevFrame->halfY;
00773 } else {
00774 prev = prevFrame->ref_y;
00775 }
00776
00777
00778
00779 #define ADD_ADD_DIFF(d,l,a,b,c,i) \
00780 l = ((a[i]+b[i]+1)>>1)-c[i]; \
00781 d += ABS(l)
00782
00783 for ( y = 0; y < 16; y++ ) {
00784 across = &(prev[fy+y][fx]);
00785 bacross = blockSoFar[y];
00786 cacross = currentBlock[y];
00787
00788 ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,0);
00789 ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,1);
00790 ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,2);
00791 ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,3);
00792 ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,4);
00793 ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,5);
00794 ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,6);
00795 ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,7);
00796 ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,8);
00797 ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,9);
00798 ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,10);
00799 ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,11);
00800 ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,12);
00801 ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,13);
00802 ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,14);
00803 ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,15);
00804
00805 if ( diff > bestSoFar ) {
00806 return diff;
00807 }
00808 }
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823 return diff;
00824 }
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840 void
00841 AddMotionBlock(block, prev, by, bx, my, mx)
00842 Block block;
00843 uint8 **prev;
00844 int by;
00845 int bx;
00846 int my;
00847 int mx;
00848 {
00849 int fy, fx;
00850 int x, y;
00851 boolean xHalf, yHalf;
00852
00853 xHalf = (ABS(mx) % 2 == 1);
00854 yHalf = (ABS(my) % 2 == 1);
00855
00856 MOTION_TO_FRAME_COORD(by, bx, (my/2), (mx/2), fy, fx);
00857
00858 if ( xHalf && yHalf ) {
00859
00860
00861
00862 if ( my < 0 ) {
00863 fy--;
00864 }
00865 if ( mx < 0 ) {
00866 fx--;
00867 }
00868
00869 for ( y = 0; y < 8; y++ ) {
00870 for ( x = 0; x < 8; x++ ) {
00871 block[y][x] += (prev[fy+y][fx+x]+prev[fy+y][fx+x+1]+
00872 prev[fy+y+1][fx+x]+prev[fy+y+1][fx+x+1]+2)>>2;
00873 }
00874 }
00875 } else if ( xHalf ) {
00876 if ( mx < 0 ) {
00877 fx--;
00878 }
00879
00880 for ( y = 0; y < 8; y++ ) {
00881 for ( x = 0; x < 8; x++ ) {
00882 block[y][x] += (prev[fy+y][fx+x]+prev[fy+y][fx+x+1]+1)>>1;
00883 }
00884 }
00885 } else if ( yHalf ) {
00886 if ( my < 0 ) {
00887 fy--;
00888 }
00889
00890 for ( y = 0; y < 8; y++ ) {
00891 for ( x = 0; x < 8; x++ ) {
00892 block[y][x] += (prev[fy+y][fx+x]+prev[fy+y+1][fx+x]+1)>>1;
00893 }
00894 }
00895 } else {
00896 for ( y = 0; y < 8; y++ ) {
00897 for ( x = 0; x < 8; x++ ) {
00898 block[y][x] += (int16)prev[fy+y][fx+x];
00899 }
00900 }
00901 }
00902 }
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918 void
00919 AddBMotionBlock(block, prev, next, by, bx, mode, fmy, fmx, bmy, bmx)
00920 Block block;
00921 uint8 **prev;
00922 uint8 **next;
00923 int by;
00924 int bx;
00925 int mode;
00926 int fmy;
00927 int fmx;
00928 int bmy;
00929 int bmx;
00930 {
00931 int x, y;
00932 Block prevBlock, nextBlock;
00933
00934 if ( mode == MOTION_FORWARD ) {
00935 AddMotionBlock(block, prev, by, bx, fmy, fmx);
00936 } else if ( mode == MOTION_BACKWARD ) {
00937 AddMotionBlock(block, next, by, bx, bmy, bmx);
00938 } else {
00939 ComputeMotionBlock(prev, by, bx, fmy, fmx, prevBlock);
00940 ComputeMotionBlock(next, by, bx, bmy, bmx, nextBlock);
00941
00942 for ( y = 0; y < 8; y++ ) {
00943 for ( x = 0; x < 8; x++ ) {
00944 block[y][x] += (prevBlock[y][x]+nextBlock[y][x]+1)/2;
00945 }
00946 }
00947 }
00948 }
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962 void
00963 BlockToData(data, block, by, bx)
00964 uint8 **data;
00965 Block block;
00966 int by;
00967 int bx;
00968 {
00969 register int x, y;
00970 register int fy, fx;
00971 register int16 blockItem;
00972
00973 BLOCK_TO_FRAME_COORD(by, bx, fy, fx);
00974
00975 for ( y = 0; y < 8; y++ ) {
00976 for ( x = 0; x < 8; x++ ) {
00977 blockItem = block[y][x];
00978 data[fy+y][fx+x] = TRUNCATE_UINT8(blockItem);
00979 }
00980 }
00981 }
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997 void
00998 BlockifyFrame(framePtr)
00999 MpegFrame *framePtr;
01000 {
01001 register int dctx, dcty;
01002 register int x, y;
01003 register int bx, by;
01004 register int fy, fx;
01005 register int16 *destPtr;
01006 register uint8 *srcPtr;
01007 register int16 *destPtr2;
01008 register uint8 *srcPtr2;
01009 Block *blockPtr;
01010 Block *blockPtr2;
01011
01012 dctx = Fsize_x / DCTSIZE;
01013 dcty = Fsize_y / DCTSIZE;
01014
01015
01016
01017
01018 for (by = 0; by < dcty; by++) {
01019 fy = by*DCTSIZE;
01020 for (bx = 0; bx < dctx; bx++) {
01021 fx = bx*DCTSIZE;
01022 blockPtr = (Block *) &(framePtr->y_blocks[by][bx][0][0]);
01023 for (y = 0; y < DCTSIZE; y++) {
01024 destPtr = &((*blockPtr)[y][0]);
01025 srcPtr = &(framePtr->orig_y[fy+y][fx]);
01026 for (x = 0; x < DCTSIZE; x++) {
01027 destPtr[x] = srcPtr[x];
01028 }
01029 }
01030 }
01031 }
01032
01033
01034
01035
01036 for (by = 0; by < (dcty >> 1); by++) {
01037 fy = by*DCTSIZE;
01038 for (bx = 0; bx < (dctx >> 1); bx++) {
01039 fx = bx*DCTSIZE;
01040 blockPtr = (Block *) &(framePtr->cr_blocks[by][bx][0][0]);
01041 blockPtr2 = (Block *) &(framePtr->cb_blocks[by][bx][0][0]);
01042 for (y = 0; y < DCTSIZE; y++) {
01043 destPtr = &((*blockPtr)[y][0]);
01044 srcPtr = &(framePtr->orig_cr[fy+y][fx]);
01045 destPtr2 = &((*blockPtr2)[y][0]);
01046 srcPtr2 = &(framePtr->orig_cb[fy+y][fx]);
01047 for (x = 0; x < DCTSIZE; x++) {
01048 destPtr[x] = srcPtr[x];
01049 destPtr2[x] = srcPtr2[x];
01050 }
01051 }
01052 }
01053 }
01054 }
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068 #ifdef UNUSED_PROCEDURES
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080 void
01081 ComputeSubSampledMotionLumBlock(prevFrame, by, bx, my, mx, motionBlock,
01082 startY, startX)
01083 MpegFrame *prevFrame;
01084 int by;
01085 int bx;
01086 int my;
01087 int mx;
01088 LumBlock motionBlock;
01089 int startY;
01090 int startX;
01091 {
01092 register uint8 *across;
01093 register int32 *macross;
01094 register int32 *lastx;
01095 register int y;
01096 uint8 **prev;
01097 int fy, fx;
01098 boolean xHalf, yHalf;
01099
01100 xHalf = (ABS(mx) % 2 == 1);
01101 yHalf = (ABS(my) % 2 == 1);
01102
01103 MOTION_TO_FRAME_COORD(by, bx, my/2, mx/2, fy, fx);
01104
01105 if ( xHalf ) {
01106 if ( mx < 0 ) {
01107 fx--;
01108 }
01109
01110 if ( yHalf ) {
01111 if ( my < 0 ) {
01112 fy--;
01113 }
01114
01115 prev = prevFrame->halfBoth;
01116 } else {
01117 prev = prevFrame->halfX;
01118 }
01119 } else if ( yHalf ) {
01120 if ( my < 0 ) {
01121 fy--;
01122 }
01123
01124 prev = prevFrame->halfY;
01125 } else {
01126 prev = prevFrame->ref_y;
01127 }
01128
01129 for ( y = startY; y < 16; y += 2 ) {
01130 across = &(prev[fy+y][fx+startX]);
01131 macross = &(motionBlock[y][startX]);
01132 lastx = &(motionBlock[y][16]);
01133 while ( macross < lastx ) {
01134 (*macross) = (*across);
01135 across += 2;
01136 macross += 2;
01137 }
01138 }
01139
01140
01141
01142
01143
01144
01145
01146
01147 }
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167 int32
01168 LumMotionErrorSubSampled(currentBlock, prevFrame, by, bx, my, mx, startY,
01169 startX)
01170 LumBlock currentBlock;
01171 MpegFrame *prevFrame;
01172 int by;
01173 int bx;
01174 int my;
01175 int mx;
01176 int startY;
01177 int startX;
01178 {
01179 register int32 diff = 0;
01180 register int32 localDiff;
01181 register int32 *cacross;
01182 register uint8 *macross;
01183 register int32 *lastx;
01184 register int y;
01185 uint8 **prev;
01186 int fy, fx;
01187 boolean xHalf, yHalf;
01188
01189 xHalf = (ABS(mx) % 2 == 1);
01190 yHalf = (ABS(my) % 2 == 1);
01191
01192 MOTION_TO_FRAME_COORD(by, bx, my/2, mx/2, fy, fx);
01193
01194 if ( xHalf ) {
01195 if ( mx < 0 ) {
01196 fx--;
01197 }
01198
01199 if ( yHalf ) {
01200 if ( my < 0 ) {
01201 fy--;
01202 }
01203
01204 prev = prevFrame->halfBoth;
01205 } else {
01206 prev = prevFrame->halfX;
01207 }
01208 } else if ( yHalf ) {
01209 if ( my < 0 ) {
01210 fy--;
01211 }
01212
01213 prev = prevFrame->halfY;
01214 } else {
01215 prev = prevFrame->ref_y;
01216 }
01217
01218 for ( y = startY; y < 16; y += 2 ) {
01219 macross = &(prev[fy+y][fx+startX]);
01220 cacross = &(currentBlock[y][startX]);
01221 lastx = &(currentBlock[y][16]);
01222 while ( cacross < lastx ) {
01223 localDiff = (*cacross)-(*macross);
01224 diff += ABS(localDiff);
01225 macross += 2;
01226 cacross += 2;
01227 }
01228 }
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244 return (int32)diff;
01245 }
01246
01247
01248 #endif