home *** CD-ROM | disk | FTP | other *** search
- /*===========================================================================*
- * block.c *
- * *
- * Block routines *
- * *
- * EXPORTED PROCEDURES: *
- * ComputeDiffDCTBlock *
- * ComputeDiffDCTs *
- * ComputeMotionBlock *
- * ComputeMotionLumBlock *
- * LumBlockMAD *
- * LumMotionError *
- * LumMotionErrorSubSampled *
- * LumAddMotionError *
- * AddMotionBlock *
- * BlockToData *
- * BlockifyFrame *
- * *
- * NOTES: MAD = Mean Absolute Difference *
- * *
- *===========================================================================*/
-
- /*
- * Copyright (c) 1993 The Regents of the University of California.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice and the following
- * two paragraphs appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
- * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
- /*
- * $Header: /n/picasso/users/keving/encode/src/RCS/block.c,v 1.4 1993/07/22 22:23:43 keving Exp keving $
- * $Log: block.c,v $
- * Revision 1.4 1993/07/22 22:23:43 keving
- * nothing
- *
- * Revision 1.3 1993/06/30 20:06:09 keving
- * nothing
- *
- * Revision 1.2 1993/06/03 21:08:08 keving
- * nothing
- *
- * Revision 1.1 1993/04/08 21:31:59 keving
- * nothing
- *
- */
-
-
- /*==============*
- * HEADER FILES *
- *==============*/
-
- #include "all.h"
- #include "mtypes.h"
- #include "frames.h"
- #include "bitio.h"
- #ifdef OS2
- /* @@@ FAT 8.3 convention */
- #include "prototyp.h"
- #else
- #include "prototypes.h"
- #endif
- #include "fsize.h"
-
-
- #undef ABS
- #define ABS(x) ((x < 0) ? (-x) : x)
-
- #define TRUNCATE_UINT8(x) ((x < 0) ? 0 : ((x > 255) ? 255 : x))
-
-
- /*==========================*
- * INITIALIZATION FUNCTIONS *
- *==========================*/
-
-
- /*===========================*
- * COMPUTE DCT OF DIFFERENCE *
- *===========================*/
-
- /*===========================================================================*
- *
- * ComputeDiffDCTBlock
- *
- * compute current-motionBlock, take the DCT, and put the difference
- * back into current
- *
- * RETURNS: current block modified
- *
- * SIDE EFFECTS: none
- *
- *===========================================================================*/
- void
- ComputeDiffDCTBlock(current, motionBlock)
- Block current;
- Block motionBlock;
- {
- register int x, y;
-
- for ( y = 0; y < 8; y++ ) {
- for ( x = 0; x < 8; x++ ) {
- current[y][x] -= motionBlock[y][x];
- }
- }
-
- mp_fwd_dct_block(current);
-
- return /* nothing */;
- }
-
-
- /*===========================================================================*
- *
- * ComputeDiffDCTs
- *
- * appropriate (according to pattern, the coded block pattern) blocks
- * of 'current' are diff'ed and DCT'd.
- *
- * RETURNS: current blocks modified
- *
- * SIDE EFFECTS: none
- *
- * PRECONDITIONS: appropriate blocks of 'current' have not yet been
- * modified
- *
- *===========================================================================*/
- void
- ComputeDiffDCTs(current, prev, by, bx, my, mx, pattern)
- MpegFrame *current;
- MpegFrame *prev;
- int by;
- int bx;
- int my;
- int mx;
- int pattern;
- {
- Block motionBlock;
-
- if ( pattern & 0x20 ) {
- ComputeMotionBlock(prev->ref_y, by, bx, my, mx, motionBlock);
- ComputeDiffDCTBlock(current->y_blocks[by][bx], motionBlock);
- }
-
- if ( pattern & 0x10 ) {
- ComputeMotionBlock(prev->ref_y, by, bx+1, my, mx, motionBlock);
- ComputeDiffDCTBlock(current->y_blocks[by][bx+1], motionBlock);
- }
-
- if ( pattern & 0x8 ) {
- ComputeMotionBlock(prev->ref_y, by+1, bx, my, mx, motionBlock);
- ComputeDiffDCTBlock(current->y_blocks[by+1][bx], motionBlock);
- }
-
- if ( pattern & 0x4 ) {
- ComputeMotionBlock(prev->ref_y, by+1, bx+1, my, mx, motionBlock);
- ComputeDiffDCTBlock(current->y_blocks[by+1][bx+1], motionBlock);
- }
-
- if ( pattern & 0x2 ) {
- ComputeMotionBlock(prev->ref_cb, by >> 1, bx >> 1, my/2, mx/2, motionBlock);
- ComputeDiffDCTBlock(current->cb_blocks[by >> 1][bx >> 1], motionBlock);
- }
-
- if ( pattern & 0x1 ) {
- ComputeMotionBlock(prev->ref_cr, by >> 1, bx >> 1, my/2, mx/2, motionBlock);
- ComputeDiffDCTBlock(current->cr_blocks[by >> 1][bx >> 1], motionBlock);
- }
- }
-
-
- /*======================*
- * COMPUTE MOTION BLOCK *
- *======================*/
-
- /*===========================================================================*
- *
- * ComputeMotionBlock
- *
- * compute the motion-compensated block
- *
- * RETURNS: motionBlock
- *
- * SIDE EFFECTS: none
- *
- * PRECONDITIONS: motion vector MUST be valid
- *
- * NOTE: could try to speed this up using halfX, halfY, halfBoth,
- * but then would have to compute for chrominance, and it's just
- * not worth the trouble (this procedure is not called relatively
- * often -- a constant number of times per macroblock)
- *
- *===========================================================================*/
- void
- ComputeMotionBlock(prev, by, bx, my, mx, motionBlock)
- uint8 **prev;
- int by;
- int bx;
- int my;
- int mx;
- Block motionBlock;
- {
- register int fy, fx;
- register int y;
- register int16 *destPtr;
- register uint8 *srcPtr;
- register uint8 *srcPtr2;
- 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++ ) {
- destPtr = motionBlock[y];
- srcPtr = &(prev[fy+y][fx]);
- srcPtr2 = &(prev[fy+y+1][fx]);
-
- destPtr[0] = (srcPtr[0]+srcPtr[1]+srcPtr2[0]+srcPtr2[1]+2)>>2;
- destPtr[1] = (srcPtr[1]+srcPtr[2]+srcPtr2[1]+srcPtr2[2]+2)>>2;
- destPtr[2] = (srcPtr[2]+srcPtr[3]+srcPtr2[2]+srcPtr2[3]+2)>>2;
- destPtr[3] = (srcPtr[3]+srcPtr[4]+srcPtr2[3]+srcPtr2[4]+2)>>2;
- destPtr[4] = (srcPtr[4]+srcPtr[5]+srcPtr2[4]+srcPtr2[5]+2)>>2;
- destPtr[5] = (srcPtr[5]+srcPtr[6]+srcPtr2[5]+srcPtr2[6]+2)>>2;
- destPtr[6] = (srcPtr[6]+srcPtr[7]+srcPtr2[6]+srcPtr2[7]+2)>>2;
- destPtr[7] = (srcPtr[7]+srcPtr[8]+srcPtr2[7]+srcPtr2[8]+2)>>2;
- }
- } else if ( xHalf ) {
- if ( mx < 0 ) {
- fx--;
- }
-
- for ( y = 0; y < 8; y++ ) {
- destPtr = motionBlock[y];
- srcPtr = &(prev[fy+y][fx]);
-
- destPtr[0] = (srcPtr[0]+srcPtr[1]+1)>>1;
- destPtr[1] = (srcPtr[1]+srcPtr[2]+1)>>1;
- destPtr[2] = (srcPtr[2]+srcPtr[3]+1)>>1;
- destPtr[3] = (srcPtr[3]+srcPtr[4]+1)>>1;
- destPtr[4] = (srcPtr[4]+srcPtr[5]+1)>>1;
- destPtr[5] = (srcPtr[5]+srcPtr[6]+1)>>1;
- destPtr[6] = (srcPtr[6]+srcPtr[7]+1)>>1;
- destPtr[7] = (srcPtr[7]+srcPtr[8]+1)>>1;
- }
- } else if ( yHalf ) {
- if ( my < 0 ) {
- fy--;
- }
-
- for ( y = 0; y < 8; y++ ) {
- destPtr = motionBlock[y];
- srcPtr = &(prev[fy+y][fx]);
- srcPtr2 = &(prev[fy+y+1][fx]);
-
- destPtr[0] = (srcPtr[0]+srcPtr2[0]+1)>>1;
- destPtr[1] = (srcPtr[1]+srcPtr2[1]+1)>>1;
- destPtr[2] = (srcPtr[2]+srcPtr2[2]+1)>>1;
- destPtr[3] = (srcPtr[3]+srcPtr2[3]+1)>>1;
- destPtr[4] = (srcPtr[4]+srcPtr2[4]+1)>>1;
- destPtr[5] = (srcPtr[5]+srcPtr2[5]+1)>>1;
- destPtr[6] = (srcPtr[6]+srcPtr2[6]+1)>>1;
- destPtr[7] = (srcPtr[7]+srcPtr2[7]+1)>>1;
- }
- } else {
- for ( y = 0; y < 8; y++ ) {
- destPtr = motionBlock[y];
- srcPtr = &(prev[fy+y][fx]);
-
- destPtr[0] = srcPtr[0];
- destPtr[1] = srcPtr[1];
- destPtr[2] = srcPtr[2];
- destPtr[3] = srcPtr[3];
- destPtr[4] = srcPtr[4];
- destPtr[5] = srcPtr[5];
- destPtr[6] = srcPtr[6];
- destPtr[7] = srcPtr[7];
- }
- }
- }
-
-
- /*===========================================================================*
- *
- * ComputeMotionLumBlock
- *
- * compute the motion-compensated luminance block
- *
- * RETURNS: motionBlock
- *
- * SIDE EFFECTS: none
- *
- * PRECONDITIONS: motion vector MUST be valid
- *
- * NOTE: see ComputeMotionBlock
- *
- *===========================================================================*/
- void
- ComputeMotionLumBlock(prevFrame, by, bx, my, mx, motionBlock)
- MpegFrame *prevFrame;
- int by;
- int bx;
- int my;
- int mx;
- LumBlock motionBlock;
- {
- register uint8 *across;
- register int32 *macross;
- 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 = 0; y < 16; y++ ) {
- 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
- *
- *===========================================================================*/
- int32
- LumBlockMAD(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
- *
- * 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!!!
- *
- *===========================================================================*/
- int32
- LumMotionError(currentBlock, prevFrame, by, bx, my, mx, bestSoFar)
- LumBlock currentBlock;
- 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 *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;
- }
-
- 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;
- }
- }
-
- /* 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;
- }
-
-
- /*===========================================================================*
- *
- * 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
- *
- *===========================================================================*/
- int32
- LumAddMotionError(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
- *
- *===========================================================================*/
- void
- AddMotionBlock(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] += (int32)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
- *
- *===========================================================================*/
- void
- AddBMotionBlock(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
- *
- *===========================================================================*/
- void
- BlockToData(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
- *
- *===========================================================================*/
- void
- BlockifyFrame(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 = &framePtr->y_blocks[by][bx];
- 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 / 2; by++) {
- fy = by*DCTSIZE;
- for (bx = 0; bx < dctx / 2; bx++) {
- fx = bx*DCTSIZE;
- blockPtr = &framePtr->cr_blocks[by][bx];
- blockPtr2 = &framePtr->cb_blocks[by][bx];
- 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
- *
- */
- void
- ComputeSubSampledMotionLumBlock(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
- *
- *===========================================================================*/
- int32
- LumMotionErrorSubSampled(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 */
-