Exemple #1
0
static void
c_output(const char *infile, const char *define, int extend, const char *outfile)
{
	definition *def;
	char *include;
	const char *outfilename;
	long tell;

	c_initialize();
	open_input(infile, define);
	outfilename = extend ? extendfile(infile, outfile) : outfile;
	open_output(infile, outfilename);
	add_warning();
	if (infile && (include = extendfile(infile, ".h"))) {
		f_print(fout, "#include \"%s\"\n", include);
		free(include);
		/* .h file already contains rpc/rpc.h */
	} else
		f_print(fout, "#include <rpc/rpc.h>\n");
	tell = ftell(fout);
	while ( (def = get_definition()) )
		emit(def);
	if (extend && tell == ftell(fout))
		unlink(outfilename);
}
Exemple #2
0
static void check_lag_in_frames_realtime_deadline(
    int lag_in_frames,
    int deadline,
    struct WarningList *warning_list) {
  if (deadline == VPX_DL_REALTIME && lag_in_frames != 0)
    add_warning(lag_in_frames_with_realtime, warning_list);
}
/*
 * generate the dispatch table
 */
static void
t_output (char *infile, char *define, int extend, char *outfile)
{
  definition *def;
  int foundprogram = 0;
  char *outfilename;
  char *incfile;

  open_input (infile, define);
  outfilename = extend ? extendfile (infile, outfile) : outfile;
  incfile = extendfile (infile, ".h");
  open_output (infile, outfilename);

  add_warning ();
  f_print (fout, "#include \"%s\"\n", incfile);

  while ((def = get_definition ())) {
    foundprogram |= (def->def_kind == DEF_PROGRAM);
  }
  if (extend && !foundprogram) {
    (void) unlink (outfilename);
    return;
  }
  write_tables ();
}
/**
 * on this pass we direct the graph to point to the right nodes
 * 
 */
void
TrexStreamsCompiler::direct_pass(GraphNodeMap *nodes) {
   
    /* second pass - direct the graph */
    for (auto p : nodes->get_nodes()) {

        GraphNode *node = p.second;
        const TrexStream *stream = node->m_stream;

        /* check the stream points on an existing stream */
        GraphNode *next_node = nodes->get(stream->m_next_stream_id);
        if (!next_node) {
            std::stringstream ss;
            ss << "stream " << node->get_stream_id() << " is pointing on non existent stream " << stream->m_next_stream_id;
            err(ss.str());
        }

        node->m_next = next_node;

        /* do we have more than one parent ? */
        next_node->m_parents.push_back(node);
    }


    /* check for multiple parents */
    for (auto p : nodes->get_nodes()) {
        GraphNode *node = p.second;

        if (node->m_parents.size() > 0 ) {
            std::stringstream ss;

            ss << "stream " << node->get_stream_id() << " is triggered by multiple streams: ";
            for (auto x : node->m_parents) {
                ss << x->get_stream_id() << " ";
            }

            add_warning(ss.str());
        }
    }
}
Exemple #5
0
de265_error de265_decode_NAL(de265_decoder_context* de265ctx, rbsp_buffer* data)
{
  decoder_context* ctx = (decoder_context*)de265ctx;

  /*
  if (ctx->num_skipped_bytes>0) {
    printf("skipped bytes:\n  ");
    for (int i=0;i<ctx->num_skipped_bytes;i++)
    printf("%d ",ctx->skipped_bytes[i]);
    printf("\n");
  }
  */

  de265_error err = DE265_OK;

  bitreader reader;
  bitreader_init(&reader, data);

  nal_header nal_hdr;
  nal_read_header(&reader, &nal_hdr);
  process_nal_hdr(ctx, &nal_hdr);

  logdebug(LogHighlevel,"NAL: 0x%x 0x%x -  %d %d\n",
           data->data[0], data->data[1],
           nal_hdr.nal_unit_type,
           nal_hdr.nuh_temporal_id);


  if (nal_hdr.nal_unit_type<32) {
    logdebug(LogHeaders,"---> read slice segment header\n");

    int sliceIndex = get_next_slice_index(ctx);
    slice_segment_header* hdr = &ctx->slice[sliceIndex];
    hdr->slice_index = sliceIndex;
    read_slice_segment_header(&reader,hdr,ctx);
    dump_slice_segment_header(hdr, ctx);

    if ((err = process_slice_segment_header(ctx, hdr)) != DE265_OK)
      { return err; }

    skip_bits(&reader,1); // TODO: why?
    prepare_for_CABAC(&reader);


    // modify entry_point_offsets

    int headerLength = reader.data - data->data;
    for (int i=0;i<ctx->num_skipped_bytes;i++)
      {
        ctx->skipped_bytes[i] -= headerLength;
      }

    for (int i=0;i<hdr->num_entry_point_offsets;i++) {
      for (int k=ctx->num_skipped_bytes-1;k>=0;k--)
        if (ctx->skipped_bytes[k] <= hdr->entry_point_offset[i]) {
          hdr->entry_point_offset[i] -= k+1;
          break;
        }
    }


    int nRows = hdr->num_entry_point_offsets +1;

    bool use_WPP = (ctx->num_worker_threads > 0 &&
                    ctx->current_pps->entropy_coding_sync_enabled_flag);

    if (ctx->num_worker_threads > 0 &&
        ctx->current_pps->entropy_coding_sync_enabled_flag == false) {
      add_warning(ctx, DE265_WARNING_NO_WPP_CANNOT_USE_MULTITHREADING, true);
    }

    if (!use_WPP) {
      init_thread_context(&hdr->thread_context[0]);

      init_CABAC_decoder(&hdr->thread_context[0].cabac_decoder,
                         reader.data,
                         reader.bytes_remaining);

      hdr->thread_context[0].shdr = hdr;
      hdr->thread_context[0].decctx = ctx;


      // fixed context 0
      if ((err=read_slice_segment_data(ctx, &hdr->thread_context[0])) != DE265_OK)
        { return err; }
    }
    else {
      for (int i=0;i<nRows;i++) {
        int dataStartIndex;
        if (i==0) { dataStartIndex=0; }
        else      { dataStartIndex=hdr->entry_point_offset[i-1]; }

        int dataEnd;
        if (i==nRows-1) dataEnd = reader.bytes_remaining;
        else            dataEnd = hdr->entry_point_offset[i];

        init_thread_context(&hdr->thread_context[i]);

        init_CABAC_decoder(&hdr->thread_context[i].cabac_decoder,
                           &reader.data[dataStartIndex],
                           dataEnd-dataStartIndex);

        hdr->thread_context[i].shdr = hdr;
        hdr->thread_context[i].decctx = ctx;
      }

      // TODO: hard-coded thread context

      add_CTB_decode_task_syntax(&hdr->thread_context[0], 0,0  ,0,0, NULL);

      /*
      for (int x=0;x<ctx->current_sps->PicWidthInCtbsY;x++)
        for (int y=0;y<ctx->current_sps->PicHeightInCtbsY;y++)
          {
            add_CTB_decode_task_syntax(&hdr->thread_context[y], x,y);
          }
      */

      flush_thread_pool(&ctx->thread_pool);
    }
  }
  else switch (nal_hdr.nal_unit_type) {
    case NAL_UNIT_VPS_NUT:
      {
        logdebug(LogHeaders,"---> read VPS\n");

        video_parameter_set vps;
        read_vps(&reader,&vps);
        dump_vps(&vps);

        process_vps(ctx, &vps);
      }
      break;

    case NAL_UNIT_SPS_NUT:
      {
        logdebug(LogHeaders,"----> read SPS\n");

        seq_parameter_set sps;

        if ((err=read_sps(&reader,&sps, &ctx->ref_pic_sets)) != DE265_OK) {
          break;
        }
        dump_sps(&sps, ctx->ref_pic_sets);

        process_sps(ctx, &sps);
      }
      break;

    case NAL_UNIT_PPS_NUT:
      {
        logdebug(LogHeaders,"----> read PPS\n");

        pic_parameter_set pps;

        init_pps(&pps);
        read_pps(&reader,&pps,ctx);
        dump_pps(&pps);

        process_pps(ctx,&pps);
      }
      break;

    case NAL_UNIT_PREFIX_SEI_NUT:
    case NAL_UNIT_SUFFIX_SEI_NUT:
      logdebug(LogHeaders,"----> read SEI\n");

      sei_message sei;

      push_current_picture_to_output_queue(ctx);

      read_sei(&reader,&sei, nal_hdr.nal_unit_type==NAL_UNIT_SUFFIX_SEI_NUT, ctx);
      dump_sei(&sei, ctx);

      err = process_sei(&sei, ctx);
      break;
    }

  return err;
}
static void
h_output (char *infile, char *define, int extend, char *outfile)
{
  definition *def;
  char *outfilename;
  long tell;
  char *guard;
  list *l;

  open_input (infile, define);
  outfilename = extend ? extendfile (infile, outfile) : outfile;
  open_output (infile, outfilename);
  add_warning ();
  guard = generate_guard (outfilename ? outfilename : infile);

  f_print (fout, "#ifndef _%s\n#define _%s\n\n", guard,
	   guard);

#if 0
  f_print (fout, "#define RPCGEN_VERSION\t%s\n\n", RPCGEN_VERSION);
  f_print (fout, "#include <rpc/rpc.h>\n\n");
#else
  f_print (fout, "#include \"%s\"\n\n", incfile);
#endif

#if 0
  f_print (fout, "#ifdef __cplusplus\n"
"\n"
"#ifndef EXTERN\n"
"#define EXTERN extern \"C\" \n"
"#define EXTERN_DEFINED_BY_%s\n"
"#endif /* !EXTERN */\n"
"#ifndef UNION_NAME\n"
"#define UNION_NAME(name) u\n"
"#define UNION_NAME_DEFINED_BY_%s 1\n"
"#endif /* !UNION_NAME */\n"
"#ifndef CONSTRUCT\n"
"#define CONSTRUCT(Type, type)                                       \\\n"
"struct Type : public type {                                         \\\n"
"  Type () { bzero ((type *) this, sizeof (type)); }                 \\\n"
"  ~Type () { xdr_free ((xdrproc_t) xdr_ ## type,                    \\\n"
"                       (char *) (type *) this); }                   \\\n"
"};\n"
"#define CONSTRUCT_DEFINED_BY_%s\n"
"#endif /* !CONSTRUCT */\n"
"\n"
"#else /* !__cplusplus */\n"
"\n"
"#ifndef EXTERN\n"
"#define EXTERN extern\n"
"#define EXTERN_DEFINED_BY_%s\n"
"#endif /* !EXTERN */\n"
"#ifndef UNION_NAME\n"
"#define UNION_NAME(name) u\n"
"#define UNION_NAME_DEFINED_BY_%s 1\n"
"#endif /* !UNION_NAME */\n"
"#ifndef CONSTRUCT\n"
"#define CONSTRUCT(Type, type)\n"
"#define CONSTRUCT_DEFINED_BY_%s\n"
"#endif /* !CONSTRUCT */\n"
"\n"
"#endif /* !__cplusplus */\n", guard, guard, guard, guard, guard, guard);
#endif

  tell = ftell (fout);
  /* print data definitions */
  while ((def = get_definition ())) {
    print_datadef (def);
  }

  /* print function declarations.  
     Do this after data definitions because they might be used as
     arguments for functions */
  for (l = defined; l != NULL; l = l->next) {
    print_funcdef (l->val);
  }
  if (extend && tell == ftell (fout)) {
    (void) unlink (outfilename);
  }
#if 0
  f_print (fout, "\n#ifdef __cplusplus\n"
	   "}\n"
	   "#endif /* __cplusplus */\n");
#endif

  f_print (fout, "\n");

#if 0
  f_print (fout,
"#ifdef EXTERN_DEFINED_BY_%s\n"
"#undef EXTERN\n"
"#undef EXTERN_DEFINED_BY_%s\n"
"#endif /* EXTERN_DEFINED_BY_%s */\n"
"#ifdef UNION_NAME_DEFINED_BY_%s\n"
"#undef UNION_NAME\n"
"#undef UNION_NAME_DEFINED_BY_%s\n"
"#endif /* UNION_NAME_DEFINED_BY_%s */\n"
"#ifdef CONSTRUCT_DEFINED_BY_%s\n"
"#undef CONSTRUCT\n"
"#undef CONSTRUCT_DEFINED_BY_%s\n"
"#endif /* CONSTRUCT_DEFINED_BY_%s */\n",
	   guard, guard, guard, guard, guard, guard, guard, guard, guard);
#endif

  f_print (fout, "\n#endif /* !_%s */\n", guard);
}
Exemple #7
0
de265_error de265_decode_NAL(de265_decoder_context* de265ctx, NAL_unit* nal)
{
  decoder_context* ctx = (decoder_context*)de265ctx;
  rbsp_buffer* data = &nal->nal_data;

  de265_error err = DE265_OK;

  bitreader reader;
  bitreader_init(&reader, data);

  nal_header nal_hdr;
  nal_read_header(&reader, &nal_hdr);
  process_nal_hdr(ctx, &nal_hdr);

  loginfo(LogHighlevel,"NAL: 0x%x 0x%x -  unit type:%s temporal id:%d\n",
          data->data[0], data->data[1],
          get_NAL_name(nal_hdr.nal_unit_type),
          nal_hdr.nuh_temporal_id);

  if (nal_hdr.nal_unit_type<32) {
    logdebug(LogHeaders,"---> read slice segment header\n");

    //printf("-------- slice header --------\n");

    int sliceIndex = get_next_slice_index(ctx);
    if (sliceIndex<0) {
      add_warning(ctx,DE265_ERROR_MAX_NUMBER_OF_SLICES_EXCEEDED, true);
      return DE265_ERROR_MAX_NUMBER_OF_SLICES_EXCEEDED;
    }

    slice_segment_header* hdr = &ctx->slice[sliceIndex];
    bool continueDecoding;
    err = read_slice_segment_header(&reader,hdr,ctx, &continueDecoding);
    if (!continueDecoding) {
      return err;
    }
    else {
      hdr->slice_index = sliceIndex;

      if (ctx->param_slice_headers_fd>=0) {
        dump_slice_segment_header(hdr, ctx, ctx->param_slice_headers_fd);
      }

      if (process_slice_segment_header(ctx, hdr, &err, nal->pts, nal->user_data) == false)
        {
          ctx->img->integrity = INTEGRITY_NOT_DECODED;
          return err;
        }

      skip_bits(&reader,1); // TODO: why?
      prepare_for_CABAC(&reader);


      // modify entry_point_offsets

      int headerLength = reader.data - data->data;
      for (int i=0;i<nal->num_skipped_bytes;i++)
        {
          nal->skipped_bytes[i] -= headerLength;
        }

      for (int i=0;i<hdr->num_entry_point_offsets;i++) {
        for (int k=nal->num_skipped_bytes-1;k>=0;k--)
          if (nal->skipped_bytes[k] <= hdr->entry_point_offset[i]) {
            hdr->entry_point_offset[i] -= k+1;
            break;
          }
      }


      const pic_parameter_set* pps = ctx->current_pps;
      int ctbsWidth = ctx->current_sps->PicWidthInCtbsY;

      int nRows = hdr->num_entry_point_offsets +1;

      bool use_WPP = (ctx->num_worker_threads > 0 &&
                      ctx->current_pps->entropy_coding_sync_enabled_flag);

      bool use_tiles = (ctx->num_worker_threads > 0 &&
                        ctx->current_pps->tiles_enabled_flag);

      if (use_WPP && use_tiles) {
        //add_warning(ctx, DE265_WARNING_STREAMS_APPLIES_TILES_AND_WPP, true);
      }

      if (ctx->num_worker_threads > 0 &&
          ctx->current_pps->entropy_coding_sync_enabled_flag == false &&
          ctx->current_pps->tiles_enabled_flag == false) {

        // TODO: new error should be: no WPP and no Tiles ...
        add_warning(ctx, DE265_WARNING_NO_WPP_CANNOT_USE_MULTITHREADING, true);
      }

      if (!use_WPP && !use_tiles) {
        // --- single threaded decoding ---

#if 0
        int thread_context_idx = get_next_thread_context_index(ctx);
        if (thread_context_idx<0) {
          assert(false); // TODO
        }
#else
        int thread_context_idx=0;
#endif

        thread_context* tctx = &ctx->thread_context[thread_context_idx];

        init_thread_context(tctx);

        init_CABAC_decoder(&tctx->cabac_decoder,
                           reader.data,
                           reader.bytes_remaining);

        tctx->shdr = hdr;
        tctx->decctx = ctx;
        tctx->CtbAddrInTS = pps->CtbAddrRStoTS[hdr->slice_segment_address];

        // fixed context 0
        if ((err=read_slice_segment_data(ctx, tctx)) != DE265_OK)
          { return err; }
      }
      else if (use_tiles && !use_WPP) {
        int nTiles = nRows;  // TODO: rename 'nRows'

        if (nTiles > MAX_THREAD_CONTEXTS) {
          return DE265_ERROR_MAX_THREAD_CONTEXTS_EXCEEDED;
        }

        assert(nTiles == pps->num_tile_columns * pps->num_tile_rows); // TODO: handle other cases

        assert(ctx->img->tasks_pending == 0);
        increase_pending_tasks(ctx->img, nTiles);

        for (int ty=0;ty<pps->num_tile_rows;ty++)
          for (int tx=0;tx<pps->num_tile_columns;tx++) {
            int tile = tx + ty*pps->num_tile_columns;

            // set thread context

            ctx->thread_context[tile].shdr = hdr;
            ctx->thread_context[tile].decctx = ctx;

            ctx->thread_context[tile].CtbAddrInTS = pps->CtbAddrRStoTS[pps->colBd[tx] + pps->rowBd[ty]*ctbsWidth];


            // init CABAC

            int dataStartIndex;
            if (tile==0) { dataStartIndex=0; }
            else         { dataStartIndex=hdr->entry_point_offset[tile-1]; }

            int dataEnd;
            if (tile==nRows-1) dataEnd = reader.bytes_remaining;
            else               dataEnd = hdr->entry_point_offset[tile];

            init_thread_context(&ctx->thread_context[tile]);

            init_CABAC_decoder(&ctx->thread_context[tile].cabac_decoder,
                               &reader.data[dataStartIndex],
                               dataEnd-dataStartIndex);
          }

        // add tasks

        for (int i=0;i<nTiles;i++) {
          add_task_decode_slice_segment(ctx, i);
        }

        wait_for_completion(ctx->img);
      }
      else {
        if (nRows > MAX_THREAD_CONTEXTS) {
          return DE265_ERROR_MAX_THREAD_CONTEXTS_EXCEEDED;
        }

        assert(ctx->img->tasks_pending == 0);
        increase_pending_tasks(ctx->img, nRows);

        //printf("-------- decode --------\n");


        for (int y=0;y<nRows;y++) {

          // set thread context

          for (int x=0;x<ctbsWidth;x++) {
            ctx->img->ctb_info[x+y*ctbsWidth].thread_context_id = y; // TODO: shouldn't be hardcoded
          }

          ctx->thread_context[y].shdr = hdr;
          ctx->thread_context[y].decctx = ctx;
          ctx->thread_context[y].CtbAddrInTS = pps->CtbAddrRStoTS[0 + y*ctbsWidth];


          // init CABAC

          int dataStartIndex;
          if (y==0) { dataStartIndex=0; }
          else      { dataStartIndex=hdr->entry_point_offset[y-1]; }

          int dataEnd;
          if (y==nRows-1) dataEnd = reader.bytes_remaining;
          else            dataEnd = hdr->entry_point_offset[y];

          init_thread_context(&ctx->thread_context[y]);

          init_CABAC_decoder(&ctx->thread_context[y].cabac_decoder,
                             &reader.data[dataStartIndex],
                             dataEnd-dataStartIndex);
        }

        // add tasks

        for (int y=0;y<nRows;y++) {
          add_task_decode_CTB_row(ctx, y, y==0);
        }

        wait_for_completion(ctx->img);
      }
    }
  }
  else switch (nal_hdr.nal_unit_type) {
    case NAL_UNIT_VPS_NUT:
      {
        logdebug(LogHeaders,"---> read VPS\n");

        video_parameter_set vps;
        err=read_vps(ctx,&reader,&vps);
        if (err != DE265_OK) {
          break;
        }

        if (ctx->param_vps_headers_fd>=0) {
          dump_vps(&vps, ctx->param_vps_headers_fd);
        }

        process_vps(ctx, &vps);
      }
      break;

    case NAL_UNIT_SPS_NUT:
      {
        logdebug(LogHeaders,"----> read SPS\n");

        seq_parameter_set sps;
        init_sps(&sps);

        if ((err=read_sps(ctx, &reader,&sps)) != DE265_OK) {
          break;
        }

        if (ctx->param_sps_headers_fd>=0) {
          dump_sps(&sps, ctx->param_sps_headers_fd);
        }

        process_sps(ctx, &sps);
      }
      break;

    case NAL_UNIT_PPS_NUT:
      {
        logdebug(LogHeaders,"----> read PPS\n");

        pic_parameter_set pps;

        init_pps(&pps);
        bool success = read_pps(&reader,&pps,ctx);

        if (ctx->param_pps_headers_fd>=0) {
          dump_pps(&pps, ctx->param_pps_headers_fd);
        }

        if (success) {
          process_pps(ctx,&pps);
        }
      }
      break;

    case NAL_UNIT_PREFIX_SEI_NUT:
    case NAL_UNIT_SUFFIX_SEI_NUT:
      logdebug(LogHeaders,"----> read SEI\n");

      sei_message sei;

      push_current_picture_to_output_queue(ctx);

      if (read_sei(&reader,&sei, nal_hdr.nal_unit_type==NAL_UNIT_SUFFIX_SEI_NUT, ctx)) {
        dump_sei(&sei, ctx);

        err = process_sei(&sei, ctx);
      }
      break;

    case NAL_UNIT_EOS_NUT:
      ctx->FirstAfterEndOfSequenceNAL = true;
      break;
    }

  return err;
}
Exemple #8
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;
}
Exemple #9
0
static void check_quantizer(int min_q, int max_q,
                            struct WarningList *warning_list) {
  const int lossless = min_q == 0 && max_q == 0;
  if (!lossless && (min_q == max_q || abs(max_q - min_q) < 8))
    add_warning(quantizer_warning_string, warning_list);
}
Exemple #10
0
de265_error read_sps(decoder_context* ctx, 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, 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) {

      return DE265_ERROR_SCALING_LIST_NOT_IMPLEMENTED;
    }
  }

  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);
  if (sps->num_short_term_ref_pic_sets < 0 ||
      sps->num_short_term_ref_pic_sets > 64) {
    add_warning(ctx, DE265_WARNING_NUMBER_OF_SHORT_TERM_REF_PIC_SETS_OUT_OF_RANGE, false);
    return DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE;
  }

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

  // allocate one more for the ref-pic-set that may be sent in the slice header
  // TODO: should use "realloc" and only reallocate if necessary
  free(*ref_pic_sets);
  *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], fh);
  }

  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 0
  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);
#endif

  // --- 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;

  sps->Log2MinPUSize = sps->Log2MinCbSizeY-1;
  sps->PicWidthInMinPUs  = sps->PicWidthInCtbsY  << (sps->Log2CtbSizeY - sps->Log2MinPUSize);
  sps->PicHeightInMinPUs = sps->PicHeightInCtbsY << (sps->Log2CtbSizeY - sps->Log2MinPUSize);

  // 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;
}
Exemple #11
0
bool read_pps(bitreader* br, pic_parameter_set* pps, decoder_context* ctx)
{
  pps->pps_read = false; // incomplete pps

  int uvlc;
  pps->pic_parameter_set_id = uvlc = get_uvlc(br);
  if (uvlc >= DE265_MAX_PPS_SETS ||
      uvlc == UVLC_ERROR) {
    add_warning(ctx, DE265_WARNING_NONEXISTING_PPS_REFERENCED, false);
    return false;
  }

  pps->seq_parameter_set_id = uvlc = get_uvlc(br);
  if (uvlc >= DE265_MAX_PPS_SETS ||
      uvlc == UVLC_ERROR) {
    add_warning(ctx, DE265_WARNING_NONEXISTING_SPS_REFERENCED, false);
    return false;
  }

  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 = uvlc = get_uvlc(br);
  if (uvlc == UVLC_ERROR) {
    add_warning(ctx, DE265_WARNING_PPS_HEADER_INVALID, false);
    return false;
  }
  pps->num_ref_idx_l0_default_active++;

  pps->num_ref_idx_l1_default_active = uvlc = get_uvlc(br);
  if (uvlc == UVLC_ERROR) {
    add_warning(ctx, DE265_WARNING_PPS_HEADER_INVALID, false);
    return false;
  }
  pps->num_ref_idx_l1_default_active++;


  seq_parameter_set* sps = get_sps(ctx, pps->seq_parameter_set_id);
  if (sps==NULL) {
    add_warning(ctx, DE265_WARNING_NONEXISTING_SPS_REFERENCED, false);
    return false;
  }

  if ((pps->pic_init_qp = get_svlc(br)) == UVLC_ERROR) {
    add_warning(ctx, DE265_WARNING_PPS_HEADER_INVALID, false);
    return false;
  }
  pps->pic_init_qp += 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) {
    if ((pps->diff_cu_qp_delta_depth = get_uvlc(br)) == UVLC_ERROR) {
      add_warning(ctx, DE265_WARNING_PPS_HEADER_INVALID, false);
      return false;
    }
  } else {
    pps->diff_cu_qp_delta_depth = 0;
  }

  if ((pps->pic_cb_qp_offset = get_svlc(br)) == UVLC_ERROR) {
    add_warning(ctx, DE265_WARNING_PPS_HEADER_INVALID, false);
    return false;
  }

  if ((pps->pic_cr_qp_offset = get_svlc(br)) == UVLC_ERROR) {
    add_warning(ctx, DE265_WARNING_PPS_HEADER_INVALID, false);
    return false;
  }

  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);
    if (pps->num_tile_columns == UVLC_ERROR ||
	pps->num_tile_columns > DE265_MAX_TILE_COLUMNS) {
      add_warning(ctx, DE265_WARNING_PPS_HEADER_INVALID, false);
      return false;
    }
    pps->num_tile_columns++;

    pps->num_tile_rows = get_uvlc(br);
    if (pps->num_tile_rows == UVLC_ERROR ||
	pps->num_tile_rows > DE265_MAX_TILE_ROWS) {
      add_warning(ctx, DE265_WARNING_PPS_HEADER_INVALID, false);
      return false;
    }
    pps->num_tile_rows++;

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

    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);
          if (pps->colWidth[i] == UVLC_ERROR) {
	    add_warning(ctx, DE265_WARNING_PPS_HEADER_INVALID, false);
	    return false;
	  }
          pps->colWidth[i]++;

          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);
          if (pps->rowHeight[i] == UVLC_ERROR) {
	    add_warning(ctx, DE265_WARNING_PPS_HEADER_INVALID, false);
	    return false;
	  }
          pps->rowHeight[i]++;
          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->TileIdRS) { free(pps->TileIdRS); }
  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->TileIdRS      = (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[i] ; x<pps->colBd[i+1] ; x++) {
            pps->TileId  [ pps->CtbAddrRStoTS[y*sps->PicWidthInCtbsY + x] ] = tIdx;
            pps->TileIdRS[ y*sps->PicWidthInCtbsY + x ] = tIdx;

            //logtrace(LogHeaders,"tileID[%d,%d] = %d\n",x,y,pps->TileIdRS[ y*sps->PicWidthInCtbsY + x ]);
          }

        tIdx++;
      }

  logtrace(LogHeaders,"Tile IDs RS:\n");
  for (int y=0;y<sps->PicHeightInCtbsY;y++) {
    for (int x=0;x<sps->PicWidthInCtbsY;x++) {
      logtrace(LogHeaders,"%2d ",pps->TileIdRS[y*sps->PicWidthInCtbsY+x]);
    }
    logtrace(LogHeaders,"\n");
  }

  // 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);
      if (pps->beta_offset == UVLC_ERROR) {
	add_warning(ctx, DE265_WARNING_PPS_HEADER_INVALID, false);
	return false;
      }
      pps->beta_offset *= 2;

      pps->tc_offset   = get_svlc(br);
      if (pps->tc_offset == UVLC_ERROR) {
	add_warning(ctx, DE265_WARNING_PPS_HEADER_INVALID, false);
	return false;
      }
      pps->tc_offset   *= 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);
  if (pps->log2_parallel_merge_level == UVLC_ERROR) {
    add_warning(ctx, DE265_WARNING_PPS_HEADER_INVALID, false);
    return false;
  }
  pps->log2_parallel_merge_level += 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;

  return true;
}