JM ldecod分析

JM ldecod分析

ldecod简单分析
解码是规范中定义的涉及参数比较少。
下面是对简单分析中的函数列表进行解释。

初始化

解码的配置文件decoder.cfg在/bin下。
输入参数管理结构 参见关键数据结构

struct video_par是解码过程中用到video参数管理上下文结构。参见关键数据结构

decode 参数管理结构,包含上面列出的两个结构。

typedef struct decoder_params
{
  InputParameters   *p_Inp;          //!< Input Parameters
  VideoParameters   *p_Vid;          //!< Image Parameters
  int64              bufferSize;     //!< buffersize for tiff reads (not currently supported)
  int                UsedBits;      // for internal statistics, is adjusted by read_se_v, read_ue_v, read_u_1
  FILE              *p_trace;        //!< Trace file
  int                bitcounter;
} DecoderParams;

OpenDecoder

int OpenDecoder(InputParameters *p_Inp)

完成的主要动作有:
创建 DecoderParams 结构, alloc_decoder(&p_Dec),并用已经解释好的输入参数结构进行初始化。

alloc_decoder

 alloc_video_params(&((*p_Dec)->p_Vid));
  alloc_params(&((*p_Dec)->p_Inp));
alloc_video_params

解码上下文管理参数 VideoParameters的初始化完成了以下若干动作:

  1. 初始化dpb buffer,MAX_NUM_DPB_LAYERS为2,解码缓冲区管理参见DPB管理
  2. 分配ppSliceList slice指针数组 最大slice为16
  3. 分配nalu空间,为最大空间8000000
  4. 分配pDecOuputPic 解码图片列表
  5. pNextPPS ,分配pps 空间
/*!
 ***********************************************************************
 * \brief
 *    Allocate the Video Parameters structure
 * \par  Output:
 *    Video Parameters VideoParameters *p_Vid
 ***********************************************************************
 */
static void alloc_video_params( VideoParameters **p_Vid)
{
  int i;
  if ((*p_Vid   =  (VideoParameters *) calloc(1, sizeof(VideoParameters)))==NULL) 
    no_mem_exit("alloc_video_params: p_Vid");

  if (((*p_Vid)->old_slice = (OldSliceParams *) calloc(1, sizeof(OldSliceParams)))==NULL) 
    no_mem_exit("alloc_video_params: p_Vid->old_slice");

  if (((*p_Vid)->snr =  (SNRParameters *)calloc(1, sizeof(SNRParameters)))==NULL) 
    no_mem_exit("alloc_video_params: p_Vid->snr");  

  // Allocate new dpb buffer
  for (i = 0; i < MAX_NUM_DPB_LAYERS; i++)
  {
    if (((*p_Vid)->p_Dpb_layer[i] =  (DecodedPictureBuffer*)calloc(1, sizeof(DecodedPictureBuffer)))==NULL) 
      no_mem_exit("alloc_video_params: p_Vid->p_Dpb_layer[i]");
    (*p_Vid)->p_Dpb_layer[i]->layer_id = i;
    reset_dpb(*p_Vid, (*p_Vid)->p_Dpb_layer[i]);
    if(((*p_Vid)->p_EncodePar[i] = (CodingParameters *)calloc(1, sizeof(CodingParameters))) == NULL)
      no_mem_exit("alloc_video_params:p_Vid->p_EncodePar[i]");
    ((*p_Vid)->p_EncodePar[i])->layer_id = i;
    if(((*p_Vid)->p_LayerPar[i] = (LayerParameters *)calloc(1, sizeof(LayerParameters))) == NULL)
      no_mem_exit("alloc_video_params:p_Vid->p_LayerPar[i]");
    ((*p_Vid)->p_LayerPar[i])->layer_id = i;
  }
  (*p_Vid)->global_init_done[0] = (*p_Vid)->global_init_done[1] = 0;

#if (ENABLE_OUTPUT_TONEMAPPING)  
  if (((*p_Vid)->seiToneMapping =  (ToneMappingSEI*)calloc(1, sizeof(ToneMappingSEI)))==NULL) 
    no_mem_exit("alloc_video_params: (*p_Vid)->seiToneMapping");  
#endif

  if(((*p_Vid)->ppSliceList = (Slice **) calloc(MAX_NUM_DECSLICES, sizeof(Slice *))) == NULL)
  {
    no_mem_exit("alloc_video_params: p_Vid->ppSliceList");
  }
  (*p_Vid)->iNumOfSlicesAllocated = MAX_NUM_DECSLICES;
  //(*p_Vid)->currentSlice = NULL;
  (*p_Vid)->pNextSlice = NULL;
  (*p_Vid)->nalu = AllocNALU(MAX_CODED_FRAME_SIZE);
  (*p_Vid)->pDecOuputPic = (DecodedPicList *)calloc(1, sizeof(DecodedPicList));
  (*p_Vid)->pNextPPS = AllocPPS();
  (*p_Vid)->first_sps = TRUE;
}

分配OldSliceParams

typedef struct old_slice_par
{
  unsigned field_pic_flag;   
  unsigned frame_num;
  int      nal_ref_idc;
  unsigned pic_oder_cnt_lsb;
  int      delta_pic_oder_cnt_bottom;
  int      delta_pic_order_cnt[2];
  byte     bottom_field_flag;
  byte     idr_flag;
  int      idr_pic_id;
  int      pps_id;
#if (MVC_EXTENSION_ENABLE)
  int      view_id;
  int      inter_view_flag;
  int      anchor_pic_flag;
#endif
  int      layer_id;
} OldSliceParams;

分配SNRParameters

typedef struct snr_par
{
  int   frame_ctr;
  float snr[3];                                //!< current SNR (component)
  float snr1[3];                               //!< SNR (dB) first frame (component)
  float snra[3];                               //!< Average component SNR (dB) remaining frames
  float sse[3];                                //!< component SSE 
  float msse[3];                                //!< Average component SSE 
} SNRParameters;

Allocate new dpb buffer
在video参数结构中管理有两个解码缓冲区

  struct decoded_picture_buffer *p_Dpb_layer[MAX_NUM_DPB_LAYERS];
  CodingParameters *p_EncodePar[MAX_NUM_DPB_LAYERS];
  LayerParameters *p_LayerPar[MAX_NUM_DPB_LAYERS];

typedef struct coding_par
{
  int layer_id;
  int profile_idc;
  int width;
  int height;
  int width_cr;                               //!< width chroma  
  int height_cr;                              //!< height chroma

  int pic_unit_bitsize_on_disk;
  short bitdepth_luma;
  short bitdepth_chroma;
  int bitdepth_scale[2];
  int bitdepth_luma_qp_scale;
  int bitdepth_chroma_qp_scale;
  unsigned int dc_pred_value_comp[MAX_PLANE]; //!< component value for DC prediction (depends on component pel bit depth)
  int max_pel_value_comp[MAX_PLANE];       //!< max value that one picture element (pixel) can take (depends on pic_unit_bitdepth)

  int yuv_format;
  int lossless_qpprime_flag;
  int num_blk8x8_uv;
  int num_uv_blocks;
  int num_cdc_coeff;
  int mb_cr_size_x;
  int mb_cr_size_y;
  int mb_cr_size_x_blk;
  int mb_cr_size_y_blk;
  int mb_cr_size;
  int mb_size[3][2];                         //!< component macroblock dimensions
  int mb_size_blk[3][2];                     //!< component macroblock dimensions 
  int mb_size_shift[3][2];
  
  int max_vmv_r;                             //!< maximum vertical motion vector range in luma quarter frame pixel units for the current level_idc
  int separate_colour_plane_flag;
  int ChromaArrayType;
  int max_frame_num;
  unsigned int PicWidthInMbs;
  unsigned int PicHeightInMapUnits;
  unsigned int FrameHeightInMbs;
  unsigned int FrameSizeInMbs;
  int iLumaPadX;
  int iLumaPadY;
  int iChromaPadX;
  int iChromaPadY;

  int subpel_x;
  int subpel_y;
  int shiftpel_x;
  int shiftpel_y;
  int total_scale;
  unsigned int oldFrameSizeInMbs;

  //padding info;
  void (*img2buf)          (imgpel** imgX, unsigned char* buf, int size_x, int size_y, int symbol_size_in_bytes, int crop_left, int crop_right, int crop_top, int crop_bottom, int iOutStride);
  int rgb_output;

  imgpel **imgY_ref;                              //!< reference frame find snr
  imgpel ***imgUV_ref;
  Macroblock *mb_data;               //!< array containing all MBs of a whole frame
  Macroblock *mb_data_JV[MAX_PLANE]; //!< mb_data to be used for 4:4:4 independent mode
  char  *intra_block;
  char  *intra_block_JV[MAX_PLANE];
  BlockPos *PicPos;  
  byte **ipredmode;                  //!< prediction type [90][74]
  byte **ipredmode_JV[MAX_PLANE];
  byte ****nz_coeff;
  int **siblock;
  int **siblock_JV[MAX_PLANE];
  int *qp_per_matrix;
  int *qp_rem_matrix;
}CodingParameters;
typedef struct layer_par
{
  int layer_id;
  struct video_par *p_Vid;
  CodingParameters *p_Cps;
  seq_parameter_set_rbsp_t *p_SPS;
  struct decoded_picture_buffer *p_Dpb;
}LayerParameters;
switch( pDecoder->p_Inp->FileFormat )
  {
  default:
  case PAR_OF_ANNEXB:
    malloc_annex_b(pDecoder->p_Vid, &pDecoder->p_Vid->annex_b);
    open_annex_b(pDecoder->p_Inp->infile, pDecoder->p_Vid->annex_b);
    break;
  case PAR_OF_RTP:
    OpenRTPFile(pDecoder->p_Inp->infile, &pDecoder->p_Vid->BitStreamFile);
    break;   
  }

根据输入文件流的类型,使用相应的模块打开文件输入流。这里有两种,标准中的H264裸流和RTP封装的网络流。

init_out_buffer(pDecoder->p_Vid);

分配一个frameStore结构。见输出图像管理

DecodeOneFrame

DecodeOneFrame(&pDecPicList);

调用 decode_one_frame(pDecoder)

decode_one_frame

decode_one_frame 工作流程
new_frame 为0,分配slice 结构给读取slice做准备。malloc_slice() 所做工作如后节所述。
初始化slice的dpb_layer 为第一个layer。
read_new_slice(currSlice) 获取slice。

slice相关的标记

enum {
  EOS = 1,    //!< End Of Sequence
  SOP = 2,    //!< Start Of Picture
  SOS = 3,     //!< Start Of Slice
  SOS_CONT = 4
};
/*!
 ***********************************************************************
 * \brief
 *    decodes one I- or P-frame
 *
 ***********************************************************************
 */
int decode_one_frame(DecoderParams *pDecoder)
{
  VideoParameters *p_Vid = pDecoder->p_Vid;
  InputParameters *p_Inp = p_Vid->p_Inp;
  int current_header, iRet;
  Slice *currSlice; // = p_Vid->currentSlice;
  Slice **ppSliceList = p_Vid->ppSliceList;
  int iSliceNo;
  
  //read one picture first;
  p_Vid->iSliceNumOfCurrPic=0; //当前slice的序号
  current_header=0;
  p_Vid->iNumOfSlicesDecoded=0;
  p_Vid->num_dec_mb = 0;
  if(p_Vid->newframe)
  {
    if(p_Vid->pNextPPS->Valid) 
    {
      //assert((int) p_Vid->pNextPPS->pic_parameter_set_id == p_Vid->pNextSlice->pic_parameter_set_id);
      MakePPSavailable (p_Vid, p_Vid->pNextPPS->pic_parameter_set_id, p_Vid->pNextPPS);
      p_Vid->pNextPPS->Valid=0;
    }

    //get the first slice from currentslice;
    assert(ppSliceList[p_Vid->iSliceNumOfCurrPic]);
    currSlice = ppSliceList[p_Vid->iSliceNumOfCurrPic];
    ppSliceList[p_Vid->iSliceNumOfCurrPic] = p_Vid->pNextSlice;
    p_Vid->pNextSlice = currSlice;
    assert(ppSliceList[p_Vid->iSliceNumOfCurrPic]->current_slice_nr == 0);
    
    currSlice = ppSliceList[p_Vid->iSliceNumOfCurrPic];

    UseParameterSet (currSlice);

    init_picture(p_Vid, currSlice, p_Inp);
    
    p_Vid->iSliceNumOfCurrPic++;
    current_header = SOS;
  }
  while(current_header != SOP && current_header !=EOS)
  {
    //no pending slices;
    assert(p_Vid->iSliceNumOfCurrPic < p_Vid->iNumOfSlicesAllocated);
    ##ppSliceList是一个slice结构的指针数组,长度为16
    if(!ppSliceList[p_Vid->iSliceNumOfCurrPic])
    {
      ppSliceList[p_Vid->iSliceNumOfCurrPic] = malloc_slice(p_Inp, p_Vid);
    }
    currSlice = ppSliceList[p_Vid->iSliceNumOfCurrPic];

    //p_Vid->currentSlice = currSlice;
    currSlice->p_Vid = p_Vid;
    currSlice->p_Inp = p_Inp;
    currSlice->p_Dpb = p_Vid->p_Dpb_layer[0]; //set default value;
    currSlice->next_header = -8888;
    currSlice->num_dec_mb = 0;
    currSlice->coeff_ctr = -1;
    currSlice->pos       =  0;
    currSlice->is_reset_coeff = FALSE;
    currSlice->is_reset_coeff_cr = FALSE;
    ### 读取一个sliceheader
    current_header = read_new_slice(currSlice);
    //init;
    currSlice->current_header = current_header;

    // error tracking of primary and redundant slices.
    Error_tracking(p_Vid, currSlice);
    // If primary and redundant are received and primary is correct, discard the redundant
    // else, primary slice will be replaced with redundant slice.
    if(currSlice->frame_num == p_Vid->previous_frame_num && currSlice->redundant_pic_cnt !=0
      && p_Vid->Is_primary_correct !=0 && current_header != EOS)
    {
      continue;
    }
    #### 当slice为中间slice,或者是第一个slice时
    if((current_header != SOP && current_header !=EOS) || (p_Vid->iSliceNumOfCurrPic==0 && current_header == SOP))
    {
       currSlice->current_slice_nr = (short) p_Vid->iSliceNumOfCurrPic;
       p_Vid->dec_picture->max_slice_id = (short) imax(currSlice->current_slice_nr, p_Vid->dec_picture->max_slice_id);
       if(p_Vid->iSliceNumOfCurrPic >0)
       {
         CopyPOC(*ppSliceList, currSlice);
         ppSliceList[p_Vid->iSliceNumOfCurrPic-1]->end_mb_nr_plus1 = currSlice->start_mb_nr;
       }
       p_Vid->iSliceNumOfCurrPic++;
       ####当slicenum超过预分配的slicelist指针数组时,扩展空间,每次扩展的空间为16
       if(p_Vid->iSliceNumOfCurrPic >= p_Vid->iNumOfSlicesAllocated)
       {
         Slice **tmpSliceList = (Slice **)realloc(p_Vid->ppSliceList, (p_Vid->iNumOfSlicesAllocated+MAX_NUM_DECSLICES)*sizeof(Slice*));
         if(!tmpSliceList)
         {
           tmpSliceList = calloc((p_Vid->iNumOfSlicesAllocated+MAX_NUM_DECSLICES), sizeof(Slice*));
           memcpy(tmpSliceList, p_Vid->ppSliceList, p_Vid->iSliceNumOfCurrPic*sizeof(Slice*));
           //free;
           free(p_Vid->ppSliceList);
           ppSliceList = p_Vid->ppSliceList = tmpSliceList;
         }
         else
         {
           //assert(tmpSliceList == p_Vid->ppSliceList);
           ppSliceList = p_Vid->ppSliceList = tmpSliceList;
           memset(p_Vid->ppSliceList+p_Vid->iSliceNumOfCurrPic, 0, sizeof(Slice*)*MAX_NUM_DECSLICES);
         }
         p_Vid->iNumOfSlicesAllocated += MAX_NUM_DECSLICES;
       }
       current_header = SOS;       
    }
    else
    {
      if(ppSliceList[p_Vid->iSliceNumOfCurrPic-1]->mb_aff_frame_flag)
       ppSliceList[p_Vid->iSliceNumOfCurrPic-1]->end_mb_nr_plus1 = p_Vid->FrameSizeInMbs/2;
      else
       ppSliceList[p_Vid->iSliceNumOfCurrPic-1]->end_mb_nr_plus1 = p_Vid->FrameSizeInMbs/(1+ppSliceList[p_Vid->iSliceNumOfCurrPic-1]->field_pic_flag);
       p_Vid->newframe = 1;
       currSlice->current_slice_nr = 0;
       //keep it in currentslice;
       ppSliceList[p_Vid->iSliceNumOfCurrPic] = p_Vid->pNextSlice;
       p_Vid->pNextSlice = currSlice; 
    }

    copy_slice_info(currSlice, p_Vid->old_slice);
  }
  iRet = current_header;
  init_picture_decoding(p_Vid);

  {
    for(iSliceNo=0; iSliceNo<p_Vid->iSliceNumOfCurrPic; iSliceNo++)
    {
      currSlice = ppSliceList[iSliceNo];
      current_header = currSlice->current_header;
      //p_Vid->currentSlice = currSlice;

      assert(current_header != EOS);
      assert(currSlice->current_slice_nr == iSliceNo);

      init_slice(p_Vid, currSlice);
      decode_slice(currSlice, current_header);

      p_Vid->iNumOfSlicesDecoded++;
      p_Vid->num_dec_mb += currSlice->num_dec_mb;
      p_Vid->erc_mvperMB += currSlice->erc_mvperMB;
    }
  }
#if MVC_EXTENSION_ENABLE
  p_Vid->last_dec_view_id = p_Vid->dec_picture->view_id;
#endif
  if(p_Vid->dec_picture->structure == FRAME)
    p_Vid->last_dec_poc = p_Vid->dec_picture->frame_poc;
  else if(p_Vid->dec_picture->structure == TOP_FIELD)
    p_Vid->last_dec_poc = p_Vid->dec_picture->top_poc;
  else if(p_Vid->dec_picture->structure == BOTTOM_FIELD)
    p_Vid->last_dec_poc = p_Vid->dec_picture->bottom_poc;
  exit_picture(p_Vid, &p_Vid->dec_picture);
  p_Vid->previous_frame_num = ppSliceList[0]->frame_num;
  return (iRet);
}

malloc_slice

/*!
 ************************************************************************
 * \brief
 *    Allocates the slice structure along with its dependent
 *    data structures
 *
 * \par Input:
 *    Input Parameters InputParameters *p_Inp,  VideoParameters *p_Vid
 ************************************************************************
 */
Slice *malloc_slice(InputParameters *p_Inp, VideoParameters *p_Vid)
{
  int i, j, memory_size = 0;
  Slice *currSlice;

  currSlice = (Slice *) calloc(1, sizeof(Slice));
  if ( currSlice  == NULL)
  {
    snprintf(errortext, ET_SIZE, "Memory allocation for Slice datastruct in NAL-mode %d failed", p_Inp->FileFormat);
    error(errortext,100);
  }

  // create all context models
  currSlice->mot_ctx = create_contexts_MotionInfo();
  currSlice->tex_ctx = create_contexts_TextureInfo();

  currSlice->max_part_nr = 3;  //! assume data partitioning (worst case) for the following mallocs()
  currSlice->partArr = AllocPartition(currSlice->max_part_nr);

  memory_size += get_mem2Dwp (&(currSlice->wp_params), 2, MAX_REFERENCE_PICTURES);

  memory_size += get_mem3Dint(&(currSlice->wp_weight), 2, MAX_REFERENCE_PICTURES, 3);
  memory_size += get_mem3Dint(&(currSlice->wp_offset), 6, MAX_REFERENCE_PICTURES, 3);
  memory_size += get_mem4Dint(&(currSlice->wbp_weight), 6, MAX_REFERENCE_PICTURES, MAX_REFERENCE_PICTURES, 3);

  memory_size += get_mem3Dpel(&(currSlice->mb_pred), MAX_PLANE, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
  memory_size += get_mem3Dpel(&(currSlice->mb_rec ), MAX_PLANE, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
  memory_size += get_mem3Dint(&(currSlice->mb_rres), MAX_PLANE, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
  memory_size += get_mem3Dint(&(currSlice->cof    ), MAX_PLANE, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
  //  memory_size += get_mem3Dint(&(currSlice->fcf    ), MAX_PLANE, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
  allocate_pred_mem(currSlice);
#if (MVC_EXTENSION_ENABLE)
  currSlice->view_id = MVC_INIT_VIEW_ID;
  currSlice->inter_view_flag = 0;
  currSlice->anchor_pic_flag = 0;
#endif
  // reference flag initialization
  for(i=0;i<17;++i)
  {
    currSlice->ref_flag[i] = 1;
  }
  for (i = 0; i < 6; i++)
  {
    currSlice->listX[i] = calloc(MAX_LIST_SIZE, sizeof (StorablePicture*)); // +1 for reordering
    if (NULL==currSlice->listX[i])
      no_mem_exit("malloc_slice: currSlice->listX[i]");
  }
  for (j = 0; j < 6; j++)
  {
    for (i = 0; i < MAX_LIST_SIZE; i++)
    {
      currSlice->listX[j][i] = NULL;
    }
    currSlice->listXsize[j]=0;
  }

  return currSlice;
}

获取一个slice header

获取slice

准备解码

static void init_picture_decoding(VideoParameters *p_Vid)
{
  Slice *pSlice = p_Vid->ppSliceList[0];
  int j, i, iDeblockMode=1;

  if(p_Vid->iSliceNumOfCurrPic >= MAX_NUM_SLICES)
  {
    error ("Maximum number of supported slices exceeded. \nPlease recompile with increased value for MAX_NUM_SLICES", 200);
  }

  if(p_Vid->pNextPPS->Valid && (int) p_Vid->pNextPPS->pic_parameter_set_id == pSlice->pic_parameter_set_id)
  {
    pic_parameter_set_rbsp_t tmpPPS;
    memcpy(&tmpPPS, &(p_Vid->PicParSet[pSlice->pic_parameter_set_id]), sizeof (pic_parameter_set_rbsp_t));
    (p_Vid->PicParSet[pSlice->pic_parameter_set_id]).slice_group_id = NULL;
    MakePPSavailable (p_Vid, p_Vid->pNextPPS->pic_parameter_set_id, p_Vid->pNextPPS);
    memcpy(p_Vid->pNextPPS, &tmpPPS, sizeof (pic_parameter_set_rbsp_t));
    tmpPPS.slice_group_id = NULL;
  }

  UseParameterSet (pSlice);
  if(pSlice->idr_flag)
    p_Vid->number=0;

  p_Vid->PicHeightInMbs = p_Vid->FrameHeightInMbs / ( 1 + pSlice->field_pic_flag );
  p_Vid->PicSizeInMbs   = p_Vid->PicWidthInMbs * p_Vid->PicHeightInMbs;
  p_Vid->FrameSizeInMbs = p_Vid->PicWidthInMbs * p_Vid->FrameHeightInMbs;
  p_Vid->structure = pSlice->structure;

  fmo_init (p_Vid, pSlice);

#if (MVC_EXTENSION_ENABLE)
  if((pSlice->layer_id>0) && (pSlice->svc_extension_flag == 0 && pSlice->NaluHeaderMVCExt.non_idr_flag == 0))
  {
   idr_memory_management(p_Vid->p_Dpb_layer[pSlice->layer_id], p_Vid->dec_picture);
  }
  update_ref_list(p_Vid->p_Dpb_layer[pSlice->view_id]);
  update_ltref_list(p_Vid->p_Dpb_layer[pSlice->view_id]);
  update_pic_num(pSlice);
  i = pSlice->view_id;
#else
  update_pic_num(pSlice);
  i = 0;
#endif
  init_Deblock(p_Vid, pSlice->mb_aff_frame_flag);
  //init mb_data;
  for(j=0; j<p_Vid->iSliceNumOfCurrPic; j++)
  {
    if(p_Vid->ppSliceList[j]->DFDisableIdc != 1)
      iDeblockMode=0;
#if (MVC_EXTENSION_ENABLE)
    assert(p_Vid->ppSliceList[j]->view_id == i);
#endif
  }
  p_Vid->iDeblockMode = iDeblockMode;
}
void update_pic_num(Slice *currSlice)
{
  unsigned int i;
  VideoParameters *p_Vid = currSlice->p_Vid;
  DecodedPictureBuffer *p_Dpb = currSlice->p_Dpb;
  seq_parameter_set_rbsp_t *active_sps = p_Vid->active_sps;

  int add_top = 0, add_bottom = 0;
  int max_frame_num = 1 << (active_sps->log2_max_frame_num_minus4 + 4);

  if (currSlice->structure == FRAME)
  {
    for (i=0; i<p_Dpb->ref_frames_in_buffer; i++)
    {
      if ( p_Dpb->fs_ref[i]->is_used==3 )
      {
        if ((p_Dpb->fs_ref[i]->frame->used_for_reference)&&(!p_Dpb->fs_ref[i]->frame->is_long_term))
        {
          if( p_Dpb->fs_ref[i]->frame_num > currSlice->frame_num )
          {
            p_Dpb->fs_ref[i]->frame_num_wrap = p_Dpb->fs_ref[i]->frame_num - max_frame_num;
          }
          else
          {
            p_Dpb->fs_ref[i]->frame_num_wrap = p_Dpb->fs_ref[i]->frame_num;
          }
          p_Dpb->fs_ref[i]->frame->pic_num = p_Dpb->fs_ref[i]->frame_num_wrap;
        }
      }
    }
    // update long_term_pic_num
    for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++)
    {
      if (p_Dpb->fs_ltref[i]->is_used==3)
      {
        if (p_Dpb->fs_ltref[i]->frame->is_long_term)
        {
          p_Dpb->fs_ltref[i]->frame->long_term_pic_num = p_Dpb->fs_ltref[i]->frame->long_term_frame_idx;
        }
      }
    }
  }
  else
  {
    if (currSlice->structure == TOP_FIELD)
    {
      add_top    = 1;
      add_bottom = 0;
    }
    else
    {
      add_top    = 0;
      add_bottom = 1;
    }

    for (i=0; i<p_Dpb->ref_frames_in_buffer; i++)
    {
      if (p_Dpb->fs_ref[i]->is_reference)
      {
        if( p_Dpb->fs_ref[i]->frame_num > currSlice->frame_num )
        {
          p_Dpb->fs_ref[i]->frame_num_wrap = p_Dpb->fs_ref[i]->frame_num - max_frame_num;
        }
        else
        {
          p_Dpb->fs_ref[i]->frame_num_wrap = p_Dpb->fs_ref[i]->frame_num;
        }
        if (p_Dpb->fs_ref[i]->is_reference & 1)
        {
          p_Dpb->fs_ref[i]->top_field->pic_num = (2 * p_Dpb->fs_ref[i]->frame_num_wrap) + add_top;
        }
        if (p_Dpb->fs_ref[i]->is_reference & 2)
        {
          p_Dpb->fs_ref[i]->bottom_field->pic_num = (2 * p_Dpb->fs_ref[i]->frame_num_wrap) + add_bottom;
        }
      }
    }
    // update long_term_pic_num
    for (i=0; i<p_Dpb->ltref_frames_in_buffer; i++)
    {
      if (p_Dpb->fs_ltref[i]->is_long_term & 1)
      {
        p_Dpb->fs_ltref[i]->top_field->long_term_pic_num = 2 * p_Dpb->fs_ltref[i]->top_field->long_term_frame_idx + add_top;
      }
      if (p_Dpb->fs_ltref[i]->is_long_term & 2)
      {
        p_Dpb->fs_ltref[i]->bottom_field->long_term_pic_num = 2 * p_Dpb->fs_ltref[i]->bottom_field->long_term_frame_idx + add_bottom;
      }
    }
  }
}
void init_slice(VideoParameters *p_Vid, Slice *currSlice)
{
  int i;

  p_Vid->active_sps = currSlice->active_sps;
  p_Vid->active_pps = currSlice->active_pps;

  currSlice->init_lists (currSlice);

#if (MVC_EXTENSION_ENABLE)
  if (currSlice->svc_extension_flag == 0 || currSlice->svc_extension_flag == 1)
    reorder_lists_mvc (currSlice, currSlice->ThisPOC);
  else
    reorder_lists (currSlice);

  if (currSlice->fs_listinterview0)
  {
    free(currSlice->fs_listinterview0);
    currSlice->fs_listinterview0 = NULL;
  }
  if (currSlice->fs_listinterview1)
  {
    free(currSlice->fs_listinterview1);
    currSlice->fs_listinterview1 = NULL;
  }
#else
  reorder_lists (currSlice);
#endif

  if (currSlice->structure==FRAME)
  {
    init_mbaff_lists(p_Vid, currSlice);
  }
  //p_Vid->recovery_point = 0;

  // update reference flags and set current p_Vid->ref_flag
  if(!(currSlice->redundant_pic_cnt != 0 && p_Vid->previous_frame_num == currSlice->frame_num))
  {
    for(i=16;i>0;i--)
    {
      currSlice->ref_flag[i] = currSlice->ref_flag[i-1];
    }
  }
  currSlice->ref_flag[0] = currSlice->redundant_pic_cnt==0 ? p_Vid->Is_primary_correct : p_Vid->Is_redundant_correct;
  //p_Vid->previous_frame_num = currSlice->frame_num; //p_Vid->frame_num;

  if((currSlice->active_sps->chroma_format_idc==0)||(currSlice->active_sps->chroma_format_idc==3))
  {
    currSlice->linfo_cbp_intra = linfo_cbp_intra_other;
    currSlice->linfo_cbp_inter = linfo_cbp_inter_other;
  }
  else
  {
    currSlice->linfo_cbp_intra = linfo_cbp_intra_normal;
    currSlice->linfo_cbp_inter = linfo_cbp_inter_normal;
  }
}
void decode_slice(Slice *currSlice, int current_header)
{
  if (currSlice->active_pps->entropy_coding_mode_flag)
  {
    init_contexts  (currSlice);
    cabac_new_slice(currSlice);
  }

  if ( (currSlice->active_pps->weighted_bipred_idc > 0  && (currSlice->slice_type == B_SLICE)) || (currSlice->active_pps->weighted_pred_flag && currSlice->slice_type !=I_SLICE))
    fill_wp_params(currSlice);

  //printf("frame picture %d %d %d\n",currSlice->structure,currSlice->ThisPOC,currSlice->direct_spatial_mv_pred_flag);

  // decode main slice information
  if ((current_header == SOP || current_header == SOS) && currSlice->ei_flag == 0)
    decode_one_slice(currSlice);

  // setMB-Nr in case this slice was lost
  // if(currSlice->ei_flag)
  //   p_Vid->current_mb_nr = currSlice->last_mb_nr + 1;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值