winamp/Src/h264dec/ldecod/src/intra8x8_pred.c

1929 lines
71 KiB
C
Raw Normal View History

2024-09-24 12:54:57 +00:00
/*!
*************************************************************************************
* \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;
}