📄 mbuffer.c
字号:
************************************************************************
*/
static int compare_pic_by_lt_pic_num_asc( const void *arg1, const void *arg2 )
{
if ( (*(StorablePicture**)arg1)->long_term_pic_num < (*(StorablePicture**)arg2)->long_term_pic_num)
return -1;
if ( (*(StorablePicture**)arg1)->long_term_pic_num > (*(StorablePicture**)arg2)->long_term_pic_num)
return 1;
else
return 0;
}
/*!
************************************************************************
* \brief
* compares two frame stores by pic_num for qsort in descending order
*
************************************************************************
*/
static int compare_fs_by_frame_num_desc( const void *arg1, const void *arg2 )
{
if ( (*(FrameStore**)arg1)->frame_num_wrap < (*(FrameStore**)arg2)->frame_num_wrap)
return 1;
if ( (*(FrameStore**)arg1)->frame_num_wrap > (*(FrameStore**)arg2)->frame_num_wrap)
return -1;
else
return 0;
}
/*!
************************************************************************
* \brief
* compares two frame stores by lt_pic_num for qsort in descending order
*
************************************************************************
*/
static int compare_fs_by_lt_pic_idx_asc( const void *arg1, const void *arg2 )
{
if ( (*(FrameStore**)arg1)->long_term_frame_idx < (*(FrameStore**)arg2)->long_term_frame_idx)
return -1;
if ( (*(FrameStore**)arg1)->long_term_frame_idx > (*(FrameStore**)arg2)->long_term_frame_idx)
return 1;
else
return 0;
}
/*!
************************************************************************
* \brief
* compares two stored pictures by poc for qsort in ascending order
*
************************************************************************
*/
static int compare_pic_by_poc_asc( const void *arg1, const void *arg2 )
{
if ( (*(StorablePicture**)arg1)->poc < (*(StorablePicture**)arg2)->poc)
return -1;
if ( (*(StorablePicture**)arg1)->poc > (*(StorablePicture**)arg2)->poc)
return 1;
else
return 0;
}
/*!
************************************************************************
* \brief
* compares two stored pictures by poc for qsort in descending order
*
************************************************************************
*/
static int compare_pic_by_poc_desc( const void *arg1, const void *arg2 )
{
if ( (*(StorablePicture**)arg1)->poc < (*(StorablePicture**)arg2)->poc)
return 1;
if ( (*(StorablePicture**)arg1)->poc > (*(StorablePicture**)arg2)->poc)
return -1;
else
return 0;
}
/*!
************************************************************************
* \brief
* compares two frame stores by poc for qsort in ascending order
*
************************************************************************
*/
static int compare_fs_by_poc_asc( const void *arg1, const void *arg2 )
{
if ( (*(FrameStore**)arg1)->poc < (*(FrameStore**)arg2)->poc)
return -1;
if ( (*(FrameStore**)arg1)->poc > (*(FrameStore**)arg2)->poc)
return 1;
else
return 0;
}
/*!
************************************************************************
* \brief
* compares two frame stores by poc for qsort in descending order
*
************************************************************************
*/
static int compare_fs_by_poc_desc( const void *arg1, const void *arg2 )
{
if ( (*(FrameStore**)arg1)->poc < (*(FrameStore**)arg2)->poc)
return 1;
if ( (*(FrameStore**)arg1)->poc > (*(FrameStore**)arg2)->poc)
return -1;
else
return 0;
}
/*!
************************************************************************
* \brief
* returns true, if picture is short term reference picture
*
************************************************************************
*/
int is_short_ref(StorablePicture *s)
{
return ((s->used_for_reference) && (!(s->is_long_term)));
}
/*!
************************************************************************
* \brief
* returns true, if picture is long term reference picture
*
************************************************************************
*/
int is_long_ref(StorablePicture *s)
{
return ((s->used_for_reference) && (s->is_long_term));
}
/*!
************************************************************************
* \brief
* Generates a alternating field list from a given FrameStore list
*
************************************************************************
*/
static void gen_pic_list_from_frame_list(PictureStructure currStrcture, FrameStore **fs_list, int list_idx, StorablePicture **list, int *list_size, int long_term)
{
int top_idx = 0;
int bot_idx = 0;
int (*is_ref)(StorablePicture *s);
if (long_term)
is_ref=is_long_ref;
else
is_ref=is_short_ref;
if (currStrcture == TOP_FIELD)
{
while ((top_idx<list_idx)||(bot_idx<list_idx))
{
for ( ; top_idx<list_idx; top_idx++)
{
if(fs_list[top_idx]->is_used & 1)
{
if(is_ref(fs_list[top_idx]->top_field))
{
// short term ref pic
list[*list_size] = fs_list[top_idx]->top_field;
(*list_size)++;
top_idx++;
break;
}
}
}
for ( ; bot_idx<list_idx; bot_idx++)
{
if(fs_list[bot_idx]->is_used & 2)
{
if(is_ref(fs_list[bot_idx]->bottom_field))
{
// short term ref pic
list[*list_size] = fs_list[bot_idx]->bottom_field;
(*list_size)++;
bot_idx++;
break;
}
}
}
}
}
if (currStrcture == BOTTOM_FIELD)
{
while ((top_idx<list_idx)||(bot_idx<list_idx))
{
for ( ; bot_idx<list_idx; bot_idx++)
{
if(fs_list[bot_idx]->is_used & 2)
{
if(is_ref(fs_list[bot_idx]->bottom_field))
{
// short term ref pic
list[*list_size] = fs_list[bot_idx]->bottom_field;
(*list_size)++;
bot_idx++;
break;
}
}
}
for ( ; top_idx<list_idx; top_idx++)
{
if(fs_list[top_idx]->is_used & 1)
{
if(is_ref(fs_list[top_idx]->top_field))
{
// short term ref pic
list[*list_size] = fs_list[top_idx]->top_field;
(*list_size)++;
top_idx++;
break;
}
}
}
}
}
}
/*!
************************************************************************
* \brief
* Initialize listX[0] and list 1 depending on current picture type
*
************************************************************************
*/
void init_lists(int currSliceType, PictureStructure currPicStructure)
{
int add_top = 0, add_bottom = 0;
unsigned i;
int j;
int MaxFrameNum = 1 << (active_sps->log2_max_frame_num_minus4 + 4);
int diff;
int list0idx = 0;
int list0idx_1 = 0;
int listltidx = 0;
FrameStore **fs_list0;
FrameStore **fs_list1;
FrameStore **fs_listlt;
StorablePicture *tmp_s;
if (currPicStructure == FRAME)
{
for (i=0; i<dpb.ref_frames_in_buffer; i++)
{
if (dpb.fs_ref[i]->is_used==3)
{
if ((dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term))
{
if( dpb.fs_ref[i]->frame_num > img->frame_num )
{
dpb.fs_ref[i]->frame_num_wrap = dpb.fs_ref[i]->frame_num - MaxFrameNum;
}
else
{
dpb.fs_ref[i]->frame_num_wrap = dpb.fs_ref[i]->frame_num;
}
dpb.fs_ref[i]->frame->pic_num = dpb.fs_ref[i]->frame_num_wrap;
}
}
}
// update long_term_pic_num
for (i=0; i<dpb.ltref_frames_in_buffer; i++)
{
if (dpb.fs_ltref[i]->is_used==3)
{
if (dpb.fs_ltref[i]->frame->is_long_term)
{
dpb.fs_ltref[i]->frame->long_term_pic_num = dpb.fs_ltref[i]->frame->long_term_frame_idx;
}
}
}
}
else
{
if (currPicStructure == TOP_FIELD)
{
add_top = 1;
add_bottom = 0;
}
else
{
add_top = 0;
add_bottom = 1;
}
for (i=0; i<dpb.ref_frames_in_buffer; i++)
{
if (dpb.fs_ref[i]->is_reference)
{
if( dpb.fs_ref[i]->frame_num > img->frame_num )
{
dpb.fs_ref[i]->frame_num_wrap = dpb.fs_ref[i]->frame_num - MaxFrameNum;
}
else
{
dpb.fs_ref[i]->frame_num_wrap = dpb.fs_ref[i]->frame_num;
}
if (dpb.fs_ref[i]->is_reference & 1)
{
dpb.fs_ref[i]->top_field->pic_num = (2 * dpb.fs_ref[i]->frame_num_wrap) + add_top;
}
if (dpb.fs_ref[i]->is_reference & 2)
{
dpb.fs_ref[i]->bottom_field->pic_num = (2 * dpb.fs_ref[i]->frame_num_wrap) + add_bottom;
}
}
}
// update long_term_pic_num
for (i=0; i<dpb.ltref_frames_in_buffer; i++)
{
if (dpb.fs_ltref[i]->is_long_term & 1)
{
dpb.fs_ltref[i]->top_field->long_term_pic_num = 2 * dpb.fs_ltref[i]->top_field->long_term_frame_idx + add_top;
}
if (dpb.fs_ltref[i]->is_long_term & 2)
{
dpb.fs_ltref[i]->bottom_field->long_term_pic_num = 2 * dpb.fs_ltref[i]->bottom_field->long_term_frame_idx + add_bottom;
}
}
}
if ((currSliceType == I_SLICE)||(currSliceType == SI_SLICE))
{
listXsize[0] = 0;
listXsize[1] = 0;
return;
}
if ((currSliceType == P_SLICE)||(currSliceType == SP_SLICE))
{
// Calculate FrameNumWrap and PicNum
if (currPicStructure == FRAME)
{
for (i=0; i<dpb.ref_frames_in_buffer; i++)
{
if (dpb.fs_ref[i]->is_used==3)
{
if ((dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term))
{
listX[0][list0idx++] = dpb.fs_ref[i]->frame;
}
}
}
// order list 0 by PicNum
qsort((void *)listX[0], list0idx, sizeof(StorablePicture*), compare_pic_by_pic_num_desc);
listXsize[0] = list0idx;
// printf("listX[0] (PicNum): "); for (i=0; i<list0idx; i++){printf ("%d ", listX[0][i]->pic_num);} printf("\n");
// long term handling
for (i=0; i<dpb.ltref_frames_in_buffer; i++)
{
if (dpb.fs_ltref[i]->is_used==3)
{
if (dpb.fs_ltref[i]->frame->is_long_term)
{
listX[0][list0idx++]=dpb.fs_ltref[i]->frame;
}
}
}
qsort((void *)&listX[0][listXsize[0]], list0idx-listXsize[0], sizeof(StorablePicture*), compare_pic_by_lt_pic_num_asc);
listXsize[0] = list0idx;
}
else
{
fs_list0 = calloc(dpb.size, sizeof (FrameStore*));
if (NULL==fs_list0)
no_mem_exit("init_lists: fs_list0");
fs_listlt = calloc(dpb.size, sizeof (FrameStore*));
if (NULL==fs_listlt)
no_mem_exit("init_lists: fs_listlt");
for (i=0; i<dpb.ref_frames_in_buffer; i++)
{
if (dpb.fs_ref[i]->is_reference)
{
fs_list0[list0idx++] = dpb.fs_ref[i];
}
}
qsort((void *)fs_list0, list0idx, sizeof(FrameStore*), compare_fs_by_frame_num_desc);
// printf("fs_list0 (FrameNum): "); for (i=0; i<list0idx; i++){printf ("%d ", fs_list0[i]->frame_num_wrap);} printf("\n");
listXsize[0] = 0;
gen_pic_list_from_frame_list(currPicStructure, fs_list0, list0idx, listX[0], &listXsize[0], 0);
// printf("listX[0] (PicNum): "); for (i=0; i<listXsize[0]; i++){printf ("%d ", listX[0][i]->pic_num);} printf("\n");
// long term handling
for (i=0; i<dpb.ltref_frames_in_buffer; i++)
{
fs_listlt[listltidx++]=dpb.fs_ltref[i];
}
qsort((void *)fs_listlt, listltidx, sizeof(FrameStore*), compare_fs_by_lt_pic_idx_asc);
gen_pic_list_from_frame_list(currPicStructure, fs_listlt, listltidx, listX[0], &listXsize[0], 1);
free(fs_list0);
free(fs_listlt);
}
listXsize[1] = 0;
}
else
{
// B-Slice
if (currPicStructure == FRAME)
{
for (i=0; i<dpb.ref_frames_in_buffer; i++)
{
if (dpb.fs_ref[i]->is_used==3)
{
if ((dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term))
{
if (img->framepoc >= dpb.fs_ref[i]->frame->poc) //!KS use >= for error concealment
// if (img->framepoc > dpb.fs_ref[i]->frame->poc)
{
listX[0][list0idx++] = dpb.fs_ref[i]->frame;
}
}
}
}
qsort((void *)listX[0], list0idx, sizeof(StorablePicture*), compare_pic_by_poc_desc);
list0idx_1 = list0idx;
for (i=0; i<dpb.ref_frames_in_buffer; i++)
{
if (dpb.fs_ref[i]->is_used==3)
{
if ((dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term))
{
if (img->framepoc < dpb.fs_ref[i]->frame->poc)
{
listX[0][list0idx++] = dpb.fs_ref[i]->frame;
}
}
}
}
qsort((void *)&listX[0][list0idx_1], list0idx-list0idx_1, sizeof(StorablePicture*), compare_pic_by_poc_asc);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -