void transform_dst(int16_t* in, int32_t* out, int shift) { int rnd = 1<<(shift-1); logtrace(LogTransform,""); for (int i=0; i<4; i++) { logtrace(LogTransform,"%d ",in[i]); } logtrace(LogTransform,"* -> "); for (int i=0; i<4; i++) { int sum=0; for (int j=0; j<4; j++) { sum += mat_8_357[j][i] * in[j]; } out[i] = Clip3(-32768,32767, (sum+rnd)>>shift); } for (int y=0; y<4; y++) { logtrace(LogTransform,"*%d ",out[y]); } logtrace(LogTransform,"*\n"); }
void transform_dct(int16_t* in, int32_t* out, int nT, int shift) { int rnd = 1<<(shift-1); logtrace(LogTransform,"DCT: "); for (int i=0; i<nT; i++) { logtrace(LogTransform,"*%d ",in[i]); } logtrace(LogTransform,"* -> "); int fact = (1<<(5-Log2(nT))); for (int i=0; i<nT; i++) { int sum=0; for (int j=0; j<nT; j++) { sum += mat_dct[fact*j][i] * in[j]; } out[i] = Clip3(-32768,32767, (sum+rnd)>>shift); } for (int y=0; y<nT; y++) { logtrace(LogTransform,"*%d ",out[y]); } logtrace(LogTransform,"*\n"); }
int main(){ printf("Hello, base!"); daemoninit(NOCHDIR, CLOSEFD); if (logopen("daemon.log") < 0) perror("main: logopen failed!"); sleep(3); logtrace("%s: enter!", timestamp()); timepoint start; timepin(&start); sleep(3); timepoint currt; timepin(&currt); timerange interval = timeint(start, currt); logtrace("time elapse: %.4f seconds!", timeint(start, currt)); logtrace("time elapse: %.4f seconds!", interval); logtrace("%s: leave!", timestamp()); logclose(); return 0; }
// Create some logs void create_logs() { logtrace(1 << " logtrace"); logtraceEx(1 << " logtraceEx", std::make_shared<LogValExtraExample>("logtraceEx_", 100)); logdebug(2 << " logdebug"); logdebugEx(2 << " logdebugEx", std::make_shared<LogValExtraExample>("logdebugEx_", 200)); loginfo(3 << " loginfo"); loginfoEx(3 <<" loginfoEx", std::make_shared<LogValExtraExample>("loginfoEx_", 300)); logwarn(4 << " logwarn"); logwarnEx(4 << " logwarnEx", std::make_shared<LogValExtraExample>("logwarnEx_", 400)); logerror(5 << " logerror"); logerrorEx(5 << " logerrorEx", std::make_shared<LogValExtraExample>("logerrorEx_", 500)); logfatal(6 << " logfatal"); logfatalEx(6 << " logfatalEx", std::make_shared<LogValExtraExample>("logfatalEx_", 600)); // mylevel make_mylevel(); logging(makelevel(MyLevel1), "7 test MyLevel1", log_tools::get_pid(), __func__, __FILE__, __LINE__); logging(makelevel(MyLevel2), "7 test MyLevel2", log_tools::get_pid(), __func__, __FILE__, __LINE__, std::make_shared<LogValExtraExample>("test MyLevel2", 700)); }
void transform_coefficients(decoder_context* ctx, slice_segment_header* shdr, int16_t* coeff, int coeffStride, int nT, int trType, int postShift) { logtrace(LogTransform,"transform --- trType: %d nT: %d\n",trType,nT); if (trType==1) { int16_t g[4][4]; int16_t col[4]; int32_t out[4]; for (int c=0; c<4; c++) { for (int y=0; y<4; y++) { col[y] = coeff[c+y*coeffStride]; } transform_dst(col,out, 7); for (int y=0; y<4; y++) { g[y][c] = out[y]; } } for (int y=0; y<4; y++) { transform_dst(&g[y][0], out,postShift); for (int x=0; x<4; x++) { coeff[x+y*coeffStride] = out[x]; } } } else { int16_t g[nT][nT]; int16_t col[nT]; int32_t out[nT]; for (int c=0; c<nT; c++) { for (int y=0; y<nT; y++) { col[y] = coeff[c+y*coeffStride]; } transform_dct(col,out, nT, 7); for (int y=0; y<nT; y++) { g[y][c] = out[y]; } } for (int y=0; y<nT; y++) { transform_dct(&g[y][0], out,nT,postShift); for (int x=0; x<nT; x++) { coeff[x+y*coeffStride] = out[x]; } } } }
BOOL fReInsertBPIf(PTARGETINFO pstTargetInfo, PREVBPINFO *pstBpInfo) { ASSERT(pstTargetInfo); ASSERT(pstBpInfo); ASSERT(pstBpInfo->dwThreadId != 0); if(pstTargetInfo->iPrevDebugState == DSTATE_WAITFOR_DBGBREAK) { logtrace(pstLogger, L"%s(): Not reinserting because prev state was DSTATE_WAITFOR_DBGBREAK", __FUNCTIONW__); return TRUE; } if(pstBpInfo->stBpInfo.iBpType & BPTYPE_USERMULTIHIT || pstBpInfo->stBpInfo.iBpType & BPTYPE_DEBUGGERMULTIHIT) { logtrace(pstLogger, L"%s(): Reinserting multi-hit BP", __FUNCTIONW__); return fBpRemove(pstTargetInfo->pListBreakpoint, &pstBpInfo->stBpInfo, pstTargetInfo); } return TRUE; }
void dump_short_term_ref_pic_set(ref_pic_set* set) { logtrace(LogHeaders,"NumDeltaPocs: %d [-:%d +:%d]\n", set->NumDeltaPocs, set->NumNegativePics, set->NumPositivePics); logtrace(LogHeaders,"DeltaPocS0:"); for (int i=0;i<set->NumNegativePics;i++) { if (i) { logtrace(LogHeaders,","); } logtrace(LogHeaders," %d/%d",set->DeltaPocS0[i],set->UsedByCurrPicS0[i]); } logtrace(LogHeaders,"\n"); logtrace(LogHeaders,"DeltaPocS1:"); for (int i=0;i<set->NumPositivePics;i++) { if (i) { logtrace(LogHeaders,","); } logtrace(LogHeaders," %d/%d",set->DeltaPocS1[i],set->UsedByCurrPicS1[i]); } logtrace(LogHeaders,"\n"); }
int main(){ //logopen("loggertest.log"); logdup(1); logtrace("%s", "Hello, LOG!!!!Hello, LOG!!!!Hello, LOG!!!!Hello, LOG!!!!Hello, LOG!!!!Hello, LOG!!!!Hello, LOG!!!!Hello, LOG!!!!Hello, LOG!!!!"); logerror("%s", "Hello, LOG!!!!"); logstats("%s", "Hello, LOG!!!!"); LOG("%s", "How about this macro?"); logclose(); return 0; }
void transform_coefficients(decoder_context* ctx, slice_segment_header* shdr, int16_t* coeff, int coeffStride, int nT, int trType, int postShift, uint8_t* dst, int dstStride) { logtrace(LogTransform,"transform --- trType: %d nT: %d\n",trType,nT); if (trType==1) { ctx->lowlevel.transform_4x4_luma_add_8(dst, coeff, dstStride); nDST_4x4++; } else { /**/ if (nT==4) { ctx->lowlevel.transform_4x4_add_8(dst,coeff,dstStride); nDCT_4x4++; } else if (nT==8) { ctx->lowlevel.transform_8x8_add_8(dst,coeff,dstStride); nDCT_8x8++; } else if (nT==16) { ctx->lowlevel.transform_16x16_add_8(dst,coeff,dstStride); nDCT_16x16++; } else { ctx->lowlevel.transform_32x32_add_8(dst,coeff,dstStride); nDCT_32x32++; } } }
// 8.7.2.1 for both EDGE_HOR and EDGE_VER at the same time void markTransformBlockBoundary(decoder_context* ctx, int x0,int y0, int log2TrafoSize,int trafoDepth, int filterLeftCbEdge, int filterTopCbEdge) { logtrace(LogDeblock,"markTransformBlockBoundary(%d,%d, %d,%d, %d,%d)\n",x0,y0, log2TrafoSize,trafoDepth, filterLeftCbEdge,filterTopCbEdge); if (get_split_transform_flag(ctx,x0,y0,trafoDepth)) { int x1 = x0 + ((1<<log2TrafoSize)>>1); int y1 = y0 + ((1<<log2TrafoSize)>>1); markTransformBlockBoundary(ctx,x0,y0,log2TrafoSize-1,trafoDepth+1, filterLeftCbEdge, filterTopCbEdge); markTransformBlockBoundary(ctx,x1,y0,log2TrafoSize-1,trafoDepth+1, DEBLOCK_FLAG_VERTI, filterTopCbEdge); markTransformBlockBoundary(ctx,x0,y1,log2TrafoSize-1,trafoDepth+1, filterLeftCbEdge, DEBLOCK_FLAG_HORIZ); markTransformBlockBoundary(ctx,x1,y1,log2TrafoSize-1,trafoDepth+1, DEBLOCK_FLAG_VERTI, DEBLOCK_FLAG_HORIZ); } else { // VER for (int k=0;k<(1<<log2TrafoSize);k+=4) {
// (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; } }
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; }
static void transform_dct_add_8(uint8_t *dst, ptrdiff_t stride, int nT, int16_t *coeffs) { int postShift = 20-8; // 8 bit int rnd1 = 1<<(7-1); int rnd2 = 1<<(postShift-1); int fact = (1<<(5-Log2(nT))); int16_t g[32*32]; // actually, only [nT*nT] used //int16_t col[32]; // actually, only [nT] used //int32_t out[32]; // actually, only [nT] used for (int c=0;c<nT;c++) { logtrace(LogTransform,"DCT-V: "); for (int i=0;i<nT;i++) { logtrace(LogTransform,"*%d ",coeffs[c+i*nT]); } logtrace(LogTransform,"* -> "); // find last non-zero coefficient to reduce computations carried out in DCT int lastCol = nT-1; for (;lastCol>=0;lastCol--) { if (coeffs[c+lastCol*nT]) { break; } } for (int i=0;i<nT;i++) { int sum=0; for (int j=0;j<=lastCol /*nT*/;j++) { sum += mat_dct[fact*j][i] * coeffs[c+j*nT]; } g[c+i*nT] = Clip3(-32768,32767, (sum+rnd1)>>7); logtrace(LogTransform,"*%d ",g[c+i*nT]); } logtrace(LogTransform,"*\n"); } for (int y=0;y<nT;y++) { logtrace(LogTransform,"DCT-H: "); for (int i=0;i<nT;i++) { logtrace(LogTransform,"*%d ",g[i+y*nT]); } logtrace(LogTransform,"* -> "); // find last non-zero coefficient to reduce computations carried out in DCT int lastCol = nT-1; for (;lastCol>=0;lastCol--) { if (g[y*nT+lastCol]) { break; } } for (int i=0;i<nT;i++) { int sum=0; for (int j=0;j<=lastCol /*nT*/;j++) { sum += mat_dct[fact*j][i] * g[y*nT+j]; } //int out = Clip3(-32768,32767, (sum+rnd2)>>postShift); int out = (sum+rnd2)>>postShift; dst[y*stride+i] = Clip1_8bit(dst[y*stride+i] + out); logtrace(LogTransform,"*%d ",out); } logtrace(LogTransform,"*\n"); } }
// (8.6.1) void decode_quantization_parameters(decoder_context* ctx, thread_context* tctx, int xC,int yC, int xCUBase, int yCUBase) { logtrace(LogTransform,">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> decode_quantization_parameters(int xC,int yC)=(%d,%d)\n", xC,yC); if (/*ctx->img->PicOrderCntVal==3 &&*/ xC==168 && yC==128) { //raise(SIGINT); } 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 = xCUBase - (xCUBase & ((1<<pps->Log2MinCuQpDeltaSize)-1)); int yQG = yCUBase - (yCUBase & ((1<<pps->Log2MinCuQpDeltaSize)-1)); logtrace(LogTransform,"QG: %d,%d\n",xQG,yQG); // 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; bool firstInCTBRow = (xQG==0); // TODO: Tiles int first_ctb_in_slice_RS = tctx->shdr->SliceAddrRS; // 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 (pps->tiles_enabled_flag) { if ((xQG & ((1 << sps->Log2CtbSizeY)-1)) == 0 && (yQG & ((1 << sps->Log2CtbSizeY)-1)) == 0) { int ctbX = xQG >> sps->Log2CtbSizeY; int ctbY = yQG >> sps->Log2CtbSizeY; firstQGInTile = is_tile_start_CTB(pps,ctbX,ctbY); } }
// (8.6.2) and (8.6.3) void scale_coefficients(decoder_context* ctx, slice_segment_header* shdr, int xT,int yT, int nT, int cIdx) { seq_parameter_set* sps = ctx->current_sps; int qP; switch (cIdx) { case 0: qP = shdr->qPYPrime; break; case 1: qP = shdr->qPCbPrime; break; case 2: qP = shdr->qPCrPrime; break; default: qP = 0; assert(0); break; // should never happen } logtrace(LogTransform,"qP: %d\n",qP); int16_t* coeff; int coeffStride; get_coeff_plane(ctx,cIdx, &coeff,&coeffStride); if (shdr->cu_transquant_bypass_flag) { assert(false); // TODO } else { // (8.6.3) int bdShift = (cIdx==0 ? sps->BitDepth_Y : sps->BitDepth_C) + Log2(nT) - 5; logtrace(LogTransform,"coefficients IN:\n"); for (int y=0; y<nT; y++) { logtrace(LogTransform," "); for (int x=0; x<nT; x++) { logtrace(LogTransform,"*%3d ", coeff[x+xT+(y+yT)*coeffStride]); } logtrace(LogTransform,"*\n"); } if (sps->scaling_list_enable_flag==0) { for (int y=0; y<nT; y++) for (int x=0; x<nT; x++) { coeff[xT+x+(y+yT)*coeffStride] = Clip3(-32768,32767, ( (coeff[x+xT+(y+yT)*coeffStride] * 16 * levelScale[qP%6] << (qP/6)) + (1<<(bdShift-1)) ) >> bdShift); } } else { assert(false); // TODO } logtrace(LogTransform,"coefficients OUT:\n"); for (int y=0; y<nT; y++) { logtrace(LogTransform," "); for (int x=0; x<nT; x++) { logtrace(LogTransform,"*%3d ", coeff[x+xT+(y+yT)*coeffStride]); } logtrace(LogTransform,"*\n"); } int bdShift2 = (cIdx==0) ? 20-sps->BitDepth_Y : 20-sps->BitDepth_C; if (get_transform_skip_flag(ctx,xT,yT,cIdx)) { for (int y=0; y<nT; y++) for (int x=0; x<nT; x++) { int16_t c = coeff[x+xT+(y+yT)*coeffStride] << 7; coeff[x+xT+(y+yT)*coeffStride] = (c+(1<<(bdShift2-1)))>>bdShift2; } } else {
static void transform_dct_add_8(uint8_t *dst, ptrdiff_t stride, int nT, int16_t *coeffs) { int postShift = 20-8; // 8 bit int rnd1 = 1<<(7-1); int rnd2 = 1<<(postShift-1); int fact = (1<<(5-Log2(nT))); int16_t g[32*32]; // actually, only [nT*nT] used // TODO: valgrind reports that dst[] contains uninitialized data. // Probably from intra-prediction. /* for (int i=0;i<nT*nT;i++) { printf("%d\n",coeffs[i]); } for (int y=0;y<nT;y++) { for (int i=0;i<nT;i++) { printf("%d ",dst[y*stride+i]); } } printf("\n"); */ for (int c=0;c<nT;c++) { logtrace(LogTransform,"DCT-V: "); for (int i=0;i<nT;i++) { logtrace(LogTransform,"*%d ",coeffs[c+i*nT]); } logtrace(LogTransform,"* -> "); // find last non-zero coefficient to reduce computations carried out in DCT int lastCol = nT-1; for (;lastCol>=0;lastCol--) { if (coeffs[c+lastCol*nT]) { break; } } for (int i=0;i<nT;i++) { int sum=0; for (int j=0;j<=lastCol /*nT*/;j++) { sum += mat_dct[fact*j][i] * coeffs[c+j*nT]; } g[c+i*nT] = Clip3(-32768,32767, (sum+rnd1)>>7); logtrace(LogTransform,"*%d ",g[c+i*nT]); } logtrace(LogTransform,"*\n"); } for (int y=0;y<nT;y++) { logtrace(LogTransform,"DCT-H: "); for (int i=0;i<nT;i++) { logtrace(LogTransform,"*%d ",g[i+y*nT]); } logtrace(LogTransform,"* -> "); // find last non-zero coefficient to reduce computations carried out in DCT int lastCol = nT-1; for (;lastCol>=0;lastCol--) { if (g[y*nT+lastCol]) { break; } } for (int i=0;i<nT;i++) { int sum=0; for (int j=0;j<=lastCol /*nT*/;j++) { sum += mat_dct[fact*j][i] * g[y*nT+j]; } //int out = Clip3(-32768,32767, (sum+rnd2)>>postShift); int out = (sum+rnd2)>>postShift; //printf("%d\n",Clip1_8bit(dst[y*stride+i])); //printf("%d\n",Clip1_8bit(out)); dst[y*stride+i] = Clip1_8bit(dst[y*stride+i] + out); logtrace(LogTransform,"*%d ",out); } logtrace(LogTransform,"*\n"); } }
void transform_4x4_luma_add_8_fallback(uint8_t *dst, int16_t *coeffs, ptrdiff_t stride) { int16_t g[4][4]; int postShift = 20-8; // 8 bit int rndV = 1<<(7-1); int rndH = 1<<(postShift-1); // --- V --- for (int c=0;c<4;c++) { logtrace(LogTransform,"DST-V: "); for (int r=0;r<4;r++) { logtrace(LogTransform,"%d ",coeffs[c+r*4]); } logtrace(LogTransform,"* -> "); for (int i=0;i<4;i++) { int sum=0; for (int j=0;j<4;j++) { sum += mat_8_357[j][i] * coeffs[c+j*4]; } g[i][c] = Clip3(-32768,32767, (sum+rndV)>>7); } for (int y=0;y<4;y++) { logtrace(LogTransform,"*%d ",g[y][c]); } logtrace(LogTransform,"*\n"); } // --- H --- for (int y=0;y<4;y++) { logtrace(LogTransform,"DST-H: "); for (int c=0;c<4;c++) { logtrace(LogTransform,"%d ",g[y][c]); } logtrace(LogTransform,"* -> "); for (int i=0;i<4;i++) { int sum=0; for (int j=0;j<4;j++) { sum += mat_8_357[j][i] * g[y][j]; } int out = Clip3(-32768,32767, (sum+rndH)>>postShift); dst[y*stride+i] = Clip1_8bit(dst[y*stride+i] + out); logtrace(LogTransform,"*%d ",out); } logtrace(LogTransform,"*\n"); } }
// (8.6.2) and (8.6.3) void scale_coefficients(decoder_context* ctx, thread_context* tctx, int xT,int yT, // position of TU in frame (chroma adapted) int x0,int y0, // position of CU in frame (chroma adapted) int nT, int cIdx) { seq_parameter_set* sps = ctx->current_sps; slice_segment_header* shdr = tctx->shdr; int qP; switch (cIdx) { case 0: qP = tctx->qPYPrime; break; case 1: qP = tctx->qPCbPrime; break; case 2: qP = tctx->qPCrPrime; break; default: qP = 0; assert(0); break; // should never happen } logtrace(LogTransform,"qP: %d\n",qP); int16_t* coeff; int coeffStride; coeff = tctx->coeffBuf; coeffStride = nT; uint8_t* pred; int stride; get_image_plane(ctx,cIdx,&pred,&stride); pred += xT + yT*stride; if (shdr->cu_transquant_bypass_flag) { assert(false); // TODO } else { // (8.6.3) int bdShift = (cIdx==0 ? sps->BitDepth_Y : sps->BitDepth_C) + Log2(nT) - 5; logtrace(LogTransform,"bdShift=%d\n",bdShift); if (sps->scaling_list_enable_flag==0) { for (int i=0;i<tctx->nCoeff[cIdx];i++) { int currCoeff = tctx->coeffList[cIdx][i]; const int m_x_y = 16; currCoeff = Clip3(-32768,32767, ( (currCoeff * m_x_y * levelScale[qP%6] << (qP/6)) + (1<<(bdShift-1)) ) >> bdShift); tctx->coeffBuf[ tctx->coeffPos[cIdx][i] ] = currCoeff; } } else { assert(false); // TODO } logtrace(LogTransform,"coefficients OUT:\n"); for (int y=0;y<nT;y++) { logtrace(LogTransform," "); for (int x=0;x<nT;x++) { logtrace(LogTransform,"*%3d ", coeff[x+y*coeffStride]); } logtrace(LogTransform,"*\n"); } int bdShift2 = (cIdx==0) ? 20-sps->BitDepth_Y : 20-sps->BitDepth_C; logtrace(LogTransform,"bdShift2=%d\n",bdShift2); logtrace(LogSlice,"get_transform_skip_flag(%d,%d, cIdx=%d)=%d\n",xT,yT,cIdx, get_transform_skip_flag(ctx,xT,yT,cIdx)); if (get_transform_skip_flag(ctx,xT,yT,cIdx)) { // NOTE: could add shortcut nT==4 && ... ctx->lowlevel.transform_skip_8(pred, coeff, stride); nSkip_4x4++; } else { int trType; if (nT==4 && cIdx==0 && get_pred_mode(ctx,xT,yT)==MODE_INTRA) { trType=1; } else { trType=0; } transform_coefficients(ctx,shdr, coeff, coeffStride, nT, trType, bdShift2, pred, stride); } }
int main(int argc, char *argv[]) { vec_t v; //int *pk; int k; logopen("l_dpq.log","w"); v=vecnew(int); logcheck(veccount(v) == 0); vecset(int,v,0,37); vecset(int,v,1,5); vecset(int,v,2,79); //logtable(v); vecsort(v,intcmp); logcheck(vecsorted(v)); //logtable(v); vecset(int,v,0,3); vecset(int,v,1,57); vecset(int,v,2,79); //logtable(v); vecsort(v,intcmp); logcheck(vecsorted(v)); //logtable(v); logtrace("random vector (small)"); srand(time(0)); for (k=0;k<=18;k++) { vecset(int,v,k,((rand() & 0xF) <<2)+k); } logtable(v); logclock { vecsort(v); } logcheck(vecsorted(v)); logtable(v); logtrace("random vector (large)"); #define N 1000 for (k=0;k<=N;k++) { vecset(int,v,k,((rand() & 0xF) <<24)+k); } logtrace("done (%d on %d)",veccount(v), vecmax(v)); //logtable(v); logclock { vecsort(v); } //logtable(v); logtrace("sorted vector"); for (k=0;k<=N;k++) { vecset(int,v,k,10000000+k); } //logtable(v); logtrace("done"); logclock { vecsort(v); } //logtable(v); vecfree(v); logclose(); exit(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); }
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]); }
/* 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; }