📄 slice.c
字号:
++i;
break;
}
memcpy ( default_order, tmp_reorder, num_ref_idx_lX_active * sizeof(int));
}
reordering_of_pic_nums_idc[i] = 3;
memcpy ( default_order, tmp_reorder, num_ref_idx_lX_active * sizeof(int));
if (list_no==0)
{
img->currentSlice->ref_pic_list_reordering_flag_l0=1;
}
else
{
img->currentSlice->ref_pic_list_reordering_flag_l1=1;
}
}
}
/*!
************************************************************************
* \brief
* decide reference picture reordering, Field only
************************************************************************
*/
void poc_ref_pic_reorder_field(StorablePicture **list, unsigned num_ref_idx_lX_active, int *reordering_of_pic_nums_idc, int *abs_diff_pic_num_minus1, int *long_term_pic_idx, int list_no)
{
unsigned int i,j,k;
int currPicNum, picNumLXPred;
int default_order[32];
int re_order[32];
int tmp_reorder[32];
int list_sign[32];
int poc_diff[32];
int fld_type[32];
int reorder_stop, no_reorder;
int tmp_value, diff;
int abs_poc_dist;
int maxPicNum;
unsigned int numRefs;
int field_used[2] = {1, 2};
int fld, idx, num_flds;
unsigned int top_idx = 0;
unsigned int bot_idx = 0;
unsigned int list_size = 0;
StorablePicture *pField[2]; // 0: TOP_FIELD, 1: BOTTOM_FIELD
FrameStore *pFrameStore;
maxPicNum = 2 * max_frame_num;
currPicNum = 2 * img->frame_num + 1;
picNumLXPred = currPicNum;
// First assign default list order.
for (i=0; i<num_ref_idx_lX_active; i++)
{
default_order[i] = list[i]->pic_num;
}
// Now access all references in buffer and assign them
// to a potential reordering list. For each one of these
// references compute the poc distance compared to current
// frame.
// look for eligible fields
idx = 0;
for (i=0; i<dpb.ref_frames_in_buffer; i++)
{
pFrameStore = dpb.fs_ref[i];
pField[0] = pFrameStore->top_field;
pField[1] = pFrameStore->bottom_field;
num_flds = (img->structure == BOTTOM_FIELD && (enc_picture->poc == (pField[0]->poc + 1) ) ) ? 1 : 2;
poc_diff[2*i ] = 0xFFFF;
poc_diff[2*i + 1] = 0xFFFF;
for ( fld = 0; fld < num_flds; fld++ )
{
if ( (pFrameStore->is_used & field_used[fld]) && pField[fld]->used_for_reference && !(pField[fld]->is_long_term) )
{
abs_poc_dist = iabs(pField[fld]->poc - enc_picture->poc) ;
poc_diff[idx] = abs_poc_dist;
re_order[idx] = pField[fld]->pic_num;
fld_type[idx] = fld + 1;
if (list_no == LIST_0)
{
list_sign[idx] = (enc_picture->poc < pField[fld]->poc) ? +1 : -1;
}
else
{
list_sign[idx] = (enc_picture->poc > pField[fld]->poc) ? +1 : -1;
}
idx++;
}
}
}
numRefs = idx;
// now sort these references based on poc (temporal) distance
for (i=0; i < numRefs-1; i++)
{
for (j = (i + 1); j < numRefs; j++)
{
if (poc_diff[i] > poc_diff[j] || (poc_diff[i] == poc_diff[j] && list_sign[j] > list_sign[i]))
{
// poc_diff
tmp_value = poc_diff[i];
poc_diff[i] = poc_diff[j];
poc_diff[j] = tmp_value;
// re_order (PicNum)
tmp_value = re_order[i];
re_order[i] = re_order[j];
re_order[j] = tmp_value;
// list_sign
tmp_value = list_sign[i];
list_sign[i] = list_sign[j];
list_sign[j] = tmp_value;
// fld_type
tmp_value = fld_type[i];
fld_type[i] = fld_type[j];
fld_type[j] = tmp_value ;
}
}
}
if (img->structure == TOP_FIELD)
{
while ((top_idx < numRefs)||(bot_idx < numRefs))
{
for ( ; top_idx < numRefs; top_idx++)
{
if ( fld_type[top_idx] == TOP_FIELD )
{
tmp_reorder[list_size] = re_order[top_idx];
list_size++;
top_idx++;
break;
}
}
for ( ; bot_idx < numRefs; bot_idx++)
{
if ( fld_type[bot_idx] == BOTTOM_FIELD )
{
tmp_reorder[list_size] = re_order[bot_idx];
list_size++;
bot_idx++;
break;
}
}
}
}
if (img->structure == BOTTOM_FIELD)
{
while ((top_idx < numRefs)||(bot_idx < numRefs))
{
for ( ; bot_idx < numRefs; bot_idx++)
{
if ( fld_type[bot_idx] == BOTTOM_FIELD )
{
tmp_reorder[list_size] = re_order[bot_idx];
list_size++;
bot_idx++;
break;
}
}
for ( ; top_idx < numRefs; top_idx++)
{
if ( fld_type[top_idx] == TOP_FIELD )
{
tmp_reorder[list_size] = re_order[top_idx];
list_size++;
top_idx++;
break;
}
}
}
}
// copy to final matrix
list_size = imin( list_size, 32 );
for ( i = 0; i < list_size; i++ )
{
re_order[i] = tmp_reorder[i];
}
// Check versus default list to see if any
// change has happened
no_reorder = 1;
for (i=0; i<num_ref_idx_lX_active; i++)
{
if (default_order[i] != re_order[i])
{
no_reorder = 0;
}
}
// If different, then signal reordering
if (no_reorder == 0)
{
for (i=0; i<num_ref_idx_lX_active; i++)
{
diff = re_order[i] - picNumLXPred;
if (diff <= 0)
{
reordering_of_pic_nums_idc[i] = 0;
abs_diff_pic_num_minus1[i] = iabs(diff)-1;
if (abs_diff_pic_num_minus1[i] < 0)
abs_diff_pic_num_minus1[i] = maxPicNum -1;
}
else
{
reordering_of_pic_nums_idc[i] = 1;
abs_diff_pic_num_minus1[i] = iabs(diff)-1;
}
picNumLXPred = re_order[i];
tmp_reorder[i] = re_order[i];
k = i;
for (j = i; j < num_ref_idx_lX_active; j++)
{
if (default_order[j] != re_order[i])
{
++k;
tmp_reorder[k] = default_order[j];
}
}
reorder_stop = 1;
for(j=i+1; j<num_ref_idx_lX_active; j++)
{
if (tmp_reorder[j] != re_order[j])
{
reorder_stop = 0;
break;
}
}
if (reorder_stop==1)
{
++i;
break;
}
memcpy ( default_order, tmp_reorder, num_ref_idx_lX_active * sizeof(int));
}
reordering_of_pic_nums_idc[i] = 3;
memcpy ( default_order, tmp_reorder, num_ref_idx_lX_active * sizeof(int));
if (list_no==0)
{
img->currentSlice->ref_pic_list_reordering_flag_l0 = 1;
}
else
{
img->currentSlice->ref_pic_list_reordering_flag_l1 = 1;
}
}
}
void UpdateMELambda(ImageParameters *img)
{
int j, k, qp;
if (params->UpdateLambdaChromaME)
{
for (j = 0; j < 6; j++)
{
for (qp = -img->bitdepth_luma_qp_scale; qp < 52; qp++)
{
for (k = 0; k < 3; k++)
{
if ((params->MEErrorMetric[k] == ERROR_SAD) && (params->ChromaMEEnable))
{
switch(params->yuv_format)
{
case YUV420:
img->lambda_mf[j][qp][k] = (3 * img->lambda_mf[j][qp][k] + 1) >> 1;
img->lambda_me[j][qp][k] *= 1.5;
break;
case YUV422:
img->lambda_mf[j][qp][k] *= 2;
img->lambda_me[j][qp][k] *= 2.0;
break;
case YUV444:
img->lambda_mf[j][qp][k] *= 3;
img->lambda_me[j][qp][k] *= 3.0;
break;
default:
break;
}
}
}
}
}
}
}
void SetLambda(int j, int qp, double lambda_scale)
{
int k;
img->lambda_md[j][qp] *= lambda_scale;
for (k = F_PEL; k <= Q_PEL; k++)
{
img->lambda_me[j][qp][k] = (params->MEErrorMetric[k] == ERROR_SSE) ? img->lambda_md[j][qp] : sqrt(img->lambda_md[j][qp]);
img->lambda_mf[j][qp][k] = LAMBDA_FACTOR (img->lambda_me[j][qp][k]);
}
}
void SetLagrangianMultipliersOn()
{
int qp, j;
double qp_temp;
double lambda_scale = 1.0 - dClip3(0.0,0.5,0.05 * (double) params->jumpd);;
if (params->UseExplicitLambdaParams == 1) // consideration of explicit lambda weights.
{
for (j = 0; j < 6; j++)
{
for (qp = -img->bitdepth_luma_qp_scale; qp < 52; qp++)
{
qp_temp = (double)qp + img->bitdepth_luma_qp_scale - SHIFT_QP;
img->lambda_md[j][qp] = params->LambdaWeight[j] * pow (2, qp_temp/3.0);
SetLambda(j, qp, ((params->MEErrorMetric[H_PEL] == ERROR_SATD && params->MEErrorMetric[Q_PEL] == ERROR_SATD) ? 1.00 : 0.95));
}
}
}
else if (params->UseExplicitLambdaParams == 2) // consideration of fixed lambda values.
{
for (j = 0; j < 6; j++)
{
for (qp = -img->bitdepth_luma_qp_scale; qp < 52; qp++)
{
qp_temp = (double)qp + img->bitdepth_luma_qp_scale - SHIFT_QP;
img->lambda_md[j][qp] = params->FixedLambda[j];
SetLambda(j, qp, ((params->MEErrorMetric[H_PEL] == ERROR_SATD && params->MEErrorMetric[Q_PEL] == ERROR_SATD) ? 1.00 : 0.95));
}
}
}
else
{
for (j = 0; j < 5; j++)
{
for (qp = -img->bitdepth_luma_qp_scale; qp < 52; qp++)
{
qp_temp = (double)qp + img->bitdepth_luma_qp_scale - SHIFT_QP;
if (params->successive_Bframe > 0)
img->lambda_md[j][qp] = 0.68 * pow (2, qp_temp/3.0)
* (j == B_SLICE && img->b_frame_to_code != 0 ? dClip3(2.00, 4.00, (qp_temp / 6.0)) : (j == SP_SLICE) ? dClip3(1.4,3.0,(qp_temp / 12.0)) : 1.0);
else
img->lambda_md[j][qp] = 0.85 * pow (2, qp_temp/3.0) * ((j == SP_SLICE) ? dClip3(1.4, 3.0,(qp_temp / 12.0)) : 1.0);
// Scale lambda due to hadamard qpel only consideration
img->lambda_md[j][qp] = ((params->MEErrorMetric[H_PEL] == ERROR_SATD && params->MEErrorMetric[Q_PEL] == ERROR_SATD) ? 1.00 : 0.95) * img->lambda_md[j][qp];
//img->lambda_md[j][qp] = (j == B_SLICE && params->BRefPictures == 2 && img->b_frame_to_code == 0 ? 0.50 : 1.00) * img->lambda_md[j][qp];
if (j == B_SLICE)
{
img->lambda_md[5][qp] = img->lambda_md[j][qp];
if (img->b_frame_to_code != 0)
{
if (params->HierarchicalCoding == 2)
img->lambda_md[5][qp] *= (1.0 - dmin(0.4, 0.2 * (double) gop_structure[img->b_frame_to_code-1].hierarchy_layer));
else
img->lambda_md[5][qp] *= 0.80;
}
SetLambda(5, qp, lambda_scale);
}
else
img->lambda_md[j][qp] *= lambda_scale;
SetLambda(j, qp, 1.0);
if (params->CtxAdptLagrangeMult == 1)
{
int lambda_qp = (qp >= 32 && !params->RCEnable) ? imax(0, qp - 4) : imax(0, qp - 6);
img->lambda_mf_factor[j][qp] = log (img->lambda_me[j][lambda_qp][Q_PEL] + 1.0) / log (2.0);
}
}
}
}
UpdateMELambda(img);
}
void SetLagrangianMultipliersOff()
{
int qp, j, k;
double qp_temp;
for (j = 0; j < 6; j++)
{
for (qp = -img->bitdepth_luma_qp_scale; qp < 52; qp++)
{
qp_temp = (double)qp + img->bitdepth_luma_qp_scale - SHIFT_QP;
switch (params->UseExplicitLambdaParams)
{
case 1: // explicit lambda weights
img->lambda_md[j][qp] = sqrt(params->LambdaWeight[j] * pow (2, qp_temp/3.0));
break;
case 2: // explicit lambda
img->lambda_md[j][qp] = sqrt(params->FixedLambda[j]);
break;
default:
img->lambda_md[j][qp] = QP2QUANT[imax(0,qp - SHIFT_QP)];
break;
}
for (k = F_PEL; k <= Q_PEL; k++)
{
img->lambda_me[j][qp][k] = (params->MEErrorMetric[k] == ERROR_SSE) ? (img->lambda_md[j][qp] * img->lambda_md[j][qp]) : img->lambda_md[j][qp];
img->lambda_mf[j][qp][k] = LAMBDA_FACTOR (img->lambda_me[j][qp][k]);
}
if (params->CtxAdptLagrangeMult == 1)
{
int lambda_qp = (qp >= 32 && !params->RCEnable) ? imax(0, qp-4) : imax(0, qp-6);
img->lambda_mf_factor[j][qp] = log (img->lambda_me[j][lambda_qp][Q_PEL] + 1.0) / log (2.0);
}
}
}
UpdateMELambda(img);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -