📄 block.c
字号:
across = &(prev[fy+y][fx]); macross = motionBlock[y]; macross[0] = across[0]; macross[1] = across[1]; macross[2] = across[2]; macross[3] = across[3]; macross[4] = across[4]; macross[5] = across[5]; macross[6] = across[6]; macross[7] = across[7]; macross[8] = across[8]; macross[9] = across[9]; macross[10] = across[10]; macross[11] = across[11]; macross[12] = across[12]; macross[13]= across[13]; macross[14] = across[14]; macross[15] = across[15]; } /* this is what's really happening, in slow motion: * * for ( y = 0; y < 16; y++, py++ ) * for ( x = 0; x < 16; x++, px++ ) * motionBlock[y][x] = prev[fy+y][fx+x]; * */}/*=======================* * BASIC ERROR FUNCTIONS * *=======================*//*===========================================================================* * * LumBlockMAD * * return the MAD of two luminance blocks * * RETURNS: the MAD, if less than bestSoFar, or * some number bigger if not * * SIDE EFFECTS: none * *===========================================================================*/int32LumBlockMAD(currentBlock, motionBlock, bestSoFar) LumBlock currentBlock; LumBlock motionBlock; int32 bestSoFar;{ register int32 diff = 0; /* max value of diff is 255*256 = 65280 */ register int32 localDiff; register int y, x; for ( y = 0; y < 16; y++ ) { for ( x = 0; x < 16; x++ ) { localDiff = currentBlock[y][x] - motionBlock[y][x]; diff += ABS(localDiff); } if ( diff > bestSoFar ) { return diff; } } return (int32)diff;}/*===========================================================================* * * LumMotionError * * return the MAD of the currentBlock and the motion-compensated block * (without TUNEing) * * RETURNS: the MAD, if less than bestSoFar, or * some number bigger if not * * SIDE EFFECTS: none * * PRECONDITIONS: motion vector MUST be valid * * NOTES: this is the procedure that is called the most, and should therefore * be the most optimized!!! * *===========================================================================*/int32LumMotionError(currentBlock, prevFrame, by, bx, my, mx, bestSoFar) LumBlock currentBlock; MpegFrame *prevFrame; int by; int bx; int my; int mx; int32 bestSoFar;{ register int32 adiff = 0, diff = 0; /* max value of diff is 255*256 = 65280 */ register int32 localDiff; register uint8 *across; register int32 *cacross; register int y; uint8 **prev; int fy, fx; boolean xHalf, yHalf; xHalf = (ABS(mx) % 2 == 1); yHalf = (ABS(my) % 2 == 1); MOTION_TO_FRAME_COORD(by, bx, my/2, mx/2, fy, fx); if ( xHalf ) { if ( mx < 0 ) { fx--; } if ( yHalf ) { if ( my < 0 ) { fy--; } prev = prevFrame->halfBoth; } else { prev = prevFrame->halfX; } } else if ( yHalf ) { if ( my < 0 ) { fy--; } prev = prevFrame->halfY; } else { prev = prevFrame->ref_y; } switch (SearchCompareMode) { case DEFAULT_SEARCH: /* Default. */ /* this is what's happening: * ComputeMotionLumBlock(prevFrame, by, bx, my, mx, lumMotionBlock); * for ( y = 0; y < 16; y++ ) * for ( x = 0; x < 16; x++ ) * { * localDiff = currentBlock[y][x] - lumMotionBlock[y][x]; * diff += ABS(localDiff); * } */ for ( y = 0; y < 16; y++ ) { across = &(prev[fy+y][fx]); cacross = currentBlock[y]; localDiff = across[0]-cacross[0]; diff += ABS(localDiff); localDiff = across[1]-cacross[1]; diff += ABS(localDiff); localDiff = across[2]-cacross[2]; diff += ABS(localDiff); localDiff = across[3]-cacross[3]; diff += ABS(localDiff); localDiff = across[4]-cacross[4]; diff += ABS(localDiff); localDiff = across[5]-cacross[5]; diff += ABS(localDiff); localDiff = across[6]-cacross[6]; diff += ABS(localDiff); localDiff = across[7]-cacross[7]; diff += ABS(localDiff); localDiff = across[8]-cacross[8]; diff += ABS(localDiff); localDiff = across[9]-cacross[9]; diff += ABS(localDiff); localDiff = across[10]-cacross[10]; diff += ABS(localDiff); localDiff = across[11]-cacross[11]; diff += ABS(localDiff); localDiff = across[12]-cacross[12]; diff += ABS(localDiff); localDiff = across[13]-cacross[13]; diff += ABS(localDiff); localDiff = across[14]-cacross[14]; diff += ABS(localDiff); localDiff = across[15]-cacross[15]; diff += ABS(localDiff); if ( diff > bestSoFar ) { return diff; } } break; case LOCAL_DCT: { Block dctdiff[4], dctquant[4]; FlatBlock quant; int x, i, tmp; int distortion=0, datarate=0; int pq = GetPQScale(); for (y = 0; y < 16; y++) { across = &(prev[fy+y][fx]); cacross = currentBlock[y]; for (x = 0; x < 16; x++) { dctdiff[(x>7)+2*(y>7)][y%8][x%8] = cacross[x]-across[x]; }} /* Calculate rate */ for (i = 0; i < 4; i++) { mp_fwd_dct_block2(dctdiff[i], dctdiff[i]); if (Mpost_QuantZigBlock(dctdiff[i], quant, pq, FALSE) == MPOST_ZERO) { /* no sense in continuing */ memset((char *)dctquant[i], 0, sizeof(Block)); } else { Mpost_UnQuantZigBlock(quant, dctquant[i], pq, FALSE); mpeg_jrevdct((int16 *)dctquant[i]); datarate += CalcRLEHuffLength(quant); } } /* Calculate distortion */ for (y = 0; y < 16; y++) { across = &(prev[fy+y][fx]); cacross = currentBlock[y]; for (x = 0; x < 16; x++) { tmp = across[x] - cacross[x] + dctquant[(x>7)+2*(y>7)][y%8][x%8]; distortion += tmp*tmp; }} distortion /= 256; distortion *= LocalDCTDistortScale; datarate *= LocalDCTRateScale; diff = (int) sqrt(distortion*distortion + datarate*datarate); break; } case NO_DC_SEARCH: { extern int32 niqtable[]; int pq = niqtable[0]*GetPQScale(); for ( y = 0; y < 16; y++ ) { across = &(prev[fy+y][fx]); cacross = currentBlock[y]; localDiff = across[0]-cacross[0]; diff += localDiff; adiff += ABS(localDiff); localDiff = across[1]-cacross[1]; diff += localDiff; adiff += ABS(localDiff); localDiff = across[2]-cacross[2]; diff += localDiff; adiff += ABS(localDiff); localDiff = across[3]-cacross[3]; diff += localDiff; adiff += ABS(localDiff); localDiff = across[4]-cacross[4]; diff += localDiff; adiff += ABS(localDiff); localDiff = across[5]-cacross[5]; diff += localDiff; adiff += ABS(localDiff); localDiff = across[6]-cacross[6]; diff += localDiff; adiff += ABS(localDiff); localDiff = across[7]-cacross[7]; diff += localDiff; adiff += ABS(localDiff); localDiff = across[8]-cacross[8]; diff += localDiff; adiff += ABS(localDiff); localDiff = across[9]-cacross[9]; diff += localDiff; adiff += ABS(localDiff); localDiff = across[10]-cacross[10]; diff += localDiff; adiff += ABS(localDiff); localDiff = across[11]-cacross[11]; diff += localDiff; adiff += ABS(localDiff); localDiff = across[12]-cacross[12]; diff += localDiff; adiff += ABS(localDiff); localDiff = across[13]-cacross[13]; diff += localDiff; adiff += ABS(localDiff); localDiff = across[14]-cacross[14]; diff += localDiff; adiff += ABS(localDiff); localDiff = across[15]-cacross[15]; diff += localDiff; adiff += ABS(localDiff); } diff /= 64*pq; /* diff is now the DC difference (with QSCALE 1) */ adiff -= 64*pq*ABS(diff); diff = adiff; } break; case DO_Mean_Squared_Distortion: for ( y = 0; y < 16; y++ ) { across = &(prev[fy+y][fx]); cacross = currentBlock[y]; localDiff = across[0]-cacross[0]; diff += localDiff*localDiff; localDiff = across[1]-cacross[1]; diff += localDiff*localDiff; localDiff = across[2]-cacross[2]; diff += localDiff*localDiff; localDiff = across[3]-cacross[3]; diff += localDiff*localDiff; localDiff = across[4]-cacross[4]; diff += localDiff*localDiff; localDiff = across[5]-cacross[5]; diff += localDiff*localDiff; localDiff = across[6]-cacross[6]; diff += localDiff*localDiff; localDiff = across[7]-cacross[7]; diff += localDiff*localDiff; localDiff = across[8]-cacross[8]; diff += localDiff*localDiff; localDiff = across[9]-cacross[9]; diff += localDiff*localDiff; localDiff = across[10]-cacross[10]; diff += localDiff*localDiff; localDiff = across[11]-cacross[11]; diff += localDiff*localDiff; localDiff = across[12]-cacross[12]; diff += localDiff*localDiff; localDiff = across[13]-cacross[13]; diff += localDiff*localDiff; localDiff = across[14]-cacross[14]; diff += localDiff*localDiff; localDiff = across[15]-cacross[15]; diff += localDiff*localDiff; if ( diff > bestSoFar ) { return diff; } } break; } /* End of Switch */ return diff;}/*===========================================================================* * * LumAddMotionError * * return the MAD of the currentBlock and the average of the blockSoFar * and the motion-compensated block (this is used for B-frame searches) * * RETURNS: the MAD, if less than bestSoFar, or * some number bigger if not * * SIDE EFFECTS: none * * PRECONDITIONS: motion vector MUST be valid * *===========================================================================*/int32LumAddMotionError(currentBlock, blockSoFar, prevFrame, by, bx, my, mx, bestSoFar) LumBlock currentBlock; LumBlock blockSoFar; MpegFrame *prevFrame; int by; int bx; int my; int mx; int32 bestSoFar;{ register int32 diff = 0; /* max value of diff is 255*256 = 65280 */ register int32 localDiff; register uint8 *across; register int32 *bacross; register int32 *cacross; register int y; uint8 **prev; int fy, fx; boolean xHalf, yHalf; xHalf = (ABS(mx) % 2 == 1); yHalf = (ABS(my) % 2 == 1); MOTION_TO_FRAME_COORD(by, bx, my/2, mx/2, fy, fx); if ( xHalf ) { if ( mx < 0 ) { fx--; } if ( yHalf ) { if ( my < 0 ) { fy--; } prev = prevFrame->halfBoth; } else { prev = prevFrame->halfX; } } else if ( yHalf ) { if ( my < 0 ) { fy--; } prev = prevFrame->halfY; } else { prev = prevFrame->ref_y; }/* do we add 1 before dividing by two? Yes -- see MPEG-1 doc page 46 */#define ADD_ADD_DIFF(d,l,a,b,c,i) \ l = ((a[i]+b[i]+1)>>1)-c[i]; \ d += ABS(l) for ( y = 0; y < 16; y++ ) { across = &(prev[fy+y][fx]); bacross = blockSoFar[y]; cacross = currentBlock[y]; ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,0); ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,1); ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,2); ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,3); ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,4); ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,5); ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,6); ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,7); ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,8); ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,9); ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,10); ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,11); ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,12); ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,13); ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,14); ADD_ADD_DIFF(diff,localDiff,across,bacross,cacross,15); if ( diff > bestSoFar ) { return diff; } } /* this is what's happening: * * ComputeMotionLumBlock(prevFrame, by, bx, my, mx, lumMotionBlock); * * for ( y = 0; y < 16; y++ ) * for ( x = 0; x < 16; x++ ) * { * localDiff = currentBlock[y][x] - lumMotionBlock[y][x]; * diff += ABS(localDiff); * } * */ return diff;}/*===========================================================================* * * AddMotionBlock * * adds the motion-compensated block to the given block * * RETURNS: block modified * * SIDE EFFECTS: none * * PRECONDITIONS: motion vector MUST be valid *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -