📄 mb_access.c
字号:
/*! ************************************************************************************* * \file mb_access.c * * \brief * Functions for macroblock neighborhoods * * \author * Main contributors (see contributors.h for copyright, address and affiliation details) * - Karsten S黨ring <suehring@hhi.de> ************************************************************************************* */#include "global.h"/*! ************************************************************************ * \brief * returns 1 if the macroblock at the given address is available ************************************************************************ */int mb_is_available(int mbAddr, int currMbAddr){ if ((mbAddr < 0) || (mbAddr > ((int)img->PicSizeInMbs - 1))) return 0; // the following line checks both: slice number and if the mb has been decoded if (img->mb_data[mbAddr].slice_nr != img->mb_data[currMbAddr].slice_nr) return 0; return 1;}/*! ************************************************************************ * \brief * Checks the availability of neighboring macroblocks of * the current macroblock for prediction and context determination; ************************************************************************ */void CheckAvailabilityOfNeighbors(){ const int mb_nr = img->current_mb_nr; Macroblock *currMB = &img->mb_data[mb_nr]; // mark all neighbors as unavailable currMB->mb_available_up = NULL; currMB->mb_available_left = NULL; if (img->MbaffFrameFlag) { currMB->mbAddrA = 2 * (mb_nr/2 - 1); currMB->mbAddrB = 2 * (mb_nr/2 - img->PicWidthInMbs); currMB->mbAddrC = 2 * (mb_nr/2 - img->PicWidthInMbs + 1); currMB->mbAddrD = 2 * (mb_nr/2 - img->PicWidthInMbs - 1); currMB->mbAvailA = mb_is_available(currMB->mbAddrA, mb_nr) && ((mb_nr/2 % img->PicWidthInMbs)!=0); currMB->mbAvailB = mb_is_available(currMB->mbAddrB, mb_nr); currMB->mbAvailC = mb_is_available(currMB->mbAddrC, mb_nr) && (((mb_nr/2 +1) % img->PicWidthInMbs)!=0); currMB->mbAvailD = mb_is_available(currMB->mbAddrD, mb_nr) && ((mb_nr/2 % img->PicWidthInMbs)!=0); } else { currMB->mbAddrA = mb_nr - 1; currMB->mbAddrB = mb_nr - img->PicWidthInMbs; currMB->mbAddrC = mb_nr - img->PicWidthInMbs + 1; currMB->mbAddrD = mb_nr - img->PicWidthInMbs - 1; currMB->mbAvailA = mb_is_available(currMB->mbAddrA, mb_nr) && ((mb_nr % img->PicWidthInMbs)!=0); currMB->mbAvailB = mb_is_available(currMB->mbAddrB, mb_nr); currMB->mbAvailC = mb_is_available(currMB->mbAddrC, mb_nr) && (((mb_nr+1) % img->PicWidthInMbs)!=0); currMB->mbAvailD = mb_is_available(currMB->mbAddrD, mb_nr) && ((mb_nr % img->PicWidthInMbs)!=0); }
if (currMB->mbAvailA) currMB->mb_available_left = &(img->mb_data[mb_nr-1]);
if (currMB->mbAvailB) currMB->mb_available_up = &(img->mb_data[mb_nr-img->PicWidthInMbs]);}/*! ************************************************************************ * \brief * returns the x and y macroblock coordinates for a given MbAddress ************************************************************************ */void get_mb_block_pos (int mb_addr, int *x, int*y){ if (img->MbaffFrameFlag) { *x = ((mb_addr/2) % img->PicWidthInMbs); *y = ( ((mb_addr/2) / img->PicWidthInMbs) * 2 + (mb_addr%2)); } else { *x = (mb_addr % img->PicWidthInMbs); *y = (mb_addr / img->PicWidthInMbs); }}/*! ************************************************************************ * \brief * returns the x and y sample coordinates for a given MbAddress ************************************************************************ */void get_mb_pos (int mb_addr, int *x, int*y){ get_mb_block_pos(mb_addr, x, y); (*x) *= MB_BLOCK_SIZE; (*y) *= MB_BLOCK_SIZE;}/*! ************************************************************************ * \brief * get neighbouring positions for non-aff coding * \param curr_mb_nr * current macroblock number (decoding order) * \param xN * input x position * \param yN * input y position * \param luma * 1 if luma coding, 0 for chroma * \param pix * returns position informations ************************************************************************ */void getNonAffNeighbour(int curr_mb_nr, int xN, int yN, int luma, PixelPos *pix){ Macroblock *currMb = &img->mb_data[curr_mb_nr]; int maxWH; if (luma) maxWH = 16; else maxWH = 8; if ((xN<0)&&(yN<0)) { pix->mb_addr = currMb->mbAddrD; pix->available = currMb->mbAvailD; } else if ((xN<0)&&((yN>=0)&&(yN<maxWH))) { pix->mb_addr = currMb->mbAddrA; pix->available = currMb->mbAvailA; } else if (((xN>=0)&&(xN<maxWH))&&(yN<0)) { pix->mb_addr = currMb->mbAddrB; pix->available = currMb->mbAvailB; } else if (((xN>=0)&&(xN<maxWH))&&((yN>=0)&&(yN<maxWH))) { pix->mb_addr = curr_mb_nr; pix->available = 1; } else if ((xN>=maxWH)&&(yN<0)) { pix->mb_addr = currMb->mbAddrC; pix->available = currMb->mbAvailC; } else { pix->available = 0; } if (pix->available) { pix->x = (xN + maxWH) % maxWH; pix->y = (yN + maxWH) % maxWH; get_mb_pos(pix->mb_addr, &(pix->pos_x), &(pix->pos_y)); if (luma) { pix->pos_x += pix->x; pix->pos_y += pix->y; } else { pix->pos_x = (pix->pos_x/2) + pix->x; pix->pos_y = (pix->pos_y/2) + pix->y; } }}/*! ************************************************************************ * \brief * get neighbouring positions for aff coding * \param curr_mb_nr * current macroblock number (decoding order) * \param xN * input x position * \param yN * input y position * \param luma * 1 if luma coding, 0 for chroma * \param pix * returns position informations ************************************************************************ */void getAffNeighbour(int curr_mb_nr, int xN, int yN, int luma, PixelPos *pix){ Macroblock *currMb = &img->mb_data[curr_mb_nr]; int maxWH; int yM = -1; if (luma) maxWH = 16; else maxWH = 8; // initialize to "not available" pix->available = 0; if(yN > (maxWH - 1)) { return; } if ((xN > (maxWH -1)) && ((yN >= 0)&&(yN < (maxWH )))) { return; } if (xN < 0) { if (yN < 0) { if(!currMb->mb_field) { // frame if (curr_mb_nr%2 == 0) { // top pix->mb_addr = currMb->mbAddrD + 1; pix->available = currMb->mbAvailD; yM = yN; } else { // bottom pix->mb_addr = currMb->mbAddrA; pix->available = currMb->mbAvailA; if (currMb->mbAvailA) { if(!img->mb_data[currMb->mbAddrA].mb_field) { yM = yN; } else { (pix->mb_addr)++; yM = (yN + maxWH) >> 1; } } } } else { // field if(curr_mb_nr % 2 == 0) { // top pix->mb_addr = currMb->mbAddrD; pix->available = currMb->mbAvailD; if (currMb->mbAvailD) { if(!img->mb_data[currMb->mbAddrD].mb_field) { (pix->mb_addr)++; yM = 2 * yN; } else { yM = yN; } } } else { // bottom pix->mb_addr = currMb->mbAddrD+1; pix->available = currMb->mbAvailD; yM = yN; } } } else { // xN < 0 && yN >= 0 if ((yN >= 0) && (yN <maxWH)) { if (!currMb->mb_field) { // frame if(curr_mb_nr % 2 == 0) { // top pix->mb_addr = currMb->mbAddrA; pix->available = currMb->mbAvailA; if (currMb->mbAvailA) { if(!img->mb_data[currMb->mbAddrA].mb_field) { yM = yN; } else { if (yN %2 == 0) { yM = yN>> 1; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -