/*! ************************************************************************ * \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; } } }
void MbAffPostProc() { byte temp[16][32]; byte ** imgY = dec_picture->imgY; byte ***imgUV = dec_picture->imgUV; int i, x, y, x0, y0, uv; for (i=0; i<(int)img->PicSizeInMbs; i+=2) { if (dec_picture->mb_field[i]) { get_mb_pos(i, &x0, &y0); for (y=0; y<(2*MB_BLOCK_SIZE);y++) for (x=0; x<MB_BLOCK_SIZE; x++) temp[x][y] = imgY[y0+y][x0+x]; for (y=0; y<MB_BLOCK_SIZE;y++) for (x=0; x<MB_BLOCK_SIZE; x++) { imgY[y0+(2*y)][x0+x] = temp[x][y]; imgY[y0+(2*y+1)][x0+x] = temp[x][y+MB_BLOCK_SIZE]; } x0 = x0/2; y0 = y0/2; for (uv=0; uv<2; uv++) { for (y=0; y<(2*MB_BLOCK_SIZE/2);y++) for (x=0; x<MB_BLOCK_SIZE/2; x++) temp[x][y] = imgUV[uv][y0+y][x0+x]; for (y=0; y<MB_BLOCK_SIZE/2;y++) for (x=0; x<MB_BLOCK_SIZE/2; x++) { imgUV[uv][y0+(2*y)][x0+x] = temp[x][y]; imgUV[uv][y0+(2*y+1)][x0+x] = temp[x][y+MB_BLOCK_SIZE/2]; } } } } }
static void DeblockMb(VideoParameters *p_Vid, imgpel **imgY, imgpel ***imgUV, int MbQAddr) { int edge; byte Strength[16]; int64 *p_Strength64 = (int64 *) Strength; short mb_x, mb_y; int filterNon8x8LumaEdgesFlag[4] = {1,1,1,1}; int filterLeftMbEdgeFlag; int filterTopMbEdgeFlag; int edge_cr; Macroblock *MbQ = &(p_Vid->mb_data[MbQAddr]) ; // current Mb Slice *currSlice = MbQ->p_Slice; int mvlimit = (p_Vid->structure!=FRAME) || (p_Vid->mb_aff_frame_flag && MbQ->mb_field) ? 2 : 4; seq_parameter_set_rbsp_t *active_sps = p_Vid->active_sps; p_Vid->mixedModeEdgeFlag = 0; // return, if filter is disabled if (MbQ->DFDisableIdc == 1) { MbQ->DeblockCall = 0; return; } MbQ->DeblockCall = 1; get_mb_pos (p_Vid, MbQAddr, p_Vid->mb_size[IS_LUMA], &mb_x, &mb_y); if (MbQ->mb_type == I8MB) assert(MbQ->luma_transform_size_8x8_flag); filterNon8x8LumaEdgesFlag[1] = filterNon8x8LumaEdgesFlag[3] = !(MbQ->luma_transform_size_8x8_flag); filterLeftMbEdgeFlag = (mb_x != 0); filterTopMbEdgeFlag = (mb_y != 0); if (p_Vid->mb_aff_frame_flag && mb_y == MB_BLOCK_SIZE && MbQ->mb_field) filterTopMbEdgeFlag = 0; if (MbQ->DFDisableIdc==2) { // don't filter at slice boundaries filterLeftMbEdgeFlag = MbQ->mbAvailA; // if this the bottom of a frame macroblock pair then always filter the top edge filterTopMbEdgeFlag = (p_Vid->mb_aff_frame_flag && !MbQ->mb_field && (MbQAddr & 0x01)) ? 1 : MbQ->mbAvailB; } CheckAvailabilityOfNeighbors(MbQ); // Vertical deblocking for (edge = 0; edge < 4 ; ++edge ) { // If cbp == 0 then deblocking for some macroblock types could be skipped if (MbQ->cbp == 0) { if (filterNon8x8LumaEdgesFlag[edge] == 0 && active_sps->chroma_format_idc!=YUV444) continue; else if (edge > 0) { if ((MbQ->mb_type == 0 && currSlice->slice_type == P_SLICE) || (MbQ->mb_type == 1) || (MbQ->mb_type == 2)) continue; else if ((edge & 0x01) && ((MbQ->mb_type == 3) || ((edge & 0x01) && MbQ->mb_type == 0 && currSlice->slice_type == B_SLICE && active_sps->direct_8x8_inference_flag))) continue; } } if( edge || filterLeftMbEdgeFlag ) { // Strength for 4 blks in 1 stripe p_Vid->GetStrengthVer(Strength, MbQ, edge << 2, mvlimit); // Strength for 4 blks in 1 stripe if ((p_Strength64[0]) || (p_Strength64[1])) // only if one of the 16 Strength bytes is != 0 { if (filterNon8x8LumaEdgesFlag[edge]) { p_Vid->EdgeLoopLumaVer( PLANE_Y, imgY, Strength, MbQ, edge << 2, p_Vid->width_padded) ; if (p_Vid->P444_joined) { p_Vid->EdgeLoopLumaVer(PLANE_U, imgUV[0], Strength, MbQ, edge << 2, p_Vid->width_padded); p_Vid->EdgeLoopLumaVer(PLANE_V, imgUV[1], Strength, MbQ, edge << 2, p_Vid->width_padded); } } if(p_Vid->yuv_format==YUV420 || p_Vid->yuv_format==YUV422 ) { edge_cr = chroma_edge[0][edge][p_Vid->yuv_format]; if( (imgUV != NULL) && (edge_cr >= 0)) { p_Vid->EdgeLoopChromaVer( imgUV[0], Strength, MbQ, edge_cr, p_Vid->width_cr + p_Vid->pad_size_uv_x * 2, 0); p_Vid->EdgeLoopChromaVer( imgUV[1], Strength, MbQ, edge_cr, p_Vid->width_cr + p_Vid->pad_size_uv_x * 2, 1); } } } } }//end edge // horizontal deblocking for( edge = 0; edge < 4 ; ++edge ) { // If cbp == 0 then deblocking for some macroblock types could be skipped if (MbQ->cbp == 0) { if (filterNon8x8LumaEdgesFlag[edge] == 0 && active_sps->chroma_format_idc==YUV420) continue; else if (edge > 0) { if (((MbQ->mb_type == PSKIP && currSlice->slice_type == P_SLICE) || (MbQ->mb_type == P16x16) || (MbQ->mb_type == P8x16))) continue; else if ((edge & 0x01) && (( MbQ->mb_type == P16x8) || (currSlice->slice_type == B_SLICE && MbQ->mb_type == BSKIP_DIRECT && active_sps->direct_8x8_inference_flag))) continue; } } if( edge || filterTopMbEdgeFlag ) { // Strength for 4 blks in 1 stripe p_Vid->GetStrengthHor(Strength, MbQ, edge << 2, mvlimit); if ((p_Strength64[0]) || (p_Strength64[1])) // only if one of the 16 Strength bytes is != 0 { if (filterNon8x8LumaEdgesFlag[edge]) { p_Vid->EdgeLoopLumaHor( PLANE_Y, imgY, Strength, MbQ, edge << 2, p_Vid->width_padded) ; if (p_Vid->P444_joined) { p_Vid->EdgeLoopLumaHor(PLANE_U, imgUV[0], Strength, MbQ, edge << 2, p_Vid->width_padded); p_Vid->EdgeLoopLumaHor(PLANE_V, imgUV[1], Strength, MbQ, edge << 2, p_Vid->width_padded); } } if(p_Vid->yuv_format==YUV420 || p_Vid->yuv_format==YUV422 ) { edge_cr = chroma_edge[1][edge][p_Vid->yuv_format]; if( (imgUV != NULL) && (edge_cr >= 0)) { p_Vid->EdgeLoopChromaHor( imgUV[0], Strength, MbQ, edge_cr, p_Vid->width_cr + p_Vid->pad_size_uv_x * 2, 0); p_Vid->EdgeLoopChromaHor( imgUV[1], Strength, MbQ, edge_cr, p_Vid->width_cr + p_Vid->pad_size_uv_x * 2, 1); } } } if (!edge && !MbQ->mb_field && p_Vid->mixedModeEdgeFlag) { // this is the extra horizontal edge between a frame macroblock pair and a field above it MbQ->DeblockCall = 2; p_Vid->GetStrengthHor(Strength, MbQ, MB_BLOCK_SIZE, mvlimit); // Strength for 4 blks in 1 stripe //if( *((int*)Strength) ) // only if one of the 4 Strength bytes is != 0 { if (filterNon8x8LumaEdgesFlag[edge]) { p_Vid->EdgeLoopLumaHor( PLANE_Y, imgY, Strength, MbQ, MB_BLOCK_SIZE, p_Vid->width_padded) ; if (p_Vid->P444_joined) { p_Vid->EdgeLoopLumaHor(PLANE_U, imgUV[0], Strength, MbQ, MB_BLOCK_SIZE, p_Vid->width_padded) ; p_Vid->EdgeLoopLumaHor(PLANE_V, imgUV[1], Strength, MbQ, MB_BLOCK_SIZE, p_Vid->width_padded) ; } } if( p_Vid->yuv_format == YUV420 || p_Vid->yuv_format==YUV422 ) { edge_cr = chroma_edge[1][edge][p_Vid->yuv_format]; if( (imgUV != NULL) && (edge_cr >= 0)) { p_Vid->EdgeLoopChromaHor( imgUV[0], Strength, MbQ, MB_BLOCK_SIZE, p_Vid->width_cr+p_Vid->pad_size_uv_x*2, 0) ; p_Vid->EdgeLoopChromaHor( imgUV[1], Strength, MbQ, MB_BLOCK_SIZE, p_Vid->width_cr+p_Vid->pad_size_uv_x*2, 1) ; } } } MbQ->DeblockCall = 1; } } }//end edge MbQ->DeblockCall = 0; }
/*! ***************************************************************************************** * \brief * Deblocking filter for one macroblock. ***************************************************************************************** */ static void get_db_strength(VideoParameters *p_Vid, StorablePicture *p, int MbQAddr) { Macroblock *MbQ = &(p_Vid->mb_data[MbQAddr]) ; // current Mb // return, if filter is disabled if (MbQ->DFDisableIdc == 1) { MbQ->DeblockCall = 0; } else { int edge; short mb_x, mb_y; int filterNon8x8LumaEdgesFlag[4] = {1,1,1,1}; int filterLeftMbEdgeFlag; int filterTopMbEdgeFlag; Slice *currSlice = MbQ->p_Slice; int mvlimit = ((p->structure!=FRAME) || (p->mb_aff_frame_flag && MbQ->mb_field)) ? 2 : 4; seq_parameter_set_rbsp_t *active_sps = p_Vid->active_sps; MbQ->DeblockCall = 1; get_mb_pos (p_Vid, MbQAddr, p_Vid->mb_size[IS_LUMA], &mb_x, &mb_y); if (MbQ->mb_type == I8MB) assert(MbQ->luma_transform_size_8x8_flag); filterNon8x8LumaEdgesFlag[1] = filterNon8x8LumaEdgesFlag[3] = !(MbQ->luma_transform_size_8x8_flag); filterLeftMbEdgeFlag = (mb_x != 0); filterTopMbEdgeFlag = (mb_y != 0); if (p->mb_aff_frame_flag && mb_y == MB_BLOCK_SIZE && MbQ->mb_field) filterTopMbEdgeFlag = 0; if (MbQ->DFDisableIdc==2) { // don't filter at slice boundaries filterLeftMbEdgeFlag = MbQ->mbAvailA; // if this the bottom of a frame macroblock pair then always filter the top edge filterTopMbEdgeFlag = (p->mb_aff_frame_flag && !MbQ->mb_field && (MbQAddr & 0x01)) ? 1 : MbQ->mbAvailB; } if (p->mb_aff_frame_flag == 1) CheckAvailabilityOfNeighborsMBAFF(MbQ); // Vertical deblocking for (edge = 0; edge < 4 ; ++edge ) { // If cbp == 0 then deblocking for some macroblock types could be skipped if (MbQ->cbp == 0 && (currSlice->slice_type == P_SLICE || currSlice->slice_type == B_SLICE)) { if (filterNon8x8LumaEdgesFlag[edge] == 0 && active_sps->chroma_format_idc != YUV444) continue; else if (edge > 0) { if (((MbQ->mb_type == PSKIP && currSlice->slice_type == P_SLICE) || (MbQ->mb_type == P16x16) || (MbQ->mb_type == P16x8))) continue; else if ((edge & 0x01) && ((MbQ->mb_type == P8x16) || (currSlice->slice_type == B_SLICE && MbQ->mb_type == BSKIP_DIRECT && active_sps->direct_8x8_inference_flag))) continue; } } if( edge || filterLeftMbEdgeFlag ) { // Strength for 4 blks in 1 stripe p_Vid->GetStrengthVer(MbQ, edge, mvlimit, p); } }//end edge // horizontal deblocking for( edge = 0; edge < 4 ; ++edge ) { // If cbp == 0 then deblocking for some macroblock types could be skipped if (MbQ->cbp == 0 && (currSlice->slice_type == P_SLICE || currSlice->slice_type == B_SLICE)) { if (filterNon8x8LumaEdgesFlag[edge] == 0 && active_sps->chroma_format_idc==YUV420) continue; else if (edge > 0) { if (((MbQ->mb_type == PSKIP && currSlice->slice_type == P_SLICE) || (MbQ->mb_type == P16x16) || (MbQ->mb_type == P8x16))) continue; else if ((edge & 0x01) && ((MbQ->mb_type == P16x8) || (currSlice->slice_type == B_SLICE && MbQ->mb_type == BSKIP_DIRECT && active_sps->direct_8x8_inference_flag))) continue; } } if( edge || filterTopMbEdgeFlag ) { p_Vid->GetStrengthHor(MbQ, edge, mvlimit, p); } }//end edge MbQ->DeblockCall = 0; } }