📄 rdopt.c
字号:
}
else if (mode == MBMODE_DIRECT)
{
/*==============================================*
*=== DIRECT PREDICTED MACROBLOCK in B-FRAME ===*
*==============================================*/
currMB->intraOrInter = INTER_MB;
img->imod = B_Direct;
get_dir (&dummy);
if (dummy != 100000000 /*MAX_DIR_SAD*/)
{
RDCost_Macroblock (&rd, mode, 0, 0, 0);
}
}
else
{
/*=====================================================*
*=== BIDIRECTIONAL PREDICTED MACROBLOCK in B-FRAME ===*
*=====================================================*/
//--- get best backward prediction ---
min_rdcost = 1e30;
for (blocktype = 1; blocktype < 8; blocktype++)
if (valid_mode[blocktype+NO_INTER_MBMODES])
{
if (backward_rdcost[blocktype] < 0.0)
{
//--- get rd-cost's ---
currMB->intraOrInter = INTER_MB;
img->imod = B_Backward;
if (!backward_me_done[blocktype])
{
SingleUnifiedMotionSearch (0, blocktype,
bw_refFrArr, tmp_bwMV, img->p_bwMV, B_BACKWARD, img->all_bmv,
rdopt->lambda_motion);
backward_me_done[mode]=1;
}
else
for (j = 0; j < 4; j++)
for (i = 0; i < 4; i++)
{
tmp_bwMV[0][img->block_y+j][img->block_x+i+4]=
img->all_bmv[i][j][0][blocktype][0];
tmp_bwMV[1][img->block_y+j][img->block_x+i+4]=
img->all_bmv[i][j][0][blocktype][1];
}
RDCost_Macroblock (&rd, blocktype+NO_INTER_MBMODES, 0, 0, blocktype);
backward_rdcost[blocktype] = rd.rdcost;
}
if (backward_rdcost[blocktype] < min_rdcost)
{
min_rdcost = backward_rdcost[blocktype];
k0 = blocktype;
}
}
blocktype_back = k0;
//--- get best forward prediction ---
min_rdcost = 1e30;
for (blocktype = 1; blocktype < 8; blocktype++)
if (valid_mode[blocktype])
{
if (forward_rdcost[blocktype] < 0.0)
{
//--- get rd-cost's ---
currMB->intraOrInter = INTER_MB;
img->imod = B_Forward;
min_inter_sad = MAX_VALUE;
for (k=0; k<max_ref_frame; k++)
#ifdef _ADDITIONAL_REFERENCE_FRAME_
if (k < input->no_multpred ||
k == input->add_ref_frame)
#endif
{
if (!forward_me_done[blocktype][k])
{
tot_for_sad[blocktype][k] = (int)floor(rdopt->lambda_motion * (1+2*floor(log(k+1)/log(2)+1e-10)));
tot_for_sad[blocktype][k] += SingleUnifiedMotionSearch (k, blocktype,
fw_refFrArr, tmp_fwMV, img->p_fwMV,
B_FORWARD, img->all_mv,
rdopt->lambda_motion);
forward_me_done[blocktype][k] = 1;
}
if (tot_for_sad[blocktype][k] < min_inter_sad)
{
k0 = k;
min_inter_sad = tot_for_sad[blocktype][k];
}
}
for ( i=0; i < 4; i++)
for (j=0; j < 4; j++)
{
tmp_fwMV[0][img->block_y+j][img->block_x+i+4]=
img->all_mv[i][j][k0][blocktype][0];
tmp_fwMV[1][img->block_y+j][img->block_x+i+4]=
img->all_mv[i][j][k0][blocktype][1];
}
RDCost_Macroblock (&rd, blocktype, k0, blocktype, 0);
forward_rdcost[blocktype] = rd.rdcost;
best_refframe [blocktype] = k0;
}
if (forward_rdcost[blocktype] < min_rdcost)
{
min_rdcost = forward_rdcost[blocktype];
k1 = blocktype;
}
}
blocktype = k1;
k0 = best_refframe[blocktype];
//===== COST CALCULATION =====
for (j = 0; j < 4; j++)
for (i = 0; i < 4; i++)
{
tmp_bwMV[0][img->block_y+j][img->block_x+i+4]=
img->all_bmv[i][j][0][blocktype_back][0];
tmp_bwMV[1][img->block_y+j][img->block_x+i+4]=
img->all_bmv[i][j][0][blocktype_back][1];
tmp_fwMV[0][img->block_y+j][img->block_x+i+4]=
img->all_mv[i][j][k0][blocktype][0];
tmp_fwMV[1][img->block_y+j][img->block_x+i+4]=
img->all_mv[i][j][k0][blocktype][1];
}
img->fw_blc_size_h = input->blc_size[blocktype][0];
img->fw_blc_size_v = input->blc_size[blocktype][1];
img->bw_blc_size_h = input->blc_size[blocktype_back][0];
img->bw_blc_size_v = input->blc_size[blocktype_back][1];
currMB->intraOrInter = INTER_MB;
img->imod = B_Bidirect;
RDCost_Macroblock (&rd, mode, k0, blocktype, blocktype_back);
}
}
/*======================================*
*=== SET PARAMETERS FOR BEST MODE ===*
*======================================*/
mode = rdopt->best_mode;
refframe = rdopt->ref_or_i16mode;
intra16mode = rdopt->ref_or_i16mode;
blocktype = rdopt->blocktype;
blocktype_back = rdopt->blocktype_back;
if (input->rdopt==2)
{
//! save the MB Mode of every macroblock
dec_mb_mode[img->mb_x][img->mb_y] = mode;
//! save ref of every macroblock
dec_mb_ref[img->mb_x][img->mb_y] = refframe;
}
//=== RECONSTRUCTED MACROBLOCK ===
for (j=0; j<MB_BLOCK_SIZE; j++)
for (i=0; i<MB_BLOCK_SIZE; i++)
imgY[img->pix_y+j][img->pix_x+i] = rdopt->rec_mb_Y[j][i];
for (j=0; j<(BLOCK_SIZE<<1); j++)
for (i=0; i<(BLOCK_SIZE<<1); i++)
{
imgUV[0][img->pix_c_y+j][img->pix_c_x+i] = rdopt->rec_mb_U[j][i];
imgUV[1][img->pix_c_y+j][img->pix_c_x+i] = rdopt->rec_mb_V[j][i];
}
//=== INTRAORINTER and IMOD ===
if (mode == MBMODE_INTRA4x4)
{
currMB->intraOrInter = INTRA_MB_4x4;
img->imod = INTRA_MB_OLD;
}
else if (mode == MBMODE_INTRA16x16)
{
currMB->intraOrInter = INTRA_MB_16x16;
img->imod = INTRA_MB_NEW;
}
else if (!bframe && (mode >= MBMODE_COPY && mode <= MBMODE_INTER4x4))
{
currMB->intraOrInter = INTER_MB;
img->imod = INTRA_MB_INTER;
}
else if (mode >= MBMODE_INTER16x16 && mode <= MBMODE_INTER4x4)
{
currMB->intraOrInter = INTER_MB;
img->imod = B_Forward;
}
else if (mode >= MBMODE_BACKWARD16x16 && mode <= MBMODE_BACKWARD4x4)
{
currMB->intraOrInter = INTER_MB;
img->imod = B_Backward;
}
else if (mode == MBMODE_BIDIRECTIONAL)
{
currMB->intraOrInter = INTER_MB;
img->imod = B_Bidirect;
}
else // mode == MBMODE_DIRECT
{
currMB->intraOrInter = INTER_MB;
img->imod = B_Direct;
}
//=== DCT-COEFFICIENTS, CBP and KAC ===
if (mode != MBMODE_COPY)
{
memcpy (img->cof, rdopt->cof, 1728*sizeof(int));
memcpy (img->cofu, rdopt->cofu, 20*sizeof(int));
currMB->cbp = rdopt->cbp;
currMB->cbp_blk = rdopt->cbp_blk;
img->kac = rdopt->kac;
if (img->imod==INTRA_MB_NEW)
currMB->cbp += 15*img->kac; // correct cbp for new intra modes: needed by CABAC
}
else
{
memset (img->cof, 0, 1728*sizeof(int));
memset (img->cofu, 0, 20*sizeof(int));
currMB->cbp = 0;
currMB->cbp_blk = 0;
img->kac = 0;
}
//=== INTRA PREDICTION MODES ===
if (mode == MBMODE_INTRA4x4)
memcpy (currMB->intra_pred_modes, rdopt->ipredmode, 16*sizeof(int));
else
{
for (i=0;i<4;i++)
for (j=0;j<4;j++)
img->ipredmode[img->block_x+i+1][img->block_y+j+1]=0;
}
//=== MOTION VECTORS, REFERENCE FRAME and BLOCK DIMENSIONS ===
//--- init all motion vectors with (0,0) ---
currMB->ref_frame = 0;
if (bframe)
for (j=0; j<BLOCK_SIZE; j++)
for (i=0; i<BLOCK_SIZE; i++)
{
tmp_fwMV[0][img->block_y+j][img->block_x+4+i] = 0;
tmp_fwMV[1][img->block_y+j][img->block_x+4+i] = 0;
tmp_bwMV[0][img->block_y+j][img->block_x+4+i] = 0;
tmp_bwMV[1][img->block_y+j][img->block_x+4+i] = 0;
}
else
for (j=0; j<BLOCK_SIZE; j++)
for (i=0; i<BLOCK_SIZE; i++)
{
tmp_mv [0][img->block_y+j][img->block_x+4+i] = 0;
tmp_mv [1][img->block_y+j][img->block_x+4+i] = 0;
}
//--- set used motion vectors ---
if (!bframe && (mode >= MBMODE_INTER16x16 && mode <= MBMODE_INTER4x4))
{
for (j=0; j<BLOCK_SIZE; j++)
for (i=0; i<BLOCK_SIZE; i++)
{
tmp_mv[0][img->block_y+j][img->block_x+4+i] = rdopt->mv[j][i][0];
tmp_mv[1][img->block_y+j][img->block_x+4+i] = rdopt->mv[j][i][1];
}
currMB->ref_frame = refframe;
img->blc_size_h = input->blc_size[blocktype][0];
img->blc_size_v = input->blc_size[blocktype][1];
}
else if (mode >= MBMODE_INTER16x16 && mode <= MBMODE_INTER4x4)
{
for (j=0; j<BLOCK_SIZE; j++)
for (i=0; i<BLOCK_SIZE; i++)
{
tmp_fwMV[0][img->block_y+j][img->block_x+4+i] = rdopt->mv[j][i][0];
tmp_fwMV[1][img->block_y+j][img->block_x+4+i] = rdopt->mv[j][i][1];
dfMV [0][img->block_y+j][img->block_x+4+i] = 0;
dfMV [1][img->block_y+j][img->block_x+4+i] = 0;
dbMV [0][img->block_y+j][img->block_x+4+i] = 0;
dbMV [1][img->block_y+j][img->block_x+4+i] = 0;
}
currMB->ref_frame = refframe;
img->fw_blc_size_h = input->blc_size[blocktype][0];
img->fw_blc_size_v = input->blc_size[blocktype][1];
}
else if (mode >= MBMODE_BACKWARD16x16 && mode <= MBMODE_BACKWARD4x4)
{
for (j=0; j<BLOCK_SIZE; j++)
for (i=0; i<BLOCK_SIZE; i++)
{
tmp_bwMV[0][img->block_y+j][img->block_x+4+i] = rdopt->bw_mv[j][i][0];
tmp_bwMV[1][img->block_y+j][img->block_x+4+i] = rdopt->bw_mv[j][i][1];
dfMV [0][img->block_y+j][img->block_x+4+i] = 0;
dfMV [1][img->block_y+j][img->block_x+4+i] = 0;
dbMV [0][img->block_y+j][img->block_x+4+i] = 0;
dbMV [1][img->block_y+j][img->block_x+4+i] = 0;
}
currMB->ref_frame = refframe;
img->bw_blc_size_h = input->blc_size[blocktype_back][0];
img->bw_blc_size_v = input->blc_size[blocktype_back][1];
}
else if (mode == MBMODE_BIDIRECTIONAL)
{
for (j=0; j<BLOCK_SIZE; j++)
for (i=0; i<BLOCK_SIZE; i++)
{
tmp_fwMV[0][img->block_y+j][img->block_x+4+i] = rdopt-> mv[j][i][0];
tmp_fwMV[1][img->block_y+j][img->block_x+4+i] = rdopt-> mv[j][i][1];
tmp_bwMV[0][img->block_y+j][img->block_x+4+i] = rdopt->bw_mv[j][i][0];
tmp_bwMV[1][img->block_y+j][img->block_x+4+i] = rdopt->bw_mv[j][i][1];
dfMV [0][img->block_y+j][img->block_x+4+i] = 0;
dfMV [1][img->block_y+j][img->block_x+4+i] = 0;
dbMV [0][img->block_y+j][img->block_x+4+i] = 0;
dbMV [1][img->block_y+j][img->block_x+4+i] = 0;
}
currMB->ref_frame = refframe;
img->fw_blc_size_h = input->blc_size[blocktype ][0];
img->fw_blc_size_v = input->blc_size[blocktype ][1];
img->bw_blc_size_h = input->blc_size[blocktype_back][0];
img->bw_blc_size_v = input->blc_size[blocktype_back][1];
}
//=== MACROBLOCK MODE ===
if (mode == MBMODE_COPY || mode == MBMODE_DIRECT)
img->mb_mode = 0;
else if (mode == MBMODE_INTRA4x4)
img->mb_mode = 8*img->type + img->imod;
else if (mode == MBMODE_INTRA16x16)
img->mb_mode = 8*img->type + img->imod + intra16mode + 12*img->kac + 4*((currMB->cbp&0xF0)>>4);
else if (mode == MBMODE_BIDIRECTIONAL)
img->mb_mode = 3;
else if (mode >= MBMODE_BACKWARD16x16 && mode <= MBMODE_BACKWARD4x4)
img->mb_mode = (blocktype_back == 1 ? blocktype_back+1 : 2*blocktype_back+1);
else if (mode >= MBMODE_INTER16x16 && mode <= MBMODE_INTER4x4 && bframe)
img->mb_mode = (blocktype == 1 ? blocktype : 2*blocktype);
else if (blocktype == M16x16_MB &&
currMB->cbp == 0 &&
currMB->ref_frame == 0 &&
tmp_mv[0][img->block_y][img->block_x+4] == 0 &&
tmp_mv[1][img->block_y][img->block_x+4] == 0)
img->mb_mode = 0;
else
img->mb_mode = blocktype;
currMB->mb_type = img->mb_mode;
/*===========================================================*
*=== SET LOOP FILTER STRENGTH and REFERENCE FRAME INFO ===*
*===========================================================*/
if (!bframe)
{
// Set reference frame information for motion vector prediction of future MBs
SetRefFrameInfo_P();
}
else
{
// Set reference frame information for motion vector prediction of future MBs
SetRefFrameInfo_B();
}
currMB->qp = img->qp ; // this should (or has to be) done somewere else, but where???
DeblockMb(img, imgY, imgUV) ; // filter this macroblock ( pixels to the right and above the MB are affected )
if (input->rdopt == 2)
{
for (j=0 ; j<input->NoOfDecoders ; j++)
DeblockMb(img, decY_best[j],NULL);
}
if (img->current_mb_nr==0)
intras=0;
if (img->number && (mode==MBMODE_INTRA4x4 || mode==MBMODE_INTRA16x16))
intras++;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -