📄 epzs.c
字号:
int searcharray = input->BiPredMotionEstimation? 2 * max (input->search_range, input->BiPredMESearchRange) + 1 : 2 * input->search_range + 1;
int searchlevels = RoundLog2 (input->search_range) - 1;
//! In this implementation we keep threshold limits fixed.
//! However one could adapt these limits based on lagrangian
//! optimization considerations (i.e. qp), while also allow
//! adaptation of the limits themselves based on content or complexity.
for (i=0;i<8;i++)
{
medthres[i] = input->EPZSMedThresScale * medthres_base[i] * pel_error_me;
maxthres[i] = input->EPZSMaxThresScale * maxthres_base[i] * pel_error_me;
minthres[i] = input->EPZSMinThresScale * minthres_base[i] * pel_error_me;
subthres[i] = input->EPZSSubPelThresScale * medthres_base[i] * pel_error_me;
}
//! Definition of pottential EPZS patterns.
//! It is possible to also define other patterns, or even use
//! resizing patterns (such as the PMVFAST scheme. These patterns
//! are only shown here as reference, while the same also holds
//! for this implementation (i.e. new conditions could be added
//! on adapting predictors, or thresholds etc. Note that search
//! could also be performed on subpel positions directly while
//! pattern needs not be restricted on integer positions only.
//! Allocate memory and assign search patterns
sdiamond = allocEPZSpattern(4);
assignEPZSpattern(sdiamond, SDIAMOND);
square = allocEPZSpattern(8);
assignEPZSpattern(square, SQUARE);
ediamond = allocEPZSpattern(12);
assignEPZSpattern(ediamond, EDIAMOND);
ldiamond = allocEPZSpattern(8);
assignEPZSpattern(ldiamond, LDIAMOND);
//! Allocate and assign window based predictors.
//! Other window types could also be used, while method could be
//! made a bit more adaptive (i.e. patterns could be assigned
//! based on neighborhood
window_predictor = allocEPZSpattern(searchlevels * 8);
window_predictor_extended = allocEPZSpattern(searchlevels * 20);
EPZSWindowPredictorInit ((short) input->search_range, window_predictor, 0);
EPZSWindowPredictorInit ((short) input->search_range, window_predictor_extended, 1);
//! Also assing search predictor memory
// maxwindow + spatial + blocktype + temporal + memspatial
predictor = allocEPZSpattern(searchlevels * 20 + 5 + 5 + 9 * (input->EPZSTemporal) + 3 * (input->EPZSSpatialMem));
//! Finally assign memory for all other elements
//! (distortion, EPZSMap, and temporal predictors)
memory_size += get_mem3Dint (&EPZSDistortion, 6, 7, img->width/BLOCK_SIZE);
memory_size += get_mem2D (&EPZSMap, searcharray, searcharray );
if (input->EPZSSpatialMem)
{
#if EPZSREF
memory_size += get_mem6Dshort (&EPZSMotion, 6, img->max_num_references, 7, 4, img->width/BLOCK_SIZE, 2);
#else
memory_size += get_mem5Dshort (&EPZSMotion, 6, 7, 4, img->width/BLOCK_SIZE, 2);
#endif
}
if (input->EPZSTemporal)
EPZSCo_located = allocEPZScolocated (img->width, img->height,
active_sps->mb_adaptive_frame_field_flag);
switch (input->EPZSPattern)
{
case 3:
searchPattern = ldiamond;
break;
case 2:
searchPattern = ediamond;
break;
case 1:
searchPattern = square;
break;
case 0:
default:
searchPattern = sdiamond;
break;
}
switch (input->EPZSDual)
{
case 4:
searchPatternD = ldiamond;
break;
case 3:
searchPatternD = ediamond;
break;
case 2:
searchPatternD = square;
break;
case 1:
default:
searchPatternD = sdiamond;
break;
}
return memory_size;
}
/*!
************************************************************************
* \brief
* Delete EPZS Alocated memory
************************************************************************
*/
void EPZSDelete (void)
{
if (input->EPZSTemporal)
freeEPZScolocated (EPZSCo_located);
free_mem2D (EPZSMap);
free_mem3Dint (EPZSDistortion, 6);
freeEPZSpattern(window_predictor_extended);
freeEPZSpattern(window_predictor);
freeEPZSpattern(predictor);
freeEPZSpattern(ldiamond);
freeEPZSpattern(ediamond);
freeEPZSpattern(sdiamond);
freeEPZSpattern(square);
if (input->EPZSSpatialMem)
{
#if EPZSREF
free_mem6Dshort (EPZSMotion, 6, img->max_num_references, 7, 4);
#else
free_mem5Dshort (EPZSMotion, 6, 7, 4);
#endif
}
}
//! For ME purposes restricting the co-located partition is not necessary.
/*!
************************************************************************
* \brief
* EPZS Slice Level Initialization
************************************************************************
*/
void
EPZSSliceInit (EPZSColocParams * p,
StorablePicture ** listX[6])
{
StorablePicture *fs, *fs_top, *fs_bottom;
StorablePicture *fs1, *fs_top1, *fs_bottom1, *fsx;
int i, j, k, jj, jdiv, loffset;
int prescale, iTRb, iTRp;
int list = img->type == B_SLICE ? LIST_1 : LIST_0;
int tempmv_scale[2];
int epzs_scale[2][6][MAX_LIST_SIZE];
int iref;
// Lets compute scaling factoes between all references in lists.
// Needed to scale spatial predictors.
for (j = LIST_0; j < 2 + (img->MbaffFrameFlag * 4); j ++)
{
for (k = 0; k < listXsize[j]; k++)
{
for (i = 0; i < listXsize[j]; i++)
{
if (j/2 == 0)
{
iTRb = Clip3 (-128, 127, enc_picture->poc - listX[j][i]->poc);
iTRp = Clip3 (-128, 127, enc_picture->poc - listX[j][k]->poc);
}
else if (j/2 == 1)
{
iTRb = Clip3 (-128, 127, enc_picture->top_poc - listX[j][i]->poc);
iTRp = Clip3 (-128, 127, enc_picture->top_poc - listX[j][k]->poc);
}
else
{
iTRb = Clip3 (-128, 127, enc_picture->bottom_poc - listX[j][i]->poc);
iTRp = Clip3 (-128, 127, enc_picture->bottom_poc - listX[j][k]->poc);
}
if (iTRp != 0)
{
prescale = (16384 + abs (iTRp / 2)) / iTRp;
mv_scale[j][i][k] = Clip3 (-2048, 2047, (iTRb * prescale + 32) >> 6);
}
else
mv_scale[j][i][k] = 256;
}
}
}
if (input->EPZSTemporal)
{
fs_top = fs_bottom = fs = listX[list][0];
if (listXsize[0]> 1)
fs_top1 = fs_bottom1 = fs1 = listX[list][1];
else
fs_top1 = fs_bottom1 = fs1 = listX[list][0];
for (j = 0; j < 6; j++)
{
for (i = 0; i < 6; i++)
{
epzs_scale[0][j][i] = 256;
epzs_scale[1][j][i] = 256;
}
}
for (j = 0; j < 2 + (img->MbaffFrameFlag * 4); j += 2)
{
for (i = 0; i < listXsize[j]; i++)
{
if (j == 0)
iTRb = Clip3 (-128, 127, enc_picture->poc - listX[LIST_0 + j][i]->poc);
else if (j == 2)
iTRb = Clip3 (-128, 127, enc_picture->top_poc - listX[LIST_0 + j][i]->poc);
else
iTRb = Clip3 (-128, 127, enc_picture->bottom_poc - listX[LIST_0 + j][i]->poc);
iTRp = Clip3 (-128, 127, listX[list + j][0]->poc - listX[LIST_0 + j][i]->poc);
if (iTRp != 0)
{
prescale = (16384 + abs (iTRp / 2)) / iTRp;
prescale = Clip3 (-2048, 2047, (iTRb * prescale + 32) >> 6);
//prescale = (iTRb * prescale + 32) >> 6;
}
else // This could not happen but lets use it in case that reference is removed.
prescale = 256;
epzs_scale[0][j][i] = (mv_scale[j][0][i] * prescale + 128) >> 8;
epzs_scale[0][j + 1][i] = prescale - 256;
if (listXsize[j]>1)
{
iTRp = Clip3 (-128, 127, listX[list + j][1]->poc - listX[LIST_0 + j][i]->poc);
if (iTRp != 0)
{
prescale = (16384 + abs (iTRp / 2)) / iTRp;
prescale = Clip3 (-2048, 2047, (iTRb * prescale + 32) >> 6);
//prescale = (iTRb * prescale + 32) >> 6;
}
else // This could not happen but lets use it for case that reference is removed.
prescale = 256;
epzs_scale[1][j][i] = (mv_scale[j][1][i] * prescale + 128) >> 8;
epzs_scale[1][j + 1][i] = prescale - 256;
}
else
{
epzs_scale[1][j][i] = epzs_scale[0][j][i];
epzs_scale[1][j + 1][i] = epzs_scale[0][j + 1][i];
}
}
}
if (img->MbaffFrameFlag)
{
fs_top = listX[list + 2][0];
fs_bottom = listX[list + 4][0];
if (listXsize[0]> 1)
{
fs_top1 = listX[list + 2][1];
fs_bottom = listX[list + 4][1];
}
}
else
{
if (img->structure != FRAME)
{
if ((img->structure != fs->structure) && (fs->coded_frame))
{
if (img->structure == TOP_FIELD)
{
fs_top = fs_bottom = fs = listX[list][0]->top_field;
fs_top1 = fs_bottom1 = fs1 = listX[list][0]->bottom_field;
}
else
{
fs_top = fs_bottom = fs = listX[list][0]->bottom_field;
fs_top1 = fs_bottom1 = fs1 = listX[list][0]->top_field;
}
}
}
}
//if (!active_sps->frame_mbs_only_flag || active_sps->direct_8x8_inference_flag)
if (!active_sps->frame_mbs_only_flag)
{
for (j = 0; j < fs->size_y >> 2; j++)
{
jj = j / 2;
jdiv = j / 2 + 4 * (j / 8);
for (i = 0; i < fs->size_x >> 2; i++)
{
if (img->MbaffFrameFlag && fs->field_frame[j][i])
{
//! Assign frame buffers for field MBs
//! Check whether we should use top or bottom field mvs.
//! Depending on the assigned poc values.
if (abs (enc_picture->poc - fs_bottom->poc) > abs (enc_picture->poc - fs_top->poc))
{
tempmv_scale[LIST_0] = 256;
tempmv_scale[LIST_1] = 0;
if (fs->ref_id [LIST_0][jdiv][i] < 0 && listXsize[LIST_0] > 1)
{
fsx = fs_top1;
loffset = 1;
}
else
{
fsx = fs_top;
loffset = 0;
}
if (fs->ref_id [LIST_0][jdiv][i] != -1)
{
for (iref=0;iref<min(img->num_ref_idx_l0_active,listXsize[LIST_0]);iref++)
{
if (enc_picture->ref_pic_num[LIST_0][iref]==fs->ref_id [LIST_0][jdiv][i])
{
tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
break;
}
}
p->mv[LIST_0][j][i][0] = (tempmv_scale[LIST_0] * fsx->mv[LIST_0][jj][i][0] + 32) >> 6;
p->mv[LIST_0][j][i][1] = (tempmv_scale[LIST_0] * fsx->mv[LIST_0][jj][i][1] + 32) >> 6;
p->mv[LIST_1][j][i][0] = (tempmv_scale[LIST_1] * fsx->mv[LIST_0][jj][i][0] + 32) >> 6;
p->mv[LIST_1][j][i][1] = (tempmv_scale[LIST_1] * fsx->mv[LIST_0][jj][i][1] + 32) >> 6;
}
else
{
p->mv[LIST_0][j][i][0] = 0;
p->mv[LIST_0][j][i][1] = 0;
p->mv[LIST_1][j][i][0] = 0;
p->mv[LIST_1][j][i][1] = 0;
}
}
else
{
tempmv_scale[LIST_0] = 256;
tempmv_scale[LIST_1] = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -