/** ------------------------------------------------------------------------------------------------------------------------------------------------ @brief: Initialization of Rate Control Based on SBAC Coding Tool @author: Jinwuk Seok 2015 5 11 ------------------------------------------------------------------------------------------------------------------------------------------------ */ void TEncTile::ETRI_InitRateControlSBACRD(TComDataCU*& pcCU) { if ( em_pcCfg->getUseRateCtrl() ) { Int estQP = em_pcSlice->getSliceQp(); Double estLambda = -1.0; Double bpp = -1.0; if ( ( em_pcPic->getSlice( 0 )->getSliceType() == I_SLICE && em_pcCfg->getForceIntraQP() ) || !em_pcCfg->getLCULevelRC() ) { estQP = em_pcSlice->getSliceQp(); } else { bpp = em_pcRateCtrl->getRCPic()->getLCUTargetBpp(em_pcSlice->getSliceType()); if ( em_pcPic->getSlice( 0 )->getSliceType() == I_SLICE) { estLambda = em_pcRateCtrl->getRCPic()->getLCUEstLambdaAndQP(bpp, em_pcSlice->getSliceQp(), &estQP); } else { estLambda = em_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp ); estQP = em_pcRateCtrl->getRCPic()->getLCUEstQP ( estLambda, em_pcSlice->getSliceQp() ); } estQP = Clip3( -em_pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, estQP ); em_pcTileRdCost->setLambda(estLambda); #if RDOQ_CHROMA_LAMBDA // set lambda for RDOQ Double weight=em_pcTileRdCost->getChromaWeight(); const Double lambdaArray[3] = { estLambda, (estLambda / weight), (estLambda / weight) }; em_pcTileTrQuant->setLambdas( lambdaArray ); #else em_pcTileTrQuant->setLambda( estLambda ); #endif } em_pcRateCtrl->setRCQP( estQP ); #if ADAPTIVE_QP_SELECTION pcCU->getSlice()->setSliceQpBase( estQP ); #endif } }
// (8.5.12) // luma: true if process invoked for luma residuals // QPy_prev: the luma quantization parameter for the // previously transformed macroblock. At the start // of each slice, it is initialized to SliceQPY // derived in Equation 7-29 void scaleAndTransform4x4Residual(int c[4][4], int r[4][4], bool luma, int *QPy_prev) { int qP, QPy, QP_y, QPc, QP_c; const int bitDepth = 8; // Standard: bitDepth = BitDepthY or BitDepthC depending // on whether this process is invoked for luma or chroma // residuals. In the baseline profile, the value of both // of these is always equal to 8. const bool sMbFlag = false; // Standard: sMbFlag is true when mb_type is equal to // SI or SP. This is never the case in baseline since // only I and P slices are allowed. // Standard: because sMbFlag is always false in baseline, qP is never // equal to QSy or QSc if (luma) { int QpBdOffsetY = 0; // Standard: = 6 * bit_depth_luma_minus8; bit_depth_luma_minus_8 == 0 in baseline QPy = ((*QPy_prev + mb_qp_delta + 52 + 2*QpBdOffsetY) % (52 + QpBdOffsetY)) - QpBdOffsetY; *QPy_prev = QPy; // TODO: provjeri qpy_prev int QP_y = QPy + QpBdOffsetY; qP = QP_y; } else { int QpBdOffsetC = 0; // Standard: = 6 * bit_depth_chroma_minus8; bit_depth_chroma_minus_8 == 0 in baseline int qPoffset = chroma_qp_index_offset; // Standard: qPoffset = second_chroma_qp_index_offset, // second_chroma_qp_index_offset == chroma_qp_index_offset when not // present. It is not present in baseline. int qPi = Clip3(-QpBdOffsetC, 51, QPy + qPoffset); QPc = qPiToQPc[qPi]; QP_c = QPc + QpBdOffsetC; qP = QP_c; } // TransformBypassModeFlag == 0 in baseline inverseResidual(bitDepth, qP, c, r, luma); }
int main( int argc, char *argv[] ) { MTC265_t h; UInt8 *pucOutBuf0 = (UInt8 *)MALLOC(MAX_OUTBUF_SIZE); UInt8 *pucOutBuf1 = (UInt8 *)MALLOC(MAX_OUTBUF_SIZE); assert( pucOutBuf0 != NULL ); assert( pucOutBuf1 != NULL ); int i; char *inFile = NULL; char *outFile = NULL; UInt nWidth = 352; UInt nHeight = 288; UInt nFrames = 1; Int iQP = 32; UInt bLMChroma= FALSE; bool g_bSeqFirst; UInt GOPSize = 1; Int IntraPeriod = 1; UInt FrameRate = 30; bool g_enableLoopFilter = FALSE; bool g_enableWriteReconFile = FALSE; //for rate control bool g_enableRateCtrl = FALSE; UInt TargetBitrate = 1000; fprintf( stdout, "\n" ); fprintf( stdout, "MTC265 Version [%s] ", MTC265_VERSION ); fprintf( stdout, "Built on [%s]", __DATE__ ); fprintf( stdout, MTC265_ONOS ); fprintf( stdout, MTC265_BITS ); fprintf( stdout, MTC265_COMPILEDBY ); fprintf( stdout, "\n\n" ); if ( argc < 2 ) { fprintf( stderr, "Usage:\n\t%s -i inYuvFile [-o hevcBin] [-w width] [-h height] [-f frames] [-q QP] [-lm] [-g GOPSize] [-ip IntraPeriod] [-lp][-wr][-fps FrameRate] [-rc] [-tbr TargetBitrate]\n", argv[0] ); return 0; } for( i=1; i<argc; i++ ) { if ( !strcmp(argv[i], "-i") ) { inFile = argv[++i]; } else if ( !strcmp(argv[i], "-o") ) { outFile = argv[++i]; } else if ( !strcmp(argv[i], "-w") ) { nWidth = atoi(argv[++i]); } else if ( !strcmp(argv[i], "-h") ) { nHeight = atoi(argv[++i]); } else if ( !strcmp(argv[i], "-f") ) { nFrames = atoi(argv[++i]); } else if ( !strcmp(argv[i], "-q") ) { iQP = atoi(argv[++i]); } else if ( !strcmp(argv[i], "-lm") ) { bLMChroma = TRUE; } else if ( !strcmp(argv[i], "-g") ) { GOPSize = atoi(argv[++i]); } else if ( !strcmp(argv[i], "-ip") ) { IntraPeriod = atoi(argv[++i]); } else if ( !strcmp(argv[i], "-lp") ) { g_enableLoopFilter = TRUE; } else if ( !strcmp(argv[i], "-wr") ) { g_enableWriteReconFile = TRUE; } else if ( !strcmp(argv[i], "-fps") ) { FrameRate = atoi(argv[++i]); } else if ( !strcmp(argv[i], "-rc") ) { g_enableRateCtrl = TRUE; } else if ( !strcmp(argv[i], "-tbr") ) { TargetBitrate = atoi(argv[++i]); } } xDefaultParams(&h); h.usWidth = nWidth; h.usHeight = nHeight; if(h.usWidth == 352 && h.usHeight ==288) { eBit[0] = 0 ; eBit[1] = 0 ; eBit[2] = 1 ; eBit[3] = 1 ; } else if(h.usWidth == 832 && h.usHeight ==480) { eBit[0] = 0 ; eBit[1] = 0 ; eBit[2] = 0.5 ; eBit[3] = 0.5 ; } else if(h.usWidth == 1280 && h.usHeight ==720) { eBit[0] = 0 ; eBit[1] = 0 ; eBit[2] = 0.5 ; eBit[3] = 0.5 ; } else { eBit[0] = 1 ; eBit[1] = 1 ; eBit[2] = 2 ; eBit[3] = 2 ; } h.ucMaxCUWidth = 32; h.ucMaxCUDepth = 3; h.ucMinCUWidth = h.ucMaxCUWidth>>h.ucMaxCUDepth; h.NumPartition = (h.ucMaxCUWidth/4)*(h.ucMaxCUWidth/4); //1<<(h.ucMaxCUDepth<<1); h.eSliceType = SLICE_I; h.iQP = iQP; double lamada_scale = Clip3((double)0.5, (double)1, (double)(1-0.05*(GOPSize-1))); h.Inter_lamada = lamada_scale * pow((double)2,(double)(iQP-12)/3); h.sqrt_Inter_lamada = sqrt(h.Inter_lamada); h.bUseLMChroma = bLMChroma; h.bUseLoopFilter = g_enableLoopFilter; h.bWriteReconFile = g_enableWriteReconFile; h.GOPSize = GOPSize; h.IntraPeriod = IntraPeriod; h.FrameRate = FrameRate; //calculate padding size h.PAD_YSIZEw = nWidth%h.ucMaxCUWidth == 0 ? 0 : h.ucMaxCUWidth - nWidth%h.ucMaxCUWidth; h.PAD_YSIZEh = nHeight%h.ucMaxCUWidth == 0 ? 0 : h.ucMaxCUWidth - nHeight%h.ucMaxCUWidth; h.PAD_CSIZEw = (h.PAD_YSIZEw)>>1; h.PAD_CSIZEh = (h.PAD_YSIZEh)>>1; Pxl *ptr; ptr = (Pxl *)MALLOC(sizeof(Pxl)*(nWidth+h.PAD_YSIZEw )*(nHeight+h.PAD_YSIZEh) * 3 / 2); assert( ptr != NULL ); xCheckParams(&h); const UInt32 nYSize = nWidth*nHeight; const UInt32 nImageSize = nYSize*3/2; xEncInit( &h, nFrames ); FILE *fpi = fopen( inFile, "rb"); FILE *fpo = fopen( outFile, "wb"); assert( fpi != NULL ); assert( fpo != NULL ); double totaltime = 0; for( i=0; i<(Int32)nFrames; i++ ) { MTC265_Frame frame; if(nWidth%h.ucMaxCUWidth == 0&&nHeight%h.ucMaxCUWidth == 0) { fread( buf, 1, nImageSize, fpi ); xFramePadding(&h, &frame, buf ,ptr); } else { assert(ptr != NULL); fread( buf, 1, nImageSize, fpi ); xFramePadding(&h, &frame, buf ,ptr); } printf("Encoding Frame[%3d] ", i); if( i==0 ) { g_bSeqFirst = TRUE; } else { g_bSeqFirst = FALSE; } long iBeforeTime = clock(); if( ( g_bSeqFirst == FALSE ) && ( g_enableRateCtrl == TRUE ) ) { if( 0.001 * totalbits * h.FrameRate / i > TargetBitrate ) { h.iQP ++; } if( 0.001 * totalbits * h.FrameRate / i < TargetBitrate ) { h.iQP --; } } printf( " < QP %d > ", h.iQP ); Int32 iEncSize = xEncEncode( &h, &frame, pucOutBuf1, MAX_OUTBUF_SIZE, g_bSeqFirst ); //calculate PSNR xCalculateAddPSNR( &h, i ); double dEncTime = (double)(clock()-iBeforeTime); printf(" [ET %5.0fms ]\n", dEncTime ); totaltime += dEncTime; fwrite( pucOutBuf1, 1, iEncSize, fpo ); } //PSNR 求平均 double M_psnrY = 0; double M_psnrU = 0; double M_psnrV = 0; for( i=0; i<(Int32)nFrames; i++ ) { M_psnrY += h.FpsnrY[i]; M_psnrU += h.FpsnrU[i]; M_psnrV += h.FpsnrV[i]; } M_psnrY = M_psnrY/nFrames; M_psnrU = M_psnrU/nFrames; M_psnrV = M_psnrV/nFrames; printf( " M-Y-PSNR " "M-U-PSNR " "M-V-PSNR \n" ); printf( "%8.4lf " "%8.4lf " "%8.4lf\n",M_psnrY,M_psnrU,M_psnrV ); //PSNR求平均end printf("\n"); printf("TotalTime: %5.0f ms\n", totaltime); printf("Bytes written to file: %u (%.3f kbps)\n", totalbits / 8, 0.001 * totalbits * h.FrameRate / nFrames ); FREE(pucOutBuf0); FREE(pucOutBuf1); fclose(fpi); fclose(fpo); xEncFree(&h); if(h.PAD_YSIZEw!=0 || h.PAD_YSIZEh!=0) { free(ptr); ptr = NULL; } printf("\nAll Done!\n"); return 0; }
/* ************************************************************************* * Function:Inverse transform 8x8 block. * Input: * Output: * Return: * Attention:input curr_blk has to be [lines][pixels] ************************************************************************* */ void inv_transform_B8 (short curr_blk[B8_SIZE][B8_SIZE]) // block to be inverse transformed. { int xx, yy; int tmp[8]; int t; int b[8]; for(yy=0; yy<8; yy++) { // Horizontal inverse transform // Reorder tmp[0]=curr_blk[yy][0]; tmp[1]=curr_blk[yy][4]; tmp[2]=curr_blk[yy][2]; tmp[3]=curr_blk[yy][6]; tmp[4]=curr_blk[yy][1]; tmp[5]=curr_blk[yy][3]; tmp[6]=curr_blk[yy][5]; tmp[7]=curr_blk[yy][7]; // Downleft Butterfly /*Lou Change*/ b[0] = ((tmp[4] - tmp[7])<<1) + tmp[4]; b[1] = ((tmp[5] + tmp[6])<<1) + tmp[5]; b[2] = ((tmp[5] - tmp[6])<<1) - tmp[6]; b[3] = ((tmp[4] + tmp[7])<<1) + tmp[7]; b[4] = ((b[0] + b[1] + b[3])<<1) + b[1]; b[5] = ((b[0] - b[1] + b[2])<<1) + b[0]; b[6] = ((-b[1] - b[2] + b[3])<<1) + b[3]; b[7] = ((b[0] - b[2] - b[3])<<1) - b[2]; /*Lou End*/ // Upleft Butterfly /*Lou Change*/ t=((tmp[2]*10)+(tmp[3]<<2)); tmp[3]=((tmp[2]<<2)-(tmp[3]*10)); tmp[2]=t; t=(tmp[0]+tmp[1])<<3; tmp[1]=(tmp[0]-tmp[1])<<3; tmp[0]=t; /*Lou End*/ //b[0]=tmp[0]+tmp[2]; // b[1]=tmp[1]+tmp[3]; // b[2]=tmp[1]-tmp[3]; // b[3]=tmp[0]-tmp[2]; b[0] = Clip3(-32768, 32767, tmp[0]+tmp[2]); b[1] = Clip3(-32768, 32767, tmp[1]+tmp[3]); b[2] = Clip3(-32768, 32767, tmp[1]-tmp[3]); b[3] = Clip3(-32768, 32767, tmp[0]-tmp[2]); // Last Butterfly /*Lou Change*/ //curr_blk[yy][0]=(short)(((b[0]+b[4])+(1<<2))>>3); //curr_blk[yy][1]=(short)(((b[1]+b[5])+(1<<2))>>3); //curr_blk[yy][2]=(short)(((b[2]+b[6])+(1<<2))>>3); //curr_blk[yy][3]=(short)(((b[3]+b[7])+(1<<2))>>3); //curr_blk[yy][7]=(short)(((b[0]-b[4])+(1<<2))>>3); //curr_blk[yy][6]=(short)(((b[1]-b[5])+(1<<2))>>3); //curr_blk[yy][5]=(short)(((b[2]-b[6])+(1<<2))>>3); //curr_blk[yy][4]=(short)(((b[3]-b[7])+(1<<2))>>3); /*Lou End*/ /*WANGJP CHANGE 20061226*/ /* Commented by cjw, 20070327 curr_blk[yy][0]=((int16)((int16)(b[0]+b[4])+4))>>3; curr_blk[yy][1]=((int16)((int16)(b[1]+b[5])+4))>>3; curr_blk[yy][2]=((int16)((int16)(b[2]+b[6])+4))>>3; curr_blk[yy][3]=((int16)((int16)(b[3]+b[7])+4))>>3; curr_blk[yy][7]=((int16)((int16)(b[0]-b[4])+4))>>3; curr_blk[yy][6]=((int16)((int16)(b[1]-b[5])+4))>>3; curr_blk[yy][5]=((int16)((int16)(b[2]-b[6])+4))>>3; curr_blk[yy][4]=((int16)((int16)(b[3]-b[7])+4))>>3; */ /*WANGJP END*/ //070305 dingdandan curr_blk[yy][0]=(short)((Clip3(-32768,32767,((b[0]+b[4])+(1<<2))))>>3); curr_blk[yy][1]=(short)((Clip3(-32768,32767,((b[1]+b[5])+(1<<2))))>>3); curr_blk[yy][2]=(short)((Clip3(-32768,32767,((b[2]+b[6])+(1<<2))))>>3); curr_blk[yy][3]=(short)((Clip3(-32768,32767,((b[3]+b[7])+(1<<2))))>>3); curr_blk[yy][7]=(short)((Clip3(-32768,32767,((b[0]-b[4])+(1<<2))))>>3); curr_blk[yy][6]=(short)((Clip3(-32768,32767,((b[1]-b[5])+(1<<2))))>>3); curr_blk[yy][5]=(short)((Clip3(-32768,32767,((b[2]-b[6])+(1<<2))))>>3); curr_blk[yy][4]=(short)((Clip3(-32768,32767,((b[3]-b[7])+(1<<2))))>>3); //070305 dingdandan } // Vertical inverse transform for(xx=0; xx<8; xx++) { // Reorder tmp[0]=curr_blk[0][xx]; tmp[1]=curr_blk[4][xx]; tmp[2]=curr_blk[2][xx]; tmp[3]=curr_blk[6][xx]; tmp[4]=curr_blk[1][xx]; tmp[5]=curr_blk[3][xx]; tmp[6]=curr_blk[5][xx]; tmp[7]=curr_blk[7][xx]; // Downleft Butterfly /*Lou Change*/ b[0] = ((tmp[4] - tmp[7])<<1) + tmp[4]; b[1] = ((tmp[5] + tmp[6])<<1) + tmp[5]; b[2] = ((tmp[5] - tmp[6])<<1) - tmp[6]; b[3] = ((tmp[4] + tmp[7])<<1) + tmp[7]; b[4] = ((b[0] + b[1] + b[3])<<1) + b[1]; b[5] = ((b[0] - b[1] + b[2])<<1) + b[0]; b[6] = ((-b[1] - b[2] + b[3])<<1) + b[3]; b[7] = ((b[0] - b[2] - b[3])<<1) - b[2]; /*Lou End*/ // Upleft Butterfly /*Lou Change*/ t=((tmp[2]*10)+(tmp[3]<<2)); tmp[3]=((tmp[2]<<2)-(tmp[3]*10)); tmp[2]=t; t=(tmp[0]+tmp[1])<<3; tmp[1]=(tmp[0]-tmp[1])<<3; tmp[0]=t; /*Lou End*/ b[0]=tmp[0]+tmp[2]; b[1]=tmp[1]+tmp[3]; b[2]=tmp[1]-tmp[3]; b[3]=tmp[0]-tmp[2]; // Last Butterfly //curr_blk[0][xx]=(b[0]+b[4]+64)>>7;/*(Clip3(-32768,32703,b[0]+b[4])+64)>>7;*/ //curr_blk[1][xx]=(b[1]+b[5]+64)>>7;/*(Clip3(-32768,32703,b[1]+b[5])+64)>>7;*/ //curr_blk[2][xx]=(b[2]+b[6]+64)>>7;/*(Clip3(-32768,32703,b[2]+b[6])+64)>>7;*/ //curr_blk[3][xx]=(b[3]+b[7]+64)>>7;/*(Clip3(-32768,32703,b[3]+b[7])+64)>>7;*/ //curr_blk[7][xx]=(b[0]-b[4]+64)>>7;/*(Clip3(-32768,32703,b[0]-b[4])+64)>>7;*/ //curr_blk[6][xx]=(b[1]-b[5]+64)>>7;/*(Clip3(-32768,32703,b[1]-b[5])+64)>>7;*/ //curr_blk[5][xx]=(b[2]-b[6]+64)>>7;/*(Clip3(-32768,32703,b[2]-b[6])+64)>>7;*/ //curr_blk[4][xx]=(b[3]-b[7]+64)>>7;/*(Clip3(-32768,32703,b[3]-b[7])+64)>>7;*/ /*WANGJP CHANGE 20061226*/ /* Commented by cjw, 20070327 curr_blk[0][xx]=((int16)((int16)(b[0]+b[4])+64))>>7; curr_blk[1][xx]=((int16)((int16)(b[1]+b[5])+64))>>7; curr_blk[2][xx]=((int16)((int16)(b[2]+b[6])+64))>>7; curr_blk[3][xx]=((int16)((int16)(b[3]+b[7])+64))>>7; curr_blk[7][xx]=((int16)((int16)(b[0]-b[4])+64))>>7; curr_blk[6][xx]=((int16)((int16)(b[1]-b[5])+64))>>7; curr_blk[5][xx]=((int16)((int16)(b[2]-b[6])+64))>>7; curr_blk[4][xx]=((int16)((int16)(b[3]-b[7])+64))>>7; */ /*WANGJP END*/ //070305 dingdandan curr_blk[0][xx]=(Clip3(-32768,32767,(b[0]+b[4])+64))>>7; curr_blk[1][xx]=(Clip3(-32768,32767,(b[1]+b[5])+64))>>7; curr_blk[2][xx]=(Clip3(-32768,32767,(b[2]+b[6])+64))>>7; curr_blk[3][xx]=(Clip3(-32768,32767,(b[3]+b[7])+64))>>7; curr_blk[7][xx]=(Clip3(-32768,32767,(b[0]-b[4])+64))>>7; curr_blk[6][xx]=(Clip3(-32768,32767,(b[1]-b[5])+64))>>7; curr_blk[5][xx]=(Clip3(-32768,32767,(b[2]-b[6])+64))>>7; curr_blk[4][xx]=(Clip3(-32768,32767,(b[3]-b[7])+64))>>7; //070305 dingdandan // //range checking // if((b[0]+b[4])<=-32768 || (b[0]+b[4])>=(32768-65 )) // printf("error\n"); // if((b[1]+b[5])<=-32768 || (b[1]+b[5])>=(32768-65 )) // printf("error\n"); // if((b[2]+b[6])<=-32768 || (b[2]+b[6])>=(32768-65 )) // printf("error\n"); // if((b[3]+b[7])<=-32768 || (b[3]+b[7])>=(32768-65 )) // printf("error\n"); // if((b[0]-b[4])<=-32768 || (b[0]-b[4])>=(32768-65 )) // printf("error\n"); // if((b[1]-b[5])<=-32768 || (b[1]-b[5])>=(32768-65 )) // printf("error\n"); // if((b[2]-b[6])<=-32768 || (b[2]-b[6])>=(32768-65 )) // printf("error\n"); // if((b[3]-b[7])<=-32768 || (b[3]-b[7])>=(32768-65 )) // printf("error\n"); } }
/*! *********************************************************************** * \brief * Checks the input parameters for consistency. *********************************************************************** */ static void PatchInp () { int bitdepth_qp_scale = 6*(input->BitDepthLuma - 8); // These variables are added for FMO FILE * sgfile=NULL; int i,j; int frame_mb_only; int mb_width, mb_height, mapunit_height; int storedBplus1; TestEncoderParams(bitdepth_qp_scale); if (input->FrameRate == 0.0) input->FrameRate = INIT_FRAME_RATE; // Set block sizes // Skip/Direct16x16 input->part_size[0][0] = 4; input->part_size[0][1] = 4; // 16x16 input->part_size[1][0] = 4; input->part_size[1][1] = 4; // 16x8 input->part_size[2][0] = 4; input->part_size[2][1] = 2; // 8x16 input->part_size[3][0] = 2; input->part_size[3][1] = 4; // 8x8 input->part_size[4][0] = 2; input->part_size[4][1] = 2; // 8x4 input->part_size[5][0] = 2; input->part_size[5][1] = 1; // 4x8 input->part_size[6][0] = 1; input->part_size[6][1] = 2; // 4x4 input->part_size[7][0] = 1; input->part_size[7][1] = 1; for (j = 0; j<8;j++) { for (i = 0; i<2; i++) { input->blc_size[j][i] = input->part_size[j][i] * BLOCK_SIZE; } } // set proper log2_max_frame_num_minus4. storedBplus1 = (input->BRefPictures ) ? input->successive_Bframe + 1: 1; if (input->Log2MaxFNumMinus4 == -1) log2_max_frame_num_minus4 = Clip3(0,12, (int) (CeilLog2(input->no_frames * storedBplus1) - 4)); else log2_max_frame_num_minus4 = input->Log2MaxFNumMinus4; if (log2_max_frame_num_minus4 == 0 && input->num_ref_frames == 16) { snprintf(errortext, ET_SIZE, " NumberReferenceFrames=%d and Log2MaxFNumMinus4=%d may lead to an invalid value of frame_num.", input->num_ref_frames, input-> Log2MaxFNumMinus4); error (errortext, 500); } // set proper log2_max_pic_order_cnt_lsb_minus4. if (input->Log2MaxPOCLsbMinus4 == - 1) log2_max_pic_order_cnt_lsb_minus4 = Clip3(0,12, (int) (CeilLog2( 2*input->no_frames * (input->jumpd + 1)) - 4)); else log2_max_pic_order_cnt_lsb_minus4 = input->Log2MaxPOCLsbMinus4; if (((1<<(log2_max_pic_order_cnt_lsb_minus4 + 3)) < input->jumpd * 4) && input->Log2MaxPOCLsbMinus4 != -1) error("log2_max_pic_order_cnt_lsb_minus4 might not be sufficient for encoding. Increase value.",400); // B picture consistency check if(input->successive_Bframe > input->jumpd) { snprintf(errortext, ET_SIZE, "Number of B-frames %d can not exceed the number of frames skipped", input->successive_Bframe); error (errortext, 400); } // Direct Mode consistency check if(input->successive_Bframe && input->direct_spatial_mv_pred_flag != DIR_SPATIAL && input->direct_spatial_mv_pred_flag != DIR_TEMPORAL) { snprintf(errortext, ET_SIZE, "Unsupported direct mode=%d, use TEMPORAL=0 or SPATIAL=1", input->direct_spatial_mv_pred_flag); error (errortext, 400); } if (input->PicInterlace>0 || input->MbInterlace>0) { if (input->directInferenceFlag==0) printf("\nDirectInferenceFlag set to 1 due to interlace coding."); input->directInferenceFlag=1; } if (input->PicInterlace>0) { if (input->IntraBottom!=0 && input->IntraBottom!=1) { snprintf(errortext, ET_SIZE, "Incorrect value %d for IntraBottom. Use 0 (disable) or 1 (enable).", input->IntraBottom); error (errortext, 400); } } // Cabac/UVLC consistency check if (input->symbol_mode != UVLC && input->symbol_mode != CABAC) { snprintf (errortext, ET_SIZE, "Unsupported symbol mode=%d, use UVLC=0 or CABAC=1",input->symbol_mode); error (errortext, 400); } // Open Files if ((p_in=open(input->infile, OPENFLAGS_READ))==-1) { snprintf(errortext, ET_SIZE, "Input file %s does not exist",input->infile); error (errortext, 500); } if (strlen (input->ReconFile) > 0 && (p_dec=open(input->ReconFile, OPENFLAGS_WRITE, OPEN_PERMISSIONS))==-1) { snprintf(errortext, ET_SIZE, "Error open file %s", input->ReconFile); error (errortext, 500); } #if TRACE if (strlen (input->TraceFile) > 0 && (p_trace=fopen(input->TraceFile,"w"))==NULL) { snprintf(errortext, ET_SIZE, "Error open file %s", input->TraceFile); error (errortext, 500); } #endif if (input->img_width % 16 != 0) { img->auto_crop_right = 16-(input->img_width % 16); } else { img->auto_crop_right=0; } if (input->PicInterlace || input->MbInterlace) { if (input->img_height % 2 != 0) { error ("even number of lines required for interlaced coding", 500); } if (input->img_height % 32 != 0) { img->auto_crop_bottom = 32-(input->img_height % 32); } else { img->auto_crop_bottom=0; } } else { if (input->img_height % 16 != 0) { img->auto_crop_bottom = 16-(input->img_height % 16); } else { img->auto_crop_bottom=0; } } if (img->auto_crop_bottom || img->auto_crop_right) { printf ("Warning: Automatical cropping activated: Coded frame Size: %dx%d\n", input->img_width+img->auto_crop_right, input->img_height+img->auto_crop_bottom); } /* // add check for MAXSLICEGROUPIDS if(input->num_slice_groups_minus1>=MAXSLICEGROUPIDS) { snprintf(errortext, ET_SIZE, "num_slice_groups_minus1 exceeds MAXSLICEGROUPIDS"); error (errortext, 500); } */ // Following codes are to read slice group configuration from SliceGroupConfigFileName for slice group type 0,2 or 6 if( (input->num_slice_groups_minus1!=0)&& ((input->slice_group_map_type == 0) || (input->slice_group_map_type == 2) || (input->slice_group_map_type == 6)) ) { if (strlen (input->SliceGroupConfigFileName) > 0 && (sgfile=fopen(input->SliceGroupConfigFileName,"r"))==NULL) { snprintf(errortext, ET_SIZE, "Error open file %s", input->SliceGroupConfigFileName); error (errortext, 500); } else { if (input->slice_group_map_type == 0) { input->run_length_minus1=(int *)malloc(sizeof(int)*(input->num_slice_groups_minus1+1)); if (NULL==input->run_length_minus1) no_mem_exit("PatchInp: input->run_length_minus1"); // each line contains one 'run_length_minus1' value for(i=0;i<=input->num_slice_groups_minus1;i++) { fscanf(sgfile,"%d",(input->run_length_minus1+i)); fscanf(sgfile,"%*[^\n]"); } } else if (input->slice_group_map_type == 2) { input->top_left=(int *)malloc(sizeof(int)*input->num_slice_groups_minus1); input->bottom_right=(int *)malloc(sizeof(int)*input->num_slice_groups_minus1); if (NULL==input->top_left) no_mem_exit("PatchInp: input->top_left"); if (NULL==input->bottom_right) no_mem_exit("PatchInp: input->bottom_right"); // every two lines contain 'top_left' and 'bottom_right' value for(i=0;i<input->num_slice_groups_minus1;i++) { fscanf(sgfile,"%d",(input->top_left+i)); fscanf(sgfile,"%*[^\n]"); fscanf(sgfile,"%d",(input->bottom_right+i)); fscanf(sgfile,"%*[^\n]"); } } else if (input->slice_group_map_type == 6) { int tmp; frame_mb_only = !(input->PicInterlace || input->MbInterlace); mb_width= (input->img_width+img->auto_crop_right)/16; mb_height= (input->img_height+img->auto_crop_bottom)/16; mapunit_height=mb_height/(2-frame_mb_only); input->slice_group_id=(byte * ) malloc(sizeof(byte)*mapunit_height*mb_width); if (NULL==input->slice_group_id) no_mem_exit("PatchInp: input->slice_group_id"); // each line contains slice_group_id for one Macroblock for (i=0;i<mapunit_height*mb_width;i++) { fscanf(sgfile,"%d", &tmp); input->slice_group_id[i]= (byte) tmp; if ( *(input->slice_group_id+i) > input->num_slice_groups_minus1 ) { snprintf(errortext, ET_SIZE, "Error read slice group information from file %s", input->SliceGroupConfigFileName); error (errortext, 500); } fscanf(sgfile,"%*[^\n]"); } } fclose(sgfile); } } if (input->PyramidRefReorder && input->PyramidCoding && (input->PicInterlace || input->MbInterlace)) { snprintf(errortext, ET_SIZE, "PyramidRefReorder Not supported with Interlace encoding methods\n"); error (errortext, 400); } if (input->PocMemoryManagement && input->PyramidCoding && (input->PicInterlace || input->MbInterlace)) { snprintf(errortext, ET_SIZE, "PocMemoryManagement not supported with Interlace encoding methods\n"); error (errortext, 400); } // frame/field consistency check if (input->PicInterlace != FRAME_CODING && input->PicInterlace != ADAPTIVE_CODING && input->PicInterlace != FIELD_CODING) { snprintf (errortext, ET_SIZE, "Unsupported PicInterlace=%d, use frame based coding=0 or field based coding=1 or adaptive=2",input->PicInterlace); error (errortext, 400); } // frame/field consistency check if (input->MbInterlace != FRAME_CODING && input->MbInterlace != ADAPTIVE_CODING && input->MbInterlace != FIELD_CODING) { snprintf (errortext, ET_SIZE, "Unsupported MbInterlace=%d, use frame based coding=0 or field based coding=1 or adaptive=2",input->MbInterlace); error (errortext, 400); } if ((!input->rdopt)&&(input->MbInterlace)) { snprintf(errortext, ET_SIZE, "MB AFF is not compatible with non-rd-optimized coding."); error (errortext, 500); } if (input->rdopt>2) { snprintf(errortext, ET_SIZE, "RDOptimization=3 mode has been deactivated do to diverging of real and simulated decoders."); error (errortext, 500); } // check RDoptimization mode and profile. FMD does not support Frex Profiles. if (input->rdopt==2 && input->ProfileIDC>=FREXT_HP) { snprintf(errortext, ET_SIZE, "Fast Mode Decision methods does not support FREX Profiles"); error (errortext, 500); } // the two HEX FME schemes support FAST Subpel ME. EPZS does not but works fine with // Hadamard reduction with similar speed up. Subpel FME may be added at a later stage // for this scheme for further speed increase. if (input->hadamard == 2 && input->FMEnable != 0 && input->FMEnable != 3) { snprintf(errortext, ET_SIZE, "UseHadamard=2 is not allowed when UseFME is set to 1 or 2."); error (errortext, 500); } // Tian Dong: May 31, 2002 // The number of frames in one sub-seq in enhanced layer should not exceed // the number of reference frame number. if ( input->NumFramesInELSubSeq >= input->num_ref_frames || input->NumFramesInELSubSeq < 0 ) { snprintf(errortext, ET_SIZE, "NumFramesInELSubSeq (%d) is out of range [0,%d).", input->NumFramesInELSubSeq, input->num_ref_frames); error (errortext, 500); } // Tian Dong: Enhanced GOP is not supported in bitstream mode. September, 2002 if ( input->NumFramesInELSubSeq > 0 && input->of_mode == PAR_OF_ANNEXB ) { snprintf(errortext, ET_SIZE, "Enhanced GOP is not supported in bitstream mode and RTP mode yet."); error (errortext, 500); } // Tian Dong (Sept 2002) // The AFF is not compatible with spare picture for the time being. if ((input->PicInterlace || input->MbInterlace) && input->SparePictureOption == TRUE) { snprintf(errortext, ET_SIZE, "AFF is not compatible with spare picture."); error (errortext, 500); } // Only the RTP mode is compatible with spare picture for the time being. if (input->of_mode != PAR_OF_RTP && input->SparePictureOption == TRUE) { snprintf(errortext, ET_SIZE, "Only RTP output mode is compatible with spare picture features."); error (errortext, 500); } if( (input->WeightedPrediction > 0 || input->WeightedBiprediction > 0) && (input->MbInterlace)) { printf("Weighted prediction coding is not supported for MB AFF currently."); error (errortext, 500); } if ( input->NumFramesInELSubSeq > 0 && input->WeightedPrediction > 0) { snprintf(errortext, ET_SIZE, "Enhanced GOP is not supported in weighted prediction coding mode yet."); error (errortext, 500); } //! the number of slice groups is forced to be 1 for slice group type 3-5 if(input->num_slice_groups_minus1 > 0) { if( (input->slice_group_map_type >= 3) && (input->slice_group_map_type<=5) ) input->num_slice_groups_minus1 = 1; } // Rate control if(input->RCEnable) { if ( ((input->img_height+img->auto_crop_bottom)*(input->img_width+img->auto_crop_right)/256)%input->basicunit!=0) { snprintf(errortext, ET_SIZE, "Frame size in macroblocks must be a multiple of BasicUnit."); error (errortext, 500); } } if ((input->successive_Bframe)&&(input->BRefPictures)&&(input->idr_enable)&&(input->intra_period)&&(input->pic_order_cnt_type!=0)) { error("Stored B pictures combined with IDR pictures only supported in Picture Order Count type 0\n",-1000); } if( !input->direct_spatial_mv_pred_flag && input->num_ref_frames<2 && input->successive_Bframe >0) error("temporal direct needs at least 2 ref frames\n",-1000); // frext if(input->Transform8x8Mode && input->sp_periodicity /*SP-frames*/) { snprintf(errortext, ET_SIZE, "\nThe new 8x8 mode is not implemented for sp-frames."); error (errortext, 500); } if(input->Transform8x8Mode && (input->ProfileIDC<FREXT_HP || input->ProfileIDC>FREXT_Hi444)) { snprintf(errortext, ET_SIZE, "\nTransform8x8Mode may be used only with ProfileIDC %d to %d.", FREXT_HP, FREXT_Hi444); error (errortext, 500); } if(input->ScalingMatrixPresentFlag && (input->ProfileIDC<FREXT_HP || input->ProfileIDC>FREXT_Hi444)) { snprintf(errortext, ET_SIZE, "\nScalingMatrixPresentFlag may be used only with ProfileIDC %d to %d.", FREXT_HP, FREXT_Hi444); error (errortext, 500); } if(input->yuv_format==YUV422 && input->ProfileIDC < FREXT_Hi422) { snprintf(errortext, ET_SIZE, "\nFRExt Profile(YUV Format) Error!\nYUV422 can be used only with ProfileIDC %d or %d\n",FREXT_Hi422, FREXT_Hi444); error (errortext, 500); } if(input->yuv_format==YUV444 && input->ProfileIDC < FREXT_Hi444) { snprintf(errortext, ET_SIZE, "\nFRExt Profile(YUV Format) Error!\nYUV444 can be used only with ProfileIDC %d.\n",FREXT_Hi444); error (errortext, 500); } // Residue Color Transform if(input->yuv_format!=YUV444 && input->residue_transform_flag) { snprintf(errortext, ET_SIZE, "\nResidue color transform is supported only in YUV444."); error (errortext, 500); } if ((input->BiPredMotionEstimation) && (input->search_range < input->BiPredMESearchRange)) { snprintf(errortext, ET_SIZE, "\nBiPredMESearchRange must be smaller or equal SearchRange."); error (errortext, 500); } if (input->EnableOpenGOP) input->PyramidRefReorder = 1; if (input->EnableOpenGOP && input->PicInterlace) { snprintf(errortext, ET_SIZE, "Open Gop currently not supported for Field coded pictures."); error (errortext, 500); } ProfileCheck(); LevelCheck(); }
// (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); }
/*! ************************************************************************ * \brief * Interpret GOP struct from input parameters ************************************************************************ */ void interpret_gop_structure() { int nLength = strlen(input->ExplicitPyramidFormat); int i =0, k, dqp, display_no; int slice_read =0, order_read = 0, stored_read = 0, qp_read =0; int coded_frame = 0; if (nLength > 0) { for (i = 0; i < nLength ; i++) { //! First lets read slice type if (slice_read == 0) { switch (input->ExplicitPyramidFormat[i]) { case 'P': case 'p': gop_structure[coded_frame].slice_type=P_SLICE; break; case 'B': case 'b': gop_structure[coded_frame].slice_type=B_SLICE; break; case 'I': case 'i': gop_structure[coded_frame].slice_type=I_SLICE; break; default: snprintf(errortext, ET_SIZE, "Slice Type invalid in ExplicitPyramidFormat param. Please check configuration file."); error (errortext, 400); break; } slice_read = 1; } else { //! Next is Display Order if (order_read == 0) { if (isdigit((int)(*(input->ExplicitPyramidFormat+i)))) { sscanf(input->ExplicitPyramidFormat+i,"%d",&display_no); gop_structure[coded_frame].display_no = display_no; order_read = 1; if (display_no<0 || display_no>=input->jumpd) { snprintf(errortext, ET_SIZE, "Invalid Frame Order value. Frame position needs to be in [0,%d] range.",input->jumpd-1); error (errortext, 400); } for (k=0;k<coded_frame;k++) { if (gop_structure[k].display_no == display_no) { snprintf(errortext, ET_SIZE, "Frame Order value %d in frame %d already used for enhancement frame %d.",display_no,coded_frame,k); error (errortext, 400); } } } else { snprintf(errortext, ET_SIZE, "Slice Type needs to be followed by Display Order. Please check configuration file."); error (errortext, 400); } } else if (order_read == 1) { if (stored_read == 0 && !(isdigit((int)(*(input->ExplicitPyramidFormat+i))))) { switch (input->ExplicitPyramidFormat[i]) { case 'E': case 'e': gop_structure[coded_frame].reference_idc = NALU_PRIORITY_DISPOSABLE; break; case 'R': case 'r': gop_structure[coded_frame].reference_idc= NALU_PRIORITY_HIGH; break; default: snprintf(errortext, ET_SIZE, "Reference_IDC invalid in ExplicitPyramidFormat param. Please check configuration file."); error (errortext, 400); break; } stored_read = 1; } else if (stored_read == 1 && qp_read == 0) { if (isdigit((int)(*(input->ExplicitPyramidFormat+i)))) { sscanf(input->ExplicitPyramidFormat+i,"%d",&dqp); if (gop_structure[coded_frame].slice_type == I_SLICE) gop_structure[coded_frame].slice_qp = input->qp0; else if (gop_structure[coded_frame].slice_type == P_SLICE) gop_structure[coded_frame].slice_qp = input->qpN; else gop_structure[coded_frame].slice_qp = input->qpB; gop_structure[coded_frame].slice_qp = Clip3(-img->bitdepth_luma_qp_scale, 51,gop_structure[coded_frame].slice_qp + dqp); qp_read = 1; } else { snprintf(errortext, ET_SIZE, "Reference_IDC needs to be followed by QP. Please check configuration file."); error (errortext, 400); } } else if (stored_read == 1 && qp_read == 1 && !(isdigit((int)(*(input->ExplicitPyramidFormat+i)))) && (i < nLength - 2)) { stored_read =0; qp_read=0; order_read=0; slice_read=0; i--; coded_frame ++; if (coded_frame >= input->jumpd ) { snprintf(errortext, ET_SIZE, "Total number of frames in Enhancement GOP need to be fewer or equal to FrameSkip parameter."); error (errortext, 400); } } } } } } else { snprintf(errortext, ET_SIZE, "ExplicitPyramidFormat is empty. Please check configuration file."); error (errortext, 400); } input->successive_Bframe = coded_frame + 1; }
//! update wp tables for explicit wp w.r.t range limitation Bool WeightPredAnalysis::xUpdatingWPParameters(TComSlice *const slice, const Int log2Denom) { const Int numComp = slice->getPic()->getPicYuvOrg()->getNumberValidComponents(); const Bool bUseHighPrecisionWeighting = slice->getSPS()->getSpsRangeExtension().getHighPrecisionOffsetsEnabledFlag(); const Int numPredDir = slice->isInterP() ? 1 : 2; assert (numPredDir <= Int(NUM_REF_PIC_LIST_01)); for ( Int refList = 0; refList < numPredDir; refList++ ) { const RefPicList eRefPicList = ( refList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 ); for ( Int refIdxTemp = 0; refIdxTemp < slice->getNumRefIdx(eRefPicList); refIdxTemp++ ) { WPACDCParam *currWeightACDCParam, *refWeightACDCParam; slice->getWpAcDcParam(currWeightACDCParam); slice->getRefPic(eRefPicList, refIdxTemp)->getSlice(0)->getWpAcDcParam(refWeightACDCParam); for ( Int comp = 0; comp < numComp; comp++ ) { const ComponentID compID = ComponentID(comp); const Int bitDepth = slice->getSPS()->getBitDepth(toChannelType(compID)); const Int range = bUseHighPrecisionWeighting ? (1<<bitDepth)/2 : 128; const Int realLog2Denom = log2Denom + (bUseHighPrecisionWeighting ? RExt__PREDICTION_WEIGHTING_ANALYSIS_DC_PRECISION : (bitDepth - 8)); const Int realOffset = ((Int)1<<(realLog2Denom-1)); // current frame const Int64 currDC = currWeightACDCParam[comp].iDC; const Int64 currAC = currWeightACDCParam[comp].iAC; // reference frame const Int64 refDC = refWeightACDCParam[comp].iDC; const Int64 refAC = refWeightACDCParam[comp].iAC; // calculating iWeight and iOffset params const Double dWeight = (refAC==0) ? (Double)1.0 : Clip3( -16.0, 15.0, ((Double)currAC / (Double)refAC) ); const Int weight = (Int)( 0.5 + dWeight * (Double)(1<<log2Denom) ); const Int offset = (Int)( ((currDC<<log2Denom) - ((Int64)weight * refDC) + (Int64)realOffset) >> realLog2Denom ); Int clippedOffset; if(isChroma(compID)) // Chroma offset range limination { const Int pred = ( range - ( ( range*weight)>>(log2Denom) ) ); const Int deltaOffset = Clip3( -4*range, 4*range-1, (offset - pred) ); // signed 10bit clippedOffset = Clip3( -range, range-1, (deltaOffset + pred) ); // signed 8bit } else // Luma offset range limitation { clippedOffset = Clip3( -range, range-1, offset); } // Weighting factor limitation const Int defaultWeight = (1<<log2Denom); const Int deltaWeight = (defaultWeight - weight); if(deltaWeight >= range || deltaWeight < -range) { return false; } m_wp[refList][refIdxTemp][comp].bPresentFlag = true; m_wp[refList][refIdxTemp][comp].iWeight = weight; m_wp[refList][refIdxTemp][comp].iOffset = clippedOffset; m_wp[refList][refIdxTemp][comp].uiLog2WeightDenom = log2Denom; } } }