diff options
Diffstat (limited to 'Src/h264dec/ldecod/src/intra8x8_pred.c')
-rw-r--r-- | Src/h264dec/ldecod/src/intra8x8_pred.c | 1928 |
1 files changed, 1928 insertions, 0 deletions
diff --git a/Src/h264dec/ldecod/src/intra8x8_pred.c b/Src/h264dec/ldecod/src/intra8x8_pred.c new file mode 100644 index 00000000..217e0ea8 --- /dev/null +++ b/Src/h264dec/ldecod/src/intra8x8_pred.c @@ -0,0 +1,1928 @@ +/*! + ************************************************************************************* + * \file intra8x8_pred.c + * + * \brief + * Functions for intra 8x8 prediction + * + * \author + * Main contributors (see contributors.h for copyright, + * address and affiliation details) + * - Yuri Vatis + * - Jan Muenster + * - Alexis Michael Tourapis <alexismt@ieee.org> + * + ************************************************************************************* + */ +#include "global.h" +#include "intra8x8_pred.h" +#include "mb_access.h" +#include "image.h" + +// Notation for comments regarding prediction and predictors. +// The pels of the 8x8 block are labeled a..p. The predictor pels above +// are labeled A..H, from the left I..P, and from above left X, as follows: +// +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 +// 17 a1 b1 c1 d1 e1 f1 g1 h1 +// 18 a2 b2 c2 d2 e2 f2 g2 h2 +// 19 a3 b3 c3 d3 e3 f3 g3 h3 +// 20 a4 b4 c4 d4 e4 f4 g4 h4 +// 21 a5 b5 c5 d5 e5 f5 g5 h5 +// 22 a6 b6 c6 d6 e6 f6 g6 h6 +// 23 a7 b7 c7 d7 e7 f7 g7 h7 +// 24 a8 b8 c8 d8 e8 f8 g8 h8 + + +static void memset_8x8(h264_imgpel_macroblock_row_t *mb_pred, int offset_x, int pred) +{ +#ifdef _M_IX86 + // benski> can't believe the shitty code that the compiler generated... this code is better + __m64 mmx_pred = _mm_set1_pi8(pred); + mb_pred = (h264_imgpel_macroblock_row_t *)&mb_pred[0][offset_x]; + *(__m64 *)mb_pred[0] = mmx_pred; + *(__m64 *)mb_pred[1] = mmx_pred; + *(__m64 *)mb_pred[2] = mmx_pred; + *(__m64 *)mb_pred[3] = mmx_pred; + *(__m64 *)mb_pred[4] = mmx_pred; + *(__m64 *)mb_pred[5] = mmx_pred; + *(__m64 *)mb_pred[6] = mmx_pred; + *(__m64 *)mb_pred[7] = mmx_pred; +#else + int ii, jj; + for (jj = 0; jj < BLOCK_SIZE_8x8; jj++) + { + for (ii = 0; ii < BLOCK_SIZE_8x8; ii++) + { + mb_pred[jj][offset_x+ii]=(imgpel) pred; + } + } +#endif +} + +static void memset_8x8_row(h264_imgpel_macroblock_row_t *mb_pred, int offset_x, const imgpel row[8]) +{ +#ifdef _M_IX86 + // benski> can't believe the shitty code that the compiler generated... this code is better + __m64 mmx_pred = *(__m64 *)row; + mb_pred = (h264_imgpel_macroblock_row_t *)&mb_pred[0][offset_x]; + *(__m64 *)mb_pred[0] = mmx_pred; + *(__m64 *)mb_pred[1] = mmx_pred; + *(__m64 *)mb_pred[2] = mmx_pred; + *(__m64 *)mb_pred[3] = mmx_pred; + *(__m64 *)mb_pred[4] = mmx_pred; + *(__m64 *)mb_pred[5] = mmx_pred; + *(__m64 *)mb_pred[6] = mmx_pred; + *(__m64 *)mb_pred[7] = mmx_pred; +#else + int jj; + for (jj = 0; jj < BLOCK_SIZE_8x8; jj++) + { + memcpy(&mb_pred[jj][offset_x], row, 8); + } +#endif +} + +/*! + ************************************************************************************* + * \brief + * Prefiltering for Intra8x8 prediction + ************************************************************************************* + */ +static __forceinline void LowPassForIntra8x8Pred(imgpel *PredPel, int block_up_left, int block_up, int block_left) +{ + imgpel LoopArray[25]; + + memcpy(&LoopArray[0], &PredPel[0], 25 * sizeof(imgpel)); + + if(block_up_left) + { + if(block_up && block_left) + { + PredPel[0] = (imgpel) ((LoopArray[17] + (LoopArray[0]<<1) + LoopArray[1] + 2)>>2); + } + else + { + if(block_up) + PredPel[0] = (imgpel) ((LoopArray[0] + (LoopArray[0]<<1) + LoopArray[1] + 2)>>2); + else if (block_left) + PredPel[0] = (imgpel) ((LoopArray[0] + (LoopArray[0]<<1) + LoopArray[17] + 2)>>2); + } + } + + if(block_up) + { + if(block_up_left) + { + PredPel[1] = (imgpel) ((LoopArray[0] + (LoopArray[1]<<1) + LoopArray[2] + 2)>>2); + } + else + PredPel[1] = (imgpel) ((LoopArray[1] + (LoopArray[1]<<1) + LoopArray[2] + 2)>>2); + + + PredPel[2] = (imgpel) ((LoopArray[2-1] + (LoopArray[2]<<1) + LoopArray[2+1] + 2)>>2); + PredPel[3] = (imgpel) ((LoopArray[3-1] + (LoopArray[3]<<1) + LoopArray[3+1] + 2)>>2); + PredPel[4] = (imgpel) ((LoopArray[4-1] + (LoopArray[4]<<1) + LoopArray[4+1] + 2)>>2); + PredPel[5] = (imgpel) ((LoopArray[5-1] + (LoopArray[5]<<1) + LoopArray[5+1] + 2)>>2); + PredPel[6] = (imgpel) ((LoopArray[6-1] + (LoopArray[6]<<1) + LoopArray[6+1] + 2)>>2); + PredPel[7] = (imgpel) ((LoopArray[7-1] + (LoopArray[7]<<1) + LoopArray[7+1] + 2)>>2); + PredPel[8] = (imgpel) ((LoopArray[8-1] + (LoopArray[8]<<1) + LoopArray[8+1] + 2)>>2); + PredPel[9] = (imgpel) ((LoopArray[9-1] + (LoopArray[9]<<1) + LoopArray[9+1] + 2)>>2); + PredPel[10] = (imgpel) ((LoopArray[10-1] + (LoopArray[10]<<1) + LoopArray[10+1] + 2)>>2); + PredPel[11] = (imgpel) ((LoopArray[11-1] + (LoopArray[11]<<1) + LoopArray[11+1] + 2)>>2); + PredPel[12] = (imgpel) ((LoopArray[12-1] + (LoopArray[12]<<1) + LoopArray[12+1] + 2)>>2); + PredPel[13] = (imgpel) ((LoopArray[13-1] + (LoopArray[13]<<1) + LoopArray[13+1] + 2)>>2); + PredPel[14] = (imgpel) ((LoopArray[14-1] + (LoopArray[14]<<1) + LoopArray[14+1] + 2)>>2); + PredPel[15] = (imgpel) ((LoopArray[15-1] + (LoopArray[15]<<1) + LoopArray[15+1] + 2)>>2); + + PredPel[16] = (imgpel) ((LoopArray[16] + (LoopArray[16]<<1) + LoopArray[15] + 2)>>2); + } + + if(block_left) + { + if(block_up_left) + PredPel[17] = (imgpel) ((LoopArray[0] + (LoopArray[17]<<1) + LoopArray[18] + 2)>>2); + else + PredPel[17] = (imgpel) ((LoopArray[17] + (LoopArray[17]<<1) + LoopArray[18] + 2)>>2); + + PredPel[18] = (imgpel) ((LoopArray[18-1] + (LoopArray[18]<<1) + LoopArray[18+1] + 2)>>2); + PredPel[19] = (imgpel) ((LoopArray[19-1] + (LoopArray[19]<<1) + LoopArray[19+1] + 2)>>2); + PredPel[20] = (imgpel) ((LoopArray[20-1] + (LoopArray[20]<<1) + LoopArray[20+1] + 2)>>2); + PredPel[21] = (imgpel) ((LoopArray[21-1] + (LoopArray[21]<<1) + LoopArray[21+1] + 2)>>2); + PredPel[22] = (imgpel) ((LoopArray[22-1] + (LoopArray[22]<<1) + LoopArray[22+1] + 2)>>2); + PredPel[23] = (imgpel) ((LoopArray[23-1] + (LoopArray[23]<<1) + LoopArray[23+1] + 2)>>2); + + PredPel[24] = (imgpel) ((LoopArray[23] + (LoopArray[24]<<1) + LoopArray[24] + 2) >> 2); + } + + //memcpy(&PredPel[0], &LoopArray[0], 25 * sizeof(imgpel)); +} + +/*! + ************************************************************************************* + * \brief + * Prefiltering for Intra8x8 prediction (Horizontal) + ************************************************************************************* + */ +static __forceinline void LowPassForIntra8x8PredHor(imgpel *PredPel, int block_up_left, int block_up, int block_left) +{ + imgpel LoopArray[16]; + + memcpy(&LoopArray[0], &PredPel[0], 16 * sizeof(imgpel)); + + if(block_up_left) + { + if(block_up && block_left) + { + PredPel[0] = (imgpel) ((PredPel[17] + (LoopArray[0]<<1) + LoopArray[1] + 2)>>2); + } + else + { + if(block_up) + PredPel[0] = (imgpel) ((LoopArray[0] + (LoopArray[0]<<1) + LoopArray[1] + 2)>>2); + else if (block_left) + PredPel[0] = (imgpel) ((LoopArray[0] + (LoopArray[0]<<1) + PredPel[17] + 2)>>2); + } + } + + if(block_up) + { + if(block_up_left) + { + PredPel[1] = (imgpel) ((LoopArray[0] + (LoopArray[1]<<1) + LoopArray[2] + 2)>>2); + } + else + PredPel[1] = (imgpel) ((LoopArray[1] + (LoopArray[1]<<1) + LoopArray[2] + 2)>>2); + + + PredPel[2] = (imgpel) ((LoopArray[2-1] + (LoopArray[2]<<1) + LoopArray[2+1] + 2)>>2); + PredPel[3] = (imgpel) ((LoopArray[3-1] + (LoopArray[3]<<1) + LoopArray[3+1] + 2)>>2); + PredPel[4] = (imgpel) ((LoopArray[4-1] + (LoopArray[4]<<1) + LoopArray[4+1] + 2)>>2); + PredPel[5] = (imgpel) ((LoopArray[5-1] + (LoopArray[5]<<1) + LoopArray[5+1] + 2)>>2); + PredPel[6] = (imgpel) ((LoopArray[6-1] + (LoopArray[6]<<1) + LoopArray[6+1] + 2)>>2); + PredPel[7] = (imgpel) ((LoopArray[7-1] + (LoopArray[7]<<1) + LoopArray[7+1] + 2)>>2); + PredPel[8] = (imgpel) ((LoopArray[8-1] + (LoopArray[8]<<1) + LoopArray[8+1] + 2)>>2); + PredPel[9] = (imgpel) ((LoopArray[9-1] + (LoopArray[9]<<1) + LoopArray[9+1] + 2)>>2); + PredPel[10] = (imgpel) ((LoopArray[10-1] + (LoopArray[10]<<1) + LoopArray[10+1] + 2)>>2); + PredPel[11] = (imgpel) ((LoopArray[11-1] + (LoopArray[11]<<1) + LoopArray[11+1] + 2)>>2); + PredPel[12] = (imgpel) ((LoopArray[12-1] + (LoopArray[12]<<1) + LoopArray[12+1] + 2)>>2); + PredPel[13] = (imgpel) ((LoopArray[13-1] + (LoopArray[13]<<1) + LoopArray[13+1] + 2)>>2); + PredPel[14] = (imgpel) ((LoopArray[14-1] + (LoopArray[14]<<1) + LoopArray[14+1] + 2)>>2); + PredPel[15] = (imgpel) ((LoopArray[15-1] + (LoopArray[15]<<1) + PredPel[15+1] + 2)>>2); + PredPel[16] = (imgpel) ((PredPel[16] + (PredPel[16]<<1) + LoopArray[15] + 2)>>2); + } + + + //memcpy(&PredPel[0], &LoopArray[0], 17 * sizeof(imgpel)); +} + +/*! + ************************************************************************************* + * \brief + * Prefiltering for Intra8x8 prediction (Vertical) + ************************************************************************************* + */ +static __forceinline void LowPassForIntra8x8PredVer(imgpel *PredPel, int block_up_left, int block_up, int block_left) +{ + // These functions need some cleanup and can be further optimized. + // For convenience, let us copy all data for now. It is obvious that the filtering makes things a bit more "complex" + int i; + imgpel LoopArray[25]; + + //memcpy(&LoopArray[0], &PredPel[0], 25 * sizeof(imgpel)); + LoopArray[0] = PredPel[0]; + LoopArray[1] = PredPel[1]; + LoopArray[17] = PredPel[17]; + LoopArray[18] = PredPel[18]; + LoopArray[19] = PredPel[19]; + LoopArray[20] = PredPel[20]; + LoopArray[21] = PredPel[21]; + LoopArray[22] = PredPel[22]; + LoopArray[23] = PredPel[23]; + LoopArray[24] = PredPel[24]; + + if(block_up_left) + { + if(block_up && block_left) + { + PredPel[0] = (imgpel) ((LoopArray[17] + (LoopArray[0]<<1) + LoopArray[1] + 2)>>2); + } + else + { + if(block_up) + PredPel[0] = (imgpel) ((LoopArray[0] + (LoopArray[0]<<1) + LoopArray[1] + 2)>>2); + else if (block_left) + PredPel[0] = (imgpel) ((LoopArray[0] + (LoopArray[0]<<1) + LoopArray[17] + 2)>>2); + } + } + + if(block_left) + { + if(block_up_left) + PredPel[17] = (imgpel) ((LoopArray[0] + (LoopArray[17]<<1) + LoopArray[18] + 2)>>2); + else + PredPel[17] = (imgpel) ((LoopArray[17] + (LoopArray[17]<<1) + LoopArray[18] + 2)>>2); + + for(i = 18; i <24; i++) + { + PredPel[i] = (imgpel) ((LoopArray[i-1] + (LoopArray[i]<<1) + LoopArray[i+1] + 2)>>2); + } + PredPel[24] = (imgpel) ((LoopArray[23] + (LoopArray[24]<<1) + LoopArray[24] + 2) >> 2); + } + + //memcpy(&PredPel[0], &LoopArray[0], 25 * sizeof(imgpel)); +} + +/*! + *********************************************************************** + * \brief + * makes and returns 8x8 DC prediction mode + * + * \return + * DECODING_OK decoding of intraprediction mode was sucessfull \n + * + *********************************************************************** + */ +static inline int intra8x8_dc_pred(Macroblock *currMB, //!< current macroblock + ColorPlane pl, //!< current image plane + int ioff, //!< pixel offset X within MB + int joff) //!< pixel offset Y within MB +{ + int s0 = 0; + imgpel PredPel[25]; // array of predictor pels + Slice *currSlice = currMB->p_Slice; + VideoParameters *p_Vid = currMB->p_Vid; + + StorablePicture *dec_picture = p_Vid->dec_picture; + imgpel **imgY = (pl) ? dec_picture->imgUV[pl - 1]->img : dec_picture->imgY->img; // For MB level frame/field coding tools -- set default to imgY + + PixelPos pix_a[8]; + PixelPos pix_b, pix_c, pix_d; + + int block_available_up; + int block_available_left; + int block_available_up_left; + int block_available_up_right; + + imgpel *pred_pels; + + if (ioff == 0) + { + p_Vid->getNeighbourNPLumaNB(currMB, joff + 0, &pix_a[0]); + p_Vid->getNeighbourNPLumaNB(currMB, joff + 1, &pix_a[1]); + p_Vid->getNeighbourNPLumaNB(currMB, joff + 2, &pix_a[2]); + p_Vid->getNeighbourNPLumaNB(currMB, joff + 3, &pix_a[3]); + p_Vid->getNeighbourNPLumaNB(currMB, joff + 4, &pix_a[4]); + p_Vid->getNeighbourNPLumaNB(currMB, joff + 5, &pix_a[5]); + p_Vid->getNeighbourNPLumaNB(currMB, joff + 6, &pix_a[6]); + p_Vid->getNeighbourNPLumaNB(currMB, joff + 7, &pix_a[7]); + + p_Vid->getNeighbour0XLuma(currMB, joff - 1, &pix_b); + p_Vid->getNeighbourPXLumaNB(currMB, 8, joff - 1, &pix_c); + p_Vid->getNeighbourNXLuma(currMB, joff - 1, &pix_d); + } + else + { // ioff == 8 + p_Vid->getNeighbourPPLumaNB(currMB, ioff - 1, joff + 0, &pix_a[0]); + p_Vid->getNeighbourPPLumaNB(currMB, ioff - 1, joff + 1, &pix_a[1]); + p_Vid->getNeighbourPPLumaNB(currMB, ioff - 1, joff + 2, &pix_a[2]); + p_Vid->getNeighbourPPLumaNB(currMB, ioff - 1, joff + 3, &pix_a[3]); + p_Vid->getNeighbourPPLumaNB(currMB, ioff - 1, joff + 4, &pix_a[4]); + p_Vid->getNeighbourPPLumaNB(currMB, ioff - 1, joff + 5, &pix_a[5]); + p_Vid->getNeighbourPPLumaNB(currMB, ioff - 1, joff + 6, &pix_a[6]); + p_Vid->getNeighbourPPLumaNB(currMB, ioff - 1, joff + 7, &pix_a[7]); + + p_Vid->getNeighbourPXLumaNB(currMB, ioff , joff - 1, &pix_b); + p_Vid->getNeighbourPXLuma(currMB, ioff + 8, joff - 1, &pix_c); + p_Vid->getNeighbourPXLumaNB(currMB, ioff - 1, joff - 1, &pix_d); + } + pix_c.available = pix_c.available &&!(ioff == 8 && joff == 8); + + if (p_Vid->active_pps->constrained_intra_pred_flag) + { + int i; + for (i=0, block_available_left=1; i<8;i++) + block_available_left &= pix_a[i].available ? p_Vid->intra_block[pix_a[i].mb_addr]: 0; + block_available_up = pix_b.available ? p_Vid->intra_block [pix_b.mb_addr] : 0; + block_available_up_right = pix_c.available ? p_Vid->intra_block [pix_c.mb_addr] : 0; + block_available_up_left = pix_d.available ? p_Vid->intra_block [pix_d.mb_addr] : 0; + } + else + { + block_available_left = pix_a[0].available; + block_available_up = pix_b.available; + block_available_up_right = pix_c.available; + block_available_up_left = pix_d.available; + } + + // form predictor pels + if (block_available_up) + { + pred_pels = &imgY[pix_b.pos_y][pix_b.pos_x]; + PredPel[1] = pred_pels[0]; + PredPel[2] = pred_pels[1]; + PredPel[3] = pred_pels[2]; + PredPel[4] = pred_pels[3]; + PredPel[5] = pred_pels[4]; + PredPel[6] = pred_pels[5]; + PredPel[7] = pred_pels[6]; + PredPel[8] = pred_pels[7]; + } + else + { + PredPel[1] = PredPel[2] = PredPel[3] = PredPel[4] = PredPel[5] = PredPel[6] = PredPel[7] = PredPel[8] = (imgpel) p_Vid->dc_pred_value_comp[pl]; + } + + if (block_available_up_right) + { + pred_pels = &imgY[pix_c.pos_y][pix_c.pos_x]; + PredPel[9] = pred_pels[0]; + PredPel[10] = pred_pels[1]; + PredPel[11] = pred_pels[2]; + PredPel[12] = pred_pels[3]; + PredPel[13] = pred_pels[4]; + PredPel[14] = pred_pels[5]; + PredPel[15] = pred_pels[6]; + PredPel[16] = pred_pels[7]; + + } + else + { + PredPel[9] = PredPel[10] = PredPel[11] = PredPel[12] = PredPel[13] = PredPel[14] = PredPel[15] = PredPel[16] = PredPel[8]; + } + + if (block_available_left) + { + PredPel[17] = imgY[pix_a[0].pos_y][pix_a[0].pos_x]; + PredPel[18] = imgY[pix_a[1].pos_y][pix_a[0].pos_x]; + PredPel[19] = imgY[pix_a[2].pos_y][pix_a[0].pos_x]; + PredPel[20] = imgY[pix_a[3].pos_y][pix_a[0].pos_x]; + PredPel[21] = imgY[pix_a[4].pos_y][pix_a[0].pos_x]; + PredPel[22] = imgY[pix_a[5].pos_y][pix_a[0].pos_x]; + PredPel[23] = imgY[pix_a[6].pos_y][pix_a[0].pos_x]; + PredPel[24] = imgY[pix_a[7].pos_y][pix_a[0].pos_x]; + } + else + { + PredPel[17] = PredPel[18] = PredPel[19] = PredPel[20] = PredPel[21] = PredPel[22] = PredPel[23] = PredPel[24] = (imgpel) p_Vid->dc_pred_value_comp[pl]; + } + + if (block_available_up_left) + { + PredPel[0] = imgY[pix_d.pos_y][pix_d.pos_x]; + } + else + { + PredPel[0] = (imgpel) p_Vid->dc_pred_value_comp[pl]; + } + + LowPassForIntra8x8Pred(&(PredPel[0]), block_available_up_left, block_available_up, block_available_left); + + if (block_available_up && block_available_left) + { + // no edge + s0 = (PredPel[1] + PredPel[2] + PredPel[3] + PredPel[4] + PredPel[5] + PredPel[6] + PredPel[7] + PredPel[8] + PredPel[17] + PredPel[18] + PredPel[19] + PredPel[20] + PredPel[21] + PredPel[22] + PredPel[23] + PredPel[24] + 8) >> 4; + } + else if (!block_available_up && block_available_left) + { + // upper edge + s0 = (PredPel[17] + PredPel[18] + PredPel[19] + PredPel[20] + PredPel[21] + PredPel[22] + PredPel[23] + PredPel[24] + 4) >> 3; + } + else if (block_available_up && !block_available_left) + { + // left edge + s0 = (PredPel[1] + PredPel[2] + PredPel[3] + PredPel[4] + PredPel[5] + PredPel[6] + PredPel[7] + PredPel[8] + 4) >> 3; + } + else //if (!block_available_up && !block_available_left) + { + // top left corner, nothing to predict from + s0 = p_Vid->dc_pred_value_comp[pl]; + } + + memset_8x8(&currSlice->mb_pred[pl][joff], ioff, s0); + + return DECODING_OK; +} + +/*! + *********************************************************************** + * \brief + * makes and returns 8x8 vertical prediction mode + * + * \return + * DECODING_OK decoding of intraprediction mode was sucessfull \n + * + *********************************************************************** + */ +static inline int intra8x8_vert_pred(Macroblock *currMB, //!< current macroblock + ColorPlane pl, //!< current image plane + int ioff, //!< pixel offset X within MB + int joff) //!< pixel offset Y within MB +{ + Slice *currSlice = currMB->p_Slice; + VideoParameters *p_Vid = currMB->p_Vid; + + int i; + imgpel PredPel[25]; // array of predictor pels + imgpel **imgY = (pl) ? p_Vid->dec_picture->imgUV[pl - 1]->img : p_Vid->dec_picture->imgY->img; // For MB level frame/field coding tools -- set default to imgY + + PixelPos pix_a[8]; + PixelPos pix_b, pix_c, pix_d; + + int block_available_up; + int block_available_left; + int block_available_up_left; + int block_available_up_right; + + + imgpel *pred_pels; + + p_Vid->getNeighbourXPLumaNB_NoPos(currMB, ioff - 1, joff + 0, &pix_a[0]); + p_Vid->getNeighbourXPLumaNB_NoPos(currMB, ioff - 1, joff + 1, &pix_a[1]); + p_Vid->getNeighbourXPLumaNB_NoPos(currMB, ioff - 1, joff + 2, &pix_a[2]); + p_Vid->getNeighbourXPLumaNB_NoPos(currMB, ioff - 1, joff + 3, &pix_a[3]); + p_Vid->getNeighbourXPLumaNB_NoPos(currMB, ioff - 1, joff + 4, &pix_a[4]); + p_Vid->getNeighbourXPLumaNB_NoPos(currMB, ioff - 1, joff + 5, &pix_a[5]); + p_Vid->getNeighbourXPLumaNB_NoPos(currMB, ioff - 1, joff + 6, &pix_a[6]); + p_Vid->getNeighbourXPLumaNB_NoPos(currMB, ioff - 1, joff + 7, &pix_a[7]); + + p_Vid->getNeighbourPXLumaNB(currMB, ioff , joff - 1, &pix_b); + p_Vid->getNeighbourPXLuma(currMB, ioff + 8, joff - 1, &pix_c); + p_Vid->getNeighbourLuma(currMB, ioff - 1, joff - 1, &pix_d); + + pix_c.available = pix_c.available &&!(ioff == 8 && joff == 8); + + if (p_Vid->active_pps->constrained_intra_pred_flag) + { + for (i=0, block_available_left=1; i<8;i++) + block_available_left &= pix_a[i].available ? p_Vid->intra_block[pix_a[i].mb_addr]: 0; + block_available_up = pix_b.available ? p_Vid->intra_block [pix_b.mb_addr] : 0; + block_available_up_right = pix_c.available ? p_Vid->intra_block [pix_c.mb_addr] : 0; + block_available_up_left = pix_d.available ? p_Vid->intra_block [pix_d.mb_addr] : 0; + } + else + { + block_available_left = pix_a[0].available; + block_available_up = pix_b.available; + block_available_up_right = pix_c.available; + block_available_up_left = pix_d.available; + } + + if (!block_available_up) + printf ("warning: Intra_8x8_Vertical prediction mode not allowed at mb %d\n", (int) p_Vid->current_mb_nr); + + // form predictor pels + if (block_available_up) + { + pred_pels = &imgY[pix_b.pos_y][pix_b.pos_x]; + PredPel[1] = *(pred_pels ++); + PredPel[2] = *(pred_pels ++); + PredPel[3] = *(pred_pels ++); + PredPel[4] = *(pred_pels ++); + PredPel[5] = *(pred_pels ++); + PredPel[6] = *(pred_pels ++); + PredPel[7] = *(pred_pels ++); + PredPel[8] = *pred_pels; + } + else + { + PredPel[1] = PredPel[2] = PredPel[3] = PredPel[4] = PredPel[5] = PredPel[6] = PredPel[7] = PredPel[8] = (imgpel) p_Vid->dc_pred_value_comp[pl]; + } + + if (block_available_up_right) + { + pred_pels = &imgY[pix_c.pos_y][pix_c.pos_x]; + PredPel[9] = *(pred_pels ++); + PredPel[10] = *(pred_pels ++); + PredPel[11] = *(pred_pels ++); + PredPel[12] = *(pred_pels ++); + PredPel[13] = *(pred_pels ++); + PredPel[14] = *(pred_pels ++); + PredPel[15] = *(pred_pels ++); + PredPel[16] = *pred_pels; + } + else + { + PredPel[9] = PredPel[10] = PredPel[11] = PredPel[12] = PredPel[13] = PredPel[14] = PredPel[15] = PredPel[16] = PredPel[8]; + } + + if (block_available_up_left) + { + PredPel[0] = imgY[pix_d.pos_y][pix_d.pos_x]; + } + else + { + PredPel[0] = (imgpel) p_Vid->dc_pred_value_comp[pl]; + } + + LowPassForIntra8x8PredHor(&(PredPel[0]), block_available_up_left, block_available_up, block_available_left); + + memset_8x8_row(&currSlice->mb_pred[pl][joff], ioff, &PredPel[1]); + + return DECODING_OK; +} + +/*! + *********************************************************************** + * \brief + * makes and returns 8x8 horizontal prediction mode + * + * \return + * DECODING_OK decoding of intraprediction mode was sucessfull \n + * + *********************************************************************** + */ +static inline int intra8x8_hor_pred(Macroblock *currMB, //!< current macroblock + ColorPlane pl, //!< current image plane + int ioff, //!< pixel offset X within MB + int joff) //!< pixel offset Y within MB +{ + Slice *currSlice = currMB->p_Slice; + VideoParameters *p_Vid = currMB->p_Vid; + + + int i,j; + imgpel PredPel[25]; // array of predictor pels + imgpel **imgY = (pl) ? p_Vid->dec_picture->imgUV[pl - 1]->img : p_Vid->dec_picture->imgY->img; // For MB level frame/field coding tools -- set default to imgY + + PixelPos pix_a[8]; + PixelPos pix_b, pix_c, pix_d; + + int block_available_up; + int block_available_left; + int block_available_up_left; + int block_available_up_right; + int jpos; + + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 0, &pix_a[0]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 1, &pix_a[1]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 2, &pix_a[2]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 3, &pix_a[3]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 4, &pix_a[4]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 5, &pix_a[5]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 6, &pix_a[6]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 7, &pix_a[7]); + + p_Vid->getNeighbourPXLumaNB(currMB, ioff , joff - 1, &pix_b); + p_Vid->getNeighbourPXLuma(currMB, ioff + 8, joff - 1, &pix_c); + p_Vid->getNeighbourLuma(currMB, ioff - 1, joff - 1, &pix_d); + + pix_c.available = pix_c.available &&!(ioff == 8 && joff == 8); + + if (p_Vid->active_pps->constrained_intra_pred_flag) + { + for (i=0, block_available_left=1; i<8;i++) + block_available_left &= pix_a[i].available ? p_Vid->intra_block[pix_a[i].mb_addr]: 0; + block_available_up = pix_b.available ? p_Vid->intra_block [pix_b.mb_addr] : 0; + block_available_up_right = pix_c.available ? p_Vid->intra_block [pix_c.mb_addr] : 0; + block_available_up_left = pix_d.available ? p_Vid->intra_block [pix_d.mb_addr] : 0; + } + else + { + block_available_left = pix_a[0].available; + block_available_up = pix_b.available; + block_available_up_right = pix_c.available; + block_available_up_left = pix_d.available; + } + + if (!block_available_left) + printf ("warning: Intra_8x8_Horizontal prediction mode not allowed at mb %d\n", (int) p_Vid->current_mb_nr); + + // form predictor pels + if (block_available_left) + { + PredPel[17] = imgY[pix_a[0].pos_y][pix_a[0].pos_x]; + PredPel[18] = imgY[pix_a[1].pos_y][pix_a[1].pos_x]; + PredPel[19] = imgY[pix_a[2].pos_y][pix_a[2].pos_x]; + PredPel[20] = imgY[pix_a[3].pos_y][pix_a[3].pos_x]; + PredPel[21] = imgY[pix_a[4].pos_y][pix_a[4].pos_x]; + PredPel[22] = imgY[pix_a[5].pos_y][pix_a[5].pos_x]; + PredPel[23] = imgY[pix_a[6].pos_y][pix_a[6].pos_x]; + PredPel[24] = imgY[pix_a[7].pos_y][pix_a[7].pos_x]; + } + else + { + PredPel[17] = PredPel[18] = PredPel[19] = PredPel[20] = PredPel[21] = PredPel[22] = PredPel[23] = PredPel[24] = (imgpel) p_Vid->dc_pred_value_comp[pl]; + } + + if (block_available_up_left) + { + PredPel[0] = imgY[pix_d.pos_y][pix_d.pos_x]; + } + else + { + PredPel[0] = (imgpel) p_Vid->dc_pred_value_comp[pl]; + } + + LowPassForIntra8x8PredVer(&(PredPel[0]), block_available_up_left, block_available_up, block_available_left); + + for (j=0; j < BLOCK_SIZE_8x8; j++) + { + jpos = j + joff; + currSlice->mb_pred[pl][jpos][ioff] = + currSlice->mb_pred[pl][jpos][ioff+1] = + currSlice->mb_pred[pl][jpos][ioff+2] = + currSlice->mb_pred[pl][jpos][ioff+3] = + currSlice->mb_pred[pl][jpos][ioff+4] = + currSlice->mb_pred[pl][jpos][ioff+5] = + currSlice->mb_pred[pl][jpos][ioff+6] = + currSlice->mb_pred[pl][jpos][ioff+7] = (imgpel) (&PredPel[17])[j]; + } + + return DECODING_OK; +} + +/*! + *********************************************************************** + * \brief + * makes and returns 8x8 diagonal down right prediction mode + * + * \return + * DECODING_OK decoding of intraprediction mode was sucessfull \n + * + *********************************************************************** + */ +static inline int intra8x8_diag_down_right_pred(Macroblock *currMB, //!< current macroblock + ColorPlane pl, //!< current image plane + int ioff, //!< pixel offset X within MB + int joff) //!< pixel offset Y within MB +{ + Slice *currSlice = currMB->p_Slice; + VideoParameters *p_Vid = currMB->p_Vid; + + + int i; + imgpel PredPel[25]; // array of predictor pels + imgpel **imgY = (pl) ? p_Vid->dec_picture->imgUV[pl - 1]->img : p_Vid->dec_picture->imgY->img; // For MB level frame/field coding tools -- set default to imgY + + PixelPos pix_a[8]; + PixelPos pix_b, pix_c, pix_d; +h264_imgpel_macroblock_row_t *pred; + int block_available_up; + int block_available_left; + int block_available_up_left; + int block_available_up_right; + + imgpel *pred_pels; + + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 0, &pix_a[0]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 1, &pix_a[1]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 2, &pix_a[2]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 3, &pix_a[3]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 4, &pix_a[4]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 5, &pix_a[5]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 6, &pix_a[6]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 7, &pix_a[7]); + + p_Vid->getNeighbourPXLumaNB(currMB, ioff , joff - 1, &pix_b); + p_Vid->getNeighbourPXLuma(currMB, ioff + 8, joff - 1, &pix_c); + p_Vid->getNeighbourLuma(currMB, ioff - 1, joff - 1, &pix_d); + + pix_c.available = pix_c.available &&!(ioff == 8 && joff == 8); + + if (p_Vid->active_pps->constrained_intra_pred_flag) + { + for (i=0, block_available_left=1; i<8;i++) + block_available_left &= pix_a[i].available ? p_Vid->intra_block[pix_a[i].mb_addr]: 0; + block_available_up = pix_b.available ? p_Vid->intra_block [pix_b.mb_addr] : 0; + block_available_up_right = pix_c.available ? p_Vid->intra_block [pix_c.mb_addr] : 0; + block_available_up_left = pix_d.available ? p_Vid->intra_block [pix_d.mb_addr] : 0; + } + else + { + block_available_left = pix_a[0].available; + block_available_up = pix_b.available; + block_available_up_right = pix_c.available; + block_available_up_left = pix_d.available; + } + + if ((!block_available_up)||(!block_available_left)||(!block_available_up_left)) + printf ("warning: Intra_8x8_Diagonal_Down_Right prediction mode not allowed at mb %d\n", (int) p_Vid->current_mb_nr); + + // form predictor pels + if (block_available_up) + { + pred_pels = &imgY[pix_b.pos_y][pix_b.pos_x]; + PredPel[1] = pred_pels[0]; + PredPel[2] = pred_pels[1]; + PredPel[3] = pred_pels[2]; + PredPel[4] = pred_pels[3]; + PredPel[5] = pred_pels[4]; + PredPel[6] = pred_pels[5]; + PredPel[7] = pred_pels[6]; + PredPel[8] = pred_pels[7]; + } + else + { + PredPel[1] = PredPel[2] = PredPel[3] = PredPel[4] = PredPel[5] = PredPel[6] = PredPel[7] = PredPel[8] = (imgpel) p_Vid->dc_pred_value_comp[pl]; + } + + if (block_available_up_right) + { + pred_pels = &imgY[pix_c.pos_y][pix_c.pos_x]; + PredPel[9] = pred_pels[0]; + PredPel[10] = pred_pels[1]; + PredPel[11] = pred_pels[2]; + PredPel[12] = pred_pels[3]; + PredPel[13] = pred_pels[4]; + PredPel[14] = pred_pels[5]; + PredPel[15] = pred_pels[6]; + PredPel[16] = pred_pels[7]; + + } + else + { + PredPel[9] = PredPel[10] = PredPel[11] = PredPel[12] = PredPel[13] = PredPel[14] = PredPel[15] = PredPel[16] = PredPel[8]; + } + + if (block_available_left) + { + PredPel[17] = imgY[pix_a[0].pos_y][pix_a[0].pos_x]; + PredPel[18] = imgY[pix_a[1].pos_y][pix_a[1].pos_x]; + PredPel[19] = imgY[pix_a[2].pos_y][pix_a[2].pos_x]; + PredPel[20] = imgY[pix_a[3].pos_y][pix_a[3].pos_x]; + PredPel[21] = imgY[pix_a[4].pos_y][pix_a[4].pos_x]; + PredPel[22] = imgY[pix_a[5].pos_y][pix_a[5].pos_x]; + PredPel[23] = imgY[pix_a[6].pos_y][pix_a[6].pos_x]; + PredPel[24] = imgY[pix_a[7].pos_y][pix_a[7].pos_x]; + } + else + { + PredPel[17] = PredPel[18] = PredPel[19] = PredPel[20] = PredPel[21] = PredPel[22] = PredPel[23] = PredPel[24] = (imgpel) p_Vid->dc_pred_value_comp[pl]; + } + + if (block_available_up_left) + { + PredPel[0] = imgY[pix_d.pos_y][pix_d.pos_x]; + } + else + { + PredPel[0] = (imgpel) p_Vid->dc_pred_value_comp[pl]; + } + + LowPassForIntra8x8Pred(&(PredPel[0]), block_available_up_left, block_available_up, block_available_left); + + // Mode DIAG_DOWN_RIGHT_PRED + pred = &currSlice->mb_pred[pl][joff]; + pred[0+7][ioff+0] = (imgpel) ((PredPel[24] + PredPel[22] + 2*(PredPel[23]) + 2) >> 2); + pred[0+6][ioff+0] = + pred[0+7][ioff+1] = (imgpel) ((PredPel[23] + PredPel[21] + 2*(PredPel[22]) + 2) >> 2); + pred[0+5][ioff+0] = + pred[0+6][ioff+1] = + pred[0+7][ioff+2] = (imgpel) ((PredPel[22] + PredPel[20] + 2*(PredPel[21]) + 2) >> 2); + pred[0+4][ioff+0] = + pred[0+5][ioff+1] = + pred[0+6][ioff+2] = + pred[0+7][ioff+3] = (imgpel) ((PredPel[21] + PredPel[19] + 2*(PredPel[20]) + 2) >> 2); + pred[0+3][ioff+0] = + pred[0+4][ioff+1] = + pred[0+5][ioff+2] = + pred[0+6][ioff+3] = + pred[0+7][ioff+4] = (imgpel) ((PredPel[20] + PredPel[18] + 2*(PredPel[19]) + 2) >> 2); + pred[0+2][ioff+0] = + pred[0+3][ioff+1] = + pred[0+4][ioff+2] = + pred[0+5][ioff+3] = + pred[0+6][ioff+4] = + pred[0+7][ioff+5] = (imgpel) ((PredPel[19] + PredPel[17] + 2*(PredPel[18]) + 2) >> 2); + pred[0+1][ioff+0] = + pred[0+2][ioff+1] = + pred[0+3][ioff+2] = + pred[0+4][ioff+3] = + pred[0+5][ioff+4] = + pred[0+6][ioff+5] = + pred[0+7][ioff+6] = (imgpel) ((PredPel[18] + PredPel[0] + 2*(PredPel[17]) + 2) >> 2); + pred[0+0][ioff+0] = + pred[0+1][ioff+1] = + pred[0+2][ioff+2] = + pred[0+3][ioff+3] = + pred[0+4][ioff+4] = + pred[0+5][ioff+5] = + pred[0+6][ioff+6] = + pred[0+7][ioff+7] = (imgpel) ((PredPel[17] + PredPel[1] + 2*(PredPel[0]) + 2) >> 2); + pred[0+0][ioff+1] = + pred[0+1][ioff+2] = + pred[0+2][ioff+3] = + pred[0+3][ioff+4] = + pred[0+4][ioff+5] = + pred[0+5][ioff+6] = + pred[0+6][ioff+7] = (imgpel) ((PredPel[0] + PredPel[2] + 2*(PredPel[1]) + 2) >> 2); + pred[0+0][ioff+2] = + pred[0+1][ioff+3] = + pred[0+2][ioff+4] = + pred[0+3][ioff+5] = + pred[0+4][ioff+6] = + pred[0+5][ioff+7] = (imgpel) ((PredPel[1] + PredPel[3] + 2*(PredPel[2]) + 2) >> 2); + pred[0+0][ioff+3] = + pred[0+1][ioff+4] = + pred[0+2][ioff+5] = + pred[0+3][ioff+6] = + pred[0+4][ioff+7] = (imgpel) ((PredPel[2] + PredPel[4] + 2*(PredPel[3]) + 2) >> 2); + pred[0+0][ioff+4] = + pred[0+1][ioff+5] = + pred[0+2][ioff+6] = + pred[0+3][ioff+7] = (imgpel) ((PredPel[3] + PredPel[5] + 2*(PredPel[4]) + 2) >> 2); + pred[0+0][ioff+5] = + pred[0+1][ioff+6] = + pred[0+2][ioff+7] = (imgpel) ((PredPel[4] + PredPel[6] + 2*(PredPel[5]) + 2) >> 2); + pred[0+0][ioff+6] = + pred[0+1][ioff+7] = (imgpel) ((PredPel[5] + PredPel[7] + 2*(PredPel[6]) + 2) >> 2); + pred[0+0][ioff+7] = (imgpel) ((PredPel[6] + PredPel[8] + 2*(PredPel[7]) + 2) >> 2); + + return DECODING_OK; +} + +/*! + *********************************************************************** + * \brief + * makes and returns 8x8 diagonal down left prediction mode + * + * \return + * DECODING_OK decoding of intraprediction mode was sucessfull \n + * + *********************************************************************** + */ +static inline int intra8x8_diag_down_left_pred(Macroblock *currMB, //!< current macroblock + ColorPlane pl, //!< current image plane + int ioff, //!< pixel offset X within MB + int joff) //!< pixel offset Y within MB +{ + Slice *currSlice = currMB->p_Slice; + VideoParameters *p_Vid = currMB->p_Vid; + h264_imgpel_macroblock_row_t *pred; + int i; + imgpel PredPel[25]; // array of predictor pels + imgpel **imgY = (pl) ? p_Vid->dec_picture->imgUV[pl - 1]->img : p_Vid->dec_picture->imgY->img; // For MB level frame/field coding tools -- set default to imgY + + PixelPos pix_a[8]; + PixelPos pix_b, pix_c, pix_d; + + int block_available_up; + int block_available_left; + int block_available_up_left; + int block_available_up_right; + + + imgpel *pred_pels; + + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 0, &pix_a[0]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 1, &pix_a[1]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 2, &pix_a[2]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 3, &pix_a[3]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 4, &pix_a[4]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 5, &pix_a[5]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 6, &pix_a[6]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 7, &pix_a[7]); + + p_Vid->getNeighbourPXLumaNB(currMB, ioff , joff - 1, &pix_b); + p_Vid->getNeighbourPXLuma(currMB, ioff + 8, joff - 1, &pix_c); + p_Vid->getNeighbourLuma(currMB, ioff - 1, joff - 1, &pix_d); + + pix_c.available = pix_c.available &&!(ioff == 8 && joff == 8); + + if (p_Vid->active_pps->constrained_intra_pred_flag) + { + for (i=0, block_available_left=1; i<8;i++) + block_available_left &= pix_a[i].available ? p_Vid->intra_block[pix_a[i].mb_addr]: 0; + block_available_up = pix_b.available ? p_Vid->intra_block [pix_b.mb_addr] : 0; + block_available_up_right = pix_c.available ? p_Vid->intra_block [pix_c.mb_addr] : 0; + block_available_up_left = pix_d.available ? p_Vid->intra_block [pix_d.mb_addr] : 0; + } + else + { + block_available_left = pix_a[0].available; + block_available_up = pix_b.available; + block_available_up_right = pix_c.available; + block_available_up_left = pix_d.available; + } + + if (!block_available_up) + printf ("warning: Intra_8x8_Diagonal_Down_Left prediction mode not allowed at mb %d\n", (int) p_Vid->current_mb_nr); + + // form predictor pels + if (block_available_up) + { + pred_pels = &imgY[pix_b.pos_y][pix_b.pos_x]; + PredPel[1] = pred_pels[0]; + PredPel[2] = pred_pels[1]; + PredPel[3] = pred_pels[2]; + PredPel[4] = pred_pels[3]; + PredPel[5] = pred_pels[4]; + PredPel[6] = pred_pels[5]; + PredPel[7] = pred_pels[6]; + PredPel[8] = pred_pels[7]; + } + else + { + PredPel[1] = PredPel[2] = PredPel[3] = PredPel[4] = PredPel[5] = PredPel[6] = PredPel[7] = PredPel[8] = (imgpel) p_Vid->dc_pred_value_comp[pl]; + } + + if (block_available_up_right) + { + pred_pels = &imgY[pix_c.pos_y][pix_c.pos_x]; + PredPel[9] = pred_pels[0]; + PredPel[10] = pred_pels[1]; + PredPel[11] = pred_pels[2]; + PredPel[12] = pred_pels[3]; + PredPel[13] = pred_pels[4]; + PredPel[14] = pred_pels[5]; + PredPel[15] = pred_pels[6]; + PredPel[16] = pred_pels[7]; + + } + else + { + PredPel[9] = PredPel[10] = PredPel[11] = PredPel[12] = PredPel[13] = PredPel[14] = PredPel[15] = PredPel[16] = PredPel[8]; + } + + if (block_available_left) + { + PredPel[17] = imgY[pix_a[0].pos_y][pix_a[0].pos_x]; + PredPel[18] = imgY[pix_a[1].pos_y][pix_a[1].pos_x]; + PredPel[19] = imgY[pix_a[2].pos_y][pix_a[2].pos_x]; + PredPel[20] = imgY[pix_a[3].pos_y][pix_a[3].pos_x]; + PredPel[21] = imgY[pix_a[4].pos_y][pix_a[4].pos_x]; + PredPel[22] = imgY[pix_a[5].pos_y][pix_a[5].pos_x]; + PredPel[23] = imgY[pix_a[6].pos_y][pix_a[6].pos_x]; + PredPel[24] = imgY[pix_a[7].pos_y][pix_a[7].pos_x]; + } + else + { + PredPel[17] = PredPel[18] = PredPel[19] = PredPel[20] = PredPel[21] = PredPel[22] = PredPel[23] = PredPel[24] = (imgpel) p_Vid->dc_pred_value_comp[pl]; + } + + if (block_available_up_left) + { + PredPel[0] = imgY[pix_d.pos_y][pix_d.pos_x]; + } + else + { + PredPel[0] = (imgpel) p_Vid->dc_pred_value_comp[pl]; + } + + LowPassForIntra8x8Pred(&(PredPel[0]), block_available_up_left, block_available_up, block_available_left); + + // Mode DIAG_DOWN_LEFT_PRED + pred = &currSlice->mb_pred[pl][joff]; + pred[0+0][ioff+0] = (imgpel) ((PredPel[1] + PredPel[3] + 2*(PredPel[2]) + 2) >> 2); + pred[0+1][ioff+0] = + pred[0+0][ioff+1] = (imgpel) ((PredPel[2] + PredPel[4] + 2*(PredPel[3]) + 2) >> 2); + pred[0+2][ioff+0] = + pred[0+1][ioff+1] = + pred[0+0][ioff+2] = (imgpel) ((PredPel[3] + PredPel[5] + 2*(PredPel[4]) + 2) >> 2); + pred[0+3][ioff+0] = + pred[0+2][ioff+1] = + pred[0+1][ioff+2] = + pred[0+0][ioff+3] = (imgpel) ((PredPel[4] + PredPel[6] + 2*(PredPel[5]) + 2) >> 2); + pred[0+4][ioff+0] = + pred[0+3][ioff+1] = + pred[0+2][ioff+2] = + pred[0+1][ioff+3] = + pred[0+0][ioff+4] = (imgpel) ((PredPel[5] + PredPel[7] + 2*(PredPel[6]) + 2) >> 2); + pred[0+5][ioff+0] = + pred[0+4][ioff+1] = + pred[0+3][ioff+2] = + pred[0+2][ioff+3] = + pred[0+1][ioff+4] = + pred[0+0][ioff+5] = (imgpel) ((PredPel[6] + PredPel[8] + 2*(PredPel[7]) + 2) >> 2); + pred[0+6][ioff+0] = + pred[0+5][ioff+1] = + pred[0+4][ioff+2] = + pred[0+3][ioff+3] = + pred[0+2][ioff+4] = + pred[0+1][ioff+5] = + pred[0+0][ioff+6] = (imgpel) ((PredPel[7] + PredPel[9] + 2*(PredPel[8]) + 2) >> 2); + pred[0+7][ioff+0] = + pred[0+6][ioff+1] = + pred[0+5][ioff+2] = + pred[0+4][ioff+3] = + pred[0+3][ioff+4] = + pred[0+2][ioff+5] = + pred[0+1][ioff+6] = + pred[0+0][ioff+7] = (imgpel) ((PredPel[8] + PredPel[10] + 2*(PredPel[9]) + 2) >> 2); + pred[0+7][ioff+1] = + pred[0+6][ioff+2] = + pred[0+5][ioff+3] = + pred[0+4][ioff+4] = + pred[0+3][ioff+5] = + pred[0+2][ioff+6] = + pred[0+1][ioff+7] = (imgpel) ((PredPel[9] + PredPel[11] + 2*(PredPel[10]) + 2) >> 2); + pred[0+7][ioff+2] = + pred[0+6][ioff+3] = + pred[0+5][ioff+4] = + pred[0+4][ioff+5] = + pred[0+3][ioff+6] = + pred[0+2][ioff+7] = (imgpel) ((PredPel[10] + PredPel[12] + 2*(PredPel[11]) + 2) >> 2); + pred[0+7][ioff+3] = + pred[0+6][ioff+4] = + pred[0+5][ioff+5] = + pred[0+4][ioff+6] = + pred[0+3][ioff+7] = (imgpel) ((PredPel[11] + PredPel[13] + 2*(PredPel[12]) + 2) >> 2); + pred[0+7][ioff+4] = + pred[0+6][ioff+5] = + pred[0+5][ioff+6] = + pred[0+4][ioff+7] = (imgpel) ((PredPel[12] + PredPel[14] + 2*(PredPel[13]) + 2) >> 2); + pred[0+7][ioff+5] = + pred[0+6][ioff+6] = + pred[0+5][ioff+7] = (imgpel) ((PredPel[13] + PredPel[15] + 2*(PredPel[14]) + 2) >> 2); + pred[0+7][ioff+6] = + pred[0+6][ioff+7] = (imgpel) ((PredPel[14] + PredPel[16] + 2*(PredPel[15]) + 2) >> 2); + pred[0+7][ioff+7] = (imgpel) ((PredPel[15] + 3*(PredPel[16]) + 2) >> 2); + + return DECODING_OK; +} + +/*! + *********************************************************************** + * \brief + * makes and returns 8x8 vertical right prediction mode + * + * \return + * DECODING_OK decoding of intraprediction mode was sucessfull \n + * + *********************************************************************** + */ +static inline int intra8x8_vert_right_pred(Macroblock *currMB, //!< current macroblock + ColorPlane pl, //!< current image plane + int ioff, //!< pixel offset X within MB + int joff) //!< pixel offset Y within MB +{ + Slice *currSlice = currMB->p_Slice; + VideoParameters *p_Vid = currMB->p_Vid; + h264_imgpel_macroblock_row_t *pred; + int i; + imgpel PredPel[25]; // array of predictor pels + imgpel **imgY = (pl) ? p_Vid->dec_picture->imgUV[pl - 1]->img : p_Vid->dec_picture->imgY->img; // For MB level frame/field coding tools -- set default to imgY + + PixelPos pix_a[8]; + PixelPos pix_b, pix_c, pix_d; + + int block_available_up; + int block_available_left; + int block_available_up_left; + int block_available_up_right; + imgpel *pred_pels; + + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 0, &pix_a[0]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 1, &pix_a[1]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 2, &pix_a[2]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 3, &pix_a[3]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 4, &pix_a[4]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 5, &pix_a[5]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 6, &pix_a[6]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 7, &pix_a[7]); + + p_Vid->getNeighbourPXLumaNB(currMB, ioff , joff - 1, &pix_b); + p_Vid->getNeighbourPXLuma(currMB, ioff + 8, joff - 1, &pix_c); + p_Vid->getNeighbourLuma(currMB, ioff - 1, joff - 1, &pix_d); + + pix_c.available = pix_c.available &&!(ioff == 8 && joff == 8); + + if (p_Vid->active_pps->constrained_intra_pred_flag) + { + for (i=0, block_available_left=1; i<8;i++) + block_available_left &= pix_a[i].available ? p_Vid->intra_block[pix_a[i].mb_addr]: 0; + block_available_up = pix_b.available ? p_Vid->intra_block [pix_b.mb_addr] : 0; + block_available_up_right = pix_c.available ? p_Vid->intra_block [pix_c.mb_addr] : 0; + block_available_up_left = pix_d.available ? p_Vid->intra_block [pix_d.mb_addr] : 0; + } + else + { + block_available_left = pix_a[0].available; + block_available_up = pix_b.available; + block_available_up_right = pix_c.available; + block_available_up_left = pix_d.available; + } + + if ((!block_available_up)||(!block_available_left)||(!block_available_up_left)) + printf ("warning: Intra_8x8_Vertical_Right prediction mode not allowed at mb %d\n", (int) p_Vid->current_mb_nr); + + // form predictor pels + if (block_available_up) + { + pred_pels = &imgY[pix_b.pos_y][pix_b.pos_x]; + PredPel[1] = pred_pels[0]; + PredPel[2] = pred_pels[1]; + PredPel[3] = pred_pels[2]; + PredPel[4] = pred_pels[3]; + PredPel[5] = pred_pels[4]; + PredPel[6] = pred_pels[5]; + PredPel[7] = pred_pels[6]; + PredPel[8] = pred_pels[7]; + } + else + { + PredPel[1] = PredPel[2] = PredPel[3] = PredPel[4] = PredPel[5] = PredPel[6] = PredPel[7] = PredPel[8] = (imgpel) p_Vid->dc_pred_value_comp[pl]; + } + + if (block_available_up_right) + { + pred_pels = &imgY[pix_c.pos_y][pix_c.pos_x]; + PredPel[9] = pred_pels[0]; + PredPel[10] = pred_pels[1]; + PredPel[11] = pred_pels[2]; + PredPel[12] = pred_pels[3]; + PredPel[13] = pred_pels[4]; + PredPel[14] = pred_pels[5]; + PredPel[15] = pred_pels[6]; + PredPel[16] = pred_pels[7]; + + } + else + { + PredPel[9] = PredPel[10] = PredPel[11] = PredPel[12] = PredPel[13] = PredPel[14] = PredPel[15] = PredPel[16] = PredPel[8]; + } + + if (block_available_left) + { + PredPel[17] = imgY[pix_a[0].pos_y][pix_a[0].pos_x]; + PredPel[18] = imgY[pix_a[1].pos_y][pix_a[1].pos_x]; + PredPel[19] = imgY[pix_a[2].pos_y][pix_a[2].pos_x]; + PredPel[20] = imgY[pix_a[3].pos_y][pix_a[3].pos_x]; + PredPel[21] = imgY[pix_a[4].pos_y][pix_a[4].pos_x]; + PredPel[22] = imgY[pix_a[5].pos_y][pix_a[5].pos_x]; + PredPel[23] = imgY[pix_a[6].pos_y][pix_a[6].pos_x]; + PredPel[24] = imgY[pix_a[7].pos_y][pix_a[7].pos_x]; + } + else + { + PredPel[17] = PredPel[18] = PredPel[19] = PredPel[20] = PredPel[21] = PredPel[22] = PredPel[23] = PredPel[24] = (imgpel) p_Vid->dc_pred_value_comp[pl]; + } + + if (block_available_up_left) + { + PredPel[0] = imgY[pix_d.pos_y][pix_d.pos_x]; + } + else + { + PredPel[0] = (imgpel) p_Vid->dc_pred_value_comp[pl]; + } + + LowPassForIntra8x8Pred(&(PredPel[0]), block_available_up_left, block_available_up, block_available_left); +pred = &currSlice->mb_pred[pl][joff]; + pred[0+0][ioff+0] = + pred[0+2][ioff+1] = + pred[0+4][ioff+2] = + pred[0+6][ioff+3] = (imgpel) ((PredPel[0] + PredPel[1] + 1) >> 1); + pred[0+0][ioff+1] = + pred[0+2][ioff+2] = + pred[0+4][ioff+3] = + pred[0+6][ioff+4] = (imgpel) ((PredPel[1] + PredPel[2] + 1) >> 1); + pred[0+0][ioff+2] = + pred[0+2][ioff+3] = + pred[0+4][ioff+4] = + pred[0+6][ioff+5] = (imgpel) ((PredPel[2] + PredPel[3] + 1) >> 1); + pred[0+0][ioff+3] = + pred[0+2][ioff+4] = + pred[0+4][ioff+5] = + pred[0+6][ioff+6] = (imgpel) ((PredPel[3] + PredPel[4] + 1) >> 1); + pred[0+0][ioff+4] = + pred[0+2][ioff+5] = + pred[0+4][ioff+6] = + pred[0+6][ioff+7] = (imgpel) ((PredPel[4] + PredPel[5] + 1) >> 1); + pred[0+0][ioff+5] = + pred[0+2][ioff+6] = + pred[0+4][ioff+7] = (imgpel) ((PredPel[5] + PredPel[6] + 1) >> 1); + pred[0+0][ioff+6] = + pred[0+2][ioff+7] = (imgpel) ((PredPel[6] + PredPel[7] + 1) >> 1); + pred[0+0][ioff+7] = (imgpel) ((PredPel[7] + PredPel[8] + 1) >> 1); + pred[0+1][ioff+0] = + pred[0+3][ioff+1] = + pred[0+5][ioff+2] = + pred[0+7][ioff+3] = (imgpel) ((PredPel[17] + PredPel[1] + 2*PredPel[0] + 2) >> 2); + pred[0+1][ioff+1] = + pred[0+3][ioff+2] = + pred[0+5][ioff+3] = + pred[0+7][ioff+4] = (imgpel) ((PredPel[0] + PredPel[2] + 2*PredPel[1] + 2) >> 2); + pred[0+1][ioff+2] = + pred[0+3][ioff+3] = + pred[0+5][ioff+4] = + pred[0+7][ioff+5] = (imgpel) ((PredPel[1] + PredPel[3] + 2*PredPel[2] + 2) >> 2); + pred[0+1][ioff+3] = + pred[0+3][ioff+4] = + pred[0+5][ioff+5] = + pred[0+7][ioff+6] = (imgpel) ((PredPel[2] + PredPel[4] + 2*PredPel[3] + 2) >> 2); + pred[0+1][ioff+4] = + pred[0+3][ioff+5] = + pred[0+5][ioff+6] = + pred[0+7][ioff+7] = (imgpel) ((PredPel[3] + PredPel[5] + 2*PredPel[4] + 2) >> 2); + pred[0+1][ioff+5] = + pred[0+3][ioff+6] = + pred[0+5][ioff+7] = (imgpel) ((PredPel[4] + PredPel[6] + 2*PredPel[5] + 2) >> 2); + pred[0+1][ioff+6] = + pred[0+3][ioff+7] = (imgpel) ((PredPel[5] + PredPel[7] + 2*PredPel[6] + 2) >> 2); + pred[0+1][ioff+7] = (imgpel) ((PredPel[6] + PredPel[8] + 2*PredPel[7] + 2) >> 2); + pred[0+2][ioff+0] = + pred[0+4][ioff+1] = + pred[0+6][ioff+2] = (imgpel) ((PredPel[18] + PredPel[0] + 2*PredPel[17] + 2) >> 2); + pred[0+3][ioff+0] = + pred[0+5][ioff+1] = + pred[0+7][ioff+2] = (imgpel) ((PredPel[19] + PredPel[17] + 2*PredPel[18] + 2) >> 2); + pred[0+4][ioff+0] = + pred[0+6][ioff+1] = (imgpel) ((PredPel[20] + PredPel[18] + 2*PredPel[19] + 2) >> 2); + pred[0+5][ioff+0] = + pred[0+7][ioff+1] = (imgpel) ((PredPel[21] + PredPel[19] + 2*PredPel[20] + 2) >> 2); + pred[0+6][ioff+0] = (imgpel) ((PredPel[22] + PredPel[20] + 2*PredPel[21] + 2) >> 2); + pred[0+7][ioff+0] = (imgpel) ((PredPel[23] + PredPel[21] + 2*PredPel[22] + 2) >> 2); + + return DECODING_OK; +} + + +/*! + *********************************************************************** + * \brief + * makes and returns 8x8 vertical left prediction mode + * + * \return + * DECODING_OK decoding of intraprediction mode was sucessfull \n + * + *********************************************************************** + */ +static inline int intra8x8_vert_left_pred(Macroblock *currMB, //!< current macroblock + ColorPlane pl, //!< current image plane + int ioff, //!< pixel offset X within MB + int joff) //!< pixel offset Y within MB +{ + Slice *currSlice = currMB->p_Slice; + VideoParameters *p_Vid = currMB->p_Vid; + + int i; + imgpel PredPel[25]; // array of predictor pels + imgpel **imgY = (pl) ? p_Vid->dec_picture->imgUV[pl - 1]->img : p_Vid->dec_picture->imgY->img; // For MB level frame/field coding tools -- set default to imgY + + PixelPos pix_a[8]; + PixelPos pix_b, pix_c, pix_d; +h264_imgpel_macroblock_row_t *pred; + int block_available_up; + int block_available_left; + int block_available_up_left; + int block_available_up_right; + + imgpel *pred_pels; + + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 0, &pix_a[0]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 1, &pix_a[1]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 2, &pix_a[2]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 3, &pix_a[3]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 4, &pix_a[4]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 5, &pix_a[5]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 6, &pix_a[6]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 7, &pix_a[7]); + + p_Vid->getNeighbourPXLumaNB(currMB, ioff , joff - 1, &pix_b); + p_Vid->getNeighbourPXLuma(currMB, ioff + 8, joff - 1, &pix_c); + p_Vid->getNeighbourLuma(currMB, ioff - 1, joff - 1, &pix_d); + + pix_c.available = pix_c.available &&!(ioff == 8 && joff == 8); + + if (p_Vid->active_pps->constrained_intra_pred_flag) + { + for (i=0, block_available_left=1; i<8;i++) + block_available_left &= pix_a[i].available ? p_Vid->intra_block[pix_a[i].mb_addr]: 0; + block_available_up = pix_b.available ? p_Vid->intra_block [pix_b.mb_addr] : 0; + block_available_up_right = pix_c.available ? p_Vid->intra_block [pix_c.mb_addr] : 0; + block_available_up_left = pix_d.available ? p_Vid->intra_block [pix_d.mb_addr] : 0; + } + else + { + block_available_left = pix_a[0].available; + block_available_up = pix_b.available; + block_available_up_right = pix_c.available; + block_available_up_left = pix_d.available; + } + + if (!block_available_up) + printf ("warning: Intra_4x4_Vertical_Left prediction mode not allowed at mb %d\n", (int) p_Vid->current_mb_nr); + + // form predictor pels + if (block_available_up) + { + pred_pels = &imgY[pix_b.pos_y][pix_b.pos_x]; + PredPel[1] = pred_pels[0]; + PredPel[2] = pred_pels[1]; + PredPel[3] = pred_pels[2]; + PredPel[4] = pred_pels[3]; + PredPel[5] = pred_pels[4]; + PredPel[6] = pred_pels[5]; + PredPel[7] = pred_pels[6]; + PredPel[8] = pred_pels[7]; + } + else + { + PredPel[1] = PredPel[2] = PredPel[3] = PredPel[4] = PredPel[5] = PredPel[6] = PredPel[7] = PredPel[8] = (imgpel) p_Vid->dc_pred_value_comp[pl]; + } + + if (block_available_up_right) + { + pred_pels = &imgY[pix_c.pos_y][pix_c.pos_x]; + PredPel[9] = pred_pels[0]; + PredPel[10] = pred_pels[1]; + PredPel[11] = pred_pels[2]; + PredPel[12] = pred_pels[3]; + PredPel[13] = pred_pels[4]; + PredPel[14] = pred_pels[5]; + PredPel[15] = pred_pels[6]; + PredPel[16] = pred_pels[7]; + + } + else + { + PredPel[9] = PredPel[10] = PredPel[11] = PredPel[12] = PredPel[13] = PredPel[14] = PredPel[15] = PredPel[16] = PredPel[8]; + } + + if (block_available_left) + { + PredPel[17] = imgY[pix_a[0].pos_y][pix_a[0].pos_x]; + PredPel[18] = imgY[pix_a[1].pos_y][pix_a[1].pos_x]; + PredPel[19] = imgY[pix_a[2].pos_y][pix_a[2].pos_x]; + PredPel[20] = imgY[pix_a[3].pos_y][pix_a[3].pos_x]; + PredPel[21] = imgY[pix_a[4].pos_y][pix_a[4].pos_x]; + PredPel[22] = imgY[pix_a[5].pos_y][pix_a[5].pos_x]; + PredPel[23] = imgY[pix_a[6].pos_y][pix_a[6].pos_x]; + PredPel[24] = imgY[pix_a[7].pos_y][pix_a[7].pos_x]; + } + else + { + PredPel[17] = PredPel[18] = PredPel[19] = PredPel[20] = PredPel[21] = PredPel[22] = PredPel[23] = PredPel[24] = (imgpel) p_Vid->dc_pred_value_comp[pl]; + } + + if (block_available_up_left) + { + PredPel[0] = imgY[pix_d.pos_y][pix_d.pos_x]; + } + else + { + PredPel[0] = (imgpel) p_Vid->dc_pred_value_comp[pl]; + } + + LowPassForIntra8x8Pred(&(PredPel[0]), block_available_up_left, block_available_up, block_available_left); +pred = &currSlice->mb_pred[pl][joff]; + pred[0+0][ioff+0] = (imgpel) ((PredPel[1] + PredPel[2] + 1) >> 1); + pred[0+0][ioff+1] = + pred[0+2][ioff+0] = (imgpel) ((PredPel[2] + PredPel[3] + 1) >> 1); + pred[0+0][ioff+2] = + pred[0+2][ioff+1] = + pred[0+4][ioff+0] = (imgpel) ((PredPel[3] + PredPel[4] + 1) >> 1); + pred[0+0][ioff+3] = + pred[0+2][ioff+2] = + pred[0+4][ioff+1] = + pred[0+6][ioff+0] = (imgpel) ((PredPel[4] + PredPel[5] + 1) >> 1); + pred[0+0][ioff+4] = + pred[0+2][ioff+3] = + pred[0+4][ioff+2] = + pred[0+6][ioff+1] = (imgpel) ((PredPel[5] + PredPel[6] + 1) >> 1); + pred[0+0][ioff+5] = + pred[0+2][ioff+4] = + pred[0+4][ioff+3] = + pred[0+6][ioff+2] = (imgpel) ((PredPel[6] + PredPel[7] + 1) >> 1); + pred[0+0][ioff+6] = + pred[0+2][ioff+5] = + pred[0+4][ioff+4] = + pred[0+6][ioff+3] = (imgpel) ((PredPel[7] + PredPel[8] + 1) >> 1); + pred[0+0][ioff+7] = + pred[0+2][ioff+6] = + pred[0+4][ioff+5] = + pred[0+6][ioff+4] = (imgpel) ((PredPel[8] + PredPel[9] + 1) >> 1); + pred[0+2][ioff+7] = + pred[0+4][ioff+6] = + pred[0+6][ioff+5] = (imgpel) ((PredPel[9] + PredPel[10] + 1) >> 1); + pred[0+4][ioff+7] = + pred[0+6][ioff+6] = (imgpel) ((PredPel[10] + PredPel[11] + 1) >> 1); + pred[0+6][ioff+7] = (imgpel) ((PredPel[11] + PredPel[12] + 1) >> 1); + pred[0+1][ioff+0] = (imgpel) ((PredPel[1] + PredPel[3] + 2*PredPel[2] + 2) >> 2); + pred[0+1][ioff+1] = + pred[0+3][ioff+0] = (imgpel) ((PredPel[2] + PredPel[4] + 2*PredPel[3] + 2) >> 2); + pred[0+1][ioff+2] = + pred[0+3][ioff+1] = + pred[0+5][ioff+0] = (imgpel) ((PredPel[3] + PredPel[5] + 2*PredPel[4] + 2) >> 2); + pred[0+1][ioff+3] = + pred[0+3][ioff+2] = + pred[0+5][ioff+1] = + pred[0+7][ioff+0] = (imgpel) ((PredPel[4] + PredPel[6] + 2*PredPel[5] + 2) >> 2); + pred[0+1][ioff+4] = + pred[0+3][ioff+3] = + pred[0+5][ioff+2] = + pred[0+7][ioff+1] = (imgpel) ((PredPel[5] + PredPel[7] + 2*PredPel[6] + 2) >> 2); + pred[0+1][ioff+5] = + pred[0+3][ioff+4] = + pred[0+5][ioff+3] = + pred[0+7][ioff+2] = (imgpel) ((PredPel[6] + PredPel[8] + 2*PredPel[7] + 2) >> 2); + pred[0+1][ioff+6] = + pred[0+3][ioff+5] = + pred[0+5][ioff+4] = + pred[0+7][ioff+3] = (imgpel) ((PredPel[7] + PredPel[9] + 2*PredPel[8] + 2) >> 2); + pred[0+1][ioff+7] = + pred[0+3][ioff+6] = + pred[0+5][ioff+5] = + pred[0+7][ioff+4] = (imgpel) ((PredPel[8] + PredPel[10] + 2*PredPel[9] + 2) >> 2); + pred[0+3][ioff+7] = + pred[0+5][ioff+6] = + pred[0+7][ioff+5] = (imgpel) ((PredPel[9] + PredPel[11] + 2*PredPel[10] + 2) >> 2); + pred[0+5][ioff+7] = + pred[0+7][ioff+6] = (imgpel) ((PredPel[10] + PredPel[12] + 2*PredPel[11] + 2) >> 2); + pred[0+7][ioff+7] = (imgpel) ((PredPel[11] + PredPel[13] + 2*PredPel[12] + 2) >> 2); + + return DECODING_OK; +} + +/*! + *********************************************************************** + * \brief + * makes and returns 8x8 horizontal up prediction mode + * + * \return + * DECODING_OK decoding of intraprediction mode was sucessfull \n + * + *********************************************************************** + */ +static inline int intra8x8_hor_up_pred(Macroblock *currMB, //!< current macroblock + ColorPlane pl, //!< current image plane + int ioff, //!< pixel offset X within MB + int joff) //!< pixel offset Y within MB +{ + Slice *currSlice = currMB->p_Slice; + VideoParameters *p_Vid = currMB->p_Vid; + + int i; + imgpel PredPel[25]; // array of predictor pels + imgpel **imgY = (pl) ? p_Vid->dec_picture->imgUV[pl - 1]->img : p_Vid->dec_picture->imgY->img; // For MB level frame/field coding tools -- set default to imgY +h264_imgpel_macroblock_row_t *pred; + PixelPos pix_a[8]; + PixelPos pix_b, pix_c, pix_d; + + int block_available_up; + int block_available_left; + int block_available_up_left; + int block_available_up_right; + + imgpel *pred_pels; + + + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 0, &pix_a[0]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 1, &pix_a[1]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 2, &pix_a[2]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 3, &pix_a[3]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 4, &pix_a[4]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 5, &pix_a[5]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 6, &pix_a[6]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 7, &pix_a[7]); + + p_Vid->getNeighbourPXLumaNB(currMB, ioff , joff - 1, &pix_b); + p_Vid->getNeighbourPXLuma(currMB, ioff + 8, joff - 1, &pix_c); + p_Vid->getNeighbourLuma(currMB, ioff - 1, joff - 1, &pix_d); + + pix_c.available = pix_c.available &&!(ioff == 8 && joff == 8); + + if (p_Vid->active_pps->constrained_intra_pred_flag) + { + for (i=0, block_available_left=1; i<8;i++) + block_available_left &= pix_a[i].available ? p_Vid->intra_block[pix_a[i].mb_addr]: 0; + block_available_up = pix_b.available ? p_Vid->intra_block [pix_b.mb_addr] : 0; + block_available_up_right = pix_c.available ? p_Vid->intra_block [pix_c.mb_addr] : 0; + block_available_up_left = pix_d.available ? p_Vid->intra_block [pix_d.mb_addr] : 0; + } + else + { + block_available_left = pix_a[0].available; + block_available_up = pix_b.available; + block_available_up_right = pix_c.available; + block_available_up_left = pix_d.available; + } + + if (!block_available_left) + printf ("warning: Intra_8x8_Horizontal_Up prediction mode not allowed at mb %d\n", (int) p_Vid->current_mb_nr); + + // form predictor pels + if (block_available_up) + { + pred_pels = &imgY[pix_b.pos_y][pix_b.pos_x]; + PredPel[1] = pred_pels[0]; + PredPel[2] = pred_pels[1]; + PredPel[3] = pred_pels[2]; + PredPel[4] = pred_pels[3]; + PredPel[5] = pred_pels[4]; + PredPel[6] = pred_pels[5]; + PredPel[7] = pred_pels[6]; + PredPel[8] = pred_pels[7]; + } + else + { + PredPel[1] = PredPel[2] = PredPel[3] = PredPel[4] = PredPel[5] = PredPel[6] = PredPel[7] = PredPel[8] = (imgpel) p_Vid->dc_pred_value_comp[pl]; + } + + if (block_available_up_right) + { + pred_pels = &imgY[pix_c.pos_y][pix_c.pos_x]; + PredPel[9] = pred_pels[0]; + PredPel[10] = pred_pels[1]; + PredPel[11] = pred_pels[2]; + PredPel[12] = pred_pels[3]; + PredPel[13] = pred_pels[4]; + PredPel[14] = pred_pels[5]; + PredPel[15] = pred_pels[6]; + PredPel[16] = pred_pels[7]; + + } + else + { + PredPel[9] = PredPel[10] = PredPel[11] = PredPel[12] = PredPel[13] = PredPel[14] = PredPel[15] = PredPel[16] = PredPel[8]; + } + + if (block_available_left) + { + PredPel[17] = imgY[pix_a[0].pos_y][pix_a[0].pos_x]; + PredPel[18] = imgY[pix_a[1].pos_y][pix_a[1].pos_x]; + PredPel[19] = imgY[pix_a[2].pos_y][pix_a[2].pos_x]; + PredPel[20] = imgY[pix_a[3].pos_y][pix_a[3].pos_x]; + PredPel[21] = imgY[pix_a[4].pos_y][pix_a[4].pos_x]; + PredPel[22] = imgY[pix_a[5].pos_y][pix_a[5].pos_x]; + PredPel[23] = imgY[pix_a[6].pos_y][pix_a[6].pos_x]; + PredPel[24] = imgY[pix_a[7].pos_y][pix_a[7].pos_x]; + } + else + { + PredPel[17] = PredPel[18] = PredPel[19] = PredPel[20] = PredPel[21] = PredPel[22] = PredPel[23] = PredPel[24] = (imgpel) p_Vid->dc_pred_value_comp[pl]; + } + + if (block_available_up_left) + { + PredPel[0] = imgY[pix_d.pos_y][pix_d.pos_x]; + } + else + { + PredPel[0] = (imgpel) p_Vid->dc_pred_value_comp[pl]; + } + + LowPassForIntra8x8Pred(&(PredPel[0]), block_available_up_left, block_available_up, block_available_left); +pred = &currSlice->mb_pred[pl][joff]; + pred[0+0][ioff+0] = (imgpel) ((PredPel[17] + PredPel[18] + 1) >> 1); + pred[0+1][ioff+0] = + pred[0+0][ioff+2] = (imgpel) ((PredPel[18] + PredPel[19] + 1) >> 1); + pred[0+2][ioff+0] = + pred[0+1][ioff+2] = + pred[0+0][ioff+4] = (imgpel) ((PredPel[19] + PredPel[20] + 1) >> 1); + pred[0+3][ioff+0] = + pred[0+2][ioff+2] = + pred[0+1][ioff+4] = + pred[0+0][ioff+6] = (imgpel) ((PredPel[20] + PredPel[21] + 1) >> 1); + pred[0+4][ioff+0] = + pred[0+3][ioff+2] = + pred[0+2][ioff+4] = + pred[0+1][ioff+6] = (imgpel) ((PredPel[21] + PredPel[22] + 1) >> 1); + pred[0+5][ioff+0] = + pred[0+4][ioff+2] = + pred[0+3][ioff+4] = + pred[0+2][ioff+6] = (imgpel) ((PredPel[22] + PredPel[23] + 1) >> 1); + pred[0+6][ioff+0] = + pred[0+5][ioff+2] = + pred[0+4][ioff+4] = + pred[0+3][ioff+6] = (imgpel) ((PredPel[23] + PredPel[24] + 1) >> 1); + pred[0+4][ioff+6] = + pred[0+4][ioff+7] = + pred[0+5][ioff+4] = + pred[0+5][ioff+5] = + pred[0+5][ioff+6] = + pred[0+5][ioff+7] = + pred[0+6][ioff+2] = + pred[0+6][ioff+3] = + pred[0+6][ioff+4] = + pred[0+6][ioff+5] = + pred[0+6][ioff+6] = + pred[0+6][ioff+7] = + pred[0+7][ioff+0] = + pred[0+7][ioff+1] = + pred[0+7][ioff+2] = + pred[0+7][ioff+3] = + pred[0+7][ioff+4] = + pred[0+7][ioff+5] = + pred[0+7][ioff+6] = + pred[0+7][ioff+7] = (imgpel) PredPel[24]; + pred[0+6][ioff+1] = + pred[0+5][ioff+3] = + pred[0+4][ioff+5] = + pred[0+3][ioff+7] = (imgpel) ((PredPel[23] + 3*PredPel[24] + 2) >> 2); + pred[0+5][ioff+1] = + pred[0+4][ioff+3] = + pred[0+3][ioff+5] = + pred[0+2][ioff+7] = (imgpel) ((PredPel[24] + PredPel[22] + 2*PredPel[23] + 2) >> 2); + pred[0+4][ioff+1] = + pred[0+3][ioff+3] = + pred[0+2][ioff+5] = + pred[0+1][ioff+7] = (imgpel) ((PredPel[23] + PredPel[21] + 2*PredPel[22] + 2) >> 2); + pred[0+3][ioff+1] = + pred[0+2][ioff+3] = + pred[0+1][ioff+5] = + pred[0+0][ioff+7] = (imgpel) ((PredPel[22] + PredPel[20] + 2*PredPel[21] + 2) >> 2); + pred[0+2][ioff+1] = + pred[0+1][ioff+3] = + pred[0+0][ioff+5] = (imgpel) ((PredPel[21] + PredPel[19] + 2*PredPel[20] + 2) >> 2); + pred[0+1][ioff+1] = + pred[0+0][ioff+3] = (imgpel) ((PredPel[20] + PredPel[18] + 2*PredPel[19] + 2) >> 2); + pred[0+0][ioff+1] = (imgpel) ((PredPel[19] + PredPel[17] + 2*PredPel[18] + 2) >> 2); + + return DECODING_OK; +} + +/*! + *********************************************************************** + * \brief + * makes and returns 8x8 horizontal down prediction mode + * + * \return + * DECODING_OK decoding of intraprediction mode was sucessfull \n + * + *********************************************************************** + */ +static inline int intra8x8_hor_down_pred(Macroblock *currMB, //!< current macroblock + ColorPlane pl, //!< current image plane + int ioff, //!< pixel offset X within MB + int joff) //!< pixel offset Y within MB +{ + Slice *currSlice = currMB->p_Slice; + VideoParameters *p_Vid = currMB->p_Vid; + + int i; + imgpel PredPel[25]; // array of predictor pels + imgpel **imgY = (pl) ? p_Vid->dec_picture->imgUV[pl - 1]->img : p_Vid->dec_picture->imgY->img; // For MB level frame/field coding tools -- set default to imgY + + PixelPos pix_a[8]; + PixelPos pix_b, pix_c, pix_d; + h264_imgpel_macroblock_row_t *pred; + int block_available_up; + int block_available_left; + int block_available_up_left; + int block_available_up_right; + + imgpel *pred_pels; + + + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 0, &pix_a[0]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 1, &pix_a[1]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 2, &pix_a[2]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 3, &pix_a[3]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 4, &pix_a[4]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 5, &pix_a[5]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 6, &pix_a[6]); + p_Vid->getNeighbourXPLumaNB(currMB, ioff - 1, joff + 7, &pix_a[7]); + + p_Vid->getNeighbourPXLumaNB(currMB, ioff , joff - 1, &pix_b); + p_Vid->getNeighbourPXLuma(currMB, ioff + 8, joff - 1, &pix_c); + p_Vid->getNeighbourLuma(currMB, ioff - 1, joff - 1, &pix_d); + pix_c.available = pix_c.available &&!(ioff == 8 && joff == 8); + + if (p_Vid->active_pps->constrained_intra_pred_flag) + { + for (i=0, block_available_left=1; i<8;i++) + block_available_left &= pix_a[i].available ? p_Vid->intra_block[pix_a[i].mb_addr]: 0; + block_available_up = pix_b.available ? p_Vid->intra_block [pix_b.mb_addr] : 0; + block_available_up_right = pix_c.available ? p_Vid->intra_block [pix_c.mb_addr] : 0; + block_available_up_left = pix_d.available ? p_Vid->intra_block [pix_d.mb_addr] : 0; + } + else + { + block_available_left = pix_a[0].available; + block_available_up = pix_b.available; + block_available_up_right = pix_c.available; + block_available_up_left = pix_d.available; + } + + if ((!block_available_up)||(!block_available_left)||(!block_available_up_left)) + printf ("warning: Intra_8x8_Horizontal_Down prediction mode not allowed at mb %d\n", (int) p_Vid->current_mb_nr); + + // form predictor pels + if (block_available_up) + { + pred_pels = &imgY[pix_b.pos_y][pix_b.pos_x]; + PredPel[1] = pred_pels[0]; + PredPel[2] = pred_pels[1]; + PredPel[3] = pred_pels[2]; + PredPel[4] = pred_pels[3]; + PredPel[5] = pred_pels[4]; + PredPel[6] = pred_pels[5]; + PredPel[7] = pred_pels[6]; + PredPel[8] = pred_pels[7]; + } + else + { + PredPel[1] = PredPel[2] = PredPel[3] = PredPel[4] = PredPel[5] = PredPel[6] = PredPel[7] = PredPel[8] = (imgpel) p_Vid->dc_pred_value_comp[pl]; + } + + if (block_available_up_right) + { + pred_pels = &imgY[pix_c.pos_y][pix_c.pos_x]; + PredPel[9] = pred_pels[0]; + PredPel[10] = pred_pels[1]; + PredPel[11] = pred_pels[2]; + PredPel[12] = pred_pels[3]; + PredPel[13] = pred_pels[4]; + PredPel[14] = pred_pels[5]; + PredPel[15] = pred_pels[6]; + PredPel[16] = pred_pels[7]; + + } + else + { + PredPel[9] = PredPel[10] = PredPel[11] = PredPel[12] = PredPel[13] = PredPel[14] = PredPel[15] = PredPel[16] = PredPel[8]; + } + + if (block_available_left) + { + PredPel[17] = imgY[pix_a[0].pos_y][pix_a[0].pos_x]; + PredPel[18] = imgY[pix_a[1].pos_y][pix_a[1].pos_x]; + PredPel[19] = imgY[pix_a[2].pos_y][pix_a[2].pos_x]; + PredPel[20] = imgY[pix_a[3].pos_y][pix_a[3].pos_x]; + PredPel[21] = imgY[pix_a[4].pos_y][pix_a[4].pos_x]; + PredPel[22] = imgY[pix_a[5].pos_y][pix_a[5].pos_x]; + PredPel[23] = imgY[pix_a[6].pos_y][pix_a[6].pos_x]; + PredPel[24] = imgY[pix_a[7].pos_y][pix_a[7].pos_x]; + } + else + { + PredPel[17] = PredPel[18] = PredPel[19] = PredPel[20] = PredPel[21] = PredPel[22] = PredPel[23] = PredPel[24] = (imgpel) p_Vid->dc_pred_value_comp[pl]; + } + + if (block_available_up_left) + { + PredPel[0] = imgY[pix_d.pos_y][pix_d.pos_x]; + } + else + { + PredPel[0] = (imgpel) p_Vid->dc_pred_value_comp[pl]; + } + + LowPassForIntra8x8Pred(&(PredPel[0]), block_available_up_left, block_available_up, block_available_left); +pred = &currSlice->mb_pred[pl][joff]; + pred[0][ioff] = + pred[0+1][ioff+2] = + pred[0+2][ioff+4] = + pred[0+3][ioff+6] = (imgpel) ((PredPel[17] + PredPel[0] + 1) >> 1); + pred[0+1][ioff] = + pred[0+2][ioff+2] = + pred[0+3][ioff+4] = + pred[0+4][ioff+6] = (imgpel) ((PredPel[18] + PredPel[17] + 1) >> 1); + pred[0+2][ioff] = + pred[0+3][ioff+2] = + pred[0+4][ioff+4] = + pred[0+5][ioff+6] = (imgpel) ((PredPel[19] + PredPel[18] + 1) >> 1); + pred[0+3][ioff] = + pred[0+4][ioff+2] = + pred[0+5][ioff+4] = + pred[0+6][ioff+6] = (imgpel) ((PredPel[20] + PredPel[19] + 1) >> 1); + pred[0+4][ioff] = + pred[0+5][ioff+2] = + pred[0+6][ioff+4] = + pred[0+7][ioff+6] = (imgpel) ((PredPel[21] + PredPel[20] + 1) >> 1); + pred[0+5][ioff] = + pred[0+6][ioff+2] = + pred[0+7][ioff+4] = (imgpel) ((PredPel[22] + PredPel[21] + 1) >> 1); + pred[0+6][ioff] = + pred[0+7][ioff+2] = (imgpel) ((PredPel[23] + PredPel[22] + 1) >> 1); + pred[0+7][ioff] = (imgpel) ((PredPel[24] + PredPel[23] + 1) >> 1); + pred[0][ioff+1] = + pred[0+1][ioff+3] = + pred[0+2][ioff+5] = + pred[0+3][ioff+7] = (imgpel) ((PredPel[17] + PredPel[1] + 2*PredPel[0] + 2) >> 2); + pred[0+1][ioff+1] = + pred[0+2][ioff+3] = + pred[0+3][ioff+5] = + pred[0+4][ioff+7] = (imgpel) ((PredPel[0] + PredPel[18] + 2*PredPel[17] + 2) >> 2); + pred[0+2][ioff+1] = + pred[0+3][ioff+3] = + pred[0+4][ioff+5] = + pred[0+5][ioff+7] = (imgpel) ((PredPel[17] + PredPel[19] + 2*PredPel[18] + 2) >> 2); + pred[0+3][ioff+1] = + pred[0+4][ioff+3] = + pred[0+5][ioff+5] = + pred[0+6][ioff+7] = (imgpel) ((PredPel[18] + PredPel[20] + 2*PredPel[19] + 2) >> 2); + pred[0+4][ioff+1] = + pred[0+5][ioff+3] = + pred[0+6][ioff+5] = + pred[0+7][ioff+7] = (imgpel) ((PredPel[19] + PredPel[21] + 2*PredPel[20] + 2) >> 2); + pred[0+5][ioff+1] = + pred[0+6][ioff+3] = + pred[0+7][ioff+5] = (imgpel) ((PredPel[20] + PredPel[22] + 2*PredPel[21] + 2) >> 2); + pred[0+6][ioff+1] = + pred[0+7][ioff+3] = (imgpel) ((PredPel[21] + PredPel[23] + 2*PredPel[22] + 2) >> 2); + pred[0+7][ioff+1] = (imgpel) ((PredPel[22] + PredPel[24] + 2*PredPel[23] + 2) >> 2); + pred[0][ioff+2] = + pred[0+1][ioff+4] = + pred[0+2][ioff+6] = (imgpel) ((PredPel[0] + PredPel[2] + 2*PredPel[1] + 2) >> 2); + pred[0][ioff+3] = + pred[0+1][ioff+5] = + pred[0+2][ioff+7] = (imgpel) ((PredPel[1] + PredPel[3] + 2*PredPel[2] + 2) >> 2); + pred[0][ioff+4] = + pred[0+1][ioff+6] = (imgpel) ((PredPel[2] + PredPel[4] + 2*PredPel[3] + 2) >> 2); + pred[0][ioff+5] = + pred[0+1][ioff+7] = (imgpel) ((PredPel[3] + PredPel[5] + 2*PredPel[4] + 2) >> 2); + pred[0][ioff+6] = (imgpel) ((PredPel[4] + PredPel[6] + 2*PredPel[5] + 2) >> 2); + pred[0][ioff+7] = (imgpel) ((PredPel[5] + PredPel[7] + 2*PredPel[6] + 2) >> 2); + + return DECODING_OK; +} + +/*! + ************************************************************************ + * \brief + * Make intra 8x8 prediction according to all 9 prediction modes. + * The routine uses left and upper neighbouring points from + * previous coded blocks to do this (if available). Notice that + * inaccessible neighbouring points are signalled with a negative + * value in the predmode array . + * + * \par Input: + * Starting point of current 8x8 block image position + * + ************************************************************************ + */ +int intrapred8x8(Macroblock *currMB, //!< Current Macroblock + ColorPlane pl, //!< Current color plane + int ioff, //!< ioff + int joff) //!< joff + +{ + VideoParameters *p_Vid = currMB->p_Vid; + int block_x = (currMB->block_x) + (ioff >> 2); + int block_y = (currMB->block_y) + (joff >> 2); + byte predmode = p_Vid->ipredmode[block_y][block_x]; + + currMB->ipmode_DPCM = predmode; //For residual DPCM + + switch (predmode) + { + case DC_PRED: + return (intra8x8_dc_pred(currMB, pl, ioff, joff)); + break; + case VERT_PRED: + return (intra8x8_vert_pred(currMB, pl, ioff, joff)); + break; + case HOR_PRED: + return (intra8x8_hor_pred(currMB, pl, ioff, joff)); + break; + case DIAG_DOWN_RIGHT_PRED: + return (intra8x8_diag_down_right_pred(currMB, pl, ioff, joff)); + break; + case DIAG_DOWN_LEFT_PRED: + return (intra8x8_diag_down_left_pred(currMB, pl, ioff, joff)); + break; + case VERT_RIGHT_PRED: + return (intra8x8_vert_right_pred(currMB, pl, ioff, joff)); + break; + case VERT_LEFT_PRED: + return (intra8x8_vert_left_pred(currMB, pl, ioff, joff)); + break; + case HOR_UP_PRED: + return (intra8x8_hor_up_pred(currMB, pl, ioff, joff)); + break; + case HOR_DOWN_PRED: + return (intra8x8_hor_down_pred(currMB, pl, ioff, joff)); + default: + printf("Error: illegal intra_8x8 prediction mode: %d\n", (int) predmode); + return SEARCH_SYNC; + break; + } + + return DECODING_OK; +} + + |