📄 switched_filters.c
字号:
2 * wp_luma_round * (1 - img->bipred_rounding_control)) >> (luma_log_weight_denom + 1)));
}
else
{
tmp = valOrg - ((tempF[i] + tempB[j] + 1 - img->bipred_rounding_control) >> 1);
}
AccErrorB[i][j][sub_pos[0]][sub_pos[1]] += (tmp * tmp);
SamplesB[i][j][sub_pos[0]][sub_pos[1]]++;
SequenceAccErrorB[i][j][sub_pos[0]][sub_pos[1]] += (tmp * tmp);
}
}
} // x
} // y
}
else //uni-directional
{
int ref_index = (ref_frame[0]!= -1)? LIST_0: LIST_1;
int ind = (ref_frame[0]!= -1)? 0: 1;
imgY = listX[ref_index][ref_frame[ind]]->imgY;
for(yi = 0; yi < 4; ++yi)
{
for(xj = 0; xj < 4; ++xj)
{
int xcoordind = Clip3Fun(0 , out4Y_width, 4 * (x + xj) + 4 * IMG_PAD_SIZE + mvx[ind]);
int ycoordind = Clip3Fun(0 , out4Y_height, 4 * (y + yi) + 4 * IMG_PAD_SIZE + mvy[ind]);
valOrg = imgY_org[y+yi][x+xj];
for(i = 0; i < NUM_SIFO; ++i)
{
// Unidirectional error is accumulated along the diagonal
tmp = valOrg - GetInterpolatedPixel(imgY, ycoordind, xcoordind, img->width, img->height, sub_pos[ind], i);
AccErrorB[i][i][sub_pos[ind]][sub_pos[ind]] += (tmp * tmp);
SamplesB[i][i][sub_pos[ind]][sub_pos[ind]]++;
SequenceAccErrorB[i][i][sub_pos[ind]][sub_pos[ind]] += (tmp * tmp);
}
} // x
} // y
} // if bidirectional
} // for(subblock = 0; subblock < 16; subblock++)
}
//
// Accumulate values to compute offset for F reference frames
//
static void AccumulateOffset0_B(int x_orig, int y_orig)
{
int x, y, xj, yi, valOrg, i;
int mvx[2], mvy[2];
int sub_pos[2], mvx_sub, mvy_sub;
int ref_frame[2];
int subblock = 0;
int out4Y_width = (img->width + 2 * IMG_PAD_SIZE) * 4 - 1;
int out4Y_height = (img->height + 2 * IMG_PAD_SIZE) * 4 - 1;
double tmp;
int filterF;
unsigned short ** imgY;
if(img->type == B_SLICE)
{
for(subblock = 0; subblock < 16; ++subblock)
{
x = x_orig + 4 * (subblock % 4);
y = y_orig + 4 * (subblock / 4);
//get motion information
for (i = 0; i < 2; ++i)
{
mvx[i] = enc_picture->mv[LIST_0+i][y/4][x/4][0];
mvy[i] = enc_picture->mv[LIST_0+i][y/4][x/4][1];
mvx_sub = (mvx[i] >= 0)? mvx[i] % 4: (4 - abs(mvx[i]) % 4) % 4;
mvy_sub = (mvy[i] >= 0)? mvy[i] % 4: (4 - abs(mvy[i]) % 4) % 4;
sub_pos[i] = mvx_sub + 4 * mvy_sub; // pos 0..15 in a 4x4 block
ref_frame[i] = enc_picture->ref_idx[LIST_0+i][y/4][x/4];
}
if(ref_frame[0] != -1)
{
imgY = listX[LIST_0][ref_frame[0]]->imgY;
for(yi = 0; yi < 4; ++yi)
{
for(xj = 0; xj < 4;++xj)
{
int xcoord0 = Clip3Fun(0 , out4Y_width, 4 * (x + xj) + 4 * IMG_PAD_SIZE + mvx[0]);
int ycoord0 = Clip3Fun(0 , out4Y_height, 4 * (y + yi) + 4 * IMG_PAD_SIZE + mvy[0]);
valOrg = imgY_org[y+yi][x+xj];
filterF = BestCombFilterB[sub_pos[0]]; // Use best filter
tmp = valOrg - GetInterpolatedPixel(imgY, ycoord0, xcoord0, img->width, img->height, sub_pos[0], filterF);
AccFrameOffsetF[ref_frame[0]] += tmp;
SamplesFrameOffsetF[ref_frame[0]]++;
if(ref_frame[0] == 0)
{
AccSubPelOffsetF[sub_pos[0]] += tmp;
SamplesSubPelOffsetF[sub_pos[0]]++;
}
} // x
} // y
}
} // for(subblock = 0; subblock < 16; subblock++)
} // if (img->type==B_SLICE)
}
//
// Computes the offsets for the F reference frames
//
static void ComputeOffset0(void)
{
int i;
int offset;
// Frame offsets
for (i = 0; i < listXsize[LIST_0]; ++i)
{
if(SamplesFrameOffsetF[i] > 0)
{
offset = (int)((double)fabs(AccFrameOffsetF[i]) / (double)SamplesFrameOffsetF[i] + 0.5);
if (AccFrameOffsetF[i] < 0)
offset = -offset;
}
else
{
offset = 0;
}
FrameOffsetF[i] = offset; // Frame offset
}
// SubPel offsets
for(i = 0; i < 16; ++i)
{
if(SamplesSubPelOffsetF[i] > 0)
{
offset = (int)((double)fabs(AccSubPelOffsetF[i]) / (double)SamplesSubPelOffsetF[i] + 0.5);
if (AccSubPelOffsetF[i] < 0)
offset = -offset;
}
else
{
offset = 0;
}
SubPelOffsetF[i] = offset;
}
}
//
// Accumulate values to compute offset for B reference frames
//
static void AccumulateOffset1_B(int x_orig, int y_orig)
{
int x, y, xj, yi, valOrg,i;
int mvx[2], mvy[2];
int sub_pos[2], mvx_sub, mvy_sub;
int ref_frame[2];
int subblock = 0;
int out4Y_width = (img->width + 2 * IMG_PAD_SIZE) * 4 - 1;
int out4Y_height = (img->height + 2 * IMG_PAD_SIZE) * 4 - 1;
double tmp, tmp1, tmp2;
double w0, w1, denom, round;
unsigned short ** imgY0;
unsigned short ** imgY1;
unsigned short ** imgY;
int tempF, tempB, tempFsp;
int filterF, filterB;
int apply_weights = ((img->filterParam == SIFO_SEQ_FILTER) && (active_pps->pic_parameter_set_id == 2));
for(subblock = 0; subblock < 16; ++subblock)
{
x = x_orig+4*(subblock%4);
y = y_orig+4*(subblock/4);
//get motion information
for (i = 0; i < 2; ++i)
{
mvx[i] = enc_picture->mv[LIST_0+i][y/4][x/4][0];
mvy[i] = enc_picture->mv[LIST_0+i][y/4][x/4][1];
mvx_sub = (mvx[i] >= 0)? mvx[i] % 4: (4 - abs(mvx[i]) % 4) % 4;
mvy_sub = (mvy[i] >= 0)? mvy[i] % 4: (4 - abs(mvy[i]) % 4) % 4;
sub_pos[i] = mvx_sub + 4 * mvy_sub; // pos 0..15 in a 4x4 block
ref_frame[i] = enc_picture->ref_idx[LIST_0+i][y/4][x/4];
}
if ((ref_frame[0] != -1) && (ref_frame[1] != -1)) // bi-directional
{
int fw_ref_idx = ref_frame[0];
int bw_ref_idx = ref_frame[1];
imgY0 = listX[LIST_0][fw_ref_idx]->imgY;
imgY1 = listX[LIST_1][bw_ref_idx]->imgY;
if(apply_weights)
{
w0 = wbp_weight[0][fw_ref_idx][bw_ref_idx][0];
w1 = wbp_weight[1][fw_ref_idx][bw_ref_idx][0];
denom = (double)(1 << (luma_log_weight_denom + 1));
round = 2.0 * wp_luma_round * (1 - img->bipred_rounding_control);
}
else
{
w0 = 1.0;
w1 = 1.0;
denom = 2.0;
round = 1.0 - img->bipred_rounding_control;
}
for(yi = 0; yi < 4; ++yi)
{
for(xj = 0; xj < 4; ++xj)
{
int xcoord0 = Clip3Fun(0 , out4Y_width, 4 * (x + xj) + 4 * IMG_PAD_SIZE + mvx[0]);
int ycoord0 = Clip3Fun(0 , out4Y_height, 4 * (y + yi) + 4 * IMG_PAD_SIZE + mvy[0]);
int xcoord1 = Clip3Fun(0 , out4Y_width, 4 * (x + xj) + 4 * IMG_PAD_SIZE + mvx[1]);
int ycoord1 = Clip3Fun(0 , out4Y_height, 4 * (y + yi) + 4 * IMG_PAD_SIZE + mvy[1]);
valOrg = imgY_org[y+yi][x+xj];
filterF = BestCombFilterB[sub_pos[0]];
filterB = BestCombFilterB[sub_pos[1]];
tempF = GetInterpolatedPixel(imgY0, ycoord0, xcoord0, img->width, img->height, sub_pos[0], filterF)
+ FrameOffsetF[fw_ref_idx];
tempB = GetInterpolatedPixel(imgY1, ycoord1, xcoord1, img->width, img->height, sub_pos[1], filterB);
tmp1 = valOrg - clip1a((int)(((w0 * tempF) + (w1 * tempB) + round) / denom));
AccFrameOffsetB[bw_ref_idx] += (denom / w1) * tmp1;
SamplesFrameOffsetB[bw_ref_idx]++;
// Sub pel calculation is for B, so it is for sub_pos[1]
if(ref_frame[1] == 0)
{
tempFsp = GetInterpolatedPixel(imgY0, ycoord0, xcoord0, img->width, img->height, sub_pos[0], filterF)
+ SubPelOffsetF[sub_pos[0]];
tmp2 = valOrg - clip1a((int)(((w0 * tempFsp) + (w1 * tempB) + round) / denom));
AccSubPelOffsetB[sub_pos[1]] += (denom / w1) * tmp2;
SamplesSubPelOffsetB[sub_pos[1]]++;
}
} // x
} // y
}
else if(ref_frame[1] != -1) // Unidirectional, consider only B
{
imgY = listX[LIST_1][ref_frame[1]]->imgY;
for(yi = 0; yi < 4; ++yi)
{
for(xj = 0; xj < 4; ++xj)
{
int xcoord1 = Clip3Fun(0 , out4Y_width, 4 * (x + xj) + 4 * IMG_PAD_SIZE + mvx[1]);
int ycoord1 = Clip3Fun(0 , out4Y_height, 4 * (y + yi) + 4 * IMG_PAD_SIZE + mvy[1]);
valOrg = imgY_org[y+yi][x+xj];
filterB = BestCombFilterB[sub_pos[1]];
tempB = GetInterpolatedPixel(imgY, ycoord1, xcoord1, img->width, img->height, sub_pos[1], filterB);
tmp = valOrg - tempB; // Use best filter
AccFrameOffsetB[ref_frame[1]] += tmp;
SamplesFrameOffsetB[ref_frame[1]]++;
if(ref_frame[1] == 0)
{
AccSubPelOffsetB[sub_pos[1]] += tmp;
SamplesSubPelOffsetB[sub_pos[1]]++;
}
} // x
} // y
}
}
}
//
// Computes the offsets for the B reference frames
//
static void ComputeOffset1(void)
{
int i;
int offset;
// Frame offsets
for(i = 0; i < listXsize[LIST_1]; ++i)
{
if(SamplesFrameOffsetB[i] > 0)
{
offset = (int)((double)fabs(AccFrameOffsetB[i]) / (double)SamplesFrameOffsetB[i] + 0.5);
if (AccFrameOffsetB[i] < 0)
offset = -offset;
}
else
{
offset = 0;
}
FrameOffsetB[i] = offset; // Frame offset
}
// SubPel offsets
for(i = 0; i < 16; ++i)
{
if(SamplesSubPelOffsetB[i] > 0)
{
offset = (int)((double)fabs(AccSubPelOffsetB[i]) / (double)SamplesSubPelOffsetB[i] + 0.5);
if(AccSubPelOffsetB[i] < 0)
offset = -offset;
}
else
{
offset = 0;
}
SubPelOffsetB[i] = offset;
}
}
//
//
//
void SwapFilteredFrames(void)
{
unsigned frame;
for(frame = 0; frame < dpb.ref_frames_in_buffer; ++frame)
{
dpb.fs_ref[frame]->frame->p_imgY_filt = dpb.fs_ref[frame]->frame->imgY_filt;
dpb.fs_ref[frame]->frame->imgY_filt = dpb.fs_ref[frame]->frame->imgY;
dpb.fs_ref[frame]->frame->imgY = dpb.fs_ref[frame]->frame->p_imgY_filt;
dpb.fs_ref[frame]->frame->p_imgY_11_filt = dpb.fs_ref[frame]->frame->imgY_11_filt;
dpb.fs_ref[frame]->frame->imgY_11_filt = dpb.fs_ref[frame]->frame->imgY_11;
dpb.fs_ref[frame]->frame->imgY_11 = dpb.fs_ref[frame]->frame->p_imgY_11_filt;
}
}
//
//
//
static void ScanMacroblocksAndApplyFunction(void fun(int, int))
{
int i, j;
if((img->type == P_SLICE) || (img->type == B_SLICE))
{
// Loop over all macroblocks and call fun()
for (i = 0; i < img->height; i = i + MB_BLOCK_SIZE)
for (j = 0; j < img->width; j = j + MB_BLOCK_SIZE)
fun(j, i);
}
}
//
// Update the filter choice for the sequence
//
static void UpdateSequenceFilters_B(void)
{
int i;
for(i = 0; i < 16; ++i)
img->filterSequence[i] = SequenceBestCombFilterB[i];
}
//
// Main entry point
//
static int ComputeFiltersAndOffsets(void)
{
int i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -