Example #1
0
// (8.6.1)
void decode_quantization_parameters(decoder_context* ctx,
                                    thread_context* tctx, int xC,int yC)
{
  logtrace(LogTransform,"decode_quantization_parameters(int xC,int yC)=(%d,%d)\n", xC,yC);

  pic_parameter_set* pps = ctx->current_pps;
  seq_parameter_set* sps = ctx->current_sps;
  slice_segment_header* shdr = tctx->shdr;

  // top left pixel position of current quantization group
  int xQG = xC - (xC & ((1<<pps->Log2MinCuQpDeltaSize)-1));
  int yQG = yC - (yC & ((1<<pps->Log2MinCuQpDeltaSize)-1));


  // we only have to set QP in the first call in a quantization-group

  /* TODO: check why this does not work with HoneyBee stream

  if (xQG == tctx->currentQG_x &&
      yQG == tctx->currentQG_y)
    {
      return;
    }
  */

  // if first QG in CU, remember last QPY of last CU previous QG

  if (xQG != tctx->currentQG_x ||
      yQG != tctx->currentQG_y)
    {
      tctx->lastQPYinPreviousQG = tctx->currentQPY;
      tctx->currentQG_x = xQG;
      tctx->currentQG_y = yQG;
    }

  int qPY_PRED;
  bool firstQGInSlice;
  bool firstQGInTile = false; // TODO
  bool firstInCTBRow = (xQG==0); // TODO
  
  int first_ctb_in_slice_RS = tctx->shdr->slice_segment_address;

  int SliceStartX = (first_ctb_in_slice_RS % sps->PicWidthInCtbsY) * sps->CtbSizeY;
  int SliceStartY = (first_ctb_in_slice_RS / sps->PicWidthInCtbsY) * sps->CtbSizeY;

  firstQGInSlice = (SliceStartX == xQG && SliceStartY == yQG);

  if (firstQGInSlice || firstQGInTile ||
      (firstInCTBRow && pps->entropy_coding_sync_enabled_flag)) {
    qPY_PRED = tctx->shdr->SliceQPY;
  }
  else {
    qPY_PRED = tctx->lastQPYinPreviousQG;
  }


  int qPYA,qPYB;

  if (available_zscan(ctx->img,xQG,yQG, xQG-1,yQG)) {
    int xTmp = (xQG-1) >> sps->Log2MinTrafoSize;
    int yTmp = (yQG  ) >> sps->Log2MinTrafoSize;
    int minTbAddrA = pps->MinTbAddrZS[xTmp + yTmp*sps->PicWidthInTbsY];
    int ctbAddrA = (minTbAddrA>>2)*(sps->Log2CtbSizeY-sps->Log2MinTrafoSize);
    if (ctbAddrA == tctx->CtbAddrInTS) {
      qPYA = get_QPY(ctx->img,sps,xQG-1,yQG);
    }
    else {
      qPYA = qPY_PRED;
    }
  }
Example #2
0
// (8.6.1)
void decode_quantization_parameters(decoder_context* ctx,
                                    thread_context* tctx, int xC,int yC)
{
  pic_parameter_set* pps = ctx->current_pps;
  seq_parameter_set* sps = ctx->current_sps;
  slice_segment_header* shdr = tctx->shdr;

  // top left pixel position of current quantization group
  int xQG = xC - (xC & ((1<<pps->Log2MinCuQpDeltaSize)-1));
  int yQG = yC - (yC & ((1<<pps->Log2MinCuQpDeltaSize)-1));

  // if first QG in CU, remember last QPY of last CU previous QG

  if ((xQG & ((1<<sps->Log2CtbSizeY)-1)) == 0 &&
      (yQG & ((1<<sps->Log2CtbSizeY)-1)) == 0) {
    tctx->lastQPYinPreviousQG = tctx->currentQPY;
  }

  int qPY_PRED;
  bool firstQGInSlice;
  bool firstQGInTile = false; // TODO
  bool firstInCTBRow = (xC==0); // TODO
  
  int first_ctb_in_slice_RS = tctx->shdr->slice_segment_address;

  int SliceStartX = (first_ctb_in_slice_RS % sps->PicWidthInCtbsY) * sps->CtbSizeY;
  int SliceStartY = (first_ctb_in_slice_RS / sps->PicWidthInCtbsY) * sps->CtbSizeY;

  firstQGInSlice = (SliceStartX == xQG && SliceStartY == yQG);

  if (firstQGInSlice || firstQGInTile ||
      (firstInCTBRow && pps->entropy_coding_sync_enabled_flag)) {
    qPY_PRED = tctx->shdr->SliceQPY;
  }
  else {
    qPY_PRED = tctx->lastQPYinPreviousQG;
  }


  int qPYA,qPYB;

  if (available_zscan(ctx,xQG,yQG, xQG-1,yQG)) {
    // unused: int xTmp = (xQG-1) >> sps->Log2MinTrafoSize;
    // unused: int yTmp = (yQG  ) >> sps->Log2MinTrafoSize;
    // unused: int minTbAddrA = pps->MinTbAddrZS[xTmp + yTmp*sps->PicWidthInTbsY];
    // unused: int ctbAddrA = (minTbAddrA>>2)*(sps->Log2CtbSizeY-sps->Log2MinTrafoSize);

    qPYA = get_QPY(ctx,xQG-1,yQG);
  }
  else {
    qPYA = qPY_PRED;
  }

  if (available_zscan(ctx,xQG,yQG, xQG,yQG-1)) {
    // unused: int xTmp = (xQG  ) >> sps->Log2MinTrafoSize;
    // unused: int yTmp = (yQG-1) >> sps->Log2MinTrafoSize;
    // unused: int minTbAddrA = pps->MinTbAddrZS[xTmp + yTmp*sps->PicWidthInTbsY];
    // unused: int ctbAddrA = (minTbAddrA>>2)*(sps->Log2CtbSizeY-sps->Log2MinTrafoSize);

    qPYB = get_QPY(ctx,xQG,yQG-1);
  }
  else {
    qPYB = qPY_PRED;
  }

  qPY_PRED = (qPYA + qPYB + 1)>>1;

  int QPY = ((qPY_PRED + shdr->CuQpDelta + 52+2*sps->QpBdOffset_Y) %
             (52 + sps->QpBdOffset_Y)) - sps->QpBdOffset_Y;

  tctx->qPYPrime = QPY + sps->QpBdOffset_Y;

  int qPiCb = Clip3(-sps->QpBdOffset_C,57, QPY+pps->pic_cb_qp_offset + shdr->slice_cb_qp_offset);
  int qPiCr = Clip3(-sps->QpBdOffset_C,57, QPY+pps->pic_cr_qp_offset + shdr->slice_cr_qp_offset);

  logtrace(LogTransform,"qPiCb:%d (%d %d), qPiCr:%d (%d %d)\n",
           qPiCb, pps->pic_cb_qp_offset, shdr->slice_cb_qp_offset,
           qPiCr, pps->pic_cr_qp_offset, shdr->slice_cr_qp_offset);

  int qPCb = table8_22(qPiCb);
  int qPCr = table8_22(qPiCr);

  tctx->qPCbPrime = qPCb + sps->QpBdOffset_C;
  tctx->qPCrPrime = qPCr + sps->QpBdOffset_C;

  set_QPY(ctx,xQG,yQG, QPY);
  tctx->currentQPY = QPY;

  logtrace(LogTransform,"qPY(%d,%d)= %d\n",xC,yC,QPY);
}