📄 block.c
字号:
*===========================================================================*/voidAddMotionBlock(block, prev, by, bx, my, mx) Block block; uint8 **prev; int by; int bx; int my; int mx;{ int fy, fx; int x, y; 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 && yHalf ) { /* really should be fy+y-1 and fy+y so do (fy-1)+y = fy+y-1 and (fy-1)+y+1 = fy+y */ if ( my < 0 ) { fy--; } if ( mx < 0 ) { fx--; } for ( y = 0; y < 8; y++ ) { for ( x = 0; x < 8; x++ ) { block[y][x] += (prev[fy+y][fx+x]+prev[fy+y][fx+x+1]+ prev[fy+y+1][fx+x]+prev[fy+y+1][fx+x+1]+2)>>2; } } } else if ( xHalf ) { if ( mx < 0 ) { fx--; } for ( y = 0; y < 8; y++ ) { for ( x = 0; x < 8; x++ ) { block[y][x] += (prev[fy+y][fx+x]+prev[fy+y][fx+x+1]+1)>>1; } } } else if ( yHalf ) { if ( my < 0 ) { fy--; } for ( y = 0; y < 8; y++ ) { for ( x = 0; x < 8; x++ ) { block[y][x] += (prev[fy+y][fx+x]+prev[fy+y+1][fx+x]+1)>>1; } } } else { for ( y = 0; y < 8; y++ ) { for ( x = 0; x < 8; x++ ) { block[y][x] += (int16)prev[fy+y][fx+x]; } } }}/*===========================================================================* * * AddBMotionBlock * * adds the motion-compensated B-frame block to the given block * * RETURNS: block modified * * SIDE EFFECTS: none * * PRECONDITIONS: motion vectors MUST be valid * *===========================================================================*/voidAddBMotionBlock(block, prev, next, by, bx, mode, fmy, fmx, bmy, bmx) Block block; uint8 **prev; uint8 **next; int by; int bx; int mode; int fmy; int fmx; int bmy; int bmx;{ int x, y; Block prevBlock, nextBlock; if ( mode == MOTION_FORWARD ) { AddMotionBlock(block, prev, by, bx, fmy, fmx); } else if ( mode == MOTION_BACKWARD ) { AddMotionBlock(block, next, by, bx, bmy, bmx); } else { ComputeMotionBlock(prev, by, bx, fmy, fmx, prevBlock); ComputeMotionBlock(next, by, bx, bmy, bmx, nextBlock); for ( y = 0; y < 8; y++ ) { for ( x = 0; x < 8; x++ ) { block[y][x] += (prevBlock[y][x]+nextBlock[y][x]+1)/2; } } }}/*===========================================================================* * * BlockToData * * copies the given block into the appropriate data area * * RETURNS: data modified * * SIDE EFFECTS: none * *===========================================================================*/voidBlockToData(data, block, by, bx) uint8 **data; Block block; int by; int bx;{ register int x, y; register int fy, fx; register int16 blockItem; BLOCK_TO_FRAME_COORD(by, bx, fy, fx); for ( y = 0; y < 8; y++ ) { for ( x = 0; x < 8; x++ ) { blockItem = block[y][x]; data[fy+y][fx+x] = TRUNCATE_UINT8(blockItem); } }}/*===========================================================================* * * BlockifyFrame * * copies data into appropriate blocks * * RETURNS: mf modified * * SIDE EFFECTS: none * * NOTES: probably shouldn't be in this file * *===========================================================================*/voidBlockifyFrame(framePtr) MpegFrame *framePtr;{ register int dctx, dcty; register int x, y; register int bx, by; register int fy, fx; register int16 *destPtr; register uint8 *srcPtr; register int16 *destPtr2; register uint8 *srcPtr2; Block *blockPtr; Block *blockPtr2; dctx = Fsize_x / DCTSIZE; dcty = Fsize_y / DCTSIZE; /* * copy y data into y_blocks */ for (by = 0; by < dcty; by++) { fy = by*DCTSIZE; for (bx = 0; bx < dctx; bx++) { fx = bx*DCTSIZE; blockPtr = (Block *) &(framePtr->y_blocks[by][bx][0][0]); for (y = 0; y < DCTSIZE; y++) { destPtr = &((*blockPtr)[y][0]); srcPtr = &(framePtr->orig_y[fy+y][fx]); for (x = 0; x < DCTSIZE; x++) { destPtr[x] = srcPtr[x]; } } } } /* * copy cr/cb data into cr/cb_blocks */ for (by = 0; by < (dcty >> 1); by++) { fy = by*DCTSIZE; for (bx = 0; bx < (dctx >> 1); bx++) { fx = bx*DCTSIZE; blockPtr = (Block *) &(framePtr->cr_blocks[by][bx][0][0]); blockPtr2 = (Block *) &(framePtr->cb_blocks[by][bx][0][0]); for (y = 0; y < DCTSIZE; y++) { destPtr = &((*blockPtr)[y][0]); srcPtr = &(framePtr->orig_cr[fy+y][fx]); destPtr2 = &((*blockPtr2)[y][0]); srcPtr2 = &(framePtr->orig_cb[fy+y][fx]); for (x = 0; x < DCTSIZE; x++) { destPtr[x] = srcPtr[x]; destPtr2[x] = srcPtr2[x]; } } } }}/*===========================================================================* * * * UNUSED PROCEDURES * * * * The following procedures are all unused by the encoder * * * * They are listed here for your convenience. You might want to use * * them if you experiment with different search techniques * * * *===========================================================================*/#ifdef UNUSED_PROCEDURES/* this procedure calculates the subsampled motion block (obviously) * * for speed, this procedure is probably not called anywhere (it is * incorporated directly into LumDiffA, LumDiffB, etc. * * but leave it here anyway for clarity * * (startY, startX) = (0,0) for A....(0,1) for B...(1,0) for C...(1,1) for D * */voidComputeSubSampledMotionLumBlock(prevFrame, by, bx, my, mx, motionBlock, startY, startX) MpegFrame *prevFrame; int by; int bx; int my; int mx; LumBlock motionBlock; int startY; int startX;{ register uint8 *across; register int32 *macross; register int32 *lastx; 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; } for ( y = startY; y < 16; y += 2 ) { across = &(prev[fy+y][fx+startX]); macross = &(motionBlock[y][startX]); lastx = &(motionBlock[y][16]); while ( macross < lastx ) { (*macross) = (*across); across += 2; macross += 2; } } /* this is what's really going on in slow motion: * * for ( y = startY; y < 16; y += 2 ) * for ( x = startX; x < 16; x += 2 ) * motionBlock[y][x] = prev[fy+y][fx+x]; * */}/*===========================================================================* * * LumMotionErrorSubSampled * * return the MAD of the currentBlock and the motion-compensated block, * subsampled 4:1 with given starting coordinates (startY, startX) * * RETURNS: the MAD * * SIDE EFFECTS: none * * PRECONDITIONS: motion vector MUST be valid * * NOTES: this procedure is never called. Instead, see subsample.c. This * procedure is provided only for possible use in extensions * *===========================================================================*/int32LumMotionErrorSubSampled(currentBlock, prevFrame, by, bx, my, mx, startY, startX) LumBlock currentBlock; MpegFrame *prevFrame; int by; int bx; int my; int mx; int startY; int startX;{ register int32 diff = 0; /* max value of diff is 255*256 = 65280 */ register int32 localDiff; register int32 *cacross; register uint8 *macross; register int32 *lastx; 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; } for ( y = startY; y < 16; y += 2 ) { macross = &(prev[fy+y][fx+startX]); cacross = &(currentBlock[y][startX]); lastx = &(currentBlock[y][16]); while ( cacross < lastx ) { localDiff = (*cacross)-(*macross); diff += ABS(localDiff); macross += 2; cacross += 2; } } /* this is what's really happening: * * ComputeSubSampledMotionLumBlock(prevFrame, by, bx, my, mx, * lumMotionBlock, startY, startX); * * for ( y = startY; y < 16; y += 2 ) * for ( x = startX; x < 16; x += 2 ) * { * localDiff = currentBlock[y][x] - lumMotionBlock[y][x]; * diff += ABS(localDiff); * } * */ return (int32)diff;}#endif /* UNUSED_PROCEDURES */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -