⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 erc_do_p.c

📁 H264视频编解码程序
💻 C
📖 第 1 页 / 共 4 页
字号:
{
    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 + -