📄 erc_do_p.c
字号:
{
unsigned i;
int j;
int MaxFrameNum = 1 << (active_sps->log2_max_frame_num_minus4 + 4);
int diff;
int list0idx = 0;
int list0idx_1 = 0;
StorablePicture *tmp_s;
if (currPicStructure == FRAME)
{
for(i=0;i<dpb.ref_frames_in_buffer; i++)
{
if(dpb.fs[i]->concealment_reference == 1)
{
if(dpb.fs[i]->frame_num > img->frame_to_conceal)
dpb.fs_ref[i]->frame_num_wrap = dpb.fs[i]->frame_num - MaxFrameNum;
else
dpb.fs_ref[i]->frame_num_wrap = dpb.fs[i]->frame_num;
dpb.fs_ref[i]->frame->pic_num = dpb.fs_ref[i]->frame_num_wrap;
}
}
}
if (currSliceType == P_SLICE)
{
// Calculate FrameNumWrap and PicNum
if (currPicStructure == FRAME)
{
for(i=0;i<dpb.used_size; i++)
{
if(dpb.fs[i]->concealment_reference == 1)
{
listX[0][list0idx++] = dpb.fs[i]->frame;
}
}
// order list 0 by PicNum
qsort((void *)listX[0], list0idx, sizeof(StorablePicture*), compare_pic_by_pic_num_desc);
listXsize[0] = list0idx;
}
}
if (currSliceType == B_SLICE)
{
if (currPicStructure == FRAME)
{
// for(i=0;i<dpb.ref_frames_in_buffer; i++)
for(i=0;i<dpb.used_size; i++)
{
if(dpb.fs[i]->concealment_reference == 1)
{
if(img->earlier_missing_poc > dpb.fs[i]->frame->poc)
listX[0][list0idx++] = dpb.fs[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++)
for(i=0;i<dpb.used_size; i++)
{
if(dpb.fs[i]->concealment_reference == 1)
{
if(img->earlier_missing_poc < dpb.fs[i]->frame->poc)
listX[0][list0idx++] = dpb.fs[i]->frame;
}
}
qsort((void *)&listX[0][list0idx_1], list0idx-list0idx_1, sizeof(StorablePicture*), compare_pic_by_poc_asc);
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;
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;
}
}
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] = min (listXsize[0], active_sps->num_ref_frames);
listXsize[1] = min (listXsize[1], active_sps->num_ref_frames);
listXsize[1] = 0;
// set the unused list entries to NULL
for (i=listXsize[0]; i< (MAX_LIST_SIZE) ; i++)
{
listX[0][i] = NULL;
}
for (i=listXsize[1]; i< (MAX_LIST_SIZE) ; i++)
{
listX[1][i] = NULL;
}
}
/*!
************************************************************************
* \brief
* Get from the dpb the picture corresponding to a POC. The POC varies
* depending on whether it is a frame copy or motion vector copy concealment.
* The frame corresponding to the POC is returned.
*
************************************************************************
*/
StorablePicture *get_pic_from_dpb(int missingpoc, unsigned int *pos)
{
int used_size = dpb.used_size - 1;
int i, concealfrom = 0;
if(img->conceal_mode == 1)
concealfrom = missingpoc - img->poc_gap;
else if (img->conceal_mode == 2)
concealfrom = missingpoc + img->poc_gap;
for(i = used_size; i >= 0; i--)
{
if(dpb.fs[i]->poc == concealfrom)
{
*pos = i;
return dpb.fs[i]->frame;
}
}
return NULL;
}
/*!
************************************************************************
* \brief
* Function to sort the POC and find the lowest number in the POC list
* Compare the integers
*
************************************************************************
*/
int comp(const void *i, const void *j)
{
return *(int *)i - *(int *)j;
}
/*!
************************************************************************
* \brief
* Initialises a node, allocates memory for the node, and returns
* a pointer to the new node.
*
************************************************************************
*/
struct concealment_node * init_node( StorablePicture* picture, int missingpoc )
{
struct concealment_node *ptr;
ptr = (struct concealment_node *) calloc( 1, sizeof(struct concealment_node ) );
if( ptr == NULL )
return (struct concealment_node *) NULL;
else {
ptr->picture = picture;
ptr->missingpocs = missingpoc;
ptr->next = NULL;
return ptr;
}
}
/*!
************************************************************************
* \brief
* Prints the details of a node
*
************************************************************************
*/
void print_node( struct concealment_node *ptr )
{
printf("Missing POC=%d\n", ptr->missingpocs );
}
/*!
************************************************************************
* \brief
* Prints all nodes from the current address passed to it.
*
************************************************************************
*/
void print_list( struct concealment_node *ptr )
{
while( ptr != NULL )
{
print_node( ptr );
ptr = ptr->next;
}
}
/*!
************************************************************************
* \brief
* Adds a node to the end of the list.
*
************************************************************************
*/
void add_node( struct concealment_node *concealment_new )
{
if( concealment_head == NULL )
{
concealment_end = concealment_head = concealment_new;
return;
}
concealment_end->next = concealment_new;
concealment_end = concealment_new;
}
/*!
************************************************************************
* \brief
* Deletes the specified node pointed to by 'ptr' from the list
*
************************************************************************
*/
void delete_node( struct concealment_node *ptr )
{
// We only need to delete the first node in the linked list
if( ptr == concealment_head ) {
concealment_head = concealment_head->next;
if( concealment_end == ptr )
concealment_end = concealment_end->next;
free(ptr);
}
}
/*!
************************************************************************
* \brief
* Deletes all nodes from the place specified by ptr
*
************************************************************************
*/
void delete_list( struct concealment_node *ptr )
{
struct concealment_node *temp;
if( concealment_head == NULL ) return;
if( ptr == concealment_head ) {
concealment_head = NULL;
concealment_end = NULL;
}
else
{
temp = concealment_head;
while( temp->next != ptr )
temp = temp->next;
concealment_end = temp;
}
while( ptr != NULL ) {
temp = ptr->next;
free( ptr );
ptr = temp;
}
}
/*!
************************************************************************
* \brief
* Stores the missing non reference frames in the concealment buffer. The
* detection is based on the POC difference in the sorted POC array. A missing
* non reference frame is detected when the dpb is full. A singly linked list
* is maintained for storing the missing non reference frames.
*
************************************************************************
*/
void conceal_non_ref_pics(int diff)
{
int missingpoc = 0;
unsigned int i, pos;
StorablePicture *conceal_from_picture = NULL;
StorablePicture *conceal_to_picture = NULL;
struct concealment_node *concealment_ptr = NULL;
int temp_used_size = dpb.used_size;
if(dpb.used_size == 0 )
return;
qsort(pocs_in_dpb, dpb.size, sizeof(int), comp);
for(i=0;i<dpb.size-diff;i++)
{
dpb.used_size = dpb.size;
if((pocs_in_dpb[i+1]-pocs_in_dpb[i])>img->poc_gap)
{
conceal_to_picture = alloc_storable_picture (FRAME, img->width, img->height, img->width_cr, img->height_cr);
missingpoc = pocs_in_dpb[i] + img->poc_gap;
// Diagnostics
// printf("\n missingpoc = %d\n",missingpoc);
if(missingpoc > img->earlier_missing_poc)
{
img->earlier_missing_poc = missingpoc;
conceal_to_picture->top_poc= missingpoc;
conceal_to_picture->bottom_poc=missingpoc;
conceal_to_picture->frame_poc=missingpoc;
conceal_to_picture->poc=missingpoc;
conceal_from_picture = get_pic_from_dpb(missingpoc, &pos);
assert(conceal_from_picture != NULL);
dpb.used_size = pos+1;
img->frame_to_conceal = conceal_from_picture->frame_num + 1;
update_ref_list_for_concealment();
img->conceal_slice_type = B_SLICE;
copy_to_conceal(conceal_from_picture, conceal_to_picture, img);
concealment_ptr = init_node( conceal_to_picture, missingpoc );
add_node(concealment_ptr);
// Diagnostics
// print_node(concealment_ptr);
}
}
}
//restore the original value
//dpb.used_size = dpb.size;
dpb.used_size = temp_used_size;
}
/*!
************************************************************************
* \brief
* Perform Sliding window decoded reference picture marking process. It
* maintains the POC s stored in the dpb at a specific instance.
*
************************************************************************
*/
void sliding_window_poc_management(StorablePicture *p)
{
unsigned int i;
if (dpb.used_size == dpb.size)
{
for(i=0;i<dpb.size-1; i++)
pocs_in_dpb[i] = pocs_in_dpb[i+1];
}
// pocs_in_dpb[dpb.used_size-1] = p->poc;
}
/*!
************************************************************************
* \brief
* Outputs the non reference frames. The POCs in the concealment buffer are
* sorted in ascending order and outputted when the lowest POC in the
* concealment buffer is lower than the lowest in the dpb. The linked list
* entry corresponding to the outputted POC is immediately deleted.
*
************************************************************************
*/
void write_lost_non_ref_pic(int poc, int p_out)
{
FrameStore concealment_fs;
if(poc > 0)
{
if((poc - dpb.last_output_poc) > img->poc_gap)
{
concealment_fs.frame = concealment_head->picture;
concealment_fs.is_output = 0;
concealment_fs.is_reference = 0;
concealment_fs.is_used = 3;
write_stored_frame(&concealment_fs, p_out);
delete_node(concealment_head);
}
}
}
/*!
************************************************************************
* \brief
* Conceals frame loss immediately after the IDR. This special case produces
* the same result for either frame copy or motion vector copy concealment.
*
************************************************************************
*/
void write_lost_ref_after_idr(int pos)
{
int temp = 1;
if(last_out_fs->frame == NULL)
{
last_out_fs->frame = alloc_storable_picture (FRAME, img->width, img->height,
img->width_cr, img->height_cr);
last_out_fs->is_used = 3;
}
if(img->conceal_mode == 2)
{
temp = 2;
img->conceal_mode = 1;
}
copy_to_conceal(dpb.fs[pos]->frame, last_out_fs->frame, img);
img->conceal_mode = temp;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -