Archived
1
0
This repository has been archived on 2024-10-17. You can view files and clone it, but cannot push or open issues or pull requests.
winamp/Src/h264dec/ldecod/src/mb_access.c
2024-09-24 14:54:57 +02:00

3389 lines
68 KiB
C

/*!
*************************************************************************************
* \file mb_access.c
*
* \brief
* Functions for macroblock neighborhoods
*
* \author
* Main contributors (see contributors.h for copyright, address and affiliation details)
* - Karsten Sühring <suehring@hhi.de>
*************************************************************************************
*/
#include "global.h"
#include "mbuffer.h"
#include "mb_access.h"
/*!
************************************************************************
* \brief
* returns 1 if the macroblock at the given address is available
************************************************************************
*/
Boolean mb_is_available(int mbAddr, const Macroblock *currMB)
{
VideoParameters *p_Vid = currMB->p_Vid;
if ((mbAddr < 0) || (mbAddr > ((int)p_Vid->dec_picture->PicSizeInMbs - 1)))
return FALSE;
// the following line checks both: slice number and if the mb has been decoded
if (!p_Vid->DeblockCall)
{
if (p_Vid->mb_data[mbAddr].slice_nr != currMB->slice_nr)
return FALSE;
}
return TRUE;
}
/*!
************************************************************************
* \brief
* Checks the availability of neighboring macroblocks of
* the current macroblock for prediction and context determination;
************************************************************************
*/
void CheckAvailabilityOfNeighbors(Macroblock *currMB)
{
VideoParameters *p_Vid = currMB->p_Vid;
const int mb_nr = currMB->mbAddrX;
// mark all neighbors as unavailable
currMB->mb_up = NULL;
currMB->mb_left = NULL;
if (p_Vid->dec_picture->mb_aff_frame_flag)
{
int cur_mb_pair = mb_nr >> 1;
currMB->mb_addr_left = 2 * (cur_mb_pair - 1);
currMB->mb_addr_up = 2 * (cur_mb_pair - p_Vid->dec_picture->PicWidthInMbs);
currMB->mb_addr_upper_right = 2 * (cur_mb_pair - p_Vid->dec_picture->PicWidthInMbs + 1);
currMB->mb_addr_upper_left = 2 * (cur_mb_pair - p_Vid->dec_picture->PicWidthInMbs - 1);
currMB->mb_avail_left = (Boolean) (mb_is_available(currMB->mb_addr_left, currMB) && ((p_Vid->PicPos[cur_mb_pair ][0])!=0));
currMB->mb_avail_up = (Boolean) (mb_is_available(currMB->mb_addr_up, currMB));
currMB->mb_avail_upper_right = (Boolean) (mb_is_available(currMB->mb_addr_upper_right, currMB) && ((p_Vid->PicPos[cur_mb_pair + 1][0])!=0));
currMB->mb_avail_upper_left = (Boolean) (mb_is_available(currMB->mb_addr_upper_left, currMB) && ((p_Vid->PicPos[cur_mb_pair ][0])!=0));
}
else
{
currMB->mb_addr_left = mb_nr - 1; // left?
currMB->mb_addr_up = mb_nr - p_Vid->dec_picture->PicWidthInMbs; // up?
currMB->mb_addr_upper_right = mb_nr - p_Vid->dec_picture->PicWidthInMbs + 1; // upper right?
currMB->mb_addr_upper_left = mb_nr - p_Vid->dec_picture->PicWidthInMbs - 1; // upper left?
currMB->mb_avail_left = (Boolean) (mb_is_available(currMB->mb_addr_left, currMB) && ((p_Vid->PicPos[mb_nr ][0])!=0));
currMB->mb_avail_up = (Boolean) (mb_is_available(currMB->mb_addr_up, currMB));
currMB->mb_avail_upper_right = (Boolean) (mb_is_available(currMB->mb_addr_upper_right, currMB) && ((p_Vid->PicPos[mb_nr + 1][0])!=0));
currMB->mb_avail_upper_left = (Boolean) (mb_is_available(currMB->mb_addr_upper_left, currMB) && ((p_Vid->PicPos[mb_nr ][0])!=0));
}
if (currMB->mb_avail_left) currMB->mb_left = &(p_Vid->mb_data[currMB->mb_addr_left]);
if (currMB->mb_avail_up) currMB->mb_up = &(p_Vid->mb_data[currMB->mb_addr_up]);
}
/*!
************************************************************************
* \brief
* returns the x and y macroblock coordinates for a given MbAddress
************************************************************************
*/
void get_mb_block_pos_normal (const h264_pic_position *PicPos, int mb_addr, short *x, short *y)
{
*x = (short) PicPos[ mb_addr ][0];
*y = (short) PicPos[ mb_addr ][1];
}
/*!
************************************************************************
* \brief
* returns the x and y macroblock coordinates for a given MbAddress
* for mbaff type slices
************************************************************************
*/
void get_mb_block_pos_mbaff (const h264_pic_position *PicPos, int mb_addr, short *x, short *y)
{
*x = (short) PicPos[mb_addr>>1][0];
*y = (short) ((PicPos[mb_addr>>1][1] << 1) + (mb_addr & 0x01));
}
/*!
************************************************************************
* \brief
* returns the x and y sample coordinates for a given MbAddress
************************************************************************
*/
void get_mb_pos (VideoParameters *p_Vid, int mb_addr, const int mb_size[2], short *x, short *y)
{
p_Vid->get_mb_block_pos(p_Vid->PicPos, mb_addr, x, y);
(*x) = (short) ((*x) * mb_size[0]);
(*y) = (short) ((*y) * mb_size[1]);
}
/*!
************************************************************************
* \brief
* get neighbouring positions for non-aff coding
* \param currMB
* current macroblock
* \param xN
* input x position
* \param yN
* input y position
* \param mb_size
* Macroblock size in pixel (according to luma or chroma MB access)
* \param pix
* returns position informations
************************************************************************
*/
void getNonAffNeighbour(const Macroblock *currMB, int xN, int yN, const int mb_size[2], PixelPos *pix)
{
VideoParameters *p_Vid = currMB->p_Vid;
int maxW = mb_size[0], maxH = mb_size[1];
if (xN < 0)
{
if (yN < 0)
{
pix->mb_addr = currMB->mb_addr_upper_left;
pix->available = currMB->mb_avail_upper_left;
}
else if (yN < maxH)
{
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
}
else
{
pix->available = FALSE;
}
}
else if (xN < maxW)
{
if (yN<0)
{
pix->mb_addr = currMB->mb_addr_up;
pix->available = currMB->mb_avail_up;
}
else if (yN < maxH)
{
pix->mb_addr = currMB->mbAddrX;
pix->available = TRUE;
}
else
{
pix->available = FALSE;
}
}
else if (yN < 0)
{
pix->mb_addr = currMB->mb_addr_upper_right;
pix->available = currMB->mb_avail_upper_right;
}
else
{
pix->available = FALSE;
}
if (pix->available || p_Vid->DeblockCall && pix->mb_addr)
{
const int *CurPos = &p_Vid->PicPos[ pix->mb_addr ][0];
pix->x = (short) (xN & (maxW - 1));
pix->pos_x = (short) (pix->x + *(CurPos++) * maxW);
pix->y = (short) (yN & (maxH - 1));
pix->pos_y = (short) (pix->y + *CurPos * maxH);
}
}
void getNonAffNeighbourXP_NoPos(const Macroblock *currMB, int xN, int yN, const int mb_size[2], PixelPos *pix)
{
VideoParameters *p_Vid = currMB->p_Vid;
int maxW = mb_size[0], maxH = mb_size[1];
if (xN < 0)
{
if (yN < maxH)
{
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
}
else
{
pix->available = FALSE;
}
}
else if (xN < maxW)
{
if (yN < maxH)
{
pix->mb_addr = currMB->mbAddrX;
pix->available = TRUE;
}
else
{
pix->available = FALSE;
}
}
else
{
pix->available = FALSE;
}
if (pix->available)
{
const int *CurPos = &p_Vid->PicPos[ pix->mb_addr ][0];
pix->x = (short) (xN & (maxW - 1));
pix->y = (short) (yN & (maxH - 1));
}
}
void getNonAffNeighbourPX_NoPos(const Macroblock *currMB, int xN, int yN, const int mb_size[2], PixelPos *pix)
{
VideoParameters *p_Vid = currMB->p_Vid;
int maxW = mb_size[0], maxH = mb_size[1];
if (xN < maxW)
{
if (yN<0)
{
pix->mb_addr = currMB->mb_addr_up;
pix->available = currMB->mb_avail_up;
}
else if (yN < maxH)
{
pix->mb_addr = currMB->mbAddrX;
pix->available = TRUE;
}
else
{
pix->available = FALSE;
}
}
else if (yN < 0)
{
pix->mb_addr = currMB->mb_addr_upper_right;
pix->available = currMB->mb_avail_upper_right;
}
else
{
pix->available = FALSE;
}
if (pix->available)
{
const int *CurPos = &p_Vid->PicPos[ pix->mb_addr ][0];
pix->x = (short) (xN & (maxW - 1));
pix->y = (short) (yN & (maxH - 1));
}
}
void getNonAffNeighbourLuma(const Macroblock *currMB, int xN, int yN, PixelPos *pix)
{
VideoParameters *p_Vid = currMB->p_Vid;
if (xN < 0)
{
if (yN < 0)
{
pix->mb_addr = currMB->mb_addr_upper_left;
pix->available = currMB->mb_avail_upper_left;
}
else if (yN < 16)
{
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
}
else
{
pix->available = FALSE;
}
}
else if (xN < 16)
{
if (yN<0)
{
pix->mb_addr = currMB->mb_addr_up;
pix->available = currMB->mb_avail_up;
}
else if (yN < 16)
{
pix->mb_addr = currMB->mbAddrX;
pix->available = TRUE;
}
else
{
pix->available = FALSE;
}
}
else if (yN < 0)
{
pix->mb_addr = currMB->mb_addr_upper_right;
pix->available = currMB->mb_avail_upper_right;
}
else
{
pix->available = FALSE;
}
if (pix->available || p_Vid->DeblockCall && pix->mb_addr)
{
const int *CurPos = &p_Vid->PicPos[ pix->mb_addr ][0];
pix->x = (short) (xN & 15);
pix->pos_x = (short) (pix->x + *(CurPos++) * 16);
pix->y = (short) (yN & 15);
pix->pos_y = (short) (pix->y + *CurPos * 16);
}
}
void getNonAffNeighbourXPLuma(const Macroblock *currMB, int xN, int yN, PixelPos *pix) // yN >= 0
{
VideoParameters *p_Vid = currMB->p_Vid;
if (xN < 0)
{
if (yN < 16)
{
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
}
else
{
pix->available = FALSE;
}
}
else if (xN < 16)
{
if (yN < 16)
{
pix->mb_addr = currMB->mbAddrX;
pix->available = TRUE;
}
else
{
pix->available = FALSE;
}
}
else
{
pix->available = FALSE;
}
if (pix->available || p_Vid->DeblockCall && pix->mb_addr)
{
const int *CurPos = &p_Vid->PicPos[ pix->mb_addr ][0];
pix->x = (short) (xN & 15);
pix->pos_x = (short) (pix->x + *(CurPos++) * 16);
pix->y = (short) (yN & 15);
pix->pos_y = (short) (pix->y + *CurPos * 16);
}
}
void getNonAffNeighbourXPLumaNB(const Macroblock *currMB, int xN, int yN, PixelPos *pix) // yN >= 0
{
VideoParameters *p_Vid = currMB->p_Vid;
assert(!p_Vid->DeblockCall);
if (xN < 0)
{
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
}
else
{
pix->mb_addr = currMB->mbAddrX;
pix->available = TRUE;
}
if (pix->available)
{
const int *CurPos = &p_Vid->PicPos[ pix->mb_addr ][0];
pix->pos_x = (short) ((xN & 15) + *(CurPos++) * 16);
pix->pos_y = (short) (yN + *CurPos * 16);
}
}
void getNonAffNeighbourPPLumaNB(const Macroblock *currMB, int xN, int yN, PixelPos *pix) // yN >= 0, xN >= 0
{
VideoParameters *p_Vid = currMB->p_Vid;
assert(!p_Vid->DeblockCall);
pix->mb_addr = currMB->mbAddrX;
pix->available = TRUE;
{
const int *CurPos = &p_Vid->PicPos[ pix->mb_addr ][0];
pix->pos_x = (short) ((xN & 15) + *(CurPos++) * 16);
pix->pos_y = (short) (yN + *CurPos * 16);
}
}
void getNonAffNeighbourXPLumaNB_NoPos(const Macroblock *currMB, int xN, int yN, PixelPos *pix) // yN >= 0
{
assert(!currMB->p_Vid->DeblockCall);
if (xN < 0)
{
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
}
else
{
pix->mb_addr = currMB->mbAddrX;
pix->available = TRUE;
}
if (pix->available)
{
pix->x = (short) (xN & 15);
pix->y = (short) (yN);
}
}
void getNonAffNeighbourNPLumaNB(const Macroblock *currMB, int yN, PixelPos *pix) // xN = -1, yN >= 0 && yN < 16
{
VideoParameters *p_Vid = currMB->p_Vid;
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (pix->available || p_Vid->DeblockCall && pix->mb_addr)
{
const int *CurPos = &p_Vid->PicPos[ pix->mb_addr ][0];
//pix->x = (short) (-1 & 15);
pix->pos_x = (short) ((-1 & 15) + *(CurPos++) * 16);
pix->y = (short) (yN);
pix->pos_y = (short) (yN + *CurPos * 16);
}
}
void getNonAffNeighbourPXLuma(const Macroblock *currMB, int xN, int yN, PixelPos *pix) // xN is >= 0
{
VideoParameters *p_Vid = currMB->p_Vid;
if (xN < 16)
{
if (yN<0)
{
pix->mb_addr = currMB->mb_addr_up;
pix->available = currMB->mb_avail_up;
}
else if (yN < 16)
{
pix->mb_addr = currMB->mbAddrX;
pix->available = TRUE;
}
else
{
pix->available = FALSE;
}
}
else if (yN < 0)
{
pix->mb_addr = currMB->mb_addr_upper_right;
pix->available = currMB->mb_avail_upper_right;
}
else
{
pix->available = FALSE;
}
if (pix->available || p_Vid->DeblockCall && pix->mb_addr)
{
const int *CurPos = &p_Vid->PicPos[ pix->mb_addr ][0];
pix->x = (short) (xN & 15);
pix->pos_x = (short) (pix->x + *(CurPos++) * 16);
pix->y = (short) (yN & 15);
pix->pos_y = (short) (pix->y + *CurPos * 16);
}
}
void getNonAffNeighbourPXLumaNB(const Macroblock *currMB, int xN, int yN, PixelPos *pix) // xN is >= 0
{
VideoParameters *p_Vid = currMB->p_Vid;
assert(!p_Vid->DeblockCall);
if (yN<0)
{
pix->mb_addr = currMB->mb_addr_up;
pix->available = currMB->mb_avail_up;
}
else
{
pix->mb_addr = currMB->mbAddrX;
pix->available = TRUE;
}
if (pix->available)
{
const int *CurPos = &p_Vid->PicPos[ pix->mb_addr ][0];
pix->pos_x = (short) (xN + *(CurPos++) * 16);
pix->pos_y = (short) ((yN & 15) + *CurPos * 16);
}
}
void getNonAffNeighbourPXLumaNB_NoPos(const Macroblock *currMB, int yN, PixelPos *pix) // xN is >= 0
{
assert(!currMB->p_Vid->DeblockCall);
if (yN<0)
{
pix->mb_addr = currMB->mb_addr_up;
pix->available = currMB->mb_avail_up;
}
else
{
pix->mb_addr = currMB->mbAddrX;
pix->available = TRUE;
}
if (pix->available)
{
pix->y = (short) (yN & 15);
}
}
void getNonAffNeighbourN0Luma(const Macroblock *currMB, PixelPos *pix) // xN = -1, yN = 0
{
VideoParameters *p_Vid = currMB->p_Vid;
assert(p_Vid->DeblockCall == 0);
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (pix->available)
{
const int *CurPos = &p_Vid->PicPos[ pix->mb_addr ][0];
pix->x = (short) (-1 & 15);
pix->pos_x = (short) (pix->x + *(CurPos++) * 16);
pix->y = 0;
pix->pos_y = (short) (*CurPos * 16);
}
}
void getNonAffNeighbourN0(const Macroblock *currMB, const int mb_size[2], PixelPos *pix) // xN = -1, yN = 0
{
VideoParameters *p_Vid = currMB->p_Vid;
int maxW = mb_size[0], maxH = mb_size[1];
assert(maxH != 0);
assert(p_Vid->DeblockCall == 0);
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (pix->available)
{
const int *CurPos = &p_Vid->PicPos[ pix->mb_addr ][0];
pix->x = (short) (-1 & (maxW - 1));
pix->pos_x = (short) (pix->x + *(CurPos++) * maxW);
pix->y = 0;
pix->pos_y = (short) (*CurPos * maxH);
}
}
void getNonAffNeighbour0N(const Macroblock *currMB, const int mb_size[2], PixelPos *pix) // xN = 0, yN = -1
{
VideoParameters *p_Vid = currMB->p_Vid;
int maxW = mb_size[0], maxH = mb_size[1];
assert(maxW != 0);
pix->mb_addr = currMB->mb_addr_up;
pix->available = currMB->mb_avail_up;
if (pix->available)
{
const int *CurPos = &p_Vid->PicPos[ pix->mb_addr ][0];
pix->x = 0;
pix->pos_x = (short) (*(CurPos++) * maxW);
pix->y = (short) (-1 & (maxH - 1));
pix->pos_y = (short) (pix->y + *CurPos * maxH);
}
}
void getNonAffNeighbour0NLuma(const Macroblock *currMB, PixelPos *pix) // xN = 0, yN = -1
{
VideoParameters *p_Vid = currMB->p_Vid;
pix->mb_addr = currMB->mb_addr_up;
pix->available = currMB->mb_avail_up;
if (pix->available)
{
const int *CurPos = &p_Vid->PicPos[ pix->mb_addr ][0];
pix->x = 0;
pix->pos_x = (short) (*(CurPos++) * 16);
pix->y = (short) (-1 & (16 - 1));
pix->pos_y = (short) (pix->y + *CurPos * 16);
}
}
void getNonAffNeighbourNX(const Macroblock *currMB, int yN, const int mb_size[2], PixelPos *pix) // xN = -1, yN full range
{
VideoParameters *p_Vid = currMB->p_Vid;
int maxW = mb_size[0], maxH = mb_size[1];
if (yN < 0)
{
pix->mb_addr = currMB->mb_addr_upper_left;
pix->available = currMB->mb_avail_upper_left;
}
else if (yN < maxH)
{
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
}
else
{
pix->available = FALSE;
}
if (pix->available || p_Vid->DeblockCall && pix->mb_addr)
{
const int *CurPos = &p_Vid->PicPos[ pix->mb_addr ][0];
pix->x = (short) (-1 & (maxW - 1));
pix->pos_x = (short) (pix->x + *(CurPos++) * maxW);
pix->y = (short) (yN & (maxH - 1));
pix->pos_y = (short) (pix->y + *CurPos * maxH);
}
}
void getNonAffNeighbourNXLuma(const Macroblock *currMB, int yN, PixelPos *pix) // xN = -1, yN full range
{
VideoParameters *p_Vid = currMB->p_Vid;
if (yN < 0)
{
pix->mb_addr = currMB->mb_addr_upper_left;
pix->available = currMB->mb_avail_upper_left;
}
else if (yN < 16)
{
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
}
else
{
pix->available = FALSE;
}
if (pix->available || p_Vid->DeblockCall && pix->mb_addr)
{
const int *CurPos = &p_Vid->PicPos[ pix->mb_addr ][0];
pix->x = (short) (-1 & (16 - 1));
pix->pos_x = (short) (pix->x + *(CurPos++) * 16);
pix->y = (short) (yN & (16 - 1));
pix->pos_y = (short) (pix->y + *CurPos * 16);
}
}
void getNonAffNeighbourNP(const Macroblock *currMB, int yN, const int mb_size[2], PixelPos *pix) // xN < 0, yN >= 0
{
VideoParameters *p_Vid = currMB->p_Vid;
int maxW = mb_size[0], maxH = mb_size[1];
if (yN < maxH)
{
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (pix->available)
{
const int *CurPos = &p_Vid->PicPos[ pix->mb_addr ][0];
pix->pos_x = (short) ((-1 & (maxW - 1)) + *(CurPos++) * maxW);
pix->pos_y = (short) (yN + *CurPos * maxH);
}
}
else
{
pix->available = FALSE;
}
}
void getNonAffNeighbourNPChromaNB(const Macroblock *currMB, int yN, const int mb_size[2], PixelPos *pix) // xN < 0, yN >= 0
{
VideoParameters *p_Vid = currMB->p_Vid;
int maxW = mb_size[0], maxH = mb_size[1];
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (pix->available)
{
const int *CurPos = &p_Vid->PicPos[ pix->mb_addr ][0];
pix->pos_x = (short) ((-1 & (maxW - 1)) + *(CurPos++) * maxW);
pix->pos_y = (short) (yN + *CurPos * maxH);
}
}
void getNonAffNeighbour0X(const Macroblock *currMB, int yN, const int mb_size[2], PixelPos *pix) // xN is guaranteed to be zero
{
VideoParameters *p_Vid = currMB->p_Vid;
int maxW = mb_size[0], maxH = mb_size[1];
if (0 < maxW)
{
if (yN<0)
{
pix->mb_addr = currMB->mb_addr_up;
pix->available = currMB->mb_avail_up;
}
else if (yN < maxH)
{
pix->mb_addr = currMB->mbAddrX;
pix->available = TRUE;
}
else
{
pix->available = FALSE;
}
}
else if (yN < 0)
{
pix->mb_addr = currMB->mb_addr_upper_right;
pix->available = currMB->mb_avail_upper_right;
}
else
{
pix->available = FALSE;
}
if (pix->available || p_Vid->DeblockCall && pix->mb_addr)
{
const int *CurPos = &p_Vid->PicPos[ pix->mb_addr ][0];
pix->x = 0;
pix->pos_x = (short) (*(CurPos++) * maxW);
pix->y = (short) (yN & (maxH - 1));
pix->pos_y = (short) (pix->y + *CurPos * maxH);
}
}
void getNonAffNeighbour0XLuma(const Macroblock *currMB, int yN, PixelPos *pix) // xN is guaranteed to be zero
{
VideoParameters *p_Vid = currMB->p_Vid;
int maxW = 16, maxH = 16;
if (yN<0)
{
pix->mb_addr = currMB->mb_addr_up;
pix->available = currMB->mb_avail_up;
}
else if (yN < 16)
{
pix->mb_addr = currMB->mbAddrX;
pix->available = TRUE;
}
else
{
pix->available = FALSE;
}
if (pix->available || p_Vid->DeblockCall && pix->mb_addr)
{
const int *CurPos = &p_Vid->PicPos[ pix->mb_addr ][0];
pix->x = 0;
pix->pos_x = (short) (*(CurPos++) * maxW);
pix->y = (short) (yN & (maxH - 1));
pix->pos_y = (short) (pix->y + *CurPos * maxH);
}
}
void getNonAffNeighbourX0(const Macroblock *currMB, int xN, const int mb_size[2], PixelPos *pix) // xN is full range, yN is 0
{
VideoParameters *p_Vid = currMB->p_Vid;
int maxW = mb_size[0], maxH = mb_size[1];
if (xN < 0)
{
if (0 < maxH)
{
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
}
else
{
pix->available = FALSE;
}
}
else if (xN < maxW)
{
if (0 < maxH)
{
pix->mb_addr = currMB->mbAddrX;
pix->available = TRUE;
}
else
{
pix->available = FALSE;
}
}
else
{
pix->available = FALSE;
}
if (pix->available || p_Vid->DeblockCall && pix->mb_addr && p_Vid)
{
const int *CurPos = &p_Vid->PicPos[ pix->mb_addr ][0];
pix->x = (short) (xN & (maxW - 1));
pix->pos_x = (short) (pix->x + *(CurPos++) * maxW);
pix->y = 0;
pix->pos_y = (short) (*CurPos * maxH);
}
}
/*!
************************************************************************
* \brief
* get neighboring positions for aff coding
* \param currMB
* current macroblock
* \param xN
* input x position
* \param yN
* input y position
* \param mb_size
* Macroblock size in pixel (according to luma or chroma MB access)
* \param pix
* returns position informations
************************************************************************
*/
void getAffNeighbour(const Macroblock *currMB, int xN, int yN, const int mb_size[2], PixelPos *pix)
{
VideoParameters *p_Vid = currMB->p_Vid;
int maxW, maxH;
int yM = -1;
maxW = mb_size[0];
maxH = mb_size[1];
// initialize to "not available"
pix->available = FALSE;
if(yN > (maxH - 1))
{
return;
}
if (xN > (maxW - 1) && yN >= 0 && yN < maxH)
{
return;
}
if (xN < 0)
{
if (yN < 0)
{
if(!currMB->mb_field)
{
// frame
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_upper_left + 1;
pix->available = currMB->mb_avail_upper_left;
yM = yN;
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
yM = yN;
}
else
{
(pix->mb_addr)++;
yM = (yN + maxH) >> 1;
}
}
}
}
else
{
// field
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_upper_left;
pix->available = currMB->mb_avail_upper_left;
if (currMB->mb_avail_upper_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_upper_left].mb_field)
{
(pix->mb_addr)++;
yM = 2 * yN;
}
else
{
yM = yN;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_upper_left+1;
pix->available = currMB->mb_avail_upper_left;
yM = yN;
}
}
}
else
{ // xN < 0 && yN >= 0
if (yN <maxH)
{
if (!currMB->mb_field)
{
// frame
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
yM = yN;
}
else
{
(pix->mb_addr)+= ((yN & 0x01) != 0);
yM = yN >> 1;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
(pix->mb_addr)++;
yM = yN;
}
else
{
(pix->mb_addr)+= ((yN & 0x01) != 0);
yM = (yN + maxH) >> 1;
}
}
}
}
else
{
// field
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
if (yN < (maxH >> 1))
{
yM = yN << 1;
}
else
{
(pix->mb_addr)++;
yM = (yN << 1 ) - maxH;
}
}
else
{
yM = yN;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
if (yN < (maxH >> 1))
{
yM = (yN << 1) + 1;
}
else
{
(pix->mb_addr)++;
yM = (yN << 1 ) + 1 - maxH;
}
}
else
{
(pix->mb_addr)++;
yM = yN;
}
}
}
}
}
}
}
else
{ // xN >= 0
if (xN >= 0 && xN < maxW)
{
if (yN<0)
{
if (!currMB->mb_field)
{
//frame
if ((currMB->mbAddrX & 0x01) == 0)
{
//top
pix->mb_addr = currMB->mb_addr_up;
// for the deblocker if the current MB is a frame and the one above is a field
// then the neighbor is the top MB of the pair
if (currMB->mb_avail_up)
{
if (!(p_Vid->DeblockCall == 1 && (p_Vid->mb_data[currMB->mb_addr_up]).mb_field))
pix->mb_addr += 1;
}
pix->available = currMB->mb_avail_up;
yM = yN;
}
else
{
// bottom
pix->mb_addr = currMB->mbAddrX - 1;
pix->available = TRUE;
yM = yN;
}
}
else
{
// field
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_up;
pix->available = currMB->mb_avail_up;
if (currMB->mb_avail_up)
{
if(!p_Vid->mb_data[currMB->mb_addr_up].mb_field)
{
(pix->mb_addr)++;
yM = 2* yN;
}
else
{
yM = yN;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_up + 1;
pix->available = currMB->mb_avail_up;
yM = yN;
}
}
}
else
{
// yN >=0
// for the deblocker if this is the extra edge then do this special stuff
if (yN == 0 && p_Vid->DeblockCall == 2)
{
pix->mb_addr = currMB->mb_addr_up + 1;
pix->available = TRUE;
yM = yN - 1;
}
else if ((yN <maxH))
{
pix->mb_addr = currMB->mbAddrX;
pix->available = TRUE;
yM = yN;
}
}
}
else
{ // xN >= maxW
if(yN < 0)
{
if (!currMB->mb_field)
{
// frame
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_upper_right + 1;
pix->available = currMB->mb_avail_upper_right;
yM = yN;
}
else
{
// bottom
pix->available = FALSE;
}
}
else
{
// field
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_upper_right;
pix->available = currMB->mb_avail_upper_right;
if (currMB->mb_avail_upper_right)
{
if(!p_Vid->mb_data[currMB->mb_addr_upper_right].mb_field)
{
(pix->mb_addr)++;
yM = 2* yN;
}
else
{
yM = yN;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_upper_right + 1;
pix->available = currMB->mb_avail_upper_right;
yM = yN;
}
}
}
}
}
if (pix->available || p_Vid->DeblockCall)
{
pix->x = (short) (xN & (maxW - 1));
pix->y = (short) (yM & (maxH - 1));
get_mb_pos(p_Vid, pix->mb_addr, mb_size, &(pix->pos_x), &(pix->pos_y));
pix->pos_x = pix->pos_x + pix->x;
pix->pos_y = pix->pos_y + pix->y;
}
}
void getAffNeighbourNX(const Macroblock *currMB, int yN, const int mb_size[2], PixelPos *pix)
{
VideoParameters *p_Vid = currMB->p_Vid;
int maxW, maxH;
int yM = -1;
int xN = -1;
maxW = mb_size[0];
maxH = mb_size[1];
// initialize to "not available"
pix->available = FALSE;
if(yN > (maxH - 1))
{
return;
}
if (xN > (maxW - 1) && yN >= 0 && yN < maxH)
{
return;
}
if (xN < 0)
{
if (yN < 0)
{
if(!currMB->mb_field)
{
// frame
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_upper_left + 1;
pix->available = currMB->mb_avail_upper_left;
yM = yN;
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
yM = yN;
}
else
{
(pix->mb_addr)++;
yM = (yN + maxH) >> 1;
}
}
}
}
else
{
// field
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_upper_left;
pix->available = currMB->mb_avail_upper_left;
if (currMB->mb_avail_upper_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_upper_left].mb_field)
{
(pix->mb_addr)++;
yM = 2 * yN;
}
else
{
yM = yN;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_upper_left+1;
pix->available = currMB->mb_avail_upper_left;
yM = yN;
}
}
}
else
{ // xN < 0 && yN >= 0
if (yN <maxH)
{
if (!currMB->mb_field)
{
// frame
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
yM = yN;
}
else
{
(pix->mb_addr)+= ((yN & 0x01) != 0);
yM = yN >> 1;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
(pix->mb_addr)++;
yM = yN;
}
else
{
(pix->mb_addr)+= ((yN & 0x01) != 0);
yM = (yN + maxH) >> 1;
}
}
}
}
else
{
// field
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
if (yN < (maxH >> 1))
{
yM = yN << 1;
}
else
{
(pix->mb_addr)++;
yM = (yN << 1 ) - maxH;
}
}
else
{
yM = yN;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
if (yN < (maxH >> 1))
{
yM = (yN << 1) + 1;
}
else
{
(pix->mb_addr)++;
yM = (yN << 1 ) + 1 - maxH;
}
}
else
{
(pix->mb_addr)++;
yM = yN;
}
}
}
}
}
}
}
else
{ // xN >= 0
if (xN >= 0 && xN < maxW)
{
if (yN<0)
{
if (!currMB->mb_field)
{
//frame
if ((currMB->mbAddrX & 0x01) == 0)
{
//top
pix->mb_addr = currMB->mb_addr_up;
// for the deblocker if the current MB is a frame and the one above is a field
// then the neighbor is the top MB of the pair
if (currMB->mb_avail_up)
{
if (!(p_Vid->DeblockCall == 1 && (p_Vid->mb_data[currMB->mb_addr_up]).mb_field))
pix->mb_addr += 1;
}
pix->available = currMB->mb_avail_up;
yM = yN;
}
else
{
// bottom
pix->mb_addr = currMB->mbAddrX - 1;
pix->available = TRUE;
yM = yN;
}
}
else
{
// field
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_up;
pix->available = currMB->mb_avail_up;
if (currMB->mb_avail_up)
{
if(!p_Vid->mb_data[currMB->mb_addr_up].mb_field)
{
(pix->mb_addr)++;
yM = 2* yN;
}
else
{
yM = yN;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_up + 1;
pix->available = currMB->mb_avail_up;
yM = yN;
}
}
}
else
{
// yN >=0
// for the deblocker if this is the extra edge then do this special stuff
if (yN == 0 && p_Vid->DeblockCall == 2)
{
pix->mb_addr = currMB->mb_addr_up + 1;
pix->available = TRUE;
yM = yN - 1;
}
else if ((yN <maxH))
{
pix->mb_addr = currMB->mbAddrX;
pix->available = TRUE;
yM = yN;
}
}
}
else
{ // xN >= maxW
if(yN < 0)
{
if (!currMB->mb_field)
{
// frame
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_upper_right + 1;
pix->available = currMB->mb_avail_upper_right;
yM = yN;
}
else
{
// bottom
pix->available = FALSE;
}
}
else
{
// field
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_upper_right;
pix->available = currMB->mb_avail_upper_right;
if (currMB->mb_avail_upper_right)
{
if(!p_Vid->mb_data[currMB->mb_addr_upper_right].mb_field)
{
(pix->mb_addr)++;
yM = 2* yN;
}
else
{
yM = yN;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_upper_right + 1;
pix->available = currMB->mb_avail_upper_right;
yM = yN;
}
}
}
}
}
if (pix->available || p_Vid->DeblockCall)
{
pix->x = (short) (xN & (maxW - 1));
pix->y = (short) (yM & (maxH - 1));
get_mb_pos(p_Vid, pix->mb_addr, mb_size, &(pix->pos_x), &(pix->pos_y));
pix->pos_x = pix->pos_x + pix->x;
pix->pos_y = pix->pos_y + pix->y;
}
}
void getAffNeighbourNXLuma(const Macroblock *currMB, int yN, PixelPos *pix)
{
const int mb_size[2]={16,16};
getAffNeighbourNX(currMB, yN, mb_size, pix);
}
void getAffNeighbourN0(const Macroblock *currMB, const int mb_size[2], PixelPos *pix)
{
VideoParameters *p_Vid = currMB->p_Vid;
int maxW, maxH;
int yM = -1;
int xN = -1;
int yN=0;
maxW = mb_size[0];
maxH = mb_size[1];
// initialize to "not available"
pix->available = FALSE;
if(yN > (maxH - 1))
{
return;
}
if (xN > (maxW - 1) && yN >= 0 && yN < maxH)
{
return;
}
if (xN < 0)
{
if (yN < 0)
{
if(!currMB->mb_field)
{
// frame
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_upper_left + 1;
pix->available = currMB->mb_avail_upper_left;
yM = yN;
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
yM = yN;
}
else
{
(pix->mb_addr)++;
yM = (yN + maxH) >> 1;
}
}
}
}
else
{
// field
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_upper_left;
pix->available = currMB->mb_avail_upper_left;
if (currMB->mb_avail_upper_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_upper_left].mb_field)
{
(pix->mb_addr)++;
yM = 2 * yN;
}
else
{
yM = yN;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_upper_left+1;
pix->available = currMB->mb_avail_upper_left;
yM = yN;
}
}
}
else
{ // xN < 0 && yN >= 0
if (yN <maxH)
{
if (!currMB->mb_field)
{
// frame
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
yM = yN;
}
else
{
(pix->mb_addr)+= ((yN & 0x01) != 0);
yM = yN >> 1;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
(pix->mb_addr)++;
yM = yN;
}
else
{
(pix->mb_addr)+= ((yN & 0x01) != 0);
yM = (yN + maxH) >> 1;
}
}
}
}
else
{
// field
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
if (yN < (maxH >> 1))
{
yM = yN << 1;
}
else
{
(pix->mb_addr)++;
yM = (yN << 1 ) - maxH;
}
}
else
{
yM = yN;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
if (yN < (maxH >> 1))
{
yM = (yN << 1) + 1;
}
else
{
(pix->mb_addr)++;
yM = (yN << 1 ) + 1 - maxH;
}
}
else
{
(pix->mb_addr)++;
yM = yN;
}
}
}
}
}
}
}
else
{ // xN >= 0
if (xN >= 0 && xN < maxW)
{
if (yN<0)
{
if (!currMB->mb_field)
{
//frame
if ((currMB->mbAddrX & 0x01) == 0)
{
//top
pix->mb_addr = currMB->mb_addr_up;
// for the deblocker if the current MB is a frame and the one above is a field
// then the neighbor is the top MB of the pair
if (currMB->mb_avail_up)
{
if (!(p_Vid->DeblockCall == 1 && (p_Vid->mb_data[currMB->mb_addr_up]).mb_field))
pix->mb_addr += 1;
}
pix->available = currMB->mb_avail_up;
yM = yN;
}
else
{
// bottom
pix->mb_addr = currMB->mbAddrX - 1;
pix->available = TRUE;
yM = yN;
}
}
else
{
// field
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_up;
pix->available = currMB->mb_avail_up;
if (currMB->mb_avail_up)
{
if(!p_Vid->mb_data[currMB->mb_addr_up].mb_field)
{
(pix->mb_addr)++;
yM = 2* yN;
}
else
{
yM = yN;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_up + 1;
pix->available = currMB->mb_avail_up;
yM = yN;
}
}
}
else
{
// yN >=0
// for the deblocker if this is the extra edge then do this special stuff
if (yN == 0 && p_Vid->DeblockCall == 2)
{
pix->mb_addr = currMB->mb_addr_up + 1;
pix->available = TRUE;
yM = yN - 1;
}
else if ((yN <maxH))
{
pix->mb_addr = currMB->mbAddrX;
pix->available = TRUE;
yM = yN;
}
}
}
else
{ // xN >= maxW
if(yN < 0)
{
if (!currMB->mb_field)
{
// frame
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_upper_right + 1;
pix->available = currMB->mb_avail_upper_right;
yM = yN;
}
else
{
// bottom
pix->available = FALSE;
}
}
else
{
// field
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_upper_right;
pix->available = currMB->mb_avail_upper_right;
if (currMB->mb_avail_upper_right)
{
if(!p_Vid->mb_data[currMB->mb_addr_upper_right].mb_field)
{
(pix->mb_addr)++;
yM = 2* yN;
}
else
{
yM = yN;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_upper_right + 1;
pix->available = currMB->mb_avail_upper_right;
yM = yN;
}
}
}
}
}
if (pix->available || p_Vid->DeblockCall)
{
pix->x = (short) (xN & (maxW - 1));
pix->y = (short) (yM & (maxH - 1));
get_mb_pos(p_Vid, pix->mb_addr, mb_size, &(pix->pos_x), &(pix->pos_y));
pix->pos_x = pix->pos_x + pix->x;
pix->pos_y = pix->pos_y + pix->y;
}
}
void getAffNeighbourLuma(const Macroblock *currMB, int xN, int yN, PixelPos *pix)
{
VideoParameters *p_Vid = currMB->p_Vid;
const int maxW=16, maxH=16;
int yM = -1;
// initialize to "not available"
pix->available = FALSE;
if(yN > (maxH - 1))
{
return;
}
if (xN > (maxW - 1) && yN >= 0 && yN < maxH)
{
return;
}
if (xN < 0)
{
if (yN < 0)
{
if(!currMB->mb_field)
{
// frame
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_upper_left + 1;
pix->available = currMB->mb_avail_upper_left;
yM = yN;
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
yM = yN;
}
else
{
(pix->mb_addr)++;
yM = (yN + maxH) >> 1;
}
}
}
}
else
{
// field
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_upper_left;
pix->available = currMB->mb_avail_upper_left;
if (currMB->mb_avail_upper_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_upper_left].mb_field)
{
(pix->mb_addr)++;
yM = 2 * yN;
}
else
{
yM = yN;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_upper_left+1;
pix->available = currMB->mb_avail_upper_left;
yM = yN;
}
}
}
else
{ // xN < 0 && yN >= 0
if (yN <maxH)
{
if (!currMB->mb_field)
{
// frame
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
yM = yN;
}
else
{
(pix->mb_addr)+= ((yN & 0x01) != 0);
yM = yN >> 1;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
(pix->mb_addr)++;
yM = yN;
}
else
{
(pix->mb_addr)+= ((yN & 0x01) != 0);
yM = (yN + maxH) >> 1;
}
}
}
}
else
{
// field
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
if (yN < (maxH >> 1))
{
yM = yN << 1;
}
else
{
(pix->mb_addr)++;
yM = (yN << 1 ) - maxH;
}
}
else
{
yM = yN;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
if (yN < (maxH >> 1))
{
yM = (yN << 1) + 1;
}
else
{
(pix->mb_addr)++;
yM = (yN << 1 ) + 1 - maxH;
}
}
else
{
(pix->mb_addr)++;
yM = yN;
}
}
}
}
}
}
}
else
{ // xN >= 0
if (xN >= 0 && xN < maxW)
{
if (yN<0)
{
if (!currMB->mb_field)
{
//frame
if ((currMB->mbAddrX & 0x01) == 0)
{
//top
pix->mb_addr = currMB->mb_addr_up;
// for the deblocker if the current MB is a frame and the one above is a field
// then the neighbor is the top MB of the pair
if (currMB->mb_avail_up)
{
if (!(p_Vid->DeblockCall == 1 && (p_Vid->mb_data[currMB->mb_addr_up]).mb_field))
pix->mb_addr += 1;
}
pix->available = currMB->mb_avail_up;
yM = yN;
}
else
{
// bottom
pix->mb_addr = currMB->mbAddrX - 1;
pix->available = TRUE;
yM = yN;
}
}
else
{
// field
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_up;
pix->available = currMB->mb_avail_up;
if (currMB->mb_avail_up)
{
if(!p_Vid->mb_data[currMB->mb_addr_up].mb_field)
{
(pix->mb_addr)++;
yM = 2* yN;
}
else
{
yM = yN;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_up + 1;
pix->available = currMB->mb_avail_up;
yM = yN;
}
}
}
else
{
// yN >=0
// for the deblocker if this is the extra edge then do this special stuff
if (yN == 0 && p_Vid->DeblockCall == 2)
{
pix->mb_addr = currMB->mb_addr_up + 1;
pix->available = TRUE;
yM = yN - 1;
}
else if (yN <maxH)
{
pix->mb_addr = currMB->mbAddrX;
pix->available = TRUE;
yM = yN;
}
}
}
else
{ // xN >= maxW
if(yN < 0)
{
if (!currMB->mb_field)
{
// frame
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_upper_right + 1;
pix->available = currMB->mb_avail_upper_right;
yM = yN;
}
else
{
// bottom
pix->available = FALSE;
}
}
else
{
// field
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_upper_right;
pix->available = currMB->mb_avail_upper_right;
if (currMB->mb_avail_upper_right)
{
if(!p_Vid->mb_data[currMB->mb_addr_upper_right].mb_field)
{
(pix->mb_addr)++;
yM = 2* yN;
}
else
{
yM = yN;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_upper_right + 1;
pix->available = currMB->mb_avail_upper_right;
yM = yN;
}
}
}
}
}
if (pix->available || p_Vid->DeblockCall)
{
pix->x = (short) (xN & (maxW - 1));
pix->y = (short) (yM & (maxH - 1));
get_mb_block_pos_mbaff(p_Vid->PicPos, pix->mb_addr, &(pix->pos_x), &(pix->pos_y));
pix->pos_x = 16*pix->pos_x + pix->x;
pix->pos_y = 16*pix->pos_y + pix->y;
}
}
void getAffNeighbourPXLumaNB(const Macroblock *currMB, int xN, int yN, PixelPos *pix)
{ // xN >= 0, yN < 16, xN < 16
VideoParameters *p_Vid = currMB->p_Vid;
const int maxW=16, maxH=16;
int yM = -1;
// initialize to "not available"
pix->available = FALSE;
if (yN<0)
{
if (!currMB->mb_field)
{
//frame
if ((currMB->mbAddrX & 0x01) == 0)
{
//top
pix->mb_addr = currMB->mb_addr_up;
// for the deblocker if the current MB is a frame and the one above is a field
// then the neighbor is the top MB of the pair
if (currMB->mb_avail_up)
{
if (!(p_Vid->DeblockCall == 1 && (p_Vid->mb_data[currMB->mb_addr_up]).mb_field))
pix->mb_addr += 1;
}
pix->available = currMB->mb_avail_up;
yM = yN;
}
else
{
// bottom
pix->mb_addr = currMB->mbAddrX - 1;
pix->available = TRUE;
yM = yN;
}
}
else
{
// field
pix->available = currMB->mb_avail_up;
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_up;
if (currMB->mb_avail_up)
{
if(!p_Vid->mb_data[currMB->mb_addr_up].mb_field)
{
(pix->mb_addr)++;
yM = 2* yN;
}
else
{
yM = yN;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_up + 1;
yM = yN;
}
}
}
else
{
// yN >=0
// for the deblocker if this is the extra edge then do this special stuff
if (yN == 0 && p_Vid->DeblockCall == 2)
{
pix->mb_addr = currMB->mb_addr_up + 1;
pix->available = TRUE;
yM = yN - 1;
}
else
{
pix->mb_addr = currMB->mbAddrX;
pix->available = TRUE;
yM = yN;
}
}
if (pix->available || p_Vid->DeblockCall)
{
pix->x = (short) (xN);
pix->y = (short) (yM & (maxH - 1));
get_mb_block_pos_mbaff(p_Vid->PicPos, pix->mb_addr, &(pix->pos_x), &(pix->pos_y));
pix->pos_x = 16*pix->pos_x + pix->x;
pix->pos_y = 16*pix->pos_y + pix->y;
}
}
void getAffNeighbourPXLumaNB_NoPos(const Macroblock *currMB, int yN, PixelPos *pix)
{ // xN >= 0, yN < 16, xN < 16, DeblockCall == 0
VideoParameters *p_Vid = currMB->p_Vid;
int yM = -1;
// initialize to "not available"
pix->available = FALSE;
if (yN<0)
{
if (!currMB->mb_field)
{
//frame
if ((currMB->mbAddrX & 0x01) == 0)
{
//top
pix->mb_addr = currMB->mb_addr_up;
// for the deblocker if the current MB is a frame and the one above is a field
// then the neighbor is the top MB of the pair
if (currMB->mb_avail_up)
{
pix->mb_addr += 1;
}
pix->available = currMB->mb_avail_up;
yM = yN;
}
else
{
// bottom
pix->mb_addr = currMB->mbAddrX - 1;
pix->available = TRUE;
yM = yN;
}
}
else
{
// field
pix->available = currMB->mb_avail_up;
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_up;
if (currMB->mb_avail_up)
{
if(!p_Vid->mb_data[currMB->mb_addr_up].mb_field)
{
(pix->mb_addr)++;
yM = 2* yN;
}
else
{
yM = yN;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_up + 1;
yM = yN;
}
}
}
else
{
// yN >=0
pix->mb_addr = currMB->mbAddrX;
pix->available = TRUE;
yM = yN;
}
if (pix->available)
{
pix->y = (short) (yM & 15);
}
}
void getAffNeighbourXPLuma(const Macroblock *currMB, int xN, int yN, PixelPos *pix)
{ // yN >= 0
VideoParameters *p_Vid = currMB->p_Vid;
const int maxW=16, maxH=16;
int yM = -1;
// initialize to "not available"
pix->available = FALSE;
if(yN > (maxH - 1))
{
return;
}
if (xN > (maxW - 1) && yN < maxH)
{
return;
}
if (xN < 0)
{
if (!currMB->mb_field)
{
// frame
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
yM = yN;
}
else
{
(pix->mb_addr)+= ((yN & 0x01) != 0);
yM = yN >> 1;
}
}
}
else
{
// bottom
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
(pix->mb_addr)++;
yM = yN;
}
else
{
(pix->mb_addr)+= ((yN & 0x01) != 0);
yM = (yN + maxH) >> 1;
}
}
}
}
else
{
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
// field
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
if (yN < (maxH >> 1))
{
yM = yN << 1;
}
else
{
(pix->mb_addr)++;
yM = (yN << 1 ) - maxH;
}
}
else
{
yM = yN;
}
}
}
else
{
// bottom
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
if (yN < (maxH >> 1))
{
yM = (yN << 1) + 1;
}
else
{
(pix->mb_addr)++;
yM = (yN << 1 ) + 1 - maxH;
}
}
else
{
(pix->mb_addr)++;
yM = yN;
}
}
}
}
}
else if (xN < maxW)
{ // xN >= 0
// yN >=0
// for the deblocker if this is the extra edge then do this special stuff
if (yN == 0 && p_Vid->DeblockCall == 2)
{
pix->mb_addr = currMB->mb_addr_up + 1;
pix->available = TRUE;
yM = yN - 1;
}
else if (yN <maxH)
{
pix->mb_addr = currMB->mbAddrX;
pix->available = TRUE;
yM = yN;
}
}
if (pix->available || p_Vid->DeblockCall)
{
pix->x = (short) (xN & (maxW - 1));
pix->y = (short) (yM & (maxH - 1));
get_mb_block_pos_mbaff(p_Vid->PicPos, pix->mb_addr, &(pix->pos_x), &(pix->pos_y));
pix->pos_x = 16*pix->pos_x + pix->x;
pix->pos_y = 16*pix->pos_y + pix->y;
}
}
void getAffNeighbourPPLumaNB(const Macroblock *currMB, int xN, int yN, PixelPos *pix)
{
VideoParameters *p_Vid = currMB->p_Vid;
// xN >= 0
// yN >=0
pix->mb_addr = currMB->mbAddrX;
pix->available = TRUE;
pix->x = (short) (xN & (16 - 1));
pix->y = (short) (yN & (16 - 1));
get_mb_block_pos_mbaff(p_Vid->PicPos, pix->mb_addr, &(pix->pos_x), &(pix->pos_y));
pix->pos_x = 16*pix->pos_x + pix->x;
pix->pos_y = 16*pix->pos_y + pix->y;
}
void getAffNeighbourNPLuma(const Macroblock *currMB, int yN, PixelPos *pix)
{ // yN >= 0
VideoParameters *p_Vid = currMB->p_Vid;
const int maxW=16, maxH=16;
int yM = -1;
// initialize to "not available"
pix->available = FALSE;
if(yN > (maxH - 1))
{
return;
}
if (yN <maxH)
{
if (!currMB->mb_field)
{
// frame
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
yM = yN;
}
else
{
(pix->mb_addr)+= ((yN & 0x01) != 0);
yM = yN >> 1;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
(pix->mb_addr)++;
yM = yN;
}
else
{
(pix->mb_addr)+= ((yN & 0x01) != 0);
yM = (yN + maxH) >> 1;
}
}
}
}
else
{
// field
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
if (yN < (maxH >> 1))
{
yM = yN << 1;
}
else
{
(pix->mb_addr)++;
yM = (yN << 1 ) - maxH;
}
}
else
{
yM = yN;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
if (yN < (maxH >> 1))
{
yM = (yN << 1) + 1;
}
else
{
(pix->mb_addr)++;
yM = (yN << 1 ) + 1 - maxH;
}
}
else
{
(pix->mb_addr)++;
yM = yN;
}
}
}
}
}
if (pix->available || p_Vid->DeblockCall)
{
pix->x = (short) (-1 & (maxW - 1));
pix->y = (short) (yM & (maxH - 1));
get_mb_block_pos_mbaff(p_Vid->PicPos, pix->mb_addr, &(pix->pos_x), &(pix->pos_y));
pix->pos_x = 16*pix->pos_x + pix->x;
pix->pos_y = 16*pix->pos_y + pix->y;
}
}
void getAffNeighbourN0Luma(const Macroblock *currMB, PixelPos *pix)
{ // xN = -1 && yN == 0
VideoParameters *p_Vid = currMB->p_Vid;
//const int maxW=16, maxH=16;
int yM = -1;
// initialize to "not available"
pix->available = FALSE;
if (!currMB->mb_field)
{
// frame
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
yM = 0;
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
(pix->mb_addr)++;
yM = 0;
}
else
{
yM = 8;
}
}
}
}
else
{
// field
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
yM = 0;
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
yM = 1;
}
else
{
(pix->mb_addr)++;
yM = 0;
}
}
}
}
if (pix->available || p_Vid->DeblockCall)
{
pix->x = (short) (-1 & 15);
pix->y = (short) (yM & 15);
get_mb_block_pos_mbaff(p_Vid->PicPos, pix->mb_addr, &(pix->pos_x), &(pix->pos_y));
pix->pos_x = 16*pix->pos_x + pix->x;
pix->pos_y = 16*pix->pos_y + pix->y;
}
}
void getAffNeighbourX0(const Macroblock *currMB, int xN, const int mb_size[2], PixelPos *pix)
{
VideoParameters *p_Vid = currMB->p_Vid;
int maxW, maxH;
int yM = -1;
maxW = mb_size[0];
maxH = mb_size[1];
// initialize to "not available"
pix->available = FALSE;
if(0 > (maxH - 1))
{
return;
}
if (xN > (maxW - 1) && 0 < maxH)
{
return;
}
if (xN < 0)
{
if (0 <maxH)
{
if (!currMB->mb_field)
{
// frame
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
yM = 0;
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
(pix->mb_addr)++;
yM = 0;
}
else
{
yM = (0 + maxH) >> 1;
}
}
}
}
else
{
// field
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
if (0 < (maxH >> 1))
{
yM = 0;
}
else
{
(pix->mb_addr)++;
yM = (0) - maxH;
}
}
else
{
yM = 0;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_left;
pix->available = currMB->mb_avail_left;
if (currMB->mb_avail_left)
{
if(!p_Vid->mb_data[currMB->mb_addr_left].mb_field)
{
if (0 < (maxH >> 1))
{
yM = 1;
}
else
{
(pix->mb_addr)++;
yM = 1 - maxH;
}
}
else
{
(pix->mb_addr)++;
yM = 0;
}
}
}
}
}
}
else
{ // xN >= 0
if (xN >= 0 && xN < maxW)
{
// yN >=0
// for the deblocker if this is the extra edge then do this special stuff
if (p_Vid->DeblockCall == 2)
{
pix->mb_addr = currMB->mb_addr_up + 1;
pix->available = TRUE;
yM = 0 - 1;
}
else if (0 <maxH)
{
pix->mb_addr = currMB->mbAddrX;
pix->available = TRUE;
yM = 0;
}
}
}
if (pix->available || p_Vid->DeblockCall)
{
pix->x = (short) (xN & (maxW - 1));
pix->y = (short) (yM & (maxH - 1));
get_mb_pos(p_Vid, pix->mb_addr, mb_size, &(pix->pos_x), &(pix->pos_y));
pix->pos_x = pix->pos_x + pix->x;
pix->pos_y = pix->pos_y + pix->y;
}
}
void getAffNeighbour0X(const Macroblock *currMB, int yN, const int mb_size[2], PixelPos *pix) // xN == 0, yN full range
{
VideoParameters *p_Vid = currMB->p_Vid;
int maxW, maxH;
int yM = -1;
maxW = mb_size[0];
maxH = mb_size[1];
// initialize to "not available"
pix->available = FALSE;
if(yN > (maxH - 1))
{
return;
}
if (0 > (maxW - 1) && yN >= 0 && yN < maxH)
{
return;
}
if (0 < maxW)
{
if (yN<0)
{
if (!currMB->mb_field)
{
//frame
if ((currMB->mbAddrX & 0x01) == 0)
{
//top
pix->mb_addr = currMB->mb_addr_up;
// for the deblocker if the current MB is a frame and the one above is a field
// then the neighbor is the top MB of the pair
if (currMB->mb_avail_up)
{
if (!(p_Vid->DeblockCall == 1 && (p_Vid->mb_data[currMB->mb_addr_up]).mb_field))
pix->mb_addr += 1;
}
pix->available = currMB->mb_avail_up;
yM = yN;
}
else
{
// bottom
pix->mb_addr = currMB->mbAddrX - 1;
pix->available = TRUE;
yM = yN;
}
}
else
{
// field
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_up;
pix->available = currMB->mb_avail_up;
if (currMB->mb_avail_up)
{
if(!p_Vid->mb_data[currMB->mb_addr_up].mb_field)
{
(pix->mb_addr)++;
yM = 2* yN;
}
else
{
yM = yN;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_up + 1;
pix->available = currMB->mb_avail_up;
yM = yN;
}
}
}
else
{
// yN >=0
// for the deblocker if this is the extra edge then do this special stuff
if (yN == 0 && p_Vid->DeblockCall == 2)
{
pix->mb_addr = currMB->mb_addr_up + 1;
pix->available = TRUE;
yM = yN - 1;
}
else if ((yN >= 0) && (yN <maxH))
{
pix->mb_addr = currMB->mbAddrX;
pix->available = TRUE;
yM = yN;
}
}
}
else
{ // xN >= maxW
if(yN < 0)
{
if (!currMB->mb_field)
{
// frame
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_upper_right + 1;
pix->available = currMB->mb_avail_upper_right;
yM = yN;
}
else
{
// bottom
pix->available = FALSE;
}
}
else
{
// field
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_upper_right;
pix->available = currMB->mb_avail_upper_right;
if (currMB->mb_avail_upper_right)
{
if(!p_Vid->mb_data[currMB->mb_addr_upper_right].mb_field)
{
(pix->mb_addr)++;
yM = 2* yN;
}
else
{
yM = yN;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_upper_right + 1;
pix->available = currMB->mb_avail_upper_right;
yM = yN;
}
}
}
}
if (pix->available || p_Vid->DeblockCall)
{
pix->x = 0;
pix->y = (short) (yM & (maxH - 1));
get_mb_pos(p_Vid, pix->mb_addr, mb_size, &(pix->pos_x), &(pix->pos_y));
pix->pos_y = pix->pos_y + pix->y;
}
}
void getAffNeighbour0XLuma(const Macroblock *currMB, int yN, PixelPos *pix) // xN == 0, yN full range
{
VideoParameters *p_Vid = currMB->p_Vid;
int maxW, maxH;
int yM = -1;
maxW = 16;
maxH = 16;
// initialize to "not available"
pix->available = FALSE;
if(yN > 15)
{
return;
}
if (yN<0)
{
if (!currMB->mb_field)
{
//frame
if ((currMB->mbAddrX & 0x01) == 0)
{
//top
pix->mb_addr = currMB->mb_addr_up;
// for the deblocker if the current MB is a frame and the one above is a field
// then the neighbor is the top MB of the pair
if (currMB->mb_avail_up)
{
if (!(p_Vid->DeblockCall == 1 && (p_Vid->mb_data[currMB->mb_addr_up]).mb_field))
pix->mb_addr += 1;
}
pix->available = currMB->mb_avail_up;
yM = yN;
}
else
{
// bottom
pix->mb_addr = currMB->mbAddrX - 1;
pix->available = TRUE;
yM = yN;
}
}
else
{
// field
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_up;
pix->available = currMB->mb_avail_up;
if (currMB->mb_avail_up)
{
if(!p_Vid->mb_data[currMB->mb_addr_up].mb_field)
{
(pix->mb_addr)++;
yM = 2* yN;
}
else
{
yM = yN;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_up + 1;
pix->available = currMB->mb_avail_up;
yM = yN;
}
}
}
else
{
// yN >=0
// for the deblocker if this is the extra edge then do this special stuff
if (yN == 0 && p_Vid->DeblockCall == 2)
{
pix->mb_addr = currMB->mb_addr_up + 1;
pix->available = TRUE;
yM = yN - 1;
}
else if ((yN >= 0) && (yN <maxH))
{
pix->mb_addr = currMB->mbAddrX;
pix->available = TRUE;
yM = yN;
}
}
if (pix->available || p_Vid->DeblockCall)
{
const int mb_size[2] = {16,16};
pix->x = 0;
pix->y = (short) (yM & (maxH - 1));
get_mb_pos(p_Vid, pix->mb_addr, mb_size, &(pix->pos_x), &(pix->pos_y));
pix->pos_y = pix->pos_y + pix->y;
}
}
void getAffNeighbour0N(const Macroblock *currMB, const int mb_size[2], PixelPos *pix) // xN == 0, yN = -1
{
VideoParameters *p_Vid = currMB->p_Vid;
int maxW, maxH;
int yM = -1;
maxW = mb_size[0];
maxH = mb_size[1];
// initialize to "not available"
pix->available = FALSE;
if (0 < maxW)
{
if (!currMB->mb_field)
{
//frame
if ((currMB->mbAddrX & 0x01) == 0)
{
//top
pix->mb_addr = currMB->mb_addr_up;
// for the deblocker if the current MB is a frame and the one above is a field
// then the neighbor is the top MB of the pair
if (currMB->mb_avail_up)
{
if (!(p_Vid->DeblockCall == 1 && (p_Vid->mb_data[currMB->mb_addr_up]).mb_field))
pix->mb_addr += 1;
}
pix->available = currMB->mb_avail_up;
yM = -1;
}
else
{
// bottom
pix->mb_addr = currMB->mbAddrX - 1;
pix->available = TRUE;
yM = -1;
}
}
else
{
// field
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_up;
pix->available = currMB->mb_avail_up;
if (currMB->mb_avail_up)
{
if(!p_Vid->mb_data[currMB->mb_addr_up].mb_field)
{
(pix->mb_addr)++;
yM = -2;
}
else
{
yM = -1;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_up + 1;
pix->available = currMB->mb_avail_up;
yM = -1;
}
}
}
else
{ // xN >= maxW
if (!currMB->mb_field)
{
// frame
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_upper_right + 1;
pix->available = currMB->mb_avail_upper_right;
yM = -1;
}
else
{
// bottom
pix->available = FALSE;
}
}
else
{
// field
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_upper_right;
pix->available = currMB->mb_avail_upper_right;
if (currMB->mb_avail_upper_right)
{
if(!p_Vid->mb_data[currMB->mb_addr_upper_right].mb_field)
{
(pix->mb_addr)++;
yM = -2;
}
else
{
yM = -1;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_upper_right + 1;
pix->available = currMB->mb_avail_upper_right;
yM = -1;
}
}
}
if (pix->available || p_Vid->DeblockCall)
{
pix->x = 0;
pix->y = (short) (yM & (maxH - 1));
get_mb_pos(p_Vid, pix->mb_addr, mb_size, &(pix->pos_x), &(pix->pos_y));
pix->pos_y = pix->pos_y + pix->y;
}
}
void getAffNeighbour0NLuma(const Macroblock *currMB, PixelPos *pix) // xN == 0, yN = -1
{
VideoParameters *p_Vid = currMB->p_Vid;
const int maxW=16, maxH=16;
int yM = -1;
// initialize to "not available"
pix->available = FALSE;
if (!currMB->mb_field)
{
//frame
if ((currMB->mbAddrX & 0x01) == 0)
{
//top
pix->mb_addr = currMB->mb_addr_up;
// for the deblocker if the current MB is a frame and the one above is a field
// then the neighbor is the top MB of the pair
if (currMB->mb_avail_up)
{
if (!(p_Vid->DeblockCall == 1 && (p_Vid->mb_data[currMB->mb_addr_up]).mb_field))
pix->mb_addr += 1;
}
pix->available = currMB->mb_avail_up;
yM = -1;
}
else
{
// bottom
pix->mb_addr = currMB->mbAddrX - 1;
pix->available = TRUE;
yM = -1;
}
}
else
{
// field
if ((currMB->mbAddrX & 0x01) == 0)
{
// top
pix->mb_addr = currMB->mb_addr_up;
pix->available = currMB->mb_avail_up;
if (currMB->mb_avail_up)
{
if(!p_Vid->mb_data[currMB->mb_addr_up].mb_field)
{
(pix->mb_addr)++;
yM = -2;
}
else
{
yM = -1;
}
}
}
else
{
// bottom
pix->mb_addr = currMB->mb_addr_up + 1;
pix->available = currMB->mb_avail_up;
yM = -1;
}
}
if (pix->available || p_Vid->DeblockCall)
{
const int mb_size[2] = {16,16};
pix->x = 0;
pix->y = (short) (yM & (maxH - 1));
get_mb_pos(p_Vid, pix->mb_addr, mb_size, &(pix->pos_x), &(pix->pos_y));
pix->pos_y = pix->pos_y + pix->y;
}
}
/*!
************************************************************************
* \brief
* get neighboring 4x4 block
* \param currMB
* current macroblock
* \param block_x
* input x block position
* \param block_y
* input y block position
* \param mb_size
* Macroblock size in pixel (according to luma or chroma MB access)
* \param pix
* returns position informations
************************************************************************
*/
void get4x4Neighbour(const Macroblock *currMB, int block_x, int block_y, const int mb_size[2], PixelPos *pix)
{
currMB->p_Vid->getNeighbour(currMB, block_x, block_y, mb_size, pix);
if (pix->available)
{
pix->x >>= 2;
pix->y >>= 2;
pix->pos_x >>= 2;
pix->pos_y >>= 2;
}
}
void get4x4NeighbourLuma(const Macroblock *currMB, int block_x, int block_y, PixelPos *pix)
{
currMB->p_Vid->getNeighbourLuma(currMB, block_x, block_y, pix);
if (pix->available)
{
pix->x >>= 2;
pix->y >>= 2;
pix->pos_x >>= 2;
pix->pos_y >>= 2;
}
}