📄 rdopt.c
字号:
memset(&enc_picture->ref_idx[LIST_0][j][img->block_x],-1, 4 * sizeof(char));
}
}
}
else
{
if (bframe)
{
for (j=0;j<4;j++)
{
block_y = img->block_y + j;
for (i=0;i<4;i++)
{
block_x = img->block_x + i;
k = 2*(j >> 1) + (i >> 1);
l = 2*(j & 0x01) + (i & 0x01);
if(mode == P8x8 && best8x8mode[k]==0)
{
enc_picture->ref_idx[LIST_0][block_y][block_x] = direct_ref_idx[LIST_0][block_y][block_x];
enc_picture->ref_idx[LIST_1][block_y][block_x] = direct_ref_idx[LIST_1][block_y][block_x];
}
else if (mode ==1 && currMB->bi_pred_me && IS_FW && IS_BW)
{
enc_picture->ref_idx[LIST_0][block_y][block_x] = 0;
enc_picture->ref_idx[LIST_1][block_y][block_x] = 0;
}
else
{
enc_picture->ref_idx[LIST_0][block_y][block_x] = (IS_FW ? best8x8fwref[mode][k] : -1);
enc_picture->ref_idx[LIST_1][block_y][block_x] = (IS_BW ? best8x8bwref[mode][k] : -1);
}
}
}
}
else
{
for (j=0;j<4;j++)
{
block_y = img->block_y + j;
for (i=0;i<4;i++)
{
block_x = img->block_x + i;
k = 2*(j >> 1) + (i >> 1);
l = 2*(j & 0x01) + (i & 0x01);
enc_picture->ref_idx[LIST_0][block_y][block_x] = (IS_FW ? best8x8fwref[mode][k] : -1);
}
}
}
}
if (bframe)
{
for (j = img->block_y; j < img->block_y + 4; j++)
for (i = img->block_x; i < img->block_x + 4;i++)
{
cur_ref[LIST_0] = (int) enc_picture->ref_idx[LIST_0][j][i];
cur_ref[LIST_1] = (int) enc_picture->ref_idx[LIST_1][j][i];
enc_picture->ref_pic_id [LIST_0][j][i] = (cur_ref[LIST_0]>=0
? enc_picture->ref_pic_num[LIST_0 + currMB->list_offset][cur_ref[LIST_0]]
: -1);
enc_picture->ref_pic_id [LIST_1][j][i] = (cur_ref[LIST_1]>=0
? enc_picture->ref_pic_num[LIST_1 + currMB->list_offset][cur_ref[LIST_1]]
: -1);
}
}
else
{
for (j = img->block_y; j < img->block_y + 4; j++)
for (i = img->block_x; i < img->block_x + 4;i++)
{
cur_ref[LIST_0] = (int) enc_picture->ref_idx[LIST_0][j][i];
enc_picture->ref_pic_id [LIST_0][j][i] = (cur_ref[LIST_0]>=0
? enc_picture->ref_pic_num[LIST_0 + currMB->list_offset][cur_ref[LIST_0]]
: -1);
}
}
#undef IS_FW
#undef IS_BW
}
#ifdef USE_INTRA_MDDT
/*!
*************************************************************************************
* \brief
* RD-optimized mode decision for INTRA16x16 mode
*
* \para Intra16x16_Mode_Decision_RDopt()
* <paragraph>
*
* \author
* - Yan Ye <yye@qualcomm.com>
*************************************************************************************
*/
void Intra16x16_Mode_Decision_RDopt (Macroblock* currMB, int* i16mode, double lambda)
{
extern int MBType2Value (Macroblock* currMB);
int i, j;
int mode16, best_mode16;
int max_mode = 4;
double rdcost, min_rdcost = 1e30;
int distortion, rate;
imgpel **imgY = enc_picture->imgY;
int x, y;
extern CSptr cs_i16;
SyntaxElement *currSE = &img->MB_SyntaxElements[currMB->currSEnr];
DataPartition* dataPart;
const int* partMap = assignSE2partition[input->partition_mode];
Slice* currSlice = img->currentSlice;
long quant_stat_best16x16[256];
int bestCofAC16[2][16*17];
int best_cbp=0;
imgpel bestRec[MB_BLOCK_SIZE][MB_BLOCK_SIZE];
intrapred_luma_16x16 (); /* make intra pred for all 4 new modes */
//if(!img->residue_transform_flag) // assume this flag is always OFF
{
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(img->current_mb_nr, -1 , i-1 , 1, &left[i]);
}
getNeighbour(img->current_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;
}
best_mode16 = DC_PRED_16;
for(mode16 = 0; mode16 < max_mode; mode16++)
{
if (input->IntraDisableInterOnly == 0 || img->type != I_SLICE)
{
if (input->Intra16x16ParDisable && (mode16==VERT_PRED_16||mode16==HOR_PRED_16))
continue;
if (input->Intra16x16PlaneDisable && mode16==PLANE_16)
continue;
}
//check if there are neighbours to predict from
if ((mode16==VERT_PRED_16 && !up_avail ) ||
(mode16==HOR_PRED_16 && !left_avail) ||
(mode16==PLANE_16 && (!left_avail || !up_avail || !left_up_avail)))
{
continue; // edge, do nothing
}
if(input->symbol_mode == UVLC)
{
currMB->cbp = dct_luma_16x16 (mode16);
} // if UVLC coding
else
{
currMB->cbp = klt_luma16x16_sep_fast (mode16);
//===== get distortion (SSD) of 4x4 block =====
distortion = 0;
for (y=0; y<16; y++)
{
for (x=0; x<16; x++)
{
distortion +=
img->quad [imgY_org[img->opix_y+y][img->opix_x+x] - imgY[img->pix_y+y][img->pix_x+x]];
}
}
store_coding_state (cs_i16);
// rate for MB_TYPE
img->i16offset = I16Offset (currMB->cbp, mode16);
currMB->mb_type = I16MB;
currSE->value1 = MBType2Value (currMB);
currSE->value2 = 0;
currSE->type = SE_MBTYPE;
if (input->symbol_mode == UVLC)
currSE->mapping = ue_linfo;
else
currSE->writing = writeMB_typeInfo_CABAC;
dataPart = &(currSlice->partArr[partMap[SE_MBTYPE]]);
dataPart->writeSyntaxElement( currSE, dataPart);
rate = currSE->len;
currSE++;
currMB->currSEnr++;
//===== RATE for LUMINANCE COEFFICIENTS =====
rate += writeCBPandLumaCoeff(1);
reset_coding_state (cs_i16);
rdcost = (double)distortion + lambda*(double)rate;
if(rdcost < min_rdcost)
{
best_mode16 = mode16;
min_rdcost = rdcost;
best_cbp = currMB->cbp;
for (j=0; j<256; j++)
{
quant_stat_best16x16[j]=quant_stat_rd16x16[j];
}
memcpy(bestCofAC16[0], img->cofAC16[0], sizeof(int)*16*17);
memcpy(bestCofAC16[1], img->cofAC16[1], sizeof(int)*16*17);
for(j = 0; j < MB_BLOCK_SIZE; j++)
memcpy(bestRec[j], &imgY[img->pix_y+j][img->pix_x], sizeof(imgpel)*MB_BLOCK_SIZE);
}
}
}
*i16mode = best_mode16;
}
for (j=0; j<256; j++)
{
img->quant_stat16x16[j]+=(quant_stat_best16x16[j]>>5);
}
currMB->cbp = best_cbp;
if(currMB->cbp)
currMB->cbp = 15;
memcpy(img->cofAC16[0], bestCofAC16[0], sizeof(int)*16*17);
memcpy(img->cofAC16[1], bestCofAC16[1], sizeof(int)*16*17);
for(y = 0; y < MB_BLOCK_SIZE; y++)
{
memcpy(&imgY[img->pix_y+y][img->pix_x], &bestRec[y][0], MB_BLOCK_SIZE*sizeof(imgpel));
}
}
#endif
/*!
*************************************************************************************
* \brief
* Intra 16x16 mode decision
*************************************************************************************
*/
void Intra16x16_Mode_Decision (Macroblock* currMB, int* i16mode)
{
// Residue Color Transform
int residue_R, residue_G, residue_B;
int c_ipmode = img->mb_data[img->current_mb_nr].c_ipred_mode;
int i, j, temp;
int pic_pix_x = img->pix_x;
int pic_pix_y = img->pix_y;
pel_t **imgY_orig = imgY_org;
pel_t ***imgUV_orig = imgUV_org;
int cr_cbp;
intrapred_luma_16x16 (); /* make intra pred for all 4 new modes */
if(!img->residue_transform_flag)
find_sad_16x16 (i16mode); /* get best new intra mode */
// Residue Color Transform
if(img->residue_transform_flag)
{
for (j=0; j < MB_BLOCK_SIZE; j++)
for (i=0; i < MB_BLOCK_SIZE; i++)
{
residue_B = imgUV_orig[0][pic_pix_y+j][pic_pix_x+i] - img->mprr_c[0][c_ipmode][j][i];
residue_G = imgY_orig[pic_pix_y+j][pic_pix_x+i] - img->mprr_2[*i16mode][j][i];
residue_R = imgUV_orig[1][pic_pix_y+j][pic_pix_x+i] - img->mprr_c[1][c_ipmode][j][i];
/* Forward Residue Transform */
resTrans_R[j][i] = residue_R-residue_B;
temp = residue_B+(resTrans_R[j][i]>>1);
resTrans_B[j][i] = residue_G-temp;
resTrans_G[j][i] = temp+(resTrans_B[j][i]>>1);
img->m7[j][i] = resTrans_G[j][i];
}
}
currMB->cbp = dct_luma_16x16 (*i16mode);
// Residue Color Transform
if(img->residue_transform_flag)
{
for (j=0; j < MB_BLOCK_SIZE; j++)
{
for (i=0; i < MB_BLOCK_SIZE; i++)
{
rec_resG[j][i] = img->m7[j][i];
img->m7[j][i] = resTrans_B[j][i];
}
}
cr_cbp = dct_chroma(0, 0);
for (j=0; j < MB_BLOCK_SIZE; j++)
{
for (i=0; i < MB_BLOCK_SIZE; i++)
{
rec_resB[j][i] = img->m7[j][i];
img->m7[j][i] = resTrans_R[j][i];
}
}
cr_cbp = dct_chroma(1, cr_cbp);
for (j = 0; j < MB_BLOCK_SIZE; j++)
{
for (i = 0; i < MB_BLOCK_SIZE; i++)
rec_resR[j][i] = img->m7[j][i];
}
currMB->cbp += (cr_cbp<<4);
/* Inverse Residue Transform */
for (j = 0; j < MB_BLOCK_SIZE; j++)
{
for (i = 0; i < MB_BLOCK_SIZE; i++)
{
temp = rec_resG[j][i]-(rec_resB[j][i]>>1);
residue_G = rec_resB[j][i]+temp;
residue_B = temp - (rec_resR[j][i]>>1);
residue_R = residue_B+rec_resR[j][i];
enc_picture->imgUV[0][pic_pix_y+j][pic_pix_x+i] = min(img->max_imgpel_value_uv,max(0,residue_B+(int)img->mprr_c[0][c_ipmode][j][i]));
enc_picture->imgY[pic_pix_y+j][pic_pix_x+i] = min(img->max_imgpel_value,max(0,residue_G+(int)img->mprr_2[*i16mode][j][i]));
enc_picture->imgUV[1][pic_pix_y+j][pic_pix_x+i] = min(img->max_imgpel_value_uv,max(0,residue_R+(int)img->mprr_c[1][c_ipmode][j][i]));
}
}
}
}
/*!
*************************************************************************************
* \brief
* Sets Coefficients and reconstruction for an 8x8 block
*************************************************************************************
*/
void SetCoeffAndReconstruction8x8 (Macroblock* currMB)
{
int block, k, j, i;
int cur_ref[2];
//============= MIXED TRANSFORM SIZES FOR 8x8 PARTITION ==============
//--------------------------------------------------------------------
int l;
int bframe = img->type==B_SLICE;
if (currMB->luma_transform_size_8x8_flag)
{
//============= set mode and ref. frames ==============
for(i = 0;i<4;i++)
{
currMB->b8mode[i] = tr8x8.part8x8mode[i];
currMB->b8pdir[i] = tr8x8.part8x8pdir[i];
}
if (bframe)
{
for (j = 0;j<4;j++)
for (i = 0;i<4;i++)
{
k = 2*(j >> 1)+(i >> 1);
l = 2*(j & 0x01)+(i & 0x01);
enc_picture->ref_idx[LIST_0][img->block_y+j][img->block_x+i] = ((currMB->b8pdir[k] & 0x01) == 0) ? tr8x8.part8x8fwref[k] : - 1;
enc_picture->ref_idx[LIST_1][img->block_y+j][img->block_x+i] = (currMB->b8pdir[k] > 0) ? tr8x8.part8x8bwref[k] : - 1;
}
}
else
{
for (j = 0;j<4;j++)
for (i = 0;i<4;i++)
{
k = 2*(j >> 1)+(i >> 1);
l = 2*(j & 0x01)+(i & 0x01);
enc_picture->ref_idx[LIST_0][img->blo
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -