diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/h264dec/ldecod/src/mb_access.c | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/h264dec/ldecod/src/mb_access.c')
-rw-r--r-- | Src/h264dec/ldecod/src/mb_access.c | 3388 |
1 files changed, 3388 insertions, 0 deletions
diff --git a/Src/h264dec/ldecod/src/mb_access.c b/Src/h264dec/ldecod/src/mb_access.c new file mode 100644 index 00000000..70f3aee2 --- /dev/null +++ b/Src/h264dec/ldecod/src/mb_access.c @@ -0,0 +1,3388 @@ + +/*! +************************************************************************************* +* \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; + } +} |