diff -r 000000000000 -r 951a5db380a0 videoeditorengine/h263decoder/src/block.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/videoeditorengine/h263decoder/src/block.cpp Fri Jan 29 14:08:33 2010 +0200 @@ -0,0 +1,1094 @@ +/* +* Copyright (c) 2010 Ixonos Plc. +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - Initial contribution +* +* Contributors: +* Ixonos Plc +* +* Description: +* Motion compensation functions. +* +*/ + + +#include "h263dConfig.h" + +#include "block.h" + +#include "errcodes.h" +#include "vdcmvc.h" +#include "debug.h" + +#ifndef blcAssert + #define blcAssert assert +#endif +#include "blcllcpy.cpp" + +/* See the description above. */ +typedef void (* blcCopyBlock_t) (u_char *, u_char *, + int, int, int, int, int, int, int, int, int, int, int, int, int); + +/* This structure is used to pass a pointer either to blcUVCountRefXY1MV or + blcUVCountRefXY4MVs. */ +typedef void (* blcUVCountRefXY_t) + (int, int, int *, int *, int *, int *, int *, int *); + + +/* + * Local function prototypes + */ + +static int blcCopyNormalYPredictionMBWith1MV( + blcCopyBlock_t copyBlock, + int *mvxArray, int *mvyArray, + u_char *dstYBlk, + u_char *srcYFrame, + int dstYXPos, int dstYYPos, + int dstYXSize, + int srcYXSize, int srcYYSize, + int fMVsOverPictureBoundaries, + int rcontrol); + +static int blcCopyNormalYPredictionMBWith4MVs( + blcCopyBlock_t copyBlock, + int *mvxArray, int *mvyArray, + u_char *dstYBlk, + u_char *srcYFrame, + int dstYXPos, int dstYYPos, + int dstYXSize, + int srcYXSize, int srcYYSize, + int fMVsOverPictureBoundaries, + int rcontrol); + +static int blcCopyUVPredictionBlocks( + blcUVCountRefXY_t uvCountSourceXY, + blcCopyBlock_t copyBlock, + int *mvxArray, int *mvyArray, + u_char *dstUBlk, u_char *dstVBlk, + u_char *srcUFrame, u_char *srcVFrame, + int dstUVXPos, int dstUVYPos, + int dstUVXSize, + int srcUVXSize, int srcUVYSize, + int fMVsOverPictureBoundaries, + int rcontrol); + +static void blcHandleRefOverPictBoundariesBC( + int xBlkSize, int yBlkSize, + int xSize, int ySize, + int subpixelX, int subpixelY, + int *sourceX, int *sourceY, + int *xlt0, int *xNormal, int *xgtmax, + int *ylt0, int *yNormal, int *ygtmax); + +static int blcIsRefOverPictBoundaries( + int xBlkSize, int yBlkSize, + int xSize, int ySize, + int subpixelX, int subpixelY, + int sourceX, int sourceY); + +static void blcUVCountMVOffset4MVs( + int *mvxArray, int *mvyArray, + int *offsetX, int *offsetY, + int *subpixelX, int *subpixelY); + +static void blcUVCountRefXY1MV( + int origoX, int origoY, + int *mvxArray, int *mvyArray, + int *sourceX, int *sourceY, + int *subpixelX, int *subpixelY); + +static void blcUVCountRefXY4MVs( + int origoX, int origoY, + int *mvxArray, int *mvyArray, + int *sourceX, int *sourceY, + int *subpixelX, int *subpixelY); + +static void blcYCountRefXY( + int mvxVal, int mvyVal, + int destX, int destY, + int *sourceX, int *sourceY, + int *subpixelX, int *subpixelY); + + +/* + * Module-scope constants + */ + +/* Clipping table to sature values to range 0..255 */ +static const u_char wholeClippingTable[4*256] = { + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255}; + +static const u_char * const clippingTable = &wholeClippingTable[512]; + + +/* + * Global functions + */ + +/* {{-output"blcAddBlock.txt"}} */ +/* + * blcAddBlock + * + * + * Parameters: + * block block array (of 64 pixels) + * dstBlk pointer to present frame in the place, + * where the block is added + * xSize X size of the frame. + * mbPlace flag that indicates the place for the current + * macroblock inside the macroblock row: + * -1 beginning of row + * 0 middle of row + * 1 end of row + * fourMVs 1 if Advanced Prediction Mode is used, otherwise 0 + * prevDiffBlock if fourMVs == 1 and mbPlace <= 0 the difference + * block is stored to prevDiffBlock for later use + * + * Function: + * This function sums the given block into block being currently decoded in + * present frame. Parameters are the table consisting a block, a pointer to + * the frame at the correct place and the width of the frame. + * + * Returns: + * Nothing. + * + */ + +void blcAddBlock(int *block, u_char *dstBlk, int xSize, + int mbPlace, u_char fourMVs, int *prevDiffBlock) +/* {{-output"blcAddBlock.txt"}} */ +{ + int i; + + if (fourMVs && mbPlace <= 0) { + MEMCPY(prevDiffBlock, block, 64 * sizeof(int)); + } + else { + for(i = 8; i; i--) { + *dstBlk++ = clippingTable[*dstBlk + *block++]; + *dstBlk++ = clippingTable[*dstBlk + *block++]; + *dstBlk++ = clippingTable[*dstBlk + *block++]; + *dstBlk++ = clippingTable[*dstBlk + *block++]; + *dstBlk++ = clippingTable[*dstBlk + *block++]; + *dstBlk++ = clippingTable[*dstBlk + *block++]; + *dstBlk++ = clippingTable[*dstBlk + *block++]; + *dstBlk++ = clippingTable[*dstBlk + *block++]; + dstBlk += xSize - 8; + } + } +} + + +/* {{-output"blcBlockToFrame.txt"}} */ +/* + * blcBlockToFrame + * + * + * Parameters: + * block block array (of 64 pixels) + * dstBlk pointer to present frame in the place, where the block is + * written + * xSize X size of the frame. + * + * Function: + * This function writes the given block into block being currently decoded + * in present frame. Parameters are the table consisting a block, a pointer + * to the frame at the correct place and the width of the frame. + * + * Returns: + * Nothing. + * + */ + +void blcBlockToFrame(int *block, u_char *dstBlk, int xSize) +/* {{-output"blcBlockToFrame.txt"}} */ +{ + int i; + + for( i = 0; i < 8; i++ ) + { + *dstBlk = clippingTable[ *block ]; + *(dstBlk+1) = clippingTable[ *(block+1) ]; + *(dstBlk+2) = clippingTable[ *(block+2) ]; + *(dstBlk+3) = clippingTable[ *(block+3) ]; + *(dstBlk+4) = clippingTable[ *(block+4) ]; + *(dstBlk+5) = clippingTable[ *(block+5) ]; + *(dstBlk+6) = clippingTable[ *(block+6) ]; + *(dstBlk+7) = clippingTable[ *(block+7) ]; + dstBlk += xSize; + block += 8; + } +} + + +/* {{-output"blcCopyPredictionMB.txt"}} */ +/* + * blcCopyPredictionMB + * + * + * Parameters: + * param input and output parameters + * + * Function: + * This function copies one macroblock from previous frame into present + * frame at the location of macroblock being currently decoded. + * The location where the macroblock is read is the location of + * the current block changed with motion vectors. + * + * Returns: + * >= 0 the function was successful + * < 0 an error occured + * + */ + +int blcCopyPredictionMB(blcCopyPredictionMBParam_t *param) +/* {{-output"blcCopyPredictionMB.txt"}} */ +{ + int + uvWidth = param->uvWidth, + uvHeight = param->uvHeight, + yWidth = uvWidth * 2, + yHeight = uvHeight * 2, + uvDstX = param->uvBlkXCoord, + uvDstY = param->uvBlkYCoord, + yDstX = uvDstX * 2, + yDstY = uvDstY * 2, + *mvx = param->mvx, + *mvy = param->mvy, + status; + + u_char + *dstYBlk = param->currYMBInFrame, + *dstUBlk = param->currUBlkInFrame, + *dstVBlk = param->currVBlkInFrame, + *srcYFrame = param->refY, + *srcUFrame = param->refU, + *srcVFrame = param->refV; + + blcCopyBlock_t copyBlock = (param->fMVsOverPictureBoundaries) ? + blcCopyBlockBC : blcCopyBlockNBC; + + blcAssert(param != NULL); + blcAssert(param->rcontrol == 0 || param->rcontrol == 1); + + /* Copy UV prediction blocks */ + status = blcCopyUVPredictionBlocks( + (param->fourMVs) ? + blcUVCountRefXY4MVs : blcUVCountRefXY1MV, + copyBlock, + mvx, mvy, + dstUBlk, dstVBlk, + srcUFrame, srcVFrame, + uvDstX, uvDstY, + uvWidth, + uvWidth, uvHeight, + param->fMVsOverPictureBoundaries, + param->rcontrol); + + if (status < 0) + return status; + + /* If Advanced Prediction is in use */ + if (param->fAdvancedPrediction) { + + // not supported + + } + + /* Else normal prediction mode is in use */ + else { + + /* Copy Y prediction MB */ + if(param->fourMVs) + status = blcCopyNormalYPredictionMBWith4MVs( + copyBlock, + mvx, mvy, + dstYBlk, + srcYFrame, + yDstX, yDstY, + yWidth, + yWidth, yHeight, + param->fMVsOverPictureBoundaries, + param->rcontrol); + else + status = blcCopyNormalYPredictionMBWith1MV( + copyBlock, + mvx, mvy, + dstYBlk, + srcYFrame, + yDstX, yDstY, + yWidth, + yWidth, yHeight, + param->fMVsOverPictureBoundaries, + param->rcontrol); + if (status < 0) + return status; + } + + return 0; +} + + + + + +/* + * Local functions + */ + + + + + +/* + * blcCopyNormalYPredictionMBWith1MV + * + * + * Parameters: + * copyBlock a pointer to either blcCopyBlockBC or + * blcCopyBlockNBC (or their Assembler versions) + * + * mvxArray an array of four for x component of MVs + * mvyArray an array of four for y component of MVs + * (Only the first entry of the array is used.) + * + * dstYBlk a pointer to the current Y macroblock + * in the destination Y frame + * + * srcYFrame the top-left corner of the source Y frame + * + * dstYXPos the x coordinate of dstYBlk (in pixels) + * dstYYPos the y coordinate of dstYBlk (in pixels) + * + * dstYXSize the width of the Y destination frame + * srcYXSize the width of the Y source frame + * srcYYSize the height of the Y source frame + * + * fMVsOverPictureBoundaries non-zero if motion vectors may point outside + * picture boundaries, zero otherwise + * + * rcontrol RCONTROL (section 6.1.2 of the H.263 standard) + * + * Function: + * This function copies a luminance prediction macroblock from the given + * source frame to the given position of the destination frame. + * The prediction macroblock is associated with one motion vector. + * + * Returns: + * >= 0 if everything is ok + * < 0 if an error occured + * + */ + +static int blcCopyNormalYPredictionMBWith1MV( + blcCopyBlock_t copyBlock, + int *mvxArray, int *mvyArray, + u_char *dstYBlk, + u_char *srcYFrame, + int dstYXPos, int dstYYPos, + int dstYXSize, + int srcYXSize, int srcYYSize, + int fMVsOverPictureBoundaries, + int rcontrol) +{ + int + mvxVal = *mvxArray, mvyVal = *mvyArray, + subpixelX, subpixelY, + xlt0, xNormal, xgtmax, + ylt0, yNormal, ygtmax, + srcXPos, srcYPos; + u_char *srcBlk; + + blcYCountRefXY(mvxVal, mvyVal, dstYXPos, dstYYPos, &srcXPos, &srcYPos, + &subpixelX, &subpixelY); + + if (fMVsOverPictureBoundaries) + blcHandleRefOverPictBoundariesBC( + 16, 16, + srcYXSize, srcYYSize, + subpixelX, subpixelY, + &srcXPos, &srcYPos, + &xlt0, &xNormal, &xgtmax, + &ylt0, &yNormal, &ygtmax); + + else { + if (blcIsRefOverPictBoundaries( + 16, 16, + srcYXSize, srcYYSize, + subpixelX, subpixelY, + srcXPos, srcYPos)) + return -1; + xlt0 = xgtmax = ylt0 = ygtmax = 0; + xNormal = yNormal = 16; + } + + srcBlk = srcYFrame + srcYPos * srcYXSize + srcXPos; + + copyBlock(srcBlk, dstYBlk, xlt0, xNormal, xgtmax, + ylt0, yNormal, ygtmax, subpixelX, subpixelY, + srcYXSize, dstYXSize, 16, 16, rcontrol); + + return 0; +} + + +/* + * blcCopyNormalYPredictionMBWith4MVs + * + * + * Parameters: + * See blcCopyNormalYPredictionMBWith1MV. + * All 4 entries of mvxArray and mvyArray are used. + * + * Function: + * This function copies a luminance prediction macroblock from the given + * source frame to the given position of the destination frame. + * The prediction macroblock is associated with four motion vectors. + * + * Returns: + * >= 0 if everything is ok + * < 0 if an error occured + * + */ + +static int blcCopyNormalYPredictionMBWith4MVs( + blcCopyBlock_t copyBlock, + int *mvxArray, int *mvyArray, + u_char *dstYBlk, + u_char *srcYFrame, + int dstYXPos, int dstYYPos, + int dstYXSize, + int srcYXSize, int srcYYSize, + int fMVsOverPictureBoundaries, + int rcontrol) +{ + int + nh, nv, + mvi = 0, + mvxVal, mvyVal, + subpixelX, subpixelY, + xlt0, xNormal, xgtmax, + ylt0, yNormal, ygtmax, + srcXPos, srcYPos; + + u_char + *srcBlk, + *origDest; + + origDest = dstYBlk; + for (nv = 0; nv <= 1; nv++, dstYYPos += 8, + origDest += (dstYXSize << 3) - 16, dstYXPos -= 16) { + for (nh = 0; nh <= 1; nh++, dstYXPos += 8, origDest += 8, mvi++) { + dstYBlk = origDest; + mvxVal = mvxArray[mvi]; + mvyVal = mvyArray[mvi]; + + blcYCountRefXY(mvxVal, mvyVal, dstYXPos, dstYYPos, &srcXPos, &srcYPos, + &subpixelX, &subpixelY); + + if (fMVsOverPictureBoundaries) + blcHandleRefOverPictBoundariesBC( + 8, 8, + srcYXSize, srcYYSize, + subpixelX, subpixelY, + &srcXPos, &srcYPos, + &xlt0, &xNormal, &xgtmax, + &ylt0, &yNormal, &ygtmax); + + else { + if (blcIsRefOverPictBoundaries( + 8, 8, + srcYXSize, srcYYSize, + subpixelX, subpixelY, + srcXPos, srcYPos)) + return -1; + xlt0 = xgtmax = ylt0 = ygtmax = 0; + xNormal = yNormal = 8; + } + + srcBlk = srcYFrame + srcYPos * srcYXSize + srcXPos; + + copyBlock(srcBlk, dstYBlk, xlt0, xNormal, xgtmax, + ylt0, yNormal, ygtmax, subpixelX, subpixelY, srcYXSize, + dstYXSize, 8, 8, rcontrol); + } + } + + return 0; +} + + + +/* + * blcCopyUVPredictionBlocks + * + * + * Parameters: + * uvCountSourceXY a pointer to either blcUVCountRefXY1MV or + * blcUVCountRefXY4MVs + * + * copyBlock a pointer to either blcCopyBlockBC or + * blcCopyBlockNBC (or their Assembler versions) + * + * mvxArray an array of four for x component of MVs + * mvyArray an array of four for y component of MVs + * + * dstUBlk a pointer to the current U block + * in the destination U frame + * dstVBlk a pointer to the current V block + * in the destination V frame + * + * srcUFrame the top-left corner of the source U frame + * srcVFrame the top-left corner of the source V frame + * + * dstUVXPos the x coordinate of dstUBlk + * dstUVYPos the y coordinate of dstUBlk + * + * dstUVXSize the width of the U and V destination frame + * srcUVXSize the width of the U and V source frame + * srcUVYSize the height of the U and V source frame + * + * fMVsOverPictureBoundaries non-zero if motion vectors may point outside + * picture boundaries, zero otherwise + * + * rcontrol RCONTROL (section 6.1.2 of the H.263 standard) + * + * Function: + * This function copies chrominance prediction blocks from the given + * source frames to the given positions of the destination frames. + * + * Returns: + * >= 0 if everything is ok + * < 0 if an error occured + * + */ + +static int blcCopyUVPredictionBlocks( + blcUVCountRefXY_t uvCountSourceXY, + blcCopyBlock_t copyBlock, + int *mvxArray, int *mvyArray, + u_char *dstUBlk, u_char *dstVBlk, + u_char *srcUFrame, u_char *srcVFrame, + int dstUVXPos, int dstUVYPos, + int dstUVXSize, + int srcUVXSize, int srcUVYSize, + int fMVsOverPictureBoundaries, + int rcontrol) +{ + int + srcXPos, + srcYPos, + subpixelX, + subpixelY, + xlt0, + xNormal, + xgtmax, + ylt0, + yNormal, + ygtmax; + + u_char *srcBlk; + + uvCountSourceXY(dstUVXPos, dstUVYPos, mvxArray, mvyArray, + &srcXPos, &srcYPos, &subpixelX, &subpixelY); + + if (fMVsOverPictureBoundaries) + blcHandleRefOverPictBoundariesBC( + 8, 8, + srcUVXSize, srcUVYSize, + subpixelX, subpixelY, + &srcXPos, &srcYPos, + &xlt0, &xNormal, &xgtmax, + &ylt0, &yNormal, &ygtmax); + + else { + if (blcIsRefOverPictBoundaries( + 8, 8, + srcUVXSize, srcUVYSize, + subpixelX, subpixelY, + srcXPos, srcYPos)) + return -1; + xlt0 = xgtmax = ylt0 = ygtmax = 0; + xNormal = yNormal = 8; + } + + /* U block */ \ + srcBlk = srcUFrame + srcYPos * srcUVXSize + srcXPos; + + /*deb0p("Copy U block\n"); + deb1p("srcBlk %x\n", srcBlk); + deb1p("dstUBlk %x\n", dstUBlk); + deb1p("xlt0 %d\n", xlt0); + deb1p("xNormal %d\n", xNormal); + deb1p("xgtmax %d\n", xgtmax); + deb1p("ylt0 %d\n", ylt0); + deb1p("yNormal %d\n", yNormal); + deb1p("ygtmax %d\n", ygtmax); + deb1p("subpixelX %d\n", subpixelX); + deb1p("subpixelY %d\n", subpixelY); + deb1p("srcUVXSize %d\n", srcUVXSize); + deb1p("dstUVXSize %d\n", dstUVXSize); + deb1p("rcontrol %d\n", rcontrol);*/ + + copyBlock(srcBlk, dstUBlk, xlt0, xNormal, xgtmax, + ylt0, yNormal, ygtmax, subpixelX, subpixelY, + srcUVXSize, dstUVXSize, 8, 8, rcontrol); + + /* V block */ \ + srcBlk = srcVFrame + srcYPos * srcUVXSize + srcXPos; + + copyBlock(srcBlk, dstVBlk, xlt0, xNormal, xgtmax, + ylt0, yNormal, ygtmax, subpixelX, subpixelY, + srcUVXSize, dstUVXSize, 8, 8, rcontrol); + + return 0; +} + + +/* + * blcHandleRefOverPictBoundariesBC + * + * + * Input parameters: + * xBlkSize the width of the block to copy + * yBlkSize the height of the block to copy + * xSize the width of the frame + * ySize the height of the frame + * + * subpixelX 1 if half pixel position is used in X direction + * subpixelY 1 if half pixel position is used in Y direction + * + * Input/output parameters: + * sourceX input: the absolute position of the source + * sourceY block (may be negative, half-pixel values are + * truncated to the next smaller integer) + * output: the coordinates of the first valid + * pixel in the source block + * + * Output parameters: + * The next parameters describe a row of source pixels. + * xlt0 the number of the source pixels in the left of + * the image area + * xNormal the number of the source pixels within + * the image area + * xgtmax the number of the source pixels in the right of + * the image area + * + * The next parameters describe a column of source pixels. + * ylt0 the number of the source pixels above + * the image area + * yNormal the number of the source pixels withing + * the image area + * ygtmax the number of the source pixels below + * the image area + * + * Function: + * This function counts how many pixels are outside the picture area + * and the coordinates of the first valid pixel in the source block. + * + * Returns: + * See output parameters. + * + */ + +static void blcHandleRefOverPictBoundariesBC( + int xBlkSize, int yBlkSize, + int xSize, int ySize, + int subpixelX, int subpixelY, + int *sourceX, int *sourceY, + int *xlt0, int *xNormal, int *xgtmax, + int *ylt0, int *yNormal, int *ygtmax) +{ + int + xSizeMinus = xSize - xBlkSize, + ySizeMinus = ySize - yBlkSize; + + if (*sourceX < 0) { + *xlt0 = (-(*sourceX) < xBlkSize) ? -(*sourceX) : xBlkSize; + *sourceX = 0; + } + else *xlt0 = 0; + + if (*sourceY < 0) { + *ylt0 = (-(*sourceY) < yBlkSize) ? -(*sourceY) : yBlkSize; + *sourceY = 0; + } + else *ylt0 = 0; + + if (*sourceX + subpixelX > xSizeMinus) { + if (*sourceX + subpixelX < xSize) + *xgtmax = *sourceX + subpixelX - xSizeMinus; + else { + *xgtmax = xBlkSize; + *sourceX = xSize - 1; + } + } + else *xgtmax = 0; + + if (*sourceY + subpixelY > ySizeMinus) { + if (*sourceY + subpixelY < ySize) + *ygtmax = *sourceY + subpixelY - ySizeMinus; + else { + *ygtmax = yBlkSize; + *sourceY = ySize - 1; + } + } + else *ygtmax = 0; + + *xNormal = xBlkSize - *xgtmax - *xlt0; + *yNormal = yBlkSize - *ygtmax - *ylt0; +} + + +/* + * blcIsRefOverPictBoundaries + * + * + * Input parameters: + * xBlkSize the width of the block to copy + * yBlkSize the height of the block to copy + * xSize the width of the frame + * ySize the height of the frame + * + * subpixelX 1 if half pixel position is used in X direction + * subpixelY 1 if half pixel position is used in Y direction + * + * sourceX the absolute position of the source + * sourceY block (may be negative, half-pixel values are + * truncated to the next smaller integer) + * + * Function: + * This function checks if the reference (source, prediction) block + * is (partly) outside the picture area. + * + * Returns: + * 1 if the reference block is (partly) outside the picture area + * 0 if the whole reference block is inside the picture area + * + */ + +static int blcIsRefOverPictBoundaries( + int xBlkSize, int yBlkSize, + int xSize, int ySize, + int subpixelX, int subpixelY, + int sourceX, int sourceY) +{ + if (sourceX < 0) + return 1; + + if (sourceY < 0) + return 1; + + if (sourceX + subpixelX > xSize - xBlkSize) + return 1; + + if (sourceY + subpixelY > ySize - yBlkSize) + return 1; + + return 0; +} + + + +/* + * blcUVCountMVOffset4MVs + * + * + * Input parameters: + * mvxArray an array of the four horizontal components of + * the motion vectors for a particular macroblock + * mvyArray an array of the four vertical components of + * the motion vectors for a particular macroblock + * + * Output parameters: + * offsetX the relative position of the source + * offsetY block (the origo is the destination block, + * half-pixel values are truncated to the next + * smaller integer) + * + * subpixelX 1 if half pixel position is used in X direction + * subpixelY 1 if half pixel position is used in Y direction + * + * Function: + * This function counts the relative position of the chrominance source block + * when it is given the motion vectors for the destination block. The macro + * uses interpolation of four motion vectors described in Annex F of H.263 + * Recommendation. + * + * Returns: + * See output parameters. + * + * + * + */ + +static void blcUVCountMVOffset4MVs( + int *mvxArray, int *mvyArray, + int *offsetX, int *offsetY, + int *subpixelX, int *subpixelY) +{ + /* These arrays define the table 16 in H.263 recommendation which is used + for interpolating chrominance motion vectors when four motion vectors + per macroblock is used. */ + static const int + halfPixelOrig16[31] = + {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + * const halfPixel16 = &halfPixelOrig16[15], + fullPixelOrig16[31] = + {-1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1}, + * const fullPixel16 = &fullPixelOrig16[15]; + + int mvSum, pixelPos; + + mvSum = mvxArray[0] + mvxArray[1] + mvxArray[2] + mvxArray[3]; + pixelPos = (mvSum % 80) / 5; + *subpixelX = halfPixel16[pixelPos]; + *offsetX = (mvSum / 80) + fullPixel16[pixelPos]; + if (mvSum < 0 && *subpixelX) + (*offsetX)--; + + mvSum = mvyArray[0] + mvyArray[1] + mvyArray[2] + mvyArray[3]; + pixelPos = (mvSum % 80) / 5; + *subpixelY = halfPixel16[pixelPos]; + *offsetY = (mvSum / 80) + fullPixel16[pixelPos]; + if (mvSum < 0 && *subpixelY) + (*offsetY)--; +} + + +/* + * blcUVCountRefXY1MV + * blcUVCountRefXY4MVs + * + * + * Input parameters: + * origoX the coordinates of the destination block + * origoY + * + * mvxArray an array of the four horizontal components of + * the motion vectors for a particular macroblock + * mvyArray an array of the four vertical components of + * the motion vectors for a particular macroblock + * In blcUVCountRefXY1MV, only the first entry of + * the array is used. + * + * Output parameters: + * sourceX the absolute position of the source + * sourceY block (may be negative, half-pixel values are + * truncated to the next smaller integer) + * + * subpixelX 1 if half pixel position is used in X direction + * subpixelY 1 if half pixel position is used in Y direction + * + * Function: + * These macros count the absolute position of the chrominance source block + * (and sets sourceX, sourceY, subpixelX and subpixelY according to it) + * when it is given the position of the destination block and + * the motion vectors for the destination block. blcUVCountRefXY4MVs + * uses interpolation of four motion vectors described in Annex F of H.263 + * Recommendation. blcUVCountRefXY1MV uses only the first motion vector + * of the array as described in chapter 6.1.1 of H.263 Recommendation. + * + * Returns: + * See output parameters. + * + * + * + */ + +static void blcUVCountRefXY1MV( + int origoX, int origoY, + int *mvxArray, int *mvyArray, + int *sourceX, int *sourceY, + int *subpixelX, int *subpixelY) +{ + int mvxVal = *mvxArray, mvyVal = *mvyArray; + + *sourceX = origoX + mvxVal / 20; + *sourceY = origoY + mvyVal / 20; + + *subpixelX = (mvxVal % 20) != 0; + *subpixelY = (mvyVal % 20) != 0; + + if (mvxVal < 0 && *subpixelX) + *sourceX -= 1; + if (mvyVal < 0 && *subpixelY) + *sourceY -= 1; +} + + +static void blcUVCountRefXY4MVs( + int origoX, int origoY, + int *mvxArray, int *mvyArray, + int *sourceX, int *sourceY, + int *subpixelX, int *subpixelY) +{ + int offX, offY; + + blcUVCountMVOffset4MVs(mvxArray, mvyArray, &offX, &offY, subpixelX, subpixelY); + *sourceX = origoX + offX; + *sourceY = origoY + offY; +} + + +/* + * blcYCountRefXY + * + * + * Input parameters: + * mvxVal motion vector components for the block + * mvyVal + * + * destX the coordinates of the destination block + * destY + * + * Output parameters: + * sourceX the absolute position of the source + * sourceY block (may be negative, half-pixel values are + * truncated to the next smaller integer) + * + * subpixelX 1 if half pixel position is used in X direction + * subpixelY 1 if half pixel position is used in Y direction + * + * Function: + * This function counts the absolute position of the luminance source block (and + * sets sourceX, sourceY, subpixelX and subpixelY according to it) when it is + * given the position of the destination block and a motion vector pointing + * to the source block. + * + * Returns: + * See output parameters. + * + * + * + */ + +static void blcYCountRefXY( + int mvxVal, int mvyVal, + int destX, int destY, + int *sourceX, int *sourceY, + int *subpixelX, int *subpixelY) +{ + *sourceX = destX + mvxVal / 10; + *sourceY = destY + mvyVal / 10; + + *subpixelX = mvxVal & 1; + *subpixelY = mvyVal & 1; + + if (mvxVal < 0 && *subpixelX) + *sourceX -= 1; + if (mvyVal < 0 && *subpixelY) + *sourceY -= 1; +} +// End of File