📄 switched_filters.c
字号:
if(img->type == P_SLICE)
{
ResetAll(img->type);
ScanMacroblocksAndApplyFunction(AccumulateError_P); // Accumulate squared error for filter decision and offsets
ComputeFiltersAndOffsets_P();
}
else if(img->type == B_SLICE)
{
ResetAll(img->type);
ScanMacroblocksAndApplyFunction(AccumulateError_B); // Accumulate squared error for frame and sequence
ComputeFilterCombination_B(); // Compute filter combination (unique filter per encoded frame)
ScanMacroblocksAndApplyFunction(AccumulateOffset0_B); // Accumulate offset data for F reference frame
ComputeOffset0(); // Compute offsets for F (one offset per REFERENCE frame)
ScanMacroblocksAndApplyFunction(AccumulateOffset1_B); // Accumulate offset data for B reference frame
ComputeOffset1(); // Compute offsets for B (one offset per REFERENCE frame)
// Copy filter settings
for(i = 0; i < 16; ++i)
img->filterFrame[i] = BestCombFilterB[i];
// Copy offsets
for(i = 0; i < 16; ++i)
{
img->subpelOffset_list0[i] = SubPelOffsetF[i];
img->subpelOffset_list1[i] = SubPelOffsetB[i];
}
for(i = 0; i < listXsize[LIST_0]; ++i)
img->imgOffset_list0[i] = FrameOffsetF[i];
for(i = 0; i < listXsize[LIST_1]; ++i)
img->imgOffset_list1[i] = FrameOffsetB[i];
}
return 1;
}
//
//
//
void initSIFOFilters()
{
static int first = 1;
if(first == 1)
{
int i, j;
first = 0;
memset(img->filterSequence, 0, 16 * sizeof(int));
memset(img->filterFrame, 0, 16 * sizeof(int));
memset(img->subpelOffset_list0, 0, 16 * sizeof(int));
memset(img->subpelOffset_list1, 0, 16 * sizeof(int));
memset(img->imgOffset_list0, 0, MAX_REFERENCE_PICTURES * sizeof(int));
memset(img->imgOffset_list0, 0, MAX_REFERENCE_PICTURES * sizeof(int));
// Assign filters
for(i = 0; i < 15; ++i)
for(j = 0; j < SQR_FILTER; ++j)
{
SIFO_FILTER[0][i][j] = STANDARD_2D_FILTER[i][j];
SIFO_FILTER[1][i][j] = SYMMETRIC_1[i][j];
SIFO_FILTER[2][i][j] = SYMMETRIC_2[i][j];
}
}
}
//
//
//
static void UnifiedOneForthPixSwitchedFilters(int *filter, int *subpelOffset, int *imgOffset, int list)
{
int i, j, offset;
int frame;
imgpel **out4Y;
int img_width, img_height;
int sub_pos, x_sub, y_sub;
int icoord, jcoord;
unsigned short ** imgY;
for(frame = 0; frame < listXsize[list]; ++frame)
{
img_width = listX[list][frame]->size_x;
img_height = listX[list][frame]->size_y;
out4Y = listX[list][frame]->imgY_ups;
imgY = listX[list][frame]->imgY;
for(i = -4 * IMG_PAD_SIZE; i < (IMG_PAD_SIZE + img_height) * 4; ++i)
{
for(j = -4 * IMG_PAD_SIZE; j < (IMG_PAD_SIZE + img_width) * 4; ++j)
{
icoord = i + 4 * IMG_PAD_SIZE;
jcoord = j + 4 * IMG_PAD_SIZE;
x_sub = jcoord % 4; // x-sub-coordinate in a 4x4block
y_sub = icoord % 4; // y-sub-coordinate in a 4x4block
sub_pos = x_sub + 4 * y_sub; // pos 0..15 in a 4x4 block
offset = (frame == 0)? subpelOffset[sub_pos]: imgOffset[frame];
assert(filter[sub_pos] < NUM_SIFO);
out4Y[icoord][jcoord] = (int) Clip3Fun(0, 255, offset +
GetInterpolatedPixel(imgY, icoord, jcoord, img_width, img_height, sub_pos, filter[sub_pos]));
}
}
offset = (frame == 0)? subpelOffset[0]: imgOffset[frame];
for(i = 0; i < img_height; ++i)
for(j = 0; j < img_width; ++j)
listX[list][frame]->imgY_filt[i][j] = (int)Clip3(0, 255, listX[list][frame]->imgY[i][j] + offset);
GenerateFullPelRepresentation(out4Y, listX[list][frame]->imgY_11_filt, img_width, img_height);
}
}
//
//
//
void UnifiedOneForthPixFiltSel(int filterParam)
{
int zeroSubpelOffsets[16] = {0};
int zeroImgOffset[MAX_REFERENCE_PICTURES] = {0};
if(img->type == P_SLICE)
{
if(filterParam == SIFO_FIRST_PASS)
{
UnifiedOneForthPixSwitchedFilters(img->filterSequence, zeroSubpelOffsets, zeroImgOffset, LIST_0);
}
else
{
UnifiedOneForthPixSwitchedFilters(img->filterFrame, img->subpelOffset_list0, img->imgOffset_list0, LIST_0);
}
}
else if(img->type == B_SLICE)
{
if((filterParam == SIFO_FIRST_PASS) || (filterParam == SIFO_SEQ_FILTER))
{
UnifiedOneForthPixSwitchedFilters(img->filterSequence, zeroSubpelOffsets, zeroImgOffset, LIST_0);
UnifiedOneForthPixSwitchedFilters(img->filterSequence, zeroSubpelOffsets, zeroImgOffset, LIST_1);
}
else
{
UnifiedOneForthPixSwitchedFilters(img->filterFrame, img->subpelOffset_list0, img->imgOffset_list0, LIST_0);
UnifiedOneForthPixSwitchedFilters(img->filterFrame, img->subpelOffset_list1, img->imgOffset_list1, LIST_1);
}
}
else
{
assert(0); // Called on a I-slice?
}
}
//
//
//
void rdPictureCodingFilterP(void)
{
int rd_qp = img->qp;
int previntras = intras;
int skip_encode = 0;
active_pps = PicParSet[0];
// Compute frame filters
ComputeFiltersAndOffsets();
img->write_macroblock = 0;
skip_encode = 0;
if(skip_encode)
{
img->rd_pass = 0;
enc_frame_picture2 = NULL;
}
else
{
img->filterParam = SIFO_FRAME_FILTER_WITH_OFFSET;
frame_picture (frame_pic_2, 1);
img->rd_pass=picture_coding_decision(frame_pic_1, frame_pic_2, rd_qp);
}
if(img->rd_pass == 0)
{
enc_picture = enc_frame_picture;
intras = previntras;
frame_pic = frame_pic_1;
}
else
{
enc_picture = enc_frame_picture2;
frame_pic = frame_pic_2;
}
// Update sequence filters
UpdateSequenceFilters_P();
}
//
//
//
static int TryImplicitWP(void)
{
int td, tb;
float b_scaling = 0.5;
if(listXsize[LIST_0] && listXsize[LIST_1])
{
td = Clip3(-128, 127, (listX[LIST_1][0]->poc - listX[LIST_0][0]->poc));
tb = Clip3(-128, 127, (enc_picture->poc - listX[LIST_0][0]->poc));
if (td != 0)
b_scaling = (float) tb / (float) td;
if(b_scaling == 0.5)
return 0;
else
return 1;
}
else
{
return 0;
}
}
//
//
//
void rdPictureCodingFilterB(void)
{
int rd_qp = img->qp;
int previntras = intras;
img->write_macroblock = 0;
if(input->GenerateMultiplePPS && TryImplicitWP())
{
// Implicit WP (POC) with sequence filters
active_pps = PicParSet[2];
img->filterParam = SIFO_SEQ_FILTER;
frame_picture(frame_pic_2, 1);
img->rd_pass = picture_coding_decision(frame_pic_1, frame_pic_2, rd_qp);
}
else
{
active_pps = PicParSet[0];
img->rd_pass = 0;
enc_frame_picture2 = NULL;
}
if(img->rd_pass == 0)
{
enc_picture = enc_frame_picture;
intras = previntras;
active_pps = PicParSet[0];
}
else
{
enc_picture = enc_frame_picture2;
previntras = intras;
}
// Compute filters on Pass 0 or Pass 1
ComputeFiltersAndOffsets();
// Frame filters and sub-pel offsets
img->write_macroblock = 0;
img->filterParam = SIFO_FRAME_FILTER_WITH_OFFSET;
frame_picture(frame_pic_3, 2);
if(img->rd_pass == 0)
img->rd_pass = 2 * picture_coding_decision(frame_pic_1, frame_pic_3, rd_qp); // 0 or 2
else
img->rd_pass += picture_coding_decision(frame_pic_2, frame_pic_3, rd_qp); // 1 or 2
if(img->rd_pass == 0)
{
enc_picture = enc_frame_picture;
}
else if(img->rd_pass == 1)
{
enc_picture = enc_frame_picture2;
}
else
{
enc_picture = enc_frame_picture3;
previntras = intras;
}
// Filters and sub-pel offsets with QP+1
img->write_macroblock = 0;
img->qp = rd_qp + 1;
img->filterParam = SIFO_FRAME_FILTER_WITH_OFFSET;
if((img->rd_pass == 0) || (img->rd_pass == 1))
{
img->filterParam = SIFO_SEQ_FILTER; // Try sequence filters with QP+1
frame_picture(frame_pic_3, 2); // Reuse frame_pic_3
}
else if(img->rd_pass == 2)
{
img->filterParam = SIFO_FRAME_FILTER_WITH_OFFSET; // Try frame filters and offsets with QP+1
frame_picture(frame_pic_2, 1); // Reuse frame_pic_2
}
if(img->rd_pass == 0)
{
img->rd_pass = picture_coding_decision(frame_pic_1, frame_pic_3, rd_qp);
if(img->rd_pass == 0)
{
enc_picture = enc_frame_picture;
intras = previntras;
img->qp = rd_qp;
img->rd_pass = 0;
}
else
{
enc_picture = enc_frame_picture3;
img->qp = rd_qp + 1;
img->rd_pass = 2;
}
}
else if(img->rd_pass == 1)
{
img->rd_pass = picture_coding_decision(frame_pic_2, frame_pic_3, rd_qp);
if(img->rd_pass == 0)
{
enc_picture = enc_frame_picture2;
intras = previntras;
img->qp = rd_qp;
img->rd_pass = 1;
}
else
{
enc_picture = enc_frame_picture3;
img->qp = rd_qp + 1;
img->rd_pass = 2;
}
}
else
{
img->rd_pass = picture_coding_decision(frame_pic_3, frame_pic_2, rd_qp);
if(img->rd_pass == 0)
{
enc_picture = enc_frame_picture3;
intras = previntras;
img->qp = rd_qp;
img->rd_pass = 2;
}
else
{
enc_picture = enc_frame_picture2;
img->qp = rd_qp + 1;
img->rd_pass = 1;
}
}
// Update sequence filters
UpdateSequenceFilters_B();
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -