📄 mbuffer.c
字号:
for (j=0; j<list0idx_1; j++)
{
listX[1][list0idx-list0idx_1+j]=listX[0][j];
}
for (j=list0idx_1; j<list0idx; j++)
{
listX[1][j-list0idx_1]=listX[0][j];
}
listXsize[0] = listXsize[1] = list0idx;
// printf("listX[0] currPoc=%d (Poc): ", img->framepoc); for (i=0; i<listXsize[0]; i++){printf ("%d ", listX[0][i]->poc);} printf("\n");
// printf("listX[1] currPoc=%d (Poc): ", img->framepoc); for (i=0; i<listXsize[1]; i++){printf ("%d ", listX[1][i]->poc);} 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;
listX[1][list0idx++]=dpb.fs_ltref[i]->frame;
}
}
}
qsort((void *)&listX[0][listXsize[0]], list0idx-listXsize[0], sizeof(StorablePicture*), compare_pic_by_lt_pic_num_asc);
qsort((void *)&listX[1][listXsize[0]], list0idx-listXsize[0], sizeof(StorablePicture*), compare_pic_by_lt_pic_num_asc);
listXsize[0] = listXsize[1] = list0idx;
}
else
{
fs_list0 = calloc(dpb.size, sizeof (FrameStore*));
if (NULL==fs_list0)
no_mem_exit("init_lists: fs_list0");
fs_list1 = calloc(dpb.size, sizeof (FrameStore*));
if (NULL==fs_list1)
no_mem_exit("init_lists: fs_list1");
fs_listlt = calloc(dpb.size, sizeof (FrameStore*));
if (NULL==fs_listlt)
no_mem_exit("init_lists: fs_listlt");
listXsize[0] = 0;
listXsize[1] = 1;
for (i=0; i<dpb.ref_frames_in_buffer; i++)
{
if (dpb.fs_ref[i]->is_used)
{
if (img->ThisPOC >= dpb.fs_ref[i]->poc)
{
fs_list0[list0idx++] = dpb.fs_ref[i];
}
}
}
qsort((void *)fs_list0, list0idx, sizeof(FrameStore*), compare_fs_by_poc_desc);
list0idx_1 = list0idx;
for (i=0; i<dpb.ref_frames_in_buffer; i++)
{
if (dpb.fs_ref[i]->is_used)
{
if (img->ThisPOC < dpb.fs_ref[i]->poc)
{
fs_list0[list0idx++] = dpb.fs_ref[i];
}
}
}
qsort((void *)&fs_list0[list0idx_1], list0idx-list0idx_1, sizeof(FrameStore*), compare_fs_by_poc_asc);
for (j=0; j<list0idx_1; j++)
{
fs_list1[list0idx-list0idx_1+j]=fs_list0[j];
}
for (j=list0idx_1; j<list0idx; j++)
{
fs_list1[j-list0idx_1]=fs_list0[j];
}
// printf("fs_list0 currPoc=%d (Poc): ", img->ThisPOC); for (i=0; i<list0idx; i++){printf ("%d ", fs_list0[i]->poc);} printf("\n");
// printf("fs_list1 currPoc=%d (Poc): ", img->ThisPOC); for (i=0; i<list0idx; i++){printf ("%d ", fs_list1[i]->poc);} printf("\n");
listXsize[0] = 0;
listXsize[1] = 0;
gen_pic_list_from_frame_list(currPicStructure, fs_list0, list0idx, listX[0], &listXsize[0], 0);
gen_pic_list_from_frame_list(currPicStructure, fs_list1, list0idx, listX[1], &listXsize[1], 0);
// printf("listX[0] currPoc=%d (Poc): ", img->framepoc); for (i=0; i<listXsize[0]; i++){printf ("%d ", listX[0][i]->poc);} printf("\n");
// printf("listX[1] currPoc=%d (Poc): ", img->framepoc); for (i=0; i<listXsize[1]; i++){printf ("%d ", listX[1][i]->poc);} 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);
gen_pic_list_from_frame_list(currPicStructure, fs_listlt, listltidx, listX[1], &listXsize[1], 1);
free(fs_list0);
free(fs_list1);
free(fs_listlt);
}
}
if ((listXsize[0] == listXsize[1]) && (listXsize[0] > 1))
{
// check if lists are identical, if yes swap first two elements of listX[1]
diff=0;
for (j = 0; j< listXsize[0]; j++)
{
if (listX[0][j]!=listX[1][j])
diff=1;
}
if (!diff)
{
tmp_s = listX[1][0];
listX[1][0]=listX[1][1];
listX[1][1]=tmp_s;
}
}
// set max size
listXsize[0] = imin (listXsize[0], img->num_ref_idx_l0_active);
listXsize[1] = imin (listXsize[1], img->num_ref_idx_l1_active);
// set the unused list entries to NULL
for (i=listXsize[0]; i< (MAX_LIST_SIZE) ; i++)
{
// listX[0][i] = NULL;
listX[0][i] = no_reference_picture;
}
for (i=listXsize[1]; i< (MAX_LIST_SIZE) ; i++)
{
// listX[1][i] = NULL;
listX[1][i] = no_reference_picture;
}
}
/*!
************************************************************************
* \brief
* Initialize listX[2..5] from lists 0 and 1
* listX[2]: list0 for current_field==top
* listX[3]: list1 for current_field==top
* listX[4]: list0 for current_field==bottom
* listX[5]: list1 for current_field==bottom
*
************************************************************************
*/
void init_mbaff_lists()
{
unsigned j;
int i;
for (i=2;i<6;i++)
{
for (j=0; j<MAX_LIST_SIZE; j++)
{
// listX[i][j] = NULL;
listX[i][j] = no_reference_picture;
}
listXsize[i]=0;
}
for (i=0; i<listXsize[0]; i++)
{
listX[2][2*i] =listX[0][i]->top_field;
listX[2][2*i+1]=listX[0][i]->bottom_field;
listX[4][2*i] =listX[0][i]->bottom_field;
listX[4][2*i+1]=listX[0][i]->top_field;
}
listXsize[2]=listXsize[4]=listXsize[0] * 2;
for (i=0; i<listXsize[1]; i++)
{
listX[3][2*i] =listX[1][i]->top_field;
listX[3][2*i+1]=listX[1][i]->bottom_field;
listX[5][2*i] =listX[1][i]->bottom_field;
listX[5][2*i+1]=listX[1][i]->top_field;
}
listXsize[3]=listXsize[5]=listXsize[1] * 2;
}
/*!
************************************************************************
* \brief
* Returns short term pic with given picNum
*
************************************************************************
*/
static StorablePicture* get_short_term_pic(int picNum)
{
unsigned i;
for (i=0; i<dpb.ref_frames_in_buffer; i++)
{
if (img->structure==FRAME)
{
if (dpb.fs_ref[i]->is_reference == 3)
if ((!dpb.fs_ref[i]->frame->is_long_term)&&(dpb.fs_ref[i]->frame->pic_num == picNum))
return dpb.fs_ref[i]->frame;
}
else
{
if (dpb.fs_ref[i]->is_reference & 1)
if ((!dpb.fs_ref[i]->top_field->is_long_term)&&(dpb.fs_ref[i]->top_field->pic_num == picNum))
return dpb.fs_ref[i]->top_field;
if (dpb.fs_ref[i]->is_reference & 2)
if ((!dpb.fs_ref[i]->bottom_field->is_long_term)&&(dpb.fs_ref[i]->bottom_field->pic_num == picNum))
return dpb.fs_ref[i]->bottom_field;
}
}
// return NULL;
return no_reference_picture;
}
/*!
************************************************************************
* \brief
* Returns short term pic with given LongtermPicNum
*
************************************************************************
*/
static StorablePicture* get_long_term_pic(int LongtermPicNum)
{
unsigned i;
for (i=0; i<dpb.ltref_frames_in_buffer; i++)
{
if (img->structure==FRAME)
{
if (dpb.fs_ltref[i]->is_reference == 3)
if ((dpb.fs_ltref[i]->frame->is_long_term)&&(dpb.fs_ltref[i]->frame->long_term_pic_num == LongtermPicNum))
return dpb.fs_ltref[i]->frame;
}
else
{
if (dpb.fs_ltref[i]->is_reference & 1)
if ((dpb.fs_ltref[i]->top_field->is_long_term)&&(dpb.fs_ltref[i]->top_field->long_term_pic_num == LongtermPicNum))
return dpb.fs_ltref[i]->top_field;
if (dpb.fs_ltref[i]->is_reference & 2)
if ((dpb.fs_ltref[i]->bottom_field->is_long_term)&&(dpb.fs_ltref[i]->bottom_field->long_term_pic_num == LongtermPicNum))
return dpb.fs_ltref[i]->bottom_field;
}
}
return NULL;
}
/*!
************************************************************************
* \brief
* Reordering process for short-term reference pictures
*
************************************************************************
*/
static void reorder_short_term(StorablePicture **RefPicListX, int num_ref_idx_lX_active_minus1, int picNumLX, int *refIdxLX)
{
int cIdx, nIdx;
StorablePicture *picLX;
picLX = get_short_term_pic(picNumLX);
for( cIdx = num_ref_idx_lX_active_minus1+1; cIdx > *refIdxLX; cIdx-- )
RefPicListX[ cIdx ] = RefPicListX[ cIdx - 1];
RefPicListX[ (*refIdxLX)++ ] = picLX;
nIdx = *refIdxLX;
for( cIdx = *refIdxLX; cIdx <= num_ref_idx_lX_active_minus1+1; cIdx++ )
if (RefPicListX[ cIdx ])
if( (RefPicListX[ cIdx ]->is_long_term ) || (RefPicListX[ cIdx ]->pic_num != picNumLX ))
RefPicListX[ nIdx++ ] = RefPicListX[ cIdx ];
}
/*!
************************************************************************
* \brief
* Reordering process for short-term reference pictures
*
************************************************************************
*/
static void reorder_long_term(StorablePicture **RefPicListX, int num_ref_idx_lX_active_minus1, int LongTermPicNum, int *refIdxLX)
{
int cIdx, nIdx;
StorablePicture *picLX;
picLX = get_long_term_pic(LongTermPicNum);
for( cIdx = num_ref_idx_lX_active_minus1+1; cIdx > *refIdxLX; cIdx-- )
RefPicListX[ cIdx ] = RefPicListX[ cIdx - 1];
RefPicListX[ (*refIdxLX)++ ] = picLX;
nIdx = *refIdxLX;
for( cIdx = *refIdxLX; cIdx <= num_ref_idx_lX_active_minus1+1; cIdx++ )
if (RefPicListX[ cIdx ])
if( (!RefPicListX[ cIdx ]->is_long_term ) || (RefPicListX[ cIdx ]->long_term_pic_num != LongTermPicNum ))
RefPicListX[ nIdx++ ] = RefPicListX[ cIdx ];
}
/*!
************************************************************************
* \brief
* Reordering process for reference picture lists
*
************************************************************************
*/
void reorder_ref_pic_list(StorablePicture **list, int *list_size, int num_ref_idx_lX_active_minus1, int *reordering_of_pic_nums_idc, int *abs_diff_pic_num_minus1, int *long_term_pic_idx)
{
int i;
int maxPicNum, currPicNum, picNumLXNoWrap, picNumLXPred, picNumLX;
int refIdxLX = 0;
if (img->structure==FRAME)
{
maxPicNum = img->MaxFrameNum;
currPicNum = img->frame_num;
}
else
{
maxPicNum = 2 * img->MaxFrameNum;
currPicNum = 2 * img->frame_num + 1;
}
picNumLXPred = currPicNum;
for (i=0; reordering_of_pic_nums_idc[i]!=3; i++)
{
if (reordering_of_pic_nums_idc[i]>3)
error ("Invalid remapping_of_pic_nums_idc command", 500);
if (reordering_of_pic_nums_idc[i] < 2)
{
if (reordering_of_pic_nums_idc[i] == 0)
{
if( picNumLXPred - ( abs_diff_pic_num_minus1[i] + 1 ) < 0 )
picNumLXNoWrap = picNumLXPred - ( abs_diff_pic_num_minus1[i] + 1 ) + maxPicNum;
else
picNumLXNoWrap = picNumLXPred - ( abs_diff_pic_num_minus1[i] + 1 );
}
else // (remapping_of_pic_nums_idc[i] == 1)
{
if( picNumLXPred + ( abs_diff_pic_num_minus1[i] + 1 ) >= maxPicNum )
picNumLXNoWrap = picNumLXPred + ( abs_diff_pic_num_minus1[i] + 1 ) - maxPicNum;
else
picNumLXNoWrap = picNumLXPred + ( abs_diff_pic_num_minus1[i] + 1 );
}
picNumLXPred = picNumLXNoWrap;
if( picNumLXNoWrap > currPicNum )
picNumLX = picNumLXNoWrap - maxPicNum;
else
picNumLX = picNumLXNoWrap;
reorder_short_term(list, num_ref_idx_lX_active_minus1, picNumLX, &refIdxLX);
}
else //(remapping_of_pic_nums_idc[i] == 2)
{
reorder_long_term(list, num_ref_idx_lX_active_minus1, long_term_pic_idx[i], &refIdxLX);
}
}
// that's a definition
*list_size = num_ref_idx_lX_active_minus1 + 1;
}
/*!
************************************************************************
* \brief
* Update the list of frame stores that contain reference frames/fields
*
************************************************************************
*/
void update_ref_list()
{
unsigned i, j;
for (i=0, j=0; i<dpb.used_size; i++)
{
if (is_short_term_reference(dpb.fs[i]))
{
dpb.fs_ref[j++]=dpb.fs[i];
}
}
dpb.ref_frames_in_buffer = j;
while (j<dpb.size)
{
dpb.fs_ref[j++]=NULL;
}
}
/*!
************************************************************************
* \brief
* Update the list of frame stores that contain long-term reference
* frames/fields
*
************************************************************************
*/
void update_ltref_list()
{
unsigned i, j;
for (i=0, j=0; i<dpb.used_size; i++)
{
if (is_long_term_reference(dpb.fs[i]))
{
dpb.fs_ltref[j++]=dpb.fs[i];
}
}
dpb.ltref_frames_in_buffer=j;
while (j<dpb.size)
{
dpb.fs_ltref[j++]=NULL;
}
}
/*!
************************************************************************
* \brief
* Perform Memory management for idr pictures
*
************************************************************************
*/
static void idr_memory_management(StorablePicture* p)
{
unsigned i;
assert (p->idr_flag);
if (p->no_output_of_prior_pics_flag)
{
// free all stored pictures
for (i=0; i<dpb.used_size; i++)
{
// reset all reference settings
free_frame_store(dpb.fs[i]);
dpb.fs[i] = alloc_frame_store();
}
for (i=0; i<dpb.ref_frames_in_buffer; i++)
{
dpb.fs_ref[i]=NULL;
}
for (i=0; i<dpb.ltref_frames_in_buffer; i++)
{
dpb.fs_ltref[i]=NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -