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

📄 erc_do_p.c

📁 H.264基于baseline解码器的C++实现源码
💻 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] = imin (listXsize[0], (int)active_sps->num_ref_frames);
  listXsize[1] = imin (listXsize[1], (int)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 = 0;
  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 + -