📄 rd_intra_jm.c
字号:
/*!
***************************************************************************
* \file rd_intra_jm.c
*
* \brief
* Rate-Distortion optimized mode decision
*
* \author
* - Heiko Schwarz <hschwarz@hhi.de>
* - Valeri George <george@hhi.de>
* - Lowell Winger <lwinger@lsil.com>
* - Alexis Michael Tourapis <alexismt@ieee.org>
* \date
* 12. April 2001
**************************************************************************
*/
#include <limits.h>
#include "global.h"
#include "image.h"
#include "macroblock.h"
#include "mb_access.h"
#include "rdopt_coding_state.h"
#include "mode_decision.h"
#include "rdopt.h"
#include "rd_intra_jm.h"
#include "q_around.h"
/*!
*************************************************************************************
* \brief
* Mode Decision for an 4x4 Intra block
*************************************************************************************
*/
int Mode_Decision_for_4x4IntraBlocks_JM_High (Macroblock *currMB, int b8, int b4, double lambda, double* min_cost, int cr_cbp[3], int is_cavlc)
{
int ipmode, best_ipmode = 0, i, j, y, dummy;
int c_nz, nonzero = 0;
int* ACLevel = img->cofAC[b8][b4][0];
int* ACRun = img->cofAC[b8][b4][1];
int c_nzCbCr[3]= {999,999, 999};
static imgpel rec4x4[4][4];
static imgpel rec4x4CbCr[2][4][4];
int uv;
double rdcost;
int block_x = ((b8 & 0x01) << 3) + ((b4 & 0x01) << 2);
int block_y = ((b8 >> 1) << 3) + ((b4 >> 1) << 2);
int pic_pix_x = img->pix_x + block_x;
int pic_pix_y = img->pix_y + block_y;
int pic_opix_x = img->opix_x + block_x;
int pic_opix_y = img->opix_y + block_y;
int pic_block_x = pic_pix_x >> 2;
int pic_block_y = pic_pix_y >> 2;
double min_rdcost = 1e30;
int left_available, up_available, all_available;
char upMode;
char leftMode;
int mostProbableMode;
PixelPos left_block;
PixelPos top_block;
int lrec4x4[4][4];
#ifdef BEST_NZ_COEFF
int best_nz_coeff = 0;
int best_coded_block_flag = 0;
int bit_pos = 1 + ((((b8>>1)<<1)+(b4>>1))<<2) + (((b8&1)<<1)+(b4&1));
static int64 cbp_bits;
if (b8==0 && b4==0)
cbp_bits = 0;
#endif
get4x4Neighbour(currMB, block_x - 1, block_y , img->mb_size[IS_LUMA], &left_block);
get4x4Neighbour(currMB, block_x, block_y - 1, img->mb_size[IS_LUMA], &top_block );
// constrained intra pred
if (params->UseConstrainedIntraPred)
{
left_block.available = left_block.available ? img->intra_block[left_block.mb_addr] : 0;
top_block.available = top_block.available ? img->intra_block[top_block.mb_addr] : 0;
}
upMode = top_block.available ? img->ipredmode[top_block.pos_y ][top_block.pos_x ] : -1;
leftMode = left_block.available ? img->ipredmode[left_block.pos_y][left_block.pos_x] : -1;
mostProbableMode = (upMode < 0 || leftMode < 0) ? DC_PRED : upMode < leftMode ? upMode : leftMode;
*min_cost = INT_MAX;
ipmode_DPCM = NO_INTRA_PMODE; ////For residual DPCM
//===== INTRA PREDICTION FOR 4x4 BLOCK =====
intrapred_4x4 (currMB, PLANE_Y, pic_pix_x, pic_pix_y, &left_available, &up_available, &all_available);
if (img->P444_joined)
{
select_plane(PLANE_U);
intrapred_4x4 (currMB, PLANE_U, pic_pix_x, pic_pix_y, &left_available, &up_available, &all_available);
select_plane(PLANE_V);
intrapred_4x4 (currMB, PLANE_V, pic_pix_x, pic_pix_y, &left_available, &up_available, &all_available);
select_plane(PLANE_Y);
}
//===== LOOP OVER ALL 4x4 INTRA PREDICTION MODES =====
for (ipmode = 0; ipmode < NO_INTRA_PMODE; ipmode++)
{
int available_mode = (all_available) || (ipmode==DC_PRED) ||
(up_available && (ipmode==VERT_PRED||ipmode==VERT_LEFT_PRED||ipmode==DIAG_DOWN_LEFT_PRED)) ||
(left_available && (ipmode==HOR_PRED||ipmode==HOR_UP_PRED));
if (valid_intra_mode(ipmode) == 0)
continue;
if( available_mode)
{
// get prediction and prediction error
generate_pred_error(&pCurImg[pic_opix_y], img->mpr_4x4[0][ipmode], &img->mb_pred[0][block_y], &img->mb_ores[0][block_y], pic_opix_x, block_x);
if (img->yuv_format == YUV444)
{
ipmode_DPCM = ipmode;
if (!IS_INDEPENDENT(params))
{
generate_pred_error(&pImgOrg[1][pic_opix_y], img->mpr_4x4[1][ipmode], &img->mb_pred[1][block_y], &img->mb_ores[1][block_y], pic_opix_x, block_x);
generate_pred_error(&pImgOrg[2][pic_opix_y], img->mpr_4x4[2][ipmode], &img->mb_pred[2][block_y], &img->mb_ores[2][block_y], pic_opix_x, block_x);
}
}
//===== store the coding state =====
//store_coding_state (currMB, cs_cm);
// get and check rate-distortion cost
#ifdef BEST_NZ_COEFF
currMB->cbp_bits[0] = cbp_bits;
#endif
if ((rdcost = RDCost_for_4x4IntraBlocks (currMB, &c_nz, b8, b4, ipmode, lambda, mostProbableMode, c_nzCbCr, is_cavlc)) < min_rdcost)
{
//--- set coefficients ---
memcpy(cofAC4x4[0],ACLevel, 18 * sizeof(int));
memcpy(cofAC4x4[1],ACRun, 18 * sizeof(int));
//--- set reconstruction ---
for (y=0; y<4; y++)
{
memcpy(rec4x4[y],&enc_picture->imgY[pic_pix_y+y][pic_pix_x], BLOCK_SIZE * sizeof(imgpel));
}
// SP/SI reconstruction
if(img->type==SP_SLICE &&(!si_frame_indicator && !sp2_frame_indicator))
{
for (y=0; y<4; y++)
{
memcpy(lrec4x4[y],&lrec[pic_pix_y+y][pic_pix_x], BLOCK_SIZE * sizeof(int));// stores the mode coefficients
}
}
if(img->P444_joined)
{
//--- set coefficients ---
for (uv=0; uv < 2; uv++)
{
memcpy(cofAC4x4CbCr[uv][0],img->cofAC[b8+4+uv*4][b4][0], 18 * sizeof(int));
memcpy(cofAC4x4CbCr[uv][1],img->cofAC[b8+4+uv*4][b4][1], 18 * sizeof(int));
cr_cbp[uv + 1] = c_nzCbCr[uv + 1];
//--- set reconstruction ---
for (y=0; y<4; y++)
{
memcpy(rec4x4CbCr[uv][y],&enc_picture->imgUV[uv][pic_pix_y+y][pic_pix_x], BLOCK_SIZE * sizeof(imgpel));
}
}
}
//--- flag if dct-coefficients must be coded ---
nonzero = c_nz;
//--- set best mode update minimum cost ---
*min_cost = rdcost;
min_rdcost = rdcost;
best_ipmode = ipmode;
#ifdef BEST_NZ_COEFF
best_nz_coeff = img->nz_coeff [img->current_mb_nr][block_x4][block_y4];
best_coded_block_flag = (int)((currMB->cbp_bits[0] >> bit_pos)&(int64)(1));
#endif
//store_coding_state (currMB, cs_ib4);
if (img->AdaptiveRounding)
{
store_adaptive_rounding (img, block_y, block_x);
}
}
#ifndef RESET_STATE
reset_coding_state (currMB, cs_cm);
#endif
}
}
#ifdef BEST_NZ_COEFF
img->nz_coeff [img->current_mb_nr][block_x4][block_y4] = best_nz_coeff;
cbp_bits &= (~(int64)(1<<bit_pos));
cbp_bits |= (int64)(best_coded_block_flag<<bit_pos);
#endif
//===== set intra mode prediction =====
img->ipredmode[pic_block_y][pic_block_x] = (char) best_ipmode;
currMB->intra_pred_modes[4*b8+b4] =
(char) (mostProbableMode == best_ipmode ? -1 : (best_ipmode < mostProbableMode ? best_ipmode : best_ipmode-1));
if(img->P444_joined)
{
ColorPlane k;
for (k = PLANE_U; k <= PLANE_V; k++)
{
select_plane(k);
for (j=0; j<4; j++)
{
for (i=0; i<4; i++)
{
img->mb_pred[k][block_y+j][block_x+i] = img->mpr_4x4[k][best_ipmode][j][i];
img->mb_ores[k][block_y+j][block_x+i] = pImgOrg[k][img->pix_y+block_y+j][img->pix_x+block_x+i] - img->mpr_4x4[k][best_ipmode][j][i];
}
}
cr_cbp[k] = pDCT_4x4(currMB, k, block_x,block_y,&dummy,1, is_cavlc);
}
select_plane(PLANE_Y);
}
//===== restore coefficients =====
memcpy (ACLevel,cofAC4x4[0], 18 * sizeof(int));
memcpy (ACRun,cofAC4x4[1], 18 * sizeof(int));
//===== restore reconstruction and prediction (needed if single coeffs are removed) =====
for (y=0; y<BLOCK_SIZE; y++)
{
memcpy (&enc_picture->imgY[pic_pix_y + y][pic_pix_x],rec4x4[y], BLOCK_SIZE * sizeof(imgpel));
memcpy (&img->mb_pred[0][block_y + y][block_x],img->mpr_4x4[0][best_ipmode][y], BLOCK_SIZE * sizeof(imgpel));
}
// SP/SI reconstuction
if(img->type==SP_SLICE &&(!si_frame_indicator && !sp2_frame_indicator))
{
for (y=0; y<BLOCK_SIZE; y++)
{
memcpy (&lrec[pic_pix_y+y][pic_pix_x], lrec4x4[y], BLOCK_SIZE * sizeof(int));//restore coefficients when encoding primary SP frame
}
}
if (img->P444_joined)
{
for (uv=0; uv < 2; uv++ )
{
//===== restore coefficients =====
memcpy(img->cofAC[b8+4+uv*4][b4][0], cofAC4x4CbCr[uv][0], 18 * sizeof(int));
memcpy(img->cofAC[b8+4+uv*4][b4][1], cofAC4x4CbCr[uv][1], 18 * sizeof(int));
//===== restore reconstruction and prediction (needed if single coeffs are removed) =====
for (y=0; y<BLOCK_SIZE; y++)
{
memcpy(&enc_picture->imgUV[uv][pic_pix_y+y][pic_pix_x],rec4x4CbCr[uv][y], BLOCK_SIZE * sizeof(imgpel));
memcpy(&img->mb_pred[uv + 1][block_y+y][block_x], img->mpr_4x4[uv + 1][best_ipmode][y], BLOCK_SIZE * sizeof(imgpel));
}
}
}
if (img->AdaptiveRounding)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -