/*!
 ************************************************************************
 * \brief
 *    read the scond part of the header (without the pic_parameter_set_id
 * \return
 *    Length of the second part of the Slice header in bits
 ************************************************************************
 */
int RestOfSliceHeader(Slice *currSlice)
{
    VideoParameters *p_Vid = currSlice->p_Vid;
    InputParameters *p_Inp = currSlice->p_Inp;
    seq_parameter_set_rbsp_t *active_sps = p_Vid->active_sps;

    byte dP_nr = assignSE2partition[currSlice->dp_mode][SE_HEADER];
    DataPartition *partition = &(currSlice->partArr[dP_nr]);
    Bitstream *currStream = partition->bitstream;

    int val, len;

    currSlice->frame_num = read_u_v (active_sps->log2_max_frame_num_minus4 + 4, "SH: frame_num", currStream, &p_Dec->UsedBits);

    /* Tian Dong: frame_num gap processing, if found */
    if(currSlice->idr_flag) //if (p_Vid->idr_flag)
    {
        p_Vid->pre_frame_num = currSlice->frame_num;
        // picture error concealment
        p_Vid->last_ref_pic_poc = 0;
        assert(currSlice->frame_num == 0);
    }

    if (active_sps->frame_mbs_only_flag)
    {
        p_Vid->structure = FRAME;
        currSlice->field_pic_flag=0;
    }
    else
    {
        // field_pic_flag   u(1)
        currSlice->field_pic_flag = read_u_1("SH: field_pic_flag", currStream, &p_Dec->UsedBits);
        if (currSlice->field_pic_flag)
        {
            // bottom_field_flag  u(1)
            currSlice->bottom_field_flag = (byte) read_u_1("SH: bottom_field_flag", currStream, &p_Dec->UsedBits);
            p_Vid->structure = currSlice->bottom_field_flag ? BOTTOM_FIELD : TOP_FIELD;
        }
        else
        {
            p_Vid->structure = FRAME;
            currSlice->bottom_field_flag = FALSE;
        }
    }

    currSlice->structure = (PictureStructure) p_Vid->structure;

    currSlice->mb_aff_frame_flag = (active_sps->mb_adaptive_frame_field_flag && (currSlice->field_pic_flag==0));
    //currSlice->mb_aff_frame_flag = p_Vid->mb_aff_frame_flag;

    if (p_Vid->structure == FRAME       )
        assert (currSlice->field_pic_flag == 0);
    if (p_Vid->structure == TOP_FIELD   )
        assert (currSlice->field_pic_flag == 1 && (currSlice->bottom_field_flag == FALSE));
    if (p_Vid->structure == BOTTOM_FIELD)
        assert (currSlice->field_pic_flag == 1 && (currSlice->bottom_field_flag == TRUE ));

    if (currSlice->idr_flag)
    {
        currSlice->idr_pic_id = read_ue_v("SH: idr_pic_id", currStream, &p_Dec->UsedBits);
    }
#if (MVC_EXTENSION_ENABLE)
    else if ( currSlice->svc_extension_flag == 0 && currSlice->NaluHeaderMVCExt.non_idr_flag == 0 )
    {
        currSlice->idr_pic_id = read_ue_v("SH: idr_pic_id", currStream, &p_Dec->UsedBits);
    }
#endif

    if (active_sps->pic_order_cnt_type == 0)
    {
        currSlice->pic_order_cnt_lsb = read_u_v(active_sps->log2_max_pic_order_cnt_lsb_minus4 + 4, "SH: pic_order_cnt_lsb", currStream, &p_Dec->UsedBits);
        if( p_Vid->active_pps->bottom_field_pic_order_in_frame_present_flag  ==  1 &&  !currSlice->field_pic_flag )
            currSlice->delta_pic_order_cnt_bottom = read_se_v("SH: delta_pic_order_cnt_bottom", currStream, &p_Dec->UsedBits);
        else
            currSlice->delta_pic_order_cnt_bottom = 0;
    }
    if( active_sps->pic_order_cnt_type == 1 )
    {
        if ( !active_sps->delta_pic_order_always_zero_flag )
        {
            currSlice->delta_pic_order_cnt[ 0 ] = read_se_v("SH: delta_pic_order_cnt[0]", currStream, &p_Dec->UsedBits);
            if( p_Vid->active_pps->bottom_field_pic_order_in_frame_present_flag  ==  1  &&  !currSlice->field_pic_flag )
                currSlice->delta_pic_order_cnt[ 1 ] = read_se_v("SH: delta_pic_order_cnt[1]", currStream, &p_Dec->UsedBits);
            else
                currSlice->delta_pic_order_cnt[ 1 ] = 0;  // set to zero if not in stream
        }
        else
        {
            currSlice->delta_pic_order_cnt[ 0 ] = 0;
            currSlice->delta_pic_order_cnt[ 1 ] = 0;
        }
    }

    //! redundant_pic_cnt is missing here
    if (p_Vid->active_pps->redundant_pic_cnt_present_flag)
    {
        currSlice->redundant_pic_cnt = read_ue_v ("SH: redundant_pic_cnt", currStream, &p_Dec->UsedBits);
    }

    if(currSlice->slice_type == B_SLICE)
    {
        currSlice->direct_spatial_mv_pred_flag = read_u_1 ("SH: direct_spatial_mv_pred_flag", currStream, &p_Dec->UsedBits);
    }

    currSlice->num_ref_idx_active[LIST_0] = p_Vid->active_pps->num_ref_idx_l0_active_minus1 + 1;
    currSlice->num_ref_idx_active[LIST_1] = p_Vid->active_pps->num_ref_idx_l1_active_minus1 + 1;

    if(p_Vid->type==P_SLICE || p_Vid->type == SP_SLICE || p_Vid->type==B_SLICE)
    {
        val = read_u_1 ("SH: num_ref_idx_override_flag", currStream, &p_Dec->UsedBits);
        if (val)
        {
            currSlice->num_ref_idx_active[LIST_0] = 1 + read_ue_v ("SH: num_ref_idx_l0_active_minus1", currStream, &p_Dec->UsedBits);

            if(p_Vid->type==B_SLICE)
            {
                currSlice->num_ref_idx_active[LIST_1] = 1 + read_ue_v ("SH: num_ref_idx_l1_active_minus1", currStream, &p_Dec->UsedBits);
            }
        }
    }
    if (currSlice->slice_type!=B_SLICE)
    {
        currSlice->num_ref_idx_active[LIST_1] = 0;
    }

#if (MVC_EXTENSION_ENABLE)
    if (currSlice->svc_extension_flag == 0 || currSlice->svc_extension_flag == 1)
        ref_pic_list_mvc_modification(currSlice);
    else
        ref_pic_list_reordering(currSlice);
#else
    ref_pic_list_reordering(currSlice);
#endif

    currSlice->weighted_pred_flag = (unsigned short) ((currSlice->slice_type == P_SLICE || currSlice->slice_type == SP_SLICE)
                                    ? p_Vid->active_pps->weighted_pred_flag
                                    : (currSlice->slice_type == B_SLICE && p_Vid->active_pps->weighted_bipred_idc == 1));
    currSlice->weighted_bipred_idc = (unsigned short) (currSlice->slice_type == B_SLICE && p_Vid->active_pps->weighted_bipred_idc > 0);

    if ((p_Vid->active_pps->weighted_pred_flag&&(p_Vid->type==P_SLICE|| p_Vid->type == SP_SLICE))||
            (p_Vid->active_pps->weighted_bipred_idc==1 && (p_Vid->type==B_SLICE)))
    {
        pred_weight_table(currSlice);
    }

    if (currSlice->nal_reference_idc)
        dec_ref_pic_marking(p_Vid, currStream, currSlice);

    if (p_Vid->active_pps->entropy_coding_mode_flag && p_Vid->type!=I_SLICE && p_Vid->type!=SI_SLICE)
    {
        currSlice->model_number = read_ue_v("SH: cabac_init_idc", currStream, &p_Dec->UsedBits);
    }
    else
    {
        currSlice->model_number = 0;
    }

    currSlice->slice_qp_delta = val = read_se_v("SH: slice_qp_delta", currStream, &p_Dec->UsedBits);
    //currSlice->qp = p_Vid->qp = 26 + p_Vid->active_pps->pic_init_qp_minus26 + val;
    currSlice->qp = 26 + p_Vid->active_pps->pic_init_qp_minus26 + val;

    if ((currSlice->qp < -p_Vid->bitdepth_luma_qp_scale) || (currSlice->qp > 51))
        error ("slice_qp_delta makes slice_qp_y out of range", 500);

    if(p_Vid->type==SP_SLICE || p_Vid->type == SI_SLICE)
    {
        if(p_Vid->type==SP_SLICE)
        {
            currSlice->sp_switch = read_u_1 ("SH: sp_for_switch_flag", currStream, &p_Dec->UsedBits);
        }
        currSlice->slice_qs_delta = val = read_se_v("SH: slice_qs_delta", currStream, &p_Dec->UsedBits);
        currSlice->qs = 26 + p_Vid->active_pps->pic_init_qs_minus26 + val;
        if ((currSlice->qs < 0) || (currSlice->qs > 51))
            error ("slice_qs_delta makes slice_qs_y out of range", 500);
    }

    if ( !HI_intra_only_profile(active_sps->profile_idc, active_sps->constrained_set3_flag) || (p_Inp->intra_profile_deblocking == 1) )
        //then read flags and parameters from bistream
    {
#if DPF_PARAM_DISP
        printf("deblocking_filter_control_present_flag:%d\n", p_Vid->active_pps->deblocking_filter_control_present_flag);
#endif
        if (p_Vid->active_pps->deblocking_filter_control_present_flag)
        {
            currSlice->DFDisableIdc = (short) read_ue_v ("SH: disable_deblocking_filter_idc", currStream, &p_Dec->UsedBits);

            if (currSlice->DFDisableIdc!=1)
            {
                currSlice->DFAlphaC0Offset = (short) (2 * read_se_v("SH: slice_alpha_c0_offset_div2", currStream, &p_Dec->UsedBits));
                currSlice->DFBetaOffset    = (short) (2 * read_se_v("SH: slice_beta_offset_div2", currStream, &p_Dec->UsedBits));
            }
            else
            {
                currSlice->DFAlphaC0Offset = currSlice->DFBetaOffset = 0;
            }
        }
        else
        {
            currSlice->DFDisableIdc = currSlice->DFAlphaC0Offset = currSlice->DFBetaOffset = 0;
        }
#if DPF_PARAM_DISP
        printf("Slice:%d, DFParameters:(%d,%d,%d)\n\n", currSlice->current_slice_nr, currSlice->DFDisableIdc, currSlice->DFAlphaC0Offset, currSlice->DFBetaOffset);
#endif
    }
    else //By default the Loop Filter is Off
    {   //444_TEMP_NOTE: change made below. 08/07/07
        //still need to parse the SEs (read flags and parameters from bistream) but will ignore
        if (p_Vid->active_pps->deblocking_filter_control_present_flag)
        {
            currSlice->DFDisableIdc = (short) read_ue_v ("SH: disable_deblocking_filter_idc", currStream, &p_Dec->UsedBits);

            if (currSlice->DFDisableIdc!=1)
            {
                currSlice->DFAlphaC0Offset = (short) (2 * read_se_v("SH: slice_alpha_c0_offset_div2", currStream, &p_Dec->UsedBits));
                currSlice->DFBetaOffset    = (short) (2 * read_se_v("SH: slice_beta_offset_div2", currStream, &p_Dec->UsedBits));
            }
        }//444_TEMP_NOTE. the end of change. 08/07/07
        //Ignore the SEs, by default the Loop Filter is Off
        currSlice->DFDisableIdc =1;
        currSlice->DFAlphaC0Offset = currSlice->DFBetaOffset = 0;
    }


    if (p_Vid->active_pps->num_slice_groups_minus1>0 && p_Vid->active_pps->slice_group_map_type>=3 &&
            p_Vid->active_pps->slice_group_map_type<=5)
    {
        len = (active_sps->pic_height_in_map_units_minus1+1)*(active_sps->pic_width_in_mbs_minus1+1)/
              (p_Vid->active_pps->slice_group_change_rate_minus1+1);
        if (((active_sps->pic_height_in_map_units_minus1+1)*(active_sps->pic_width_in_mbs_minus1+1))%
                (p_Vid->active_pps->slice_group_change_rate_minus1+1))
            len +=1;

        len = CeilLog2(len+1);

        currSlice->slice_group_change_cycle = read_u_v (len, "SH: slice_group_change_cycle", currStream, &p_Dec->UsedBits);
    }
    p_Vid->PicHeightInMbs = p_Vid->FrameHeightInMbs / ( 1 + currSlice->field_pic_flag );
    p_Vid->PicSizeInMbs   = p_Vid->PicWidthInMbs * p_Vid->PicHeightInMbs;
    p_Vid->FrameSizeInMbs = p_Vid->PicWidthInMbs * p_Vid->FrameHeightInMbs;

    return p_Dec->UsedBits;
}
Beispiel #2
0
/*!
 ************************************************************************
 * \brief
 *    read the weighted prediction tables
 ************************************************************************
 */
static void pred_weight_table(Slice *currSlice)
{
  VideoParameters *p_Vid = currSlice->p_Vid;
  seq_parameter_set_rbsp_t *active_sps = p_Vid->active_sps;
  byte dP_nr = assignSE2partition[currSlice->dp_mode][SE_HEADER];
  DataPartition *partition = &(currSlice->partArr[dP_nr]);
  Bitstream *currStream = partition->bitstream;
  int luma_weight_flag_l0, luma_weight_flag_l1, chroma_weight_flag_l0, chroma_weight_flag_l1;
  int i,j;

  currSlice->luma_log2_weight_denom = (unsigned short) read_ue_v ("SH: luma_log2_weight_denom", currStream, &p_Dec->UsedBits);
  currSlice->wp_round_luma = currSlice->luma_log2_weight_denom ? 1<<(currSlice->luma_log2_weight_denom - 1): 0;

  if ( 0 != active_sps->chroma_format_idc)
  {
    currSlice->chroma_log2_weight_denom = (unsigned short) read_ue_v ("SH: chroma_log2_weight_denom", currStream, &p_Dec->UsedBits);
    currSlice->wp_round_chroma = currSlice->chroma_log2_weight_denom ? 1<<(currSlice->chroma_log2_weight_denom - 1): 0;
  }

  reset_wp_params(currSlice);

  for (i=0; i<currSlice->num_ref_idx_active[LIST_0]; i++)
  {
    luma_weight_flag_l0 = read_u_1("SH: luma_weight_flag_l0", currStream, &p_Dec->UsedBits);

    if (luma_weight_flag_l0)
    {
      currSlice->wp_weight[LIST_0][i][0] = read_se_v ("SH: luma_weight_l0", currStream, &p_Dec->UsedBits);
      currSlice->wp_offset[LIST_0][i][0] = read_se_v ("SH: luma_offset_l0", currStream, &p_Dec->UsedBits);
      currSlice->wp_offset[LIST_0][i][0] = currSlice->wp_offset[LIST_0][i][0]<<(p_Vid->bitdepth_luma - 8);
    }
    else
    {
      currSlice->wp_weight[LIST_0][i][0] = 1 << currSlice->luma_log2_weight_denom;
      currSlice->wp_offset[LIST_0][i][0] = 0;
    }

    if (active_sps->chroma_format_idc != 0)
    {
      chroma_weight_flag_l0 = read_u_1 ("SH: chroma_weight_flag_l0", currStream, &p_Dec->UsedBits);

      for (j=1; j<3; j++)
      {
        if (chroma_weight_flag_l0)
        {
          currSlice->wp_weight[LIST_0][i][j] = read_se_v("SH: chroma_weight_l0", currStream, &p_Dec->UsedBits);
          currSlice->wp_offset[LIST_0][i][j] = read_se_v("SH: chroma_offset_l0", currStream, &p_Dec->UsedBits);
          currSlice->wp_offset[LIST_0][i][j] = currSlice->wp_offset[LIST_0][i][j]<<(p_Vid->bitdepth_chroma-8);
        }
        else
        {
          currSlice->wp_weight[LIST_0][i][j] = 1<<currSlice->chroma_log2_weight_denom;
          currSlice->wp_offset[LIST_0][i][j] = 0;
        }
      }
    }
  }
  if ((currSlice->slice_type == B_SLICE) && p_Vid->active_pps->weighted_bipred_idc == 1)
  {
    for (i=0; i<currSlice->num_ref_idx_active[LIST_1]; i++)
    {
      luma_weight_flag_l1 = read_u_1("SH: luma_weight_flag_l1", currStream, &p_Dec->UsedBits);

      if (luma_weight_flag_l1)
      {
        currSlice->wp_weight[LIST_1][i][0] = read_se_v ("SH: luma_weight_l1", currStream, &p_Dec->UsedBits);
        currSlice->wp_offset[LIST_1][i][0] = read_se_v ("SH: luma_offset_l1", currStream, &p_Dec->UsedBits);
        currSlice->wp_offset[LIST_1][i][0] = currSlice->wp_offset[LIST_1][i][0]<<(p_Vid->bitdepth_luma-8);
      }
      else
      {
        currSlice->wp_weight[LIST_1][i][0] = 1<<currSlice->luma_log2_weight_denom;
        currSlice->wp_offset[LIST_1][i][0] = 0;
      }

      if (active_sps->chroma_format_idc != 0)
      {
        chroma_weight_flag_l1 = read_u_1 ("SH: chroma_weight_flag_l1", currStream, &p_Dec->UsedBits);

        for (j=1; j<3; j++)
        {
          if (chroma_weight_flag_l1)
          {
            currSlice->wp_weight[LIST_1][i][j] = read_se_v("SH: chroma_weight_l1", currStream, &p_Dec->UsedBits);
            currSlice->wp_offset[LIST_1][i][j] = read_se_v("SH: chroma_offset_l1", currStream, &p_Dec->UsedBits);
            currSlice->wp_offset[LIST_1][i][j] = currSlice->wp_offset[LIST_1][i][j]<<(p_Vid->bitdepth_chroma-8);
          }
          else
          {
            currSlice->wp_weight[LIST_1][i][j] = 1<<currSlice->chroma_log2_weight_denom;
            currSlice->wp_offset[LIST_1][i][j] = 0;
          }
        }
      }
    }
  }
}
Beispiel #3
0
/*!
 ************************************************************************
 * \brief
 *    read the memory control operations
 ************************************************************************
 */
void dec_ref_pic_marking(VideoParameters *p_Vid, Bitstream *currStream, Slice *pSlice)
{
  int val;

  DecRefPicMarking_t *tmp_drpm,*tmp_drpm2;

  // free old buffer content
  while (pSlice->dec_ref_pic_marking_buffer)
  {
    tmp_drpm=pSlice->dec_ref_pic_marking_buffer;

    pSlice->dec_ref_pic_marking_buffer=tmp_drpm->Next;
    free (tmp_drpm);
  }

#if (MVC_EXTENSION_ENABLE)
  if ( pSlice->idr_flag || (pSlice->svc_extension_flag == 0 && pSlice->NaluHeaderMVCExt.non_idr_flag == 0) )
#else
  if (pSlice->idr_flag)
#endif
  {
    pSlice->no_output_of_prior_pics_flag = read_u_1("SH: no_output_of_prior_pics_flag", currStream, &p_Dec->UsedBits);
    p_Vid->no_output_of_prior_pics_flag = pSlice->no_output_of_prior_pics_flag;
    pSlice->long_term_reference_flag = read_u_1("SH: long_term_reference_flag", currStream, &p_Dec->UsedBits);
  }
  else
  {
    pSlice->adaptive_ref_pic_buffering_flag = read_u_1("SH: adaptive_ref_pic_buffering_flag", currStream, &p_Dec->UsedBits);
    if (pSlice->adaptive_ref_pic_buffering_flag)
    {
      // read Memory Management Control Operation
      do
      {
        tmp_drpm=(DecRefPicMarking_t*)calloc (1,sizeof (DecRefPicMarking_t));
        tmp_drpm->Next=NULL;

        val = tmp_drpm->memory_management_control_operation = read_ue_v("SH: memory_management_control_operation", currStream, &p_Dec->UsedBits);

        if ((val==1)||(val==3))
        {
          tmp_drpm->difference_of_pic_nums_minus1 = read_ue_v("SH: difference_of_pic_nums_minus1", currStream, &p_Dec->UsedBits);
        }
        if (val==2)
        {
          tmp_drpm->long_term_pic_num = read_ue_v("SH: long_term_pic_num", currStream, &p_Dec->UsedBits);
        }

        if ((val==3)||(val==6))
        {
          tmp_drpm->long_term_frame_idx = read_ue_v("SH: long_term_frame_idx", currStream, &p_Dec->UsedBits);
        }
        if (val==4)
        {
          tmp_drpm->max_long_term_frame_idx_plus1 = read_ue_v("SH: max_long_term_pic_idx_plus1", currStream, &p_Dec->UsedBits);
        }

        // add command
        if (pSlice->dec_ref_pic_marking_buffer==NULL)
        {
          pSlice->dec_ref_pic_marking_buffer=tmp_drpm;
        }
        else
        {
          tmp_drpm2=pSlice->dec_ref_pic_marking_buffer;
          while (tmp_drpm2->Next!=NULL) tmp_drpm2=tmp_drpm2->Next;
          tmp_drpm2->Next=tmp_drpm;
        }

      }
      while (val != 0);
    }
  }
}
Beispiel #4
0
static void ref_pic_list_mvc_modification(Slice *currSlice)
{
  //VideoParameters *p_Vid = currSlice->p_Vid;
  byte dP_nr = assignSE2partition[currSlice->dp_mode][SE_HEADER];
  DataPartition *partition = &(currSlice->partArr[dP_nr]);
  Bitstream *currStream = partition->bitstream;
  int i, val;

  alloc_ref_pic_list_reordering_buffer(currSlice);

  if ((currSlice->slice_type % 5) != I_SLICE && (currSlice->slice_type % 5) != SI_SLICE)
  {
    val = currSlice->ref_pic_list_reordering_flag[LIST_0] = read_u_1 ("SH: ref_pic_list_modification_flag_l0", currStream, &p_Dec->UsedBits);

    if (val)
    {
      i=0;
      do
      {
        val = currSlice->modification_of_pic_nums_idc[LIST_0][i] = read_ue_v("SH: modification_of_pic_nums_idc_l0", currStream, &p_Dec->UsedBits);
        if (val==0 || val==1)
        {
          currSlice->abs_diff_pic_num_minus1[LIST_0][i] = read_ue_v("SH: abs_diff_pic_num_minus1_l0", currStream, &p_Dec->UsedBits);
        }
        else
        {
          if (val==2)
          {
            currSlice->long_term_pic_idx[LIST_0][i] = read_ue_v("SH: long_term_pic_idx_l0", currStream, &p_Dec->UsedBits);
          }
          else if (val==4 || val==5)
          {
            currSlice->abs_diff_view_idx_minus1[LIST_0][i] = read_ue_v("SH: abs_diff_view_idx_minus1_l0", currStream, &p_Dec->UsedBits);
          }
        }
        i++;
        // assert (i>img->num_ref_idx_l0_active);
      } while (val != 3);
    }
  }

  if ((currSlice->slice_type % 5) == B_SLICE)
  {
    val = currSlice->ref_pic_list_reordering_flag[LIST_1] = read_u_1 ("SH: ref_pic_list_reordering_flag_l1", currStream, &p_Dec->UsedBits);

    if (val)
    {
      i=0;
      do
      {
        val = currSlice->modification_of_pic_nums_idc[LIST_1][i] = read_ue_v("SH: modification_of_pic_nums_idc_l1", currStream, &p_Dec->UsedBits);
        if (val==0 || val==1)
        {
          currSlice->abs_diff_pic_num_minus1[LIST_1][i] = read_ue_v("SH: abs_diff_pic_num_minus1_l1", currStream, &p_Dec->UsedBits);
        }
        else
        {
          if (val==2)
          {
            currSlice->long_term_pic_idx[LIST_1][i] = read_ue_v("SH: long_term_pic_idx_l1", currStream, &p_Dec->UsedBits);
          }
          else if (val==4 || val==5)
          {
            currSlice->abs_diff_view_idx_minus1[LIST_1][i] = read_ue_v("SH: abs_diff_view_idx_minus1_l1", currStream, &p_Dec->UsedBits);
          }
        }
        i++;
        // assert (i>img->num_ref_idx_l1_active);
      } while (val != 3);
    }
  }

  // set reference index of redundant slices.
  if(currSlice->redundant_pic_cnt && (currSlice->slice_type != I_SLICE) )
  {
    currSlice->redundant_slice_ref_idx = currSlice->abs_diff_pic_num_minus1[LIST_0][0] + 1;
  }
}