Example #1
0
int  get_svlc(bitreader* br)
{
  int v = get_uvlc(br);
  if (v==0) return v;
  bool negative = ((v&1)==0);
  return negative ? -v/2 : (v+1)/2;
}
Example #2
0
void read_short_term_ref_pic_set(bitreader* br, ref_pic_set* sets, int idxRps, int num_short_term_ref_pic_sets)
{
  char inter_ref_pic_set_prediction_flag=0;

  if (idxRps != 0) {
    inter_ref_pic_set_prediction_flag = get_bits(br,1);
  }

  if (inter_ref_pic_set_prediction_flag) {

    int delta_idx;
    if (idxRps == num_short_term_ref_pic_sets) {
      delta_idx = get_uvlc(br)+1;
    } else {
      delta_idx = 1;
    }

    int RIdx = idxRps - delta_idx;
    assert(RIdx>=0);

    int delta_rps_sign = get_bits(br,1);
    int abs_delta_rps  = get_uvlc(br)+1;
    int DeltaRPS = (delta_rps_sign ? -abs_delta_rps : abs_delta_rps);

    // bits are stored in this order:
    // - all bits for negative Pocs (forward),
    // - then all bits for positive Pocs (forward),
    // - then bits for '0'

    logtrace(LogHeaders,"predicted from %d with delta %d\n",RIdx,DeltaRPS);

    int nDeltaPocsRIdx= sets[RIdx].NumDeltaPocs;
    char *const used_by_curr_pic_flag = (char *)alloca((nDeltaPocsRIdx+1) * sizeof(char));
    char *const use_delta_flag = (char *)alloca((nDeltaPocsRIdx+1) * sizeof(char));

    for (int j=0;j<=nDeltaPocsRIdx;j++) {
      used_by_curr_pic_flag[j] = get_bits(br,1);
      if (!used_by_curr_pic_flag[j]) {
        use_delta_flag[j] = get_bits(br,1);
      } else {
        use_delta_flag[j] = 1;
      }
    }

    logtrace(LogHeaders,"flags: ");
    for (int j=0;j<=nDeltaPocsRIdx;j++) {
      logtrace(LogHeaders,"%d ", use_delta_flag[j]);
    }
    logtrace(LogHeaders,"\n");

    int nNegativeRIdx = sets[RIdx].NumNegativePics;

    // --- update list 0 (negative Poc) ---
    // Iterate through all Pocs in decreasing value order (positive reverse, 0, negative forward).

    int i=0;
    for (int j=sets[RIdx].NumPositivePics-1;j>=0;j--) {
      int dPoc = sets[RIdx].DeltaPocS1[j] + DeltaRPS;
      if (dPoc<0 && use_delta_flag[nNegativeRIdx+j]) {
        sets[idxRps].DeltaPocS0[i] = dPoc;
        sets[idxRps].UsedByCurrPicS0[i] = used_by_curr_pic_flag[nNegativeRIdx+j];
        i++;
      }
    }

    if (DeltaRPS<0 && use_delta_flag[nDeltaPocsRIdx]) {
      sets[idxRps].DeltaPocS0[i] = DeltaRPS;
      sets[idxRps].UsedByCurrPicS0[i] = used_by_curr_pic_flag[nDeltaPocsRIdx];
      i++;
    }

    for (int j=0;j<nNegativeRIdx;j++) {
      int dPoc = sets[RIdx].DeltaPocS0[j] + DeltaRPS;
      if (dPoc<0 && use_delta_flag[j]) {
        sets[idxRps].DeltaPocS0[i] = dPoc;
        sets[idxRps].UsedByCurrPicS0[i] = used_by_curr_pic_flag[j];
        i++;
      }
    }

    sets[idxRps].NumNegativePics = i;


    // --- update list 1 (positive Poc) ---
    // Iterate through all Pocs in increasing value order (negative reverse, 0, positive forward)

    i=0;
    for (int j=sets[RIdx].NumNegativePics-1;j>=0;j--) {
      int dPoc = sets[RIdx].DeltaPocS0[j] + DeltaRPS;
      if (dPoc>0 && use_delta_flag[j]) {
        sets[idxRps].DeltaPocS1[i] = dPoc;
        sets[idxRps].UsedByCurrPicS1[i] = used_by_curr_pic_flag[j];
        i++;
      }
    }

    if (DeltaRPS>0 && use_delta_flag[nDeltaPocsRIdx]) {
      sets[idxRps].DeltaPocS1[i] = DeltaRPS;
      sets[idxRps].UsedByCurrPicS1[i] = used_by_curr_pic_flag[nDeltaPocsRIdx];
      i++;
    }

    for (int j=0;j<sets[RIdx].NumPositivePics;j++) {
      int dPoc = sets[RIdx].DeltaPocS1[j] + DeltaRPS;
      if (dPoc>0 && use_delta_flag[nNegativeRIdx+j]) {
        sets[idxRps].DeltaPocS1[i] = dPoc;
        sets[idxRps].UsedByCurrPicS1[i] = used_by_curr_pic_flag[nNegativeRIdx+j];
        i++;
      }
    }

    sets[idxRps].NumPositivePics = i;

    sets[idxRps].NumDeltaPocs = sets[idxRps].NumNegativePics + sets[idxRps].NumPositivePics;

  } else {
    int num_negative_pics = get_uvlc(br);
    int num_positive_pics = get_uvlc(br);

    assert(num_negative_pics + num_positive_pics <= MAX_NUM_REF_PICS);


    sets[idxRps].NumNegativePics = num_negative_pics;
    sets[idxRps].NumPositivePics = num_positive_pics;
    sets[idxRps].NumDeltaPocs = num_positive_pics + num_negative_pics;

    int lastPocS=0;
    for (int i=0;i<num_negative_pics;i++) {
      int  delta_poc_s0 = get_uvlc(br)+1;
      char used_by_curr_pic_s0_flag = get_bits(br,1);

      logtrace(LogHeaders,"neg: %d %d\n", delta_poc_s0, used_by_curr_pic_s0_flag);

      sets[idxRps].DeltaPocS0[i]      = lastPocS - delta_poc_s0;
      sets[idxRps].UsedByCurrPicS0[i] = used_by_curr_pic_s0_flag;
      lastPocS = sets[idxRps].DeltaPocS0[i];
    }

    lastPocS=0;
    for (int i=0;i<num_positive_pics;i++) {
      int  delta_poc_s1 = get_uvlc(br)+1;
      char used_by_curr_pic_s1_flag = get_bits(br,1);

      logtrace(LogHeaders,"pos: %d %d\n", delta_poc_s1, used_by_curr_pic_s1_flag);

      sets[idxRps].DeltaPocS1[i]      = lastPocS + delta_poc_s1;
      sets[idxRps].UsedByCurrPicS1[i] = used_by_curr_pic_s1_flag;
      lastPocS = sets[idxRps].DeltaPocS1[i];
    }
  }


  compute_NumPoc(&sets[idxRps]);
}
Example #3
0
de265_error read_sps(bitreader* br, seq_parameter_set* sps, ref_pic_set** ref_pic_sets)
{
  sps->video_parameter_set_id = get_bits(br,4);
  sps->sps_max_sub_layers     = get_bits(br,3) +1;
  if (sps->sps_max_sub_layers>7) {
    return DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE;
  }

  sps->sps_temporal_id_nesting_flag = get_bits(br,1);

  read_profile_tier_level(br,&sps->profile_tier_level, true, sps->sps_max_sub_layers);

  sps->seq_parameter_set_id = get_uvlc(br);


  // --- decode chroma type ---

  sps->chroma_format_idc = get_uvlc(br);

  if (sps->chroma_format_idc == 3) {
    sps->separate_colour_plane_flag = get_bits(br,1);
  }
  else {
    sps->separate_colour_plane_flag = 0;
  }

  if (sps->separate_colour_plane_flag) {
    sps->ChromaArrayType = 0;
  }
  else {
    sps->ChromaArrayType = sps->chroma_format_idc;
  }

  sps->SubWidthC  = SubWidthC [sps->chroma_format_idc];
  sps->SubHeightC = SubHeightC[sps->chroma_format_idc];


  // --- picture size ---

  sps->pic_width_in_luma_samples = get_uvlc(br);
  sps->pic_height_in_luma_samples = get_uvlc(br);

  sps->conformance_window_flag = get_bits(br,1);

  if (sps->conformance_window_flag) {
    sps->conf_win_left_offset  = get_uvlc(br);
    sps->conf_win_right_offset = get_uvlc(br);
    sps->conf_win_top_offset   = get_uvlc(br);
    sps->conf_win_bottom_offset= get_uvlc(br);
  }
  else {
    sps->conf_win_left_offset  = 0;
    sps->conf_win_right_offset = 0;
    sps->conf_win_top_offset   = 0;
    sps->conf_win_bottom_offset= 0;
  }

  if (sps->ChromaArrayType==0) {
    sps->WinUnitX = 1;
    sps->WinUnitY = 1;
  }
  else {
    sps->WinUnitX = SubWidthC[sps->chroma_format_idc];
    sps->WinUnitY = SubHeightC[sps->chroma_format_idc];
  }


  sps->bit_depth_luma   = get_uvlc(br) +8;
  sps->bit_depth_chroma = get_uvlc(br) +8;

  sps->log2_max_pic_order_cnt_lsb = get_uvlc(br) +4;
  sps->MaxPicOrderCntLsb = 1<<(sps->log2_max_pic_order_cnt_lsb);


  // --- sub_layer_ordering_info ---

  sps->sps_sub_layer_ordering_info_present_flag = get_bits(br,1);

  int firstLayer = (sps->sps_sub_layer_ordering_info_present_flag ?
                    0 : sps->sps_max_sub_layers-1 );

  for (int i=firstLayer ; i <= sps->sps_max_sub_layers-1; i++ ) {
    sps->sps_max_dec_pic_buffering[i] = get_uvlc(br);
    sps->sps_max_num_reorder_pics[i]  = get_uvlc(br);
    sps->sps_max_latency_increase[i]  = get_uvlc(br);
  }

  // copy info to all layers if only specified once

  if (sps->sps_sub_layer_ordering_info_present_flag) {
    int ref = sps->sps_max_sub_layers-1;
    for (int i=0 ; i < sps->sps_max_sub_layers-1; i++ ) {
      sps->sps_max_dec_pic_buffering[i] = sps->sps_max_dec_pic_buffering[ref];
      sps->sps_max_num_reorder_pics[i]  = sps->sps_max_num_reorder_pics[ref];
      sps->sps_max_latency_increase[i]  = sps->sps_max_latency_increase[ref];
    }
  }


  sps->log2_min_luma_coding_block_size = get_uvlc(br)+3;
  sps->log2_diff_max_min_luma_coding_block_size = get_uvlc(br);
  sps->log2_min_transform_block_size = get_uvlc(br)+2;
  sps->log2_diff_max_min_transform_block_size = get_uvlc(br);
  sps->max_transform_hierarchy_depth_inter = get_uvlc(br);
  sps->max_transform_hierarchy_depth_intra = get_uvlc(br);
  sps->scaling_list_enable_flag = get_bits(br,1);

  if (sps->scaling_list_enable_flag) {

    sps->sps_scaling_list_data_present_flag = get_bits(br,1);
    if (sps->sps_scaling_list_data_present_flag) {

      assert(0);
      //scaling_list_data()
    }
  }

  sps->amp_enabled_flag = get_bits(br,1);
  sps->sample_adaptive_offset_enabled_flag = get_bits(br,1);
  sps->pcm_enabled_flag = get_bits(br,1);
  if (sps->pcm_enabled_flag) {
    sps->pcm_sample_bit_depth_luma = get_bits(br,4)+1;
    sps->pcm_sample_bit_depth_chroma = get_bits(br,4)+1;
    sps->log2_min_pcm_luma_coding_block_size = get_uvlc(br)+3;
    sps->log2_diff_max_min_pcm_luma_coding_block_size = get_uvlc(br);
    sps->pcm_loop_filter_disable_flag = get_bits(br,1);
  }

  sps->num_short_term_ref_pic_sets = get_uvlc(br);

  // --- allocate reference pic set ---

  // allocate one more for the ref-pic-set that may be sent in the slice header
  *ref_pic_sets = (ref_pic_set *)calloc(sizeof(ref_pic_set), sps->num_short_term_ref_pic_sets + 1);

  for (int i = 0; i < sps->num_short_term_ref_pic_sets; i++) {

    //alloc_ref_pic_set(&(*ref_pic_sets)[i],
    //sps->sps_max_dec_pic_buffering[sps->sps_max_sub_layers-1]);

    read_short_term_ref_pic_set(br,*ref_pic_sets, i, sps->num_short_term_ref_pic_sets);

    dump_short_term_ref_pic_set(&(*ref_pic_sets)[i]);
  }

  sps->long_term_ref_pics_present_flag = get_bits(br,1);

  if (sps->long_term_ref_pics_present_flag) {

    sps->num_long_term_ref_pics_sps = get_uvlc(br);
    if (sps->num_long_term_ref_pics_sps > 32) {
      return DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE;
    }

    for (int i = 0; i < sps->num_long_term_ref_pics_sps; i++ ) {
      sps->lt_ref_pic_poc_lsb_sps[i] = get_bits(br, sps->log2_max_pic_order_cnt_lsb);
      sps->used_by_curr_pic_lt_sps_flag[i] = get_bits(br,1);
    }
  }
  else {
    sps->num_long_term_ref_pics_sps = 0; // NOTE: missing definition in standard !
  }

  sps->sps_temporal_mvp_enabled_flag = get_bits(br,1);
  sps->strong_intra_smoothing_enable_flag = get_bits(br,1);
  sps->vui_parameters_present_flag = get_bits(br,1);

  if (sps->vui_parameters_present_flag) {
    assert(false);
    /*
      vui_parameters()

        sps_extension_flag
        u(1)
        if( sps_extension_flag )

          while( more_rbsp_data() )

            sps_extension_data_flag
              u(1)
              rbsp_trailing_bits()
    */
  }

  sps->sps_extension_flag = get_bits(br,1);
  if (sps->sps_extension_flag) {
    assert(false);
  }

  check_rbsp_trailing_bits(br);


  // --- compute derived values ---

  sps->BitDepth_Y   = sps->bit_depth_luma;
  sps->QpBdOffset_Y = 6*(sps->bit_depth_luma-8);
  sps->BitDepth_C   = sps->bit_depth_chroma;
  sps->QpBdOffset_C = 6*(sps->bit_depth_chroma-8);

  sps->Log2MinCbSizeY = sps->log2_min_luma_coding_block_size;
  sps->Log2CtbSizeY = sps->Log2MinCbSizeY + sps->log2_diff_max_min_luma_coding_block_size;
  sps->MinCbSizeY = 1 << sps->Log2MinCbSizeY;
  sps->CtbSizeY = 1 << sps->Log2CtbSizeY;
  sps->PicWidthInMinCbsY = sps->pic_width_in_luma_samples / sps->MinCbSizeY;
  sps->PicWidthInCtbsY   = ceil_div(sps->pic_width_in_luma_samples, sps->CtbSizeY);
  sps->PicHeightInMinCbsY = sps->pic_height_in_luma_samples / sps->MinCbSizeY;
  sps->PicHeightInCtbsY   = ceil_div(sps->pic_height_in_luma_samples,sps->CtbSizeY);
  sps->PicSizeInMinCbsY   = sps->PicWidthInMinCbsY * sps->PicHeightInMinCbsY;
  sps->PicSizeInCtbsY = sps->PicWidthInCtbsY * sps->PicHeightInCtbsY;
  sps->PicSizeInSamplesY = sps->pic_width_in_luma_samples * sps->pic_height_in_luma_samples;

  if (sps->chroma_format_idc==0 || sps->separate_colour_plane_flag) {
    sps->CtbWidthC  = 0;
    sps->CtbHeightC = 0;
  }
  else {
    sps->CtbWidthC  = sps->CtbSizeY / sps->SubWidthC;
    sps->CtbHeightC = sps->CtbSizeY / sps->SubHeightC;
  }

  sps->Log2MinTrafoSize = sps->log2_min_transform_block_size;
  sps->Log2MaxTrafoSize = sps->log2_min_transform_block_size + sps->log2_diff_max_min_transform_block_size;

  // the following are not in the standard
  sps->PicWidthInTbsY  = sps->PicWidthInCtbsY  << (sps->Log2CtbSizeY - sps->Log2MinTrafoSize);
  sps->PicHeightInTbsY = sps->PicHeightInCtbsY << (sps->Log2CtbSizeY - sps->Log2MinTrafoSize);
  sps->PicSizeInTbsY = sps->PicWidthInTbsY * sps->PicHeightInTbsY;

  sps->sps_read = true;

  return DE265_OK;
}
Example #4
0
void read_pps(bitreader* br, pic_parameter_set* pps, decoder_context* ctx)
{
    pps->pic_parameter_set_id = get_uvlc(br);
    pps->seq_parameter_set_id = get_uvlc(br);
    pps->dependent_slice_segments_enabled_flag = get_bits(br,1);
    pps->output_flag_present_flag = get_bits(br,1);
    pps->num_extra_slice_header_bits = get_bits(br,3);
    pps->sign_data_hiding_flag = get_bits(br,1);
    pps->cabac_init_present_flag = get_bits(br,1);
    pps->num_ref_idx_l0_default_active = get_uvlc(br)+1;
    pps->num_ref_idx_l1_default_active = get_uvlc(br)+1;

    seq_parameter_set* sps = get_sps(ctx, pps->seq_parameter_set_id);

    pps->pic_init_qp = get_svlc(br)+26;
    pps->constrained_intra_pred_flag = get_bits(br,1);
    pps->transform_skip_enabled_flag = get_bits(br,1);
    pps->cu_qp_delta_enabled_flag = get_bits(br,1);

    if (pps->cu_qp_delta_enabled_flag) {
        pps->diff_cu_qp_delta_depth = get_uvlc(br);
    } else {
        pps->diff_cu_qp_delta_depth = 0;
    }

    pps->pic_cb_qp_offset = get_svlc(br);
    pps->pic_cr_qp_offset  = get_svlc(br);
    pps->pps_slice_chroma_qp_offsets_present_flag = get_bits(br,1);
    pps->weighted_pred_flag = get_bits(br,1);
    pps->weighted_bipred_flag = get_bits(br,1);
    pps->transquant_bypass_enable_flag = get_bits(br,1);
    pps->tiles_enabled_flag = get_bits(br,1);
    pps->entropy_coding_sync_enabled_flag = get_bits(br,1);


    // --- tiles ---

    if (pps->tiles_enabled_flag ) {
        pps->num_tile_columns = get_uvlc(br)+1;
        pps->num_tile_rows    = get_uvlc(br)+1;
        pps->uniform_spacing_flag = get_bits(br,1);

        assert(pps->num_tile_columns <= DE265_MAX_TILE_COLUMNS);
        assert(pps->num_tile_rows    <= DE265_MAX_TILE_ROWS);

        if (pps->uniform_spacing_flag==false) {
            int lastColumnWidth = sps->PicWidthInCtbsY;
            int lastRowHeight   = sps->PicHeightInCtbsY;

            for (int i=0; i<pps->num_tile_columns-1; i++)
            {
                pps->colWidth[i] = get_uvlc(br)+1;
                lastColumnWidth -= pps->colWidth[i];
            }

            pps->colWidth[pps->num_tile_columns-1] = lastColumnWidth;

            for (int i=0; i<pps->num_tile_rows-1; i++)
            {
                pps->rowHeight[i] = get_uvlc(br)+1;
                lastRowHeight -= pps->rowHeight[i];
            }

            pps->rowHeight[pps->num_tile_rows-1] = lastRowHeight;
        }

        pps->loop_filter_across_tiles_enabled_flag = get_bits(br,1);

    } else {
        pps->num_tile_columns = 1;
        pps->num_tile_rows    = 1;
        pps->uniform_spacing_flag = 1;
    }



    if (pps->uniform_spacing_flag) {

        // set columns widths

        int *const colPos = (int *)alloca((pps->num_tile_columns+1) * sizeof(int));

        for (int i=0; i<=pps->num_tile_columns; i++) {
            colPos[i] = i*sps->PicWidthInCtbsY / pps->num_tile_columns;
        }
        for (int i=0; i<pps->num_tile_columns; i++) {
            pps->colWidth[i] = colPos[i+1] - colPos[i];
        }

        // set row heights

        int *const rowPos = (int *)alloca((pps->num_tile_rows+1) * sizeof(int));

        for (int i=0; i<=pps->num_tile_rows; i++) {
            rowPos[i] = i*sps->PicHeightInCtbsY / pps->num_tile_rows;
        }
        for (int i=0; i<pps->num_tile_rows; i++) {
            pps->rowHeight[i] = rowPos[i+1] - rowPos[i];
        }
    }


    // set tile boundaries

    pps->colBd[0]=0;
    for (int i=0; i<pps->num_tile_columns; i++) {
        pps->colBd[i+1] = pps->colBd[i] + pps->colWidth[i];
    }

    pps->rowBd[0]=0;
    for (int i=0; i<pps->num_tile_rows; i++) {
        pps->rowBd[i+1] = pps->rowBd[i] + pps->rowHeight[i];
    }



    // alloc raster scan arrays

    if (pps->CtbAddrRStoTS) {
        free(pps->CtbAddrRStoTS);
    }
    if (pps->CtbAddrTStoRS) {
        free(pps->CtbAddrTStoRS);
    }
    if (pps->TileId) {
        free(pps->TileId);
    }
    if (pps->MinTbAddrZS) {
        free(pps->MinTbAddrZS);
    }

    pps->CtbAddrRStoTS = (int *)malloc( sizeof(int) * sps->PicSizeInCtbsY );
    pps->CtbAddrTStoRS = (int *)malloc( sizeof(int) * sps->PicSizeInCtbsY );
    pps->TileId        = (int *)malloc( sizeof(int) * sps->PicSizeInCtbsY );
    pps->MinTbAddrZS   = (int *)malloc( sizeof(int) * sps->PicSizeInTbsY  );


    // raster scan (RS) <-> tile scan (TS) conversion

    for (int ctbAddrRS=0 ; ctbAddrRS < sps->PicSizeInCtbsY ; ctbAddrRS++)
    {
        int tbX = ctbAddrRS % sps->PicWidthInCtbsY;
        int tbY = ctbAddrRS / sps->PicWidthInCtbsY;
        int tileX=-1,tileY=-1;

        for (int i=0; i<pps->num_tile_columns; i++)
            if (tbX >= pps->colBd[i])
                tileX=i;

        for (int j=0; j<pps->num_tile_rows; j++)
            if (tbY >= pps->rowBd[j])
                tileY=j;

        pps->CtbAddrRStoTS[ctbAddrRS] = 0;
        for (int i=0; i<tileX; i++)
            pps->CtbAddrRStoTS[ctbAddrRS] += pps->rowHeight[tileY]*pps->colWidth[i];

        for (int j=0; j<tileY; j++)
        {
            //pps->CtbAddrRStoTS[ctbAddrRS] += (tbY - pps->rowBd[tileY])*pps->colWidth[tileX];
            //pps->CtbAddrRStoTS[ctbAddrRS] += tbX - pps->colBd[tileX];

            pps->CtbAddrRStoTS[ctbAddrRS] += sps->PicWidthInCtbsY * pps->rowHeight[j];
        }

        assert(tileX>=0 && tileY>=0);

        pps->CtbAddrRStoTS[ctbAddrRS] += (tbY-pps->rowBd[tileY])*pps->colWidth[tileX];
        pps->CtbAddrRStoTS[ctbAddrRS] +=  tbX - pps->colBd[tileX];


        // inverse mapping

        pps->CtbAddrTStoRS[ pps->CtbAddrRStoTS[ctbAddrRS] ] = ctbAddrRS;
    }


    logtrace(LogHeaders,"6.5.1 CtbAddrRSToTS\n");
    for (int y=0; y<sps->PicHeightInCtbsY; y++)
    {
        for (int x=0; x<sps->PicWidthInCtbsY; x++)
        {
            logtrace(LogHeaders,"%3d ", pps->CtbAddrRStoTS[x + y*sps->PicWidthInCtbsY]);
        }

        logtrace(LogHeaders,"\n");
    }


    // tile id

    for (int j=0, tIdx=0 ; j<pps->num_tile_rows ; j++)
        for (int i=0 ; i<pps->num_tile_columns; i++)
        {
            for (int y=pps->rowBd[j] ; y<pps->rowBd[j+1] ; y++)
                for (int x=pps->colBd[j] ; x<pps->colBd[j+1] ; x++)
                    pps->TileId[ pps->CtbAddrRStoTS[y*sps->PicWidthInCtbsY + x] ] = tIdx;

            tIdx++;
        }

    // 6.5.2 Z-scan order array initialization process

    for (int y=0; y<sps->PicHeightInTbsY; y++)
        for (int x=0; x<sps->PicWidthInTbsY; x++)
        {
            int tbX = (x<<sps->Log2MinTrafoSize)>>sps->Log2CtbSizeY;
            int tbY = (y<<sps->Log2MinTrafoSize)>>sps->Log2CtbSizeY;
            int ctbAddrRS = sps->PicWidthInCtbsY*tbY + tbX;

            pps->MinTbAddrZS[x + y*sps->PicWidthInTbsY] = pps->CtbAddrRStoTS[ctbAddrRS]
                    << ((sps->Log2CtbSizeY-sps->Log2MinTrafoSize)*2);

            int p=0;
            for (int i=0 ; i<(sps->Log2CtbSizeY - sps->Log2MinTrafoSize) ; i++) {
                int m=1<<i;
                p += (m & x ? m*m : 0) + (m & y ? 2*m*m : 0);
            }

            pps->MinTbAddrZS[x + y*sps->PicWidthInTbsY] += p;
        }


    // --- debug logging ---

    /*
    logtrace(LogHeaders,"6.5.2 Z-scan order array\n");
    for (int y=0;y<sps->PicHeightInTbsY;y++)
      {
        for (int x=0;x<sps->PicWidthInTbsY;x++)
          {
            logtrace(LogHeaders,"%4d ", pps->MinTbAddrZS[x + y*sps->PicWidthInTbsY]);
          }

        logtrace(LogHeaders,"\n");
      }

    for (int i=0;i<sps->PicSizeInTbsY;i++)
      {
        for (int y=0;y<sps->PicHeightInTbsY;y++)
          {
            for (int x=0;x<sps->PicWidthInTbsY;x++)
              {
                if (pps->MinTbAddrZS[x + y*sps->PicWidthInTbsY] == i) {
                  logtrace(LogHeaders,"%d %d\n",x,y);
                }
              }
          }
      }
    */

    // END tiles


    pps->Log2MinCuQpDeltaSize = sps->Log2CtbSizeY - pps->diff_cu_qp_delta_depth;


    pps->beta_offset = 0; // default value
    pps->tc_offset   = 0; // default value

    pps->pps_loop_filter_across_slices_enabled_flag = get_bits(br,1);
    pps->deblocking_filter_control_present_flag = get_bits(br,1);
    if (pps->deblocking_filter_control_present_flag) {
        pps->deblocking_filter_override_enabled_flag = get_bits(br,1);
        pps->pic_disable_deblocking_filter_flag = get_bits(br,1);
        if (!pps->pic_disable_deblocking_filter_flag) {
            pps->beta_offset = get_svlc(br)*2;
            pps->tc_offset   = get_svlc(br)*2;
        }
    }
    else {
        pps->deblocking_filter_override_enabled_flag = 0;
        pps->pic_disable_deblocking_filter_flag = 0;
    }

    pps->pic_scaling_list_data_present_flag = get_bits(br,1);
    if (pps->pic_scaling_list_data_present_flag) {
        assert(false);
        //scaling_list_data()
    }

    pps->lists_modification_present_flag = get_bits(br,1);
    pps->log2_parallel_merge_level = get_uvlc(br)+2;
    pps->slice_segment_header_extension_present_flag = get_bits(br,1);
    pps->pps_extension_flag = get_bits(br,1);

    if (pps->pps_extension_flag) {
        assert(false);
        /*
          while( more_rbsp_data() )

          pps_extension_data_flag
          u(1)
          rbsp_trailing_bits()

          }
        */
    }


    pps->pps_read = true;
}
Example #5
0
/* A ref-pic-set is coded either coded
   - as a list of the relative POC deltas themselves, or
   - by shifting an existing ref-pic-set by some number of frames
   When shifting an existing set, the frame 0 is also shifted as an additional reference frame.
   When coding the ref-pic-sets in the SPS, predicition is always from the previous set.
   In the slice header, the ref-pic-set can use any previous set as reference.
 */
bool read_short_term_ref_pic_set(decoder_context* ctx,
                                 const seq_parameter_set* sps,
                                 bitreader* br,
                                 ref_pic_set* out_set, // where to store the read set
                                 int idxRps,  // index of the set to be read
                                 const ref_pic_set* sets, // previously read sets
                                 bool sliceRefPicSet) // is this in the slice header?
{
  // --- is this set coded in prediction mode (not possible for the first set)

  char inter_ref_pic_set_prediction_flag;

  if (idxRps != 0) {
    inter_ref_pic_set_prediction_flag = get_bits(br,1);
  }
  else {
    inter_ref_pic_set_prediction_flag = 0;
  }



  if (inter_ref_pic_set_prediction_flag) {
    int vlc;

    /* Only for the last ref_pic_set (that's the one coded in the slice header),
       we can specify relative to which reference set we code the set. */

    int delta_idx;
    if (sliceRefPicSet) { // idxRps == num_short_term_ref_pic_sets) {
      delta_idx = vlc = get_uvlc(br);
      delta_idx++;
    } else {
      delta_idx = 1;
    }

    int RIdx = idxRps - delta_idx; // this is our source set, which we will modify
    assert(RIdx>=0);

    int delta_rps_sign = get_bits(br,1);
    int abs_delta_rps  = vlc = get_uvlc(br);
    abs_delta_rps++;
    int DeltaRPS = (delta_rps_sign ? -abs_delta_rps : abs_delta_rps);

    // bits are stored in this order:
    // - all bits for negative Pocs (forward),
    // - then all bits for positive Pocs (forward),
    // - then bits for '0', shifting of the current picture
    // in total, these are 'nDeltaPocsRIdx'+1 bits

    logtrace(LogHeaders,"predicted from %d with delta %d\n",RIdx,DeltaRPS);

    int nDeltaPocsRIdx= sets[RIdx].NumDeltaPocs; // size of source set
    char *const used_by_curr_pic_flag = (char *)alloca((nDeltaPocsRIdx+1) * sizeof(char));
    char *const use_delta_flag = (char *)alloca((nDeltaPocsRIdx+1) * sizeof(char));

    for (int j=0;j<=nDeltaPocsRIdx;j++) {
      used_by_curr_pic_flag[j] = get_bits(br,1);
      if (used_by_curr_pic_flag[j]) {
        use_delta_flag[j] = 1;  // if this frame is used, we also have to apply the delta
      } else {
        use_delta_flag[j] = get_bits(br,1);  // otherwise, it is only optionally included
      }
    }

    logtrace(LogHeaders,"flags: ");
    for (int j=0;j<=nDeltaPocsRIdx;j++) {
      logtrace(LogHeaders,"%d ", use_delta_flag[j]);
    }
    logtrace(LogHeaders,"\n");

    int nNegativeRIdx = sets[RIdx].NumNegativePics;
    int nPositiveRIdx = sets[RIdx].NumPositivePics;

    // --- update list 0 (negative Poc) ---
    // Iterate through all Pocs in decreasing value order (positive reverse, 0, negative forward).

    int i=0; // target index

    // positive list
    for (int j=nPositiveRIdx-1;j>=0;j--) {
      int dPoc = sets[RIdx].DeltaPocS1[j] + DeltaRPS; // new delta
      if (dPoc<0 && use_delta_flag[nNegativeRIdx+j]) {
        out_set->DeltaPocS0[i] = dPoc;
        out_set->UsedByCurrPicS0[i] = used_by_curr_pic_flag[nNegativeRIdx+j];
        i++;
      }
    }

    // frame 0
    if (DeltaRPS<0 && use_delta_flag[nDeltaPocsRIdx]) {
      out_set->DeltaPocS0[i] = DeltaRPS;
      out_set->UsedByCurrPicS0[i] = used_by_curr_pic_flag[nDeltaPocsRIdx];
      i++;
    }

    // negative list
    for (int j=0;j<nNegativeRIdx;j++) {
      int dPoc = sets[RIdx].DeltaPocS0[j] + DeltaRPS;
      if (dPoc<0 && use_delta_flag[j]) {
        out_set->DeltaPocS0[i] = dPoc;
        out_set->UsedByCurrPicS0[i] = used_by_curr_pic_flag[j];
        i++;
      }
    }

    out_set->NumNegativePics = i;


    // --- update list 1 (positive Poc) ---
    // Iterate through all Pocs in increasing value order (negative reverse, 0, positive forward)

    i=0; // target index

    // negative list
    for (int j=nNegativeRIdx-1;j>=0;j--) {
      int dPoc = sets[RIdx].DeltaPocS0[j] + DeltaRPS;
      if (dPoc>0 && use_delta_flag[j]) {
        out_set->DeltaPocS1[i] = dPoc;
        out_set->UsedByCurrPicS1[i] = used_by_curr_pic_flag[j];
        i++;
      }
    }

    // frame 0
    if (DeltaRPS>0 && use_delta_flag[nDeltaPocsRIdx]) {
      out_set->DeltaPocS1[i] = DeltaRPS;
      out_set->UsedByCurrPicS1[i] = used_by_curr_pic_flag[nDeltaPocsRIdx];
      i++;
    }

    // positive list
    for (int j=0;j<nPositiveRIdx;j++) {
      int dPoc = sets[RIdx].DeltaPocS1[j] + DeltaRPS;
      if (dPoc>0 && use_delta_flag[nNegativeRIdx+j]) {
        out_set->DeltaPocS1[i] = dPoc;
        out_set->UsedByCurrPicS1[i] = used_by_curr_pic_flag[nNegativeRIdx+j];
        i++;
      }
    }

    out_set->NumPositivePics = i;

    out_set->NumDeltaPocs = out_set->NumNegativePics + out_set->NumPositivePics;

  } else {

    // --- first, read the number of past and future frames in this set ---

    int num_negative_pics = get_uvlc(br);
    int num_positive_pics = get_uvlc(br);

    // total number of reference pictures may not exceed buffer capacity
    if (num_negative_pics + num_positive_pics >
        sps->sps_max_dec_pic_buffering[ sps->sps_max_sub_layers-1 ]) {
      add_warning(ctx, DE265_WARNING_MAX_NUM_REF_PICS_EXCEEDED, false);
      return false;
    }


    out_set->NumNegativePics = num_negative_pics;
    out_set->NumPositivePics = num_positive_pics;
    out_set->NumDeltaPocs = num_positive_pics + num_negative_pics;


    // --- now, read the deltas between the reference frames to fill the lists ---

    // past frames

    int lastPocS=0;
    for (int i=0;i<num_negative_pics;i++) {
      int  delta_poc_s0 = get_uvlc(br)+1;
      char used_by_curr_pic_s0_flag = get_bits(br,1);

      out_set->DeltaPocS0[i]      = lastPocS - delta_poc_s0;
      out_set->UsedByCurrPicS0[i] = used_by_curr_pic_s0_flag;
      lastPocS = out_set->DeltaPocS0[i];
    }

    // future frames

    lastPocS=0;
    for (int i=0;i<num_positive_pics;i++) {
      int  delta_poc_s1 = get_uvlc(br)+1;
      char used_by_curr_pic_s1_flag = get_bits(br,1);

      out_set->DeltaPocS1[i]      = lastPocS + delta_poc_s1;
      out_set->UsedByCurrPicS1[i] = used_by_curr_pic_s1_flag;
      lastPocS = out_set->DeltaPocS1[i];
    }
  }


  compute_NumPoc(out_set);

  return true;
}