/*
* 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