📄 block.c
字号:
/*!
*************************************************************************************
* \file block.c
*
* \brief
* Process one block
*
* \author
* Main contributors (see contributors.h for copyright, address and affiliation details)
* - Inge Lille-Langoy <inge.lille-langoy@telenor.com>
* - Rickard Sjoberg <rickard.sjoberg@era.ericsson.se>
* - Stephan Wenger <stewe@cs.tu-berlin.de>
* - Jani Lainema <jani.lainema@nokia.com>
* - Detlev Marpe <marpe@hhi.de>
* - Thomas Wedi <wedi@tnt.uni-hannover.de>
* - Ragip Kurceren <ragip.kurceren@nokia.com>
* - Greg Conklin <gregc@real.com>
*************************************************************************************
*/
#include "contributors.h"
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <string.h>
#include <math.h>
#include "global.h"
#include "image.h"
#include "mb_access.h"
#include "block.h"
#include "vlc.h"
const int quant_coef[6][4][4] = {
{{13107, 8066,13107, 8066},{ 8066, 5243, 8066, 5243},{13107, 8066,13107, 8066},{ 8066, 5243, 8066, 5243}},
{{11916, 7490,11916, 7490},{ 7490, 4660, 7490, 4660},{11916, 7490,11916, 7490},{ 7490, 4660, 7490, 4660}},
{{10082, 6554,10082, 6554},{ 6554, 4194, 6554, 4194},{10082, 6554,10082, 6554},{ 6554, 4194, 6554, 4194}},
{{ 9362, 5825, 9362, 5825},{ 5825, 3647, 5825, 3647},{ 9362, 5825, 9362, 5825},{ 5825, 3647, 5825, 3647}},
{{ 8192, 5243, 8192, 5243},{ 5243, 3355, 5243, 3355},{ 8192, 5243, 8192, 5243},{ 5243, 3355, 5243, 3355}},
{{ 7282, 4559, 7282, 4559},{ 4559, 2893, 4559, 2893},{ 7282, 4559, 7282, 4559},{ 4559, 2893, 4559, 2893}}
};
const int dequant_coef[6][4][4] = {
{{10, 13, 10, 13},{ 13, 16, 13, 16},{10, 13, 10, 13},{ 13, 16, 13, 16}},
{{11, 14, 11, 14},{ 14, 18, 14, 18},{11, 14, 11, 14},{ 14, 18, 14, 18}},
{{13, 16, 13, 16},{ 16, 20, 16, 20},{13, 16, 13, 16},{ 16, 20, 16, 20}},
{{14, 18, 14, 18},{ 18, 23, 18, 23},{14, 18, 14, 18},{ 18, 23, 18, 23}},
{{16, 20, 16, 20},{ 20, 25, 20, 25},{16, 20, 16, 20},{ 20, 25, 20, 25}},
{{18, 23, 18, 23},{ 23, 29, 23, 29},{18, 23, 18, 23},{ 23, 29, 23, 29}}
};
static const int A[4][4] = {
{ 16, 20, 16, 20},
{ 20, 25, 20, 25},
{ 16, 20, 16, 20},
{ 20, 25, 20, 25}
};
// Notation for comments regarding prediction and predictors.
// The pels of the 4x4 block are labelled a..p. The predictor pels above
// are labelled A..H, from the left I..P, and from above left X, as follows:
//
// X A B C D E F G H
// I a b c d
// J e f g h
// K i j k l
// L m n o p
//
// Predictor array index definitions
#define P_X (PredPel[0])
#define P_A (PredPel[1])
#define P_B (PredPel[2])
#define P_C (PredPel[3])
#define P_D (PredPel[4])
#define P_E (PredPel[5])
#define P_F (PredPel[6])
#define P_G (PredPel[7])
#define P_H (PredPel[8])
#define P_I (PredPel[9])
#define P_J (PredPel[10])
#define P_K (PredPel[11])
#define P_L (PredPel[12])
/*!
************************************************************************
* \brief
* Make intra 4x4 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 4x4 block image posision
*
* \par Output:
* none
************************************************************************
*/
void intrapred_luma(int img_x,int img_y, int *left_available, int *up_available, int *all_available)
{
int i,j;
int s0;
int PredPel[13]; // array of predictor pels
imgpel **imgY = enc_picture->imgY; // For MB level frame/field coding tools -- set default to imgY
int ioff = (img_x & 15);
int joff = (img_y & 15);
int mb_nr=img->current_mb_nr;
PixelPos pix_a[4];
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;
for (i=0;i<4;i++)
{
getNeighbour(mb_nr, ioff -1 , joff +i , 1, &pix_a[i]);
}
getNeighbour(mb_nr, ioff , joff -1 , 1, &pix_b);
getNeighbour(mb_nr, ioff +4 , joff -1 , 1, &pix_c);
getNeighbour(mb_nr, ioff -1 , joff -1 , 1, &pix_d);
pix_c.available = pix_c.available && !(((ioff==4)||(ioff==12)) && ((joff==4)||(joff==12)));
if (input->UseConstrainedIntraPred)
{
for (i=0, block_available_left=1; i<4;i++)
block_available_left &= pix_a[i].available ? img->intra_block[pix_a[i].mb_addr]: 0;
block_available_up = pix_b.available ? img->intra_block [pix_b.mb_addr] : 0;
block_available_up_right = pix_c.available ? img->intra_block [pix_c.mb_addr] : 0;
block_available_up_left = pix_d.available ? img->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;
}
*left_available = block_available_left;
*up_available = block_available_up;
*all_available = block_available_up && block_available_left && block_available_up_left;
i = (img_x & 15);
j = (img_y & 15);
// form predictor pels
if (block_available_up)
{
P_A = imgY[pix_b.pos_y][pix_b.pos_x+0];
P_B = imgY[pix_b.pos_y][pix_b.pos_x+1];
P_C = imgY[pix_b.pos_y][pix_b.pos_x+2];
P_D = imgY[pix_b.pos_y][pix_b.pos_x+3];
}
else
{
P_A = P_B = P_C = P_D = img->dc_pred_value;
}
if (block_available_up_right)
{
P_E = imgY[pix_c.pos_y][pix_c.pos_x+0];
P_F = imgY[pix_c.pos_y][pix_c.pos_x+1];
P_G = imgY[pix_c.pos_y][pix_c.pos_x+2];
P_H = imgY[pix_c.pos_y][pix_c.pos_x+3];
}
else
{
P_E = P_F = P_G = P_H = P_D;
}
if (block_available_left)
{
P_I = imgY[pix_a[0].pos_y][pix_a[0].pos_x];
P_J = imgY[pix_a[1].pos_y][pix_a[1].pos_x];
P_K = imgY[pix_a[2].pos_y][pix_a[2].pos_x];
P_L = imgY[pix_a[3].pos_y][pix_a[3].pos_x];
}
else
{
P_I = P_J = P_K = P_L = img->dc_pred_value;
}
if (block_available_up_left)
{
P_X = imgY[pix_d.pos_y][pix_d.pos_x];
}
else
{
P_X = img->dc_pred_value;
}
for(i=0;i<9;i++)
img->mprr[i][0][0]=-1;
///////////////////////////////
// make DC prediction
///////////////////////////////
s0 = 0;
if (block_available_up && block_available_left)
{
// no edge
s0 = (P_A + P_B + P_C + P_D + P_I + P_J + P_K + P_L + 4) >> (BLOCK_SHIFT + 1);
}
else if (!block_available_up && block_available_left)
{
// upper edge
s0 = (P_I + P_J + P_K + P_L + 2) >> BLOCK_SHIFT;;
}
else if (block_available_up && !block_available_left)
{
// left edge
s0 = (P_A + P_B + P_C + P_D + 2) >> BLOCK_SHIFT;
}
else //if (!block_available_up && !block_available_left)
{
// top left corner, nothing to predict from
s0 = img->dc_pred_value;
}
// store DC prediction
for (j=0; j < BLOCK_SIZE; j++)
{
for (i=0; i < BLOCK_SIZE; i++)
img->mprr[DC_PRED][j][i] = s0;
}
///////////////////////////////
// make horiz and vert prediction
///////////////////////////////
for (i=0; i < BLOCK_SIZE; i++)
{
img->mprr[VERT_PRED][0][i] =
img->mprr[VERT_PRED][1][i] =
img->mprr[VERT_PRED][2][i] =
img->mprr[VERT_PRED][3][i] = (&P_A)[i];
img->mprr[HOR_PRED][i][0] =
img->mprr[HOR_PRED][i][1] =
img->mprr[HOR_PRED][i][2] =
img->mprr[HOR_PRED][i][3] = (&P_I)[i];
}
if(!block_available_up)
img->mprr[VERT_PRED][0][0]=-1;
if(!block_available_left)
img->mprr[HOR_PRED][0][0]=-1;
if (block_available_up)
{
// Mode DIAG_DOWN_LEFT_PRED
img->mprr[DIAG_DOWN_LEFT_PRED][0][0] = (P_A + P_C + 2*(P_B) + 2) >> 2;
img->mprr[DIAG_DOWN_LEFT_PRED][0][1] =
img->mprr[DIAG_DOWN_LEFT_PRED][1][0] = (P_B + P_D + 2*(P_C) + 2) >> 2;
img->mprr[DIAG_DOWN_LEFT_PRED][0][2] =
img->mprr[DIAG_DOWN_LEFT_PRED][1][1] =
img->mprr[DIAG_DOWN_LEFT_PRED][2][0] = (P_C + P_E + 2*(P_D) + 2) >> 2;
img->mprr[DIAG_DOWN_LEFT_PRED][0][3] =
img->mprr[DIAG_DOWN_LEFT_PRED][1][2] =
img->mprr[DIAG_DOWN_LEFT_PRED][2][1] =
img->mprr[DIAG_DOWN_LEFT_PRED][3][0] = (P_D + P_F + 2*(P_E) + 2) >> 2;
img->mprr[DIAG_DOWN_LEFT_PRED][1][3] =
img->mprr[DIAG_DOWN_LEFT_PRED][2][2] =
img->mprr[DIAG_DOWN_LEFT_PRED][3][1] = (P_E + P_G + 2*(P_F) + 2) >> 2;
img->mprr[DIAG_DOWN_LEFT_PRED][2][3] =
img->mprr[DIAG_DOWN_LEFT_PRED][3][2] = (P_F + P_H + 2*(P_G) + 2) >> 2;
img->mprr[DIAG_DOWN_LEFT_PRED][3][3] = (P_G + 3*(P_H) + 2) >> 2;
// Mode VERT_LEFT_PRED
img->mprr[VERT_LEFT_PRED][0][0] = (P_A + P_B + 1) >> 1;
img->mprr[VERT_LEFT_PRED][0][1] =
img->mprr[VERT_LEFT_PRED][2][0] = (P_B + P_C + 1) >> 1;
img->mprr[VERT_LEFT_PRED][0][2] =
img->mprr[VERT_LEFT_PRED][2][1] = (P_C + P_D + 1) >> 1;
img->mprr[VERT_LEFT_PRED][0][3] =
img->mprr[VERT_LEFT_PRED][2][2] = (P_D + P_E + 1) >> 1;
img->mprr[VERT_LEFT_PRED][2][3] = (P_E + P_F + 1) >> 1;
img->mprr[VERT_LEFT_PRED][1][0] = (P_A + 2*P_B + P_C + 2) >> 2;
img->mprr[VERT_LEFT_PRED][1][1] =
img->mprr[VERT_LEFT_PRED][3][0] = (P_B + 2*P_C + P_D + 2) >> 2;
img->mprr[VERT_LEFT_PRED][1][2] =
img->mprr[VERT_LEFT_PRED][3][1] = (P_C + 2*P_D + P_E + 2) >> 2;
img->mprr[VERT_LEFT_PRED][1][3] =
img->mprr[VERT_LEFT_PRED][3][2] = (P_D + 2*P_E + P_F + 2) >> 2;
img->mprr[VERT_LEFT_PRED][3][3] = (P_E + 2*P_F + P_G + 2) >> 2;
}
/* Prediction according to 'diagonal' modes */
if (block_available_left)
{
// Mode HOR_UP_PRED
img->mprr[HOR_UP_PRED][0][0] = (P_I + P_J + 1) >> 1;
img->mprr[HOR_UP_PRED][0][1] = (P_I + 2*P_J + P_K + 2) >> 2;
img->mprr[HOR_UP_PRED][0][2] =
img->mprr[HOR_UP_PRED][1][0] = (P_J + P_K + 1) >> 1;
img->mprr[HOR_UP_PRED][0][3] =
img->mprr[HOR_UP_PRED][1][1] = (P_J + 2*P_K + P_L + 2) >> 2;
img->mprr[HOR_UP_PRED][1][2] =
img->mprr[HOR_UP_PRED][2][0] = (P_K + P_L + 1) >> 1;
img->mprr[HOR_UP_PRED][1][3] =
img->mprr[HOR_UP_PRED][2][1] = (P_K + 2*P_L + P_L + 2) >> 2;
img->mprr[HOR_UP_PRED][3][0] =
img->mprr[HOR_UP_PRED][2][2] =
img->mprr[HOR_UP_PRED][2][3] =
img->mprr[HOR_UP_PRED][3][1] =
img->mprr[HOR_UP_PRED][3][2] =
img->mprr[HOR_UP_PRED][3][3] = P_L;
}
/* Prediction according to 'diagonal' modes */
if (block_available_up && block_available_left && block_available_up_left)
{
// Mode DIAG_DOWN_RIGHT_PRED
img->mprr[DIAG_DOWN_RIGHT_PRED][3][0] = (P_L + 2*P_K + P_J + 2) >> 2;
img->mprr[DIAG_DOWN_RIGHT_PRED][2][0] =
img->mprr[DIAG_DOWN_RIGHT_PRED][3][1] = (P_K + 2*P_J + P_I + 2) >> 2;
img->mprr[DIAG_DOWN_RIGHT_PRED][1][0] =
img->mprr[DIAG_DOWN_RIGHT_PRED][2][1] =
img->mprr[DIAG_DOWN_RIGHT_PRED][3][2] = (P_J + 2*P_I + P_X + 2) >> 2;
img->mprr[DIAG_DOWN_RIGHT_PRED][0][0] =
img->mprr[DIAG_DOWN_RIGHT_PRED][1][1] =
img->mprr[DIAG_DOWN_RIGHT_PRED][2][2] =
img->mprr[DIAG_DOWN_RIGHT_PRED][3][3] = (P_I + 2*P_X + P_A + 2) >> 2;
img->mprr[DIAG_DOWN_RIGHT_PRED][0][1] =
img->mprr[DIAG_DOWN_RIGHT_PRED][1][2] =
img->mprr[DIAG_DOWN_RIGHT_PRED][2][3] = (P_X + 2*P_A + P_B + 2) >> 2;
img->mprr[DIAG_DOWN_RIGHT_PRED][0][2] =
img->mprr[DIAG_DOWN_RIGHT_PRED][1][3] = (P_A + 2*P_B + P_C + 2) >> 2;
img->mprr[DIAG_DOWN_RIGHT_PRED][0][3] = (P_B + 2*P_C + P_D + 2) >> 2;
// Mode VERT_RIGHT_PRED
img->mprr[VERT_RIGHT_PRED][0][0] =
img->mprr[VERT_RIGHT_PRED][2][1] = (P_X + P_A + 1) >> 1;
img->mprr[VERT_RIGHT_PRED][0][1] =
img->mprr[VERT_RIGHT_PRED][2][2] = (P_A + P_B + 1) >> 1;
img->mprr[VERT_RIGHT_PRED][0][2] =
img->mprr[VERT_RIGHT_PRED][2][3] = (P_B + P_C + 1) >> 1;
img->mprr[VERT_RIGHT_PRED][0][3] = (P_C + P_D + 1) >> 1;
img->mprr[VERT_RIGHT_PRED][1][0] =
img->mprr[VERT_RIGHT_PRED][3][1] = (P_I + 2*P_X + P_A + 2) >> 2;
img->mprr[VERT_RIGHT_PRED][1][1] =
img->mprr[VERT_RIGHT_PRED][3][2] = (P_X + 2*P_A + P_B + 2) >> 2;
img->mprr[VERT_RIGHT_PRED][1][2] =
img->mprr[VERT_RIGHT_PRED][3][3] = (P_A + 2*P_B + P_C + 2) >> 2;
img->mprr[VERT_RIGHT_PRED][1][3] = (P_B + 2*P_C + P_D + 2) >> 2;
img->mprr[VERT_RIGHT_PRED][2][0] = (P_X + 2*P_I + P_J + 2) >> 2;
img->mprr[VERT_RIGHT_PRED][3][0] = (P_I + 2*P_J + P_K + 2) >> 2;
// Mode HOR_DOWN_PRED
img->mprr[HOR_DOWN_PRED][0][0] =
img->mprr[HOR_DOWN_PRED][1][2] = (P_X + P_I + 1) >> 1;
img->mprr[HOR_DOWN_PRED][0][1] =
img->mprr[HOR_DOWN_PRED][1][3] = (P_I + 2*P_X + P_A + 2) >> 2;
img->mprr[HOR_DOWN_PRED][0][2] = (P_X + 2*P_A + P_B + 2) >> 2;
img->mprr[HOR_DOWN_PRED][0][3] = (P_A + 2*P_B + P_C + 2) >> 2;
img->mprr[HOR_DOWN_PRED][1][0] =
img->mprr[HOR_DOWN_PRED][2][2] = (P_I + P_J + 1) >> 1;
img->mprr[HOR_DOWN_PRED][1][1] =
img->mprr[HOR_DOWN_PRED][2][3] = (P_X + 2*P_I + P_J + 2) >> 2;
img->mprr[HOR_DOWN_PRED][2][0] =
img->mprr[HOR_DOWN_PRED][3][2] = (P_J + P_K + 1) >> 1;
img->mprr[HOR_DOWN_PRED][2][1] =
img->mprr[HOR_DOWN_PRED][3][3] = (P_I + 2*P_J + P_K + 2) >> 2;
img->mprr[HOR_DOWN_PRED][3][0] = (P_K + P_L + 1) >> 1;
img->mprr[HOR_DOWN_PRED][3][1] = (P_J + 2*P_K + P_L + 2) >> 2;
}
}
/*!
************************************************************************
* \brief
* 16x16 based luma prediction
*
* \par Input:
* Image parameters
*
* \par Output:
* none
************************************************************************
*/
void intrapred_luma_16x16()
{
int s0=0,s1,s2;
imgpel s[2][16];
int i,j;
int ih,iv;
int ib,ic,iaa;
imgpel **imgY_pred = enc_picture->imgY; // For Mb level field/frame coding tools -- default to frame pred
int mb_nr = img->current_mb_nr;
PixelPos up; //!< pixel position p(0,-1)
PixelPos left[17]; //!< pixel positions p(-1, -1..15)
int up_avail, left_avail, left_up_avail;
for (i=0;i<17;i++)
{
getNeighbour(mb_nr, -1, i-1, 1, &left[i]);
}
getNeighbour(mb_nr, 0, -1, 1, &up);
if (!(input->UseConstrainedIntraPred))
{
up_avail = up.available;
left_avail = left[1].available;
left_up_avail = left[0].available;
}
else
{
up_avail = up.available ? img->intra_block[up.mb_addr] : 0;
for (i=1, left_avail=1; i<17;i++)
left_avail &= left[i].available ? img->intra_block[left[i].mb_addr]: 0;
left_up_avail = left[0].available ? img->intra_block[left[0].mb_addr]: 0;
}
s1=s2=0;
// make DC prediction
if (up_avail)
{
for (i=0; i < MB_BLOCK_SIZE; i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -