# HG changeset patch # User Jayashri Murugan # Date 1537464480 25200 # Thu Sep 20 10:28:00 2018 -0700 # Node ID d571bdb0b0ae9894dce12d9d0fc3ea4d639a01a2 # Parent 23a8a7456916d98040b56a09a93ce3b1149613d9 Reuse CU depth for B frame and allow I, P frame to follow x265 depth decision
diff -r 23a8a7456916 -r d571bdb0b0ae source/common/param.cpp --- a/source/common/param.cpp Wed Sep 19 14:30:48 2018 -0700 +++ b/source/common/param.cpp Thu Sep 20 10:28:00 2018 -0700 @@ -1157,6 +1157,10 @@ { p->bAnalysisType = AVC_INFO; } + else if (strcmp(strdup(value), "hevc") == 0) + { + p->bAnalysisType = HEVC_INFO; + } else if (strcmp(strdup(value), "off") == 0) { p->bAnalysisType = NO_INFO; @@ -1714,7 +1718,11 @@ TOOLVAL(param->lookaheadThreads, "lthreads=%d") TOOLVAL(param->bCTUInfo, "ctu-info=%d"); if (param->bAnalysisType == AVC_INFO) + { TOOLOPT(param->bAnalysisType, "refine-analysis-type=avc"); + } + else if (param->bAnalysisType == HEVC_INFO) + TOOLOPT(param->bAnalysisType, "refine-analysis-type=hevc"); TOOLOPT(param->bDynamicRefine, "dynamic-refine"); if (param->maxSlices > 1) TOOLVAL(param->maxSlices, "slices=%d"); diff -r 23a8a7456916 -r d571bdb0b0ae source/encoder/analysis.cpp --- a/source/encoder/analysis.cpp Wed Sep 19 14:30:48 2018 -0700 +++ b/source/encoder/analysis.cpp Thu Sep 20 10:28:00 2018 -0700 @@ -275,7 +275,8 @@ /* generate residual for entire CTU at once and copy to reconPic */ encodeResidue(ctu, cuGeom); } - else if ((m_param->analysisLoad && m_param->analysisReuseLevel == 10) || ((m_param->bAnalysisType == AVC_INFO) && m_param->analysisReuseLevel >= 7 && ctu.m_numPartitions <= 16)) + else if ((m_param->analysisLoad && m_param->analysisReuseLevel == 10 && (!(m_param->bAnalysisType == HEVC_INFO) || m_slice->m_sliceType != P_SLICE)) || + ((m_param->bAnalysisType == AVC_INFO) && m_param->analysisReuseLevel >= 7 && ctu.m_numPartitions <= 16)) { x265_analysis_inter_data* interDataCTU = m_frame->m_analysisData.interData; int posCTU = ctu.m_cuAddr * numPartition; @@ -516,7 +517,7 @@ bool mightSplit = !(cuGeom.flags & CUGeom::LEAF); bool mightNotSplit = !(cuGeom.flags & CUGeom::SPLIT_MANDATORY); - bool bAlreadyDecided = m_param->intraRefine != 4 && parentCTU.m_lumaIntraDir[cuGeom.absPartIdx] != (uint8_t)ALL_IDX; + bool bAlreadyDecided = m_param->intraRefine != 4 && parentCTU.m_lumaIntraDir[cuGeom.absPartIdx] != (uint8_t)ALL_IDX && !(m_param->bAnalysisType == HEVC_INFO); bool bDecidedDepth = m_param->intraRefine != 4 && parentCTU.m_cuDepth[cuGeom.absPartIdx] == depth; int split = 0; if (m_param->intraRefine && m_param->intraRefine != 4) @@ -2423,7 +2424,7 @@ (m_refineLevel && cuGeom.log2CUSize == (uint32_t)(g_log2Size[m_param->minCUSize] + 1)))); td.split = split; - if (bDecidedDepth && mightNotSplit) + if ((bDecidedDepth && mightNotSplit) || (m_param->bAnalysisType == HEVC_INFO && parentCTU.m_cuDepth[cuGeom.absPartIdx] == 4)) { setLambdaFromQP(parentCTU, qp, lqp); @@ -2562,7 +2563,10 @@ if (m_refineLevel > 1 || (m_refineLevel && parentCTU.m_predMode[cuGeom.absPartIdx] == MODE_SKIP && !mode.cu.isSkipped(0))) { - m_evaluateInter = 1; + if (parentCTU.m_cuDepth[cuGeom.absPartIdx] < 4 && mightNotSplit) + m_evaluateInter = 1; + else + bDecidedDepth = true; m_param->rdLevel > 4 ? compressInterCU_rd5_6(parentCTU, cuGeom, qp) : compressInterCU_rd0_4(parentCTU, cuGeom, qp); m_evaluateInter = 0; } diff -r 23a8a7456916 -r d571bdb0b0ae source/encoder/api.cpp --- a/source/encoder/api.cpp Wed Sep 19 14:30:48 2018 -0700 +++ b/source/encoder/api.cpp Thu Sep 20 10:28:00 2018 -0700 @@ -463,20 +463,20 @@ //Allocate memory for intraData pointer CHECKED_MALLOC_ZERO(intraData, x265_analysis_intra_data, 1); CHECKED_MALLOC(intraData->depth, uint8_t, analysis->numPartitions * analysis->numCUsInFrame); - CHECKED_MALLOC(intraData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame); - CHECKED_MALLOC(intraData->partSizes, char, analysis->numPartitions * analysis->numCUsInFrame); - CHECKED_MALLOC(intraData->chromaModes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame); + CHECKED_MALLOC_ZERO(intraData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame); + CHECKED_MALLOC_ZERO(intraData->partSizes, char, analysis->numPartitions * analysis->numCUsInFrame); + CHECKED_MALLOC_ZERO(intraData->chromaModes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame); if (param->rc.cuTree) - CHECKED_MALLOC(intraData->cuQPOff, int8_t, analysis->numPartitions * analysis->numCUsInFrame); + CHECKED_MALLOC_ZERO(intraData->cuQPOff, int8_t, analysis->numPartitions * analysis->numCUsInFrame); analysis->intraData = intraData; //Allocate memory for interData pointer based on ReuseLevels CHECKED_MALLOC_ZERO(interData, x265_analysis_inter_data, 1); CHECKED_MALLOC(interData->depth, uint8_t, analysis->numPartitions * analysis->numCUsInFrame); - CHECKED_MALLOC(interData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame); + CHECKED_MALLOC_ZERO(interData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame); if (param->rc.cuTree) - CHECKED_MALLOC(interData->cuQPOff, int8_t, analysis->numPartitions * analysis->numCUsInFrame); + CHECKED_MALLOC_ZERO(interData->cuQPOff, int8_t, analysis->numPartitions * analysis->numCUsInFrame); CHECKED_MALLOC_ZERO(interData->mvpIdx[0], uint8_t, analysis->numPartitions * analysis->numCUsInFrame); CHECKED_MALLOC_ZERO(interData->mvpIdx[1], uint8_t, analysis->numPartitions * analysis->numCUsInFrame); CHECKED_MALLOC_ZERO(interData->mv[0], x265_analysis_MV, analysis->numPartitions * analysis->numCUsInFrame); @@ -484,16 +484,16 @@ if (param->analysisReuseLevel > 4) { - CHECKED_MALLOC(interData->partSize, uint8_t, analysis->numPartitions * analysis->numCUsInFrame); + CHECKED_MALLOC_ZERO(interData->partSize, uint8_t, analysis->numPartitions * analysis->numCUsInFrame); CHECKED_MALLOC_ZERO(interData->mergeFlag, uint8_t, analysis->numPartitions * analysis->numCUsInFrame); } if (param->analysisReuseLevel >= 7) { - CHECKED_MALLOC(interData->interDir, uint8_t, analysis->numPartitions * analysis->numCUsInFrame); - CHECKED_MALLOC(interData->sadCost, int64_t, analysis->numPartitions * analysis->numCUsInFrame); + CHECKED_MALLOC_ZERO(interData->interDir, uint8_t, analysis->numPartitions * analysis->numCUsInFrame); + CHECKED_MALLOC_ZERO(interData->sadCost, int64_t, analysis->numPartitions * analysis->numCUsInFrame); for (int dir = 0; dir < numDir; dir++) { - CHECKED_MALLOC(interData->refIdx[dir], int8_t, analysis->numPartitions * analysis->numCUsInFrame); + CHECKED_MALLOC_ZERO(interData->refIdx[dir], int8_t, analysis->numPartitions * analysis->numCUsInFrame); CHECKED_MALLOC_ZERO(analysis->modeFlag[dir], uint8_t, analysis->numPartitions * analysis->numCUsInFrame); } } diff -r 23a8a7456916 -r d571bdb0b0ae source/encoder/encoder.cpp --- a/source/encoder/encoder.cpp Wed Sep 19 14:30:48 2018 -0700 +++ b/source/encoder/encoder.cpp Thu Sep 20 10:28:00 2018 -0700 @@ -1145,7 +1145,7 @@ { /* reads analysis data for the frame and allocates memory based on slicetype */ static int paramBytes = 0; - if (!inFrame->m_poc) + if (!inFrame->m_poc && m_param->bAnalysisType != HEVC_INFO) { x265_analysis_data analysisData = pic_in->analysisData; paramBytes = validateAnalysisData(&analysisData, 0); @@ -2885,7 +2885,7 @@ p->rc.rfConstantMin = 0; } - if ((p->analysisLoad || p->analysisSave) && p->rc.cuTree && p->analysisReuseLevel < 10) + if (!(p->bAnalysisType == HEVC_INFO) && (p->analysisLoad || p->analysisSave) && p->rc.cuTree && p->analysisReuseLevel < 10) { x265_log(p, X265_LOG_WARNING, "cu-tree works only with analysis reuse level 10, Disabling cu-tree\n"); p->rc.cuTree = 0; @@ -2954,7 +2954,7 @@ p->interRefine = 1; } - if (p->limitTU && (p->interRefine || p->bDynamicRefine)) + if (!(p->bAnalysisType == HEVC_INFO) && p->limitTU && (p->interRefine || p->bDynamicRefine)) { x265_log(p, X265_LOG_WARNING, "Inter refinement does not support limitTU. Disabling limitTU.\n"); p->limitTU = 0; @@ -3465,6 +3465,8 @@ } if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType == X265_TYPE_I) { + if (m_param->bAnalysisType == HEVC_INFO) + return; if (m_param->analysisReuseLevel < 2) return; @@ -3542,98 +3544,107 @@ bIntraInInter = (analysis->sliceType == X265_TYPE_P || m_param->bIntraInBFrames); if (bIntraInInter) numBuf++; } - - tempBuf = X265_MALLOC(uint8_t, depthBytes * numBuf); - depthBuf = tempBuf; - modeBuf = tempBuf + depthBytes; - if (m_param->rc.cuTree) - cuQPBuf = X265_MALLOC(int8_t, depthBytes); - - X265_FREAD(depthBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->depth); - X265_FREAD(modeBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->modes); - if (m_param->rc.cuTree) { X265_FREAD(cuQPBuf, sizeof(int8_t), depthBytes, m_analysisFileIn, interPic->cuQPOff); } - - if (m_param->analysisReuseLevel > 4) + if (m_param->bAnalysisType == HEVC_INFO) + { + depthBytes = analysis->numCUsInFrame * analysis->numPartitions; + memcpy(((x265_analysis_inter_data *)analysis->interData)->depth, interPic->depth, depthBytes); + } + else { - partSize = modeBuf + depthBytes; - mergeFlag = partSize + depthBytes; - X265_FREAD(partSize, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->partSize); - X265_FREAD(mergeFlag, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->mergeFlag); - - if (m_param->analysisReuseLevel == 10) + tempBuf = X265_MALLOC(uint8_t, depthBytes * numBuf); + depthBuf = tempBuf; + modeBuf = tempBuf + depthBytes; + if (m_param->rc.cuTree) + cuQPBuf = X265_MALLOC(int8_t, depthBytes); + + X265_FREAD(depthBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->depth); + X265_FREAD(modeBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->modes); + if (m_param->rc.cuTree) { X265_FREAD(cuQPBuf, sizeof(int8_t), depthBytes, m_analysisFileIn, interPic->cuQPOff); } + + if (m_param->analysisReuseLevel > 4) { - interDir = mergeFlag + depthBytes; - X265_FREAD(interDir, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->interDir); - if (bIntraInInter) + partSize = modeBuf + depthBytes; + mergeFlag = partSize + depthBytes; + X265_FREAD(partSize, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->partSize); + X265_FREAD(mergeFlag, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->mergeFlag); + + if (m_param->analysisReuseLevel == 10) { - chromaDir = interDir + depthBytes; - X265_FREAD(chromaDir, sizeof(uint8_t), depthBytes, m_analysisFileIn, intraPic->chromaModes); - } - for (uint32_t i = 0; i < numDir; i++) - { - mvpIdx[i] = X265_MALLOC(uint8_t, depthBytes); - refIdx[i] = X265_MALLOC(int8_t, depthBytes); - mv[i] = X265_MALLOC(MV, depthBytes); - X265_FREAD(mvpIdx[i], sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->mvpIdx[i]); - X265_FREAD(refIdx[i], sizeof(int8_t), depthBytes, m_analysisFileIn, interPic->refIdx[i]); - X265_FREAD(mv[i], sizeof(MV), depthBytes, m_analysisFileIn, interPic->mv[i]); + interDir = mergeFlag + depthBytes; + X265_FREAD(interDir, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->interDir); + if (bIntraInInter) + { + chromaDir = interDir + depthBytes; + X265_FREAD(chromaDir, sizeof(uint8_t), depthBytes, m_analysisFileIn, intraPic->chromaModes); + } + for (uint32_t i = 0; i < numDir; i++) + { + mvpIdx[i] = X265_MALLOC(uint8_t, depthBytes); + refIdx[i] = X265_MALLOC(int8_t, depthBytes); + mv[i] = X265_MALLOC(MV, depthBytes); + X265_FREAD(mvpIdx[i], sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->mvpIdx[i]); + X265_FREAD(refIdx[i], sizeof(int8_t), depthBytes, m_analysisFileIn, interPic->refIdx[i]); + X265_FREAD(mv[i], sizeof(MV), depthBytes, m_analysisFileIn, interPic->mv[i]); + } } } - } - - size_t count = 0; - for (uint32_t d = 0; d < depthBytes; d++) - { - int bytes = analysis->numPartitions >> (depthBuf[d] * 2); - if (m_param->scaleFactor && modeBuf[d] == MODE_INTRA && depthBuf[d] == 0) - depthBuf[d] = 1; - memset(&(analysis->interData)->depth[count], depthBuf[d], bytes); - memset(&(analysis->interData)->modes[count], modeBuf[d], bytes); - if (m_param->rc.cuTree) - memset(&(analysis->interData)->cuQPOff[count], cuQPBuf[d], bytes); - if (m_param->analysisReuseLevel > 4) + + size_t count = 0; + for (uint32_t d = 0; d < depthBytes; d++) { - if (m_param->scaleFactor && modeBuf[d] == MODE_INTRA && partSize[d] == SIZE_NxN) - partSize[d] = SIZE_2Nx2N; - memset(&(analysis->interData)->partSize[count], partSize[d], bytes); - int numPU = (modeBuf[d] == MODE_INTRA) ? 1 : nbPartsTable[(int)partSize[d]]; - for (int pu = 0; pu < numPU; pu++) + int bytes = analysis->numPartitions >> (depthBuf[d] * 2); + if (m_param->scaleFactor && modeBuf[d] == MODE_INTRA && depthBuf[d] == 0) + depthBuf[d] = 1; + memset(&(analysis->interData)->depth[count], depthBuf[d], bytes); + memset(&(analysis->interData)->modes[count], modeBuf[d], bytes); + if (m_param->rc.cuTree) + memset(&(analysis->interData)->cuQPOff[count], cuQPBuf[d], bytes); + if (m_param->analysisReuseLevel > 4) { - if (pu) d++; - (analysis->interData)->mergeFlag[count + pu] = mergeFlag[d]; - if (m_param->analysisReuseLevel == 10) + if (m_param->scaleFactor && modeBuf[d] == MODE_INTRA && partSize[d] == SIZE_NxN) + partSize[d] = SIZE_2Nx2N; + memset(&(analysis->interData)->partSize[count], partSize[d], bytes); + int numPU = (modeBuf[d] == MODE_INTRA) ? 1 : nbPartsTable[(int)partSize[d]]; + for (int pu = 0; pu < numPU; pu++) { - (analysis->interData)->interDir[count + pu] = interDir[d]; - for (uint32_t i = 0; i < numDir; i++) + if (pu) d++; + (analysis->interData)->mergeFlag[count + pu] = mergeFlag[d]; + if (m_param->analysisReuseLevel == 10) { - (analysis->interData)->mvpIdx[i][count + pu] = mvpIdx[i][d]; - (analysis->interData)->refIdx[i][count + pu] = refIdx[i][d]; - if (m_param->scaleFactor) + (analysis->interData)->interDir[count + pu] = interDir[d]; + for (uint32_t i = 0; i < numDir; i++) { - mv[i][d].x *= (int16_t)m_param->scaleFactor; - mv[i][d].y *= (int16_t)m_param->scaleFactor; + (analysis->interData)->mvpIdx[i][count + pu] = mvpIdx[i][d]; + (analysis->interData)->refIdx[i][count + pu] = refIdx[i][d]; + if (m_param->scaleFactor) + { + mv[i][d].x *= (int16_t)m_param->scaleFactor; + mv[i][d].y *= (int16_t)m_param->scaleFactor; + } + memcpy(&(analysis->interData)->mv[i][count + pu], &mv[i][d], sizeof(MV)); } - memcpy(&(analysis->interData)->mv[i][count + pu], &mv[i][d], sizeof(MV)); } } + if (m_param->analysisReuseLevel == 10 && bIntraInInter) + memset(&(analysis->intraData)->chromaModes[count], chromaDir[d], bytes); } - if (m_param->analysisReuseLevel == 10 && bIntraInInter) - memset(&(analysis->intraData)->chromaModes[count], chromaDir[d], bytes); + count += bytes; } - count += bytes; + + if (m_param->rc.cuTree) + X265_FREE(cuQPBuf); + X265_FREE(tempBuf); } - - if (m_param->rc.cuTree) - X265_FREE(cuQPBuf); - X265_FREE(tempBuf); - if (m_param->analysisReuseLevel == 10) { - for (uint32_t i = 0; i < numDir; i++) + if (m_param->bAnalysisType != HEVC_INFO) { - X265_FREE(mvpIdx[i]); - X265_FREE(refIdx[i]); - X265_FREE(mv[i]); + for (uint32_t i = 0; i < numDir; i++) + { + X265_FREE(mvpIdx[i]); + X265_FREE(refIdx[i]); + X265_FREE(mv[i]); + } } if (bIntraInInter) { diff -r 23a8a7456916 -r d571bdb0b0ae source/encoder/slicetype.cpp --- a/source/encoder/slicetype.cpp Wed Sep 19 14:30:48 2018 -0700 +++ b/source/encoder/slicetype.cpp Thu Sep 20 10:28:00 2018 -0700 @@ -1090,7 +1090,7 @@ if (m_param->rc.cuTree && !m_param->rc.bStatRead) /* update row satds based on cutree offsets */ curFrame->m_lowres.satdCost = frameCostRecalculate(frames, p0, p1, b); - else if (!m_param->analysisLoad || m_param->scaleFactor) + else if (!m_param->analysisLoad || m_param->scaleFactor || m_param->bAnalysisType == HEVC_INFO) { if (m_param->rc.aqMode) curFrame->m_lowres.satdCost = curFrame->m_lowres.costEstAq[b - p0][p1 - b]; @@ -1245,7 +1245,7 @@ } int bframes, brefs; - if (!m_param->analysisLoad) + if (!m_param->analysisLoad || m_param->bAnalysisType == HEVC_INFO) { for (bframes = 0, brefs = 0;; bframes++) { diff -r 23a8a7456916 -r d571bdb0b0ae source/x265.h --- a/source/x265.h Wed Sep 19 14:30:48 2018 -0700 +++ b/source/x265.h Thu Sep 20 10:28:00 2018 -0700 @@ -317,6 +317,7 @@ { NO_INFO = 0, AVC_INFO = 1, + HEVC_INFO = 2, }AnalysisRefineType; /* Arbitrary User SEI diff -r 23a8a7456916 -r d571bdb0b0ae source/x265cli.h --- a/source/x265cli.h Wed Sep 19 14:30:48 2018 -0700 +++ b/source/x265cli.h Thu Sep 20 10:28:00 2018 -0700 @@ -501,7 +501,7 @@ H0(" --analysis-load <filename> Load analysis buffers from the file specified. Default Disabled\n"); H0(" --analysis-reuse-file <filename> Specify file name used for either dumping or reading analysis data. Deault x265_analysis.dat\n"); H0(" --analysis-reuse-level <1..10> Level of analysis reuse indicates amount of info stored/reused in save/load mode, 1:least..10:most. Default %d\n", param->analysisReuseLevel); - H0(" --refine-analysis-type <string> Reuse anlaysis information received through API call. Supported options are avc. Default disabled - %d\n", param->bAnalysisType); + H0(" --refine-analysis-type <string> Reuse anlaysis information received through API call. Supported options are avc and hevc. Default disabled - %d\n", param->bAnalysisType); H0(" --scale-factor <int> Specify factor by which input video is scaled down for analysis save mode. Default %d\n", param->scaleFactor); H0(" --refine-intra <0..4> Enable intra refinement for encode that uses analysis-load.\n" " - 0 : Forces both mode and depth from the save encode.\n"
# HG changeset patch # User Jayashri Murugan # Date 1537464480 25200 # Thu Sep 20 10:28:00 2018 -0700 # Node ID d571bdb0b0ae9894dce12d9d0fc3ea4d639a01a2 # Parent 23a8a7456916d98040b56a09a93ce3b1149613d9 Reuse CU depth for B frame and allow I, P frame to follow x265 depth decision diff -r 23a8a7456916 -r d571bdb0b0ae source/common/param.cpp --- a/source/common/param.cpp Wed Sep 19 14:30:48 2018 -0700 +++ b/source/common/param.cpp Thu Sep 20 10:28:00 2018 -0700 @@ -1157,6 +1157,10 @@ { p->bAnalysisType = AVC_INFO; } + else if (strcmp(strdup(value), "hevc") == 0) + { + p->bAnalysisType = HEVC_INFO; + } else if (strcmp(strdup(value), "off") == 0) { p->bAnalysisType = NO_INFO; @@ -1714,7 +1718,11 @@ TOOLVAL(param->lookaheadThreads, "lthreads=%d") TOOLVAL(param->bCTUInfo, "ctu-info=%d"); if (param->bAnalysisType == AVC_INFO) + { TOOLOPT(param->bAnalysisType, "refine-analysis-type=avc"); + } + else if (param->bAnalysisType == HEVC_INFO) + TOOLOPT(param->bAnalysisType, "refine-analysis-type=hevc"); TOOLOPT(param->bDynamicRefine, "dynamic-refine"); if (param->maxSlices > 1) TOOLVAL(param->maxSlices, "slices=%d"); diff -r 23a8a7456916 -r d571bdb0b0ae source/encoder/analysis.cpp --- a/source/encoder/analysis.cpp Wed Sep 19 14:30:48 2018 -0700 +++ b/source/encoder/analysis.cpp Thu Sep 20 10:28:00 2018 -0700 @@ -275,7 +275,8 @@ /* generate residual for entire CTU at once and copy to reconPic */ encodeResidue(ctu, cuGeom); } - else if ((m_param->analysisLoad && m_param->analysisReuseLevel == 10) || ((m_param->bAnalysisType == AVC_INFO) && m_param->analysisReuseLevel >= 7 && ctu.m_numPartitions <= 16)) + else if ((m_param->analysisLoad && m_param->analysisReuseLevel == 10 && (!(m_param->bAnalysisType == HEVC_INFO) || m_slice->m_sliceType != P_SLICE)) || + ((m_param->bAnalysisType == AVC_INFO) && m_param->analysisReuseLevel >= 7 && ctu.m_numPartitions <= 16)) { x265_analysis_inter_data* interDataCTU = m_frame->m_analysisData.interData; int posCTU = ctu.m_cuAddr * numPartition; @@ -516,7 +517,7 @@ bool mightSplit = !(cuGeom.flags & CUGeom::LEAF); bool mightNotSplit = !(cuGeom.flags & CUGeom::SPLIT_MANDATORY); - bool bAlreadyDecided = m_param->intraRefine != 4 && parentCTU.m_lumaIntraDir[cuGeom.absPartIdx] != (uint8_t)ALL_IDX; + bool bAlreadyDecided = m_param->intraRefine != 4 && parentCTU.m_lumaIntraDir[cuGeom.absPartIdx] != (uint8_t)ALL_IDX && !(m_param->bAnalysisType == HEVC_INFO); bool bDecidedDepth = m_param->intraRefine != 4 && parentCTU.m_cuDepth[cuGeom.absPartIdx] == depth; int split = 0; if (m_param->intraRefine && m_param->intraRefine != 4) @@ -2423,7 +2424,7 @@ (m_refineLevel && cuGeom.log2CUSize == (uint32_t)(g_log2Size[m_param->minCUSize] + 1)))); td.split = split; - if (bDecidedDepth && mightNotSplit) + if ((bDecidedDepth && mightNotSplit) || (m_param->bAnalysisType == HEVC_INFO && parentCTU.m_cuDepth[cuGeom.absPartIdx] == 4)) { setLambdaFromQP(parentCTU, qp, lqp); @@ -2562,7 +2563,10 @@ if (m_refineLevel > 1 || (m_refineLevel && parentCTU.m_predMode[cuGeom.absPartIdx] == MODE_SKIP && !mode.cu.isSkipped(0))) { - m_evaluateInter = 1; + if (parentCTU.m_cuDepth[cuGeom.absPartIdx] < 4 && mightNotSplit) + m_evaluateInter = 1; + else + bDecidedDepth = true; m_param->rdLevel > 4 ? compressInterCU_rd5_6(parentCTU, cuGeom, qp) : compressInterCU_rd0_4(parentCTU, cuGeom, qp); m_evaluateInter = 0; } diff -r 23a8a7456916 -r d571bdb0b0ae source/encoder/api.cpp --- a/source/encoder/api.cpp Wed Sep 19 14:30:48 2018 -0700 +++ b/source/encoder/api.cpp Thu Sep 20 10:28:00 2018 -0700 @@ -463,20 +463,20 @@ //Allocate memory for intraData pointer CHECKED_MALLOC_ZERO(intraData, x265_analysis_intra_data, 1); CHECKED_MALLOC(intraData->depth, uint8_t, analysis->numPartitions * analysis->numCUsInFrame); - CHECKED_MALLOC(intraData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame); - CHECKED_MALLOC(intraData->partSizes, char, analysis->numPartitions * analysis->numCUsInFrame); - CHECKED_MALLOC(intraData->chromaModes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame); + CHECKED_MALLOC_ZERO(intraData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame); + CHECKED_MALLOC_ZERO(intraData->partSizes, char, analysis->numPartitions * analysis->numCUsInFrame); + CHECKED_MALLOC_ZERO(intraData->chromaModes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame); if (param->rc.cuTree) - CHECKED_MALLOC(intraData->cuQPOff, int8_t, analysis->numPartitions * analysis->numCUsInFrame); + CHECKED_MALLOC_ZERO(intraData->cuQPOff, int8_t, analysis->numPartitions * analysis->numCUsInFrame); analysis->intraData = intraData; //Allocate memory for interData pointer based on ReuseLevels CHECKED_MALLOC_ZERO(interData, x265_analysis_inter_data, 1); CHECKED_MALLOC(interData->depth, uint8_t, analysis->numPartitions * analysis->numCUsInFrame); - CHECKED_MALLOC(interData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame); + CHECKED_MALLOC_ZERO(interData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame); if (param->rc.cuTree) - CHECKED_MALLOC(interData->cuQPOff, int8_t, analysis->numPartitions * analysis->numCUsInFrame); + CHECKED_MALLOC_ZERO(interData->cuQPOff, int8_t, analysis->numPartitions * analysis->numCUsInFrame); CHECKED_MALLOC_ZERO(interData->mvpIdx[0], uint8_t, analysis->numPartitions * analysis->numCUsInFrame); CHECKED_MALLOC_ZERO(interData->mvpIdx[1], uint8_t, analysis->numPartitions * analysis->numCUsInFrame); CHECKED_MALLOC_ZERO(interData->mv[0], x265_analysis_MV, analysis->numPartitions * analysis->numCUsInFrame); @@ -484,16 +484,16 @@ if (param->analysisReuseLevel > 4) { - CHECKED_MALLOC(interData->partSize, uint8_t, analysis->numPartitions * analysis->numCUsInFrame); + CHECKED_MALLOC_ZERO(interData->partSize, uint8_t, analysis->numPartitions * analysis->numCUsInFrame); CHECKED_MALLOC_ZERO(interData->mergeFlag, uint8_t, analysis->numPartitions * analysis->numCUsInFrame); } if (param->analysisReuseLevel >= 7) { - CHECKED_MALLOC(interData->interDir, uint8_t, analysis->numPartitions * analysis->numCUsInFrame); - CHECKED_MALLOC(interData->sadCost, int64_t, analysis->numPartitions * analysis->numCUsInFrame); + CHECKED_MALLOC_ZERO(interData->interDir, uint8_t, analysis->numPartitions * analysis->numCUsInFrame); + CHECKED_MALLOC_ZERO(interData->sadCost, int64_t, analysis->numPartitions * analysis->numCUsInFrame); for (int dir = 0; dir < numDir; dir++) { - CHECKED_MALLOC(interData->refIdx[dir], int8_t, analysis->numPartitions * analysis->numCUsInFrame); + CHECKED_MALLOC_ZERO(interData->refIdx[dir], int8_t, analysis->numPartitions * analysis->numCUsInFrame); CHECKED_MALLOC_ZERO(analysis->modeFlag[dir], uint8_t, analysis->numPartitions * analysis->numCUsInFrame); } } diff -r 23a8a7456916 -r d571bdb0b0ae source/encoder/encoder.cpp --- a/source/encoder/encoder.cpp Wed Sep 19 14:30:48 2018 -0700 +++ b/source/encoder/encoder.cpp Thu Sep 20 10:28:00 2018 -0700 @@ -1145,7 +1145,7 @@ { /* reads analysis data for the frame and allocates memory based on slicetype */ static int paramBytes = 0; - if (!inFrame->m_poc) + if (!inFrame->m_poc && m_param->bAnalysisType != HEVC_INFO) { x265_analysis_data analysisData = pic_in->analysisData; paramBytes = validateAnalysisData(&analysisData, 0); @@ -2885,7 +2885,7 @@ p->rc.rfConstantMin = 0; } - if ((p->analysisLoad || p->analysisSave) && p->rc.cuTree && p->analysisReuseLevel < 10) + if (!(p->bAnalysisType == HEVC_INFO) && (p->analysisLoad || p->analysisSave) && p->rc.cuTree && p->analysisReuseLevel < 10) { x265_log(p, X265_LOG_WARNING, "cu-tree works only with analysis reuse level 10, Disabling cu-tree\n"); p->rc.cuTree = 0; @@ -2954,7 +2954,7 @@ p->interRefine = 1; } - if (p->limitTU && (p->interRefine || p->bDynamicRefine)) + if (!(p->bAnalysisType == HEVC_INFO) && p->limitTU && (p->interRefine || p->bDynamicRefine)) { x265_log(p, X265_LOG_WARNING, "Inter refinement does not support limitTU. Disabling limitTU.\n"); p->limitTU = 0; @@ -3465,6 +3465,8 @@ } if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType == X265_TYPE_I) { + if (m_param->bAnalysisType == HEVC_INFO) + return; if (m_param->analysisReuseLevel < 2) return; @@ -3542,98 +3544,107 @@ bIntraInInter = (analysis->sliceType == X265_TYPE_P || m_param->bIntraInBFrames); if (bIntraInInter) numBuf++; } - - tempBuf = X265_MALLOC(uint8_t, depthBytes * numBuf); - depthBuf = tempBuf; - modeBuf = tempBuf + depthBytes; - if (m_param->rc.cuTree) - cuQPBuf = X265_MALLOC(int8_t, depthBytes); - - X265_FREAD(depthBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->depth); - X265_FREAD(modeBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->modes); - if (m_param->rc.cuTree) { X265_FREAD(cuQPBuf, sizeof(int8_t), depthBytes, m_analysisFileIn, interPic->cuQPOff); } - - if (m_param->analysisReuseLevel > 4) + if (m_param->bAnalysisType == HEVC_INFO) + { + depthBytes = analysis->numCUsInFrame * analysis->numPartitions; + memcpy(((x265_analysis_inter_data *)analysis->interData)->depth, interPic->depth, depthBytes); + } + else { - partSize = modeBuf + depthBytes; - mergeFlag = partSize + depthBytes; - X265_FREAD(partSize, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->partSize); - X265_FREAD(mergeFlag, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->mergeFlag); - - if (m_param->analysisReuseLevel == 10) + tempBuf = X265_MALLOC(uint8_t, depthBytes * numBuf); + depthBuf = tempBuf; + modeBuf = tempBuf + depthBytes; + if (m_param->rc.cuTree) + cuQPBuf = X265_MALLOC(int8_t, depthBytes); + + X265_FREAD(depthBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->depth); + X265_FREAD(modeBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->modes); + if (m_param->rc.cuTree) { X265_FREAD(cuQPBuf, sizeof(int8_t), depthBytes, m_analysisFileIn, interPic->cuQPOff); } + + if (m_param->analysisReuseLevel > 4) { - interDir = mergeFlag + depthBytes; - X265_FREAD(interDir, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->interDir); - if (bIntraInInter) + partSize = modeBuf + depthBytes; + mergeFlag = partSize + depthBytes; + X265_FREAD(partSize, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->partSize); + X265_FREAD(mergeFlag, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->mergeFlag); + + if (m_param->analysisReuseLevel == 10) { - chromaDir = interDir + depthBytes; - X265_FREAD(chromaDir, sizeof(uint8_t), depthBytes, m_analysisFileIn, intraPic->chromaModes); - } - for (uint32_t i = 0; i < numDir; i++) - { - mvpIdx[i] = X265_MALLOC(uint8_t, depthBytes); - refIdx[i] = X265_MALLOC(int8_t, depthBytes); - mv[i] = X265_MALLOC(MV, depthBytes); - X265_FREAD(mvpIdx[i], sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->mvpIdx[i]); - X265_FREAD(refIdx[i], sizeof(int8_t), depthBytes, m_analysisFileIn, interPic->refIdx[i]); - X265_FREAD(mv[i], sizeof(MV), depthBytes, m_analysisFileIn, interPic->mv[i]); + interDir = mergeFlag + depthBytes; + X265_FREAD(interDir, sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->interDir); + if (bIntraInInter) + { + chromaDir = interDir + depthBytes; + X265_FREAD(chromaDir, sizeof(uint8_t), depthBytes, m_analysisFileIn, intraPic->chromaModes); + } + for (uint32_t i = 0; i < numDir; i++) + { + mvpIdx[i] = X265_MALLOC(uint8_t, depthBytes); + refIdx[i] = X265_MALLOC(int8_t, depthBytes); + mv[i] = X265_MALLOC(MV, depthBytes); + X265_FREAD(mvpIdx[i], sizeof(uint8_t), depthBytes, m_analysisFileIn, interPic->mvpIdx[i]); + X265_FREAD(refIdx[i], sizeof(int8_t), depthBytes, m_analysisFileIn, interPic->refIdx[i]); + X265_FREAD(mv[i], sizeof(MV), depthBytes, m_analysisFileIn, interPic->mv[i]); + } } } - } - - size_t count = 0; - for (uint32_t d = 0; d < depthBytes; d++) - { - int bytes = analysis->numPartitions >> (depthBuf[d] * 2); - if (m_param->scaleFactor && modeBuf[d] == MODE_INTRA && depthBuf[d] == 0) - depthBuf[d] = 1; - memset(&(analysis->interData)->depth[count], depthBuf[d], bytes); - memset(&(analysis->interData)->modes[count], modeBuf[d], bytes); - if (m_param->rc.cuTree) - memset(&(analysis->interData)->cuQPOff[count], cuQPBuf[d], bytes); - if (m_param->analysisReuseLevel > 4) + + size_t count = 0; + for (uint32_t d = 0; d < depthBytes; d++) { - if (m_param->scaleFactor && modeBuf[d] == MODE_INTRA && partSize[d] == SIZE_NxN) - partSize[d] = SIZE_2Nx2N; - memset(&(analysis->interData)->partSize[count], partSize[d], bytes); - int numPU = (modeBuf[d] == MODE_INTRA) ? 1 : nbPartsTable[(int)partSize[d]]; - for (int pu = 0; pu < numPU; pu++) + int bytes = analysis->numPartitions >> (depthBuf[d] * 2); + if (m_param->scaleFactor && modeBuf[d] == MODE_INTRA && depthBuf[d] == 0) + depthBuf[d] = 1; + memset(&(analysis->interData)->depth[count], depthBuf[d], bytes); + memset(&(analysis->interData)->modes[count], modeBuf[d], bytes); + if (m_param->rc.cuTree) + memset(&(analysis->interData)->cuQPOff[count], cuQPBuf[d], bytes); + if (m_param->analysisReuseLevel > 4) { - if (pu) d++; - (analysis->interData)->mergeFlag[count + pu] = mergeFlag[d]; - if (m_param->analysisReuseLevel == 10) + if (m_param->scaleFactor && modeBuf[d] == MODE_INTRA && partSize[d] == SIZE_NxN) + partSize[d] = SIZE_2Nx2N; + memset(&(analysis->interData)->partSize[count], partSize[d], bytes); + int numPU = (modeBuf[d] == MODE_INTRA) ? 1 : nbPartsTable[(int)partSize[d]]; + for (int pu = 0; pu < numPU; pu++) { - (analysis->interData)->interDir[count + pu] = interDir[d]; - for (uint32_t i = 0; i < numDir; i++) + if (pu) d++; + (analysis->interData)->mergeFlag[count + pu] = mergeFlag[d]; + if (m_param->analysisReuseLevel == 10) { - (analysis->interData)->mvpIdx[i][count + pu] = mvpIdx[i][d]; - (analysis->interData)->refIdx[i][count + pu] = refIdx[i][d]; - if (m_param->scaleFactor) + (analysis->interData)->interDir[count + pu] = interDir[d]; + for (uint32_t i = 0; i < numDir; i++) { - mv[i][d].x *= (int16_t)m_param->scaleFactor; - mv[i][d].y *= (int16_t)m_param->scaleFactor; + (analysis->interData)->mvpIdx[i][count + pu] = mvpIdx[i][d]; + (analysis->interData)->refIdx[i][count + pu] = refIdx[i][d]; + if (m_param->scaleFactor) + { + mv[i][d].x *= (int16_t)m_param->scaleFactor; + mv[i][d].y *= (int16_t)m_param->scaleFactor; + } + memcpy(&(analysis->interData)->mv[i][count + pu], &mv[i][d], sizeof(MV)); } - memcpy(&(analysis->interData)->mv[i][count + pu], &mv[i][d], sizeof(MV)); } } + if (m_param->analysisReuseLevel == 10 && bIntraInInter) + memset(&(analysis->intraData)->chromaModes[count], chromaDir[d], bytes); } - if (m_param->analysisReuseLevel == 10 && bIntraInInter) - memset(&(analysis->intraData)->chromaModes[count], chromaDir[d], bytes); + count += bytes; } - count += bytes; + + if (m_param->rc.cuTree) + X265_FREE(cuQPBuf); + X265_FREE(tempBuf); } - - if (m_param->rc.cuTree) - X265_FREE(cuQPBuf); - X265_FREE(tempBuf); - if (m_param->analysisReuseLevel == 10) { - for (uint32_t i = 0; i < numDir; i++) + if (m_param->bAnalysisType != HEVC_INFO) { - X265_FREE(mvpIdx[i]); - X265_FREE(refIdx[i]); - X265_FREE(mv[i]); + for (uint32_t i = 0; i < numDir; i++) + { + X265_FREE(mvpIdx[i]); + X265_FREE(refIdx[i]); + X265_FREE(mv[i]); + } } if (bIntraInInter) { diff -r 23a8a7456916 -r d571bdb0b0ae source/encoder/slicetype.cpp --- a/source/encoder/slicetype.cpp Wed Sep 19 14:30:48 2018 -0700 +++ b/source/encoder/slicetype.cpp Thu Sep 20 10:28:00 2018 -0700 @@ -1090,7 +1090,7 @@ if (m_param->rc.cuTree && !m_param->rc.bStatRead) /* update row satds based on cutree offsets */ curFrame->m_lowres.satdCost = frameCostRecalculate(frames, p0, p1, b); - else if (!m_param->analysisLoad || m_param->scaleFactor) + else if (!m_param->analysisLoad || m_param->scaleFactor || m_param->bAnalysisType == HEVC_INFO) { if (m_param->rc.aqMode) curFrame->m_lowres.satdCost = curFrame->m_lowres.costEstAq[b - p0][p1 - b]; @@ -1245,7 +1245,7 @@ } int bframes, brefs; - if (!m_param->analysisLoad) + if (!m_param->analysisLoad || m_param->bAnalysisType == HEVC_INFO) { for (bframes = 0, brefs = 0;; bframes++) { diff -r 23a8a7456916 -r d571bdb0b0ae source/x265.h --- a/source/x265.h Wed Sep 19 14:30:48 2018 -0700 +++ b/source/x265.h Thu Sep 20 10:28:00 2018 -0700 @@ -317,6 +317,7 @@ { NO_INFO = 0, AVC_INFO = 1, + HEVC_INFO = 2, }AnalysisRefineType; /* Arbitrary User SEI diff -r 23a8a7456916 -r d571bdb0b0ae source/x265cli.h --- a/source/x265cli.h Wed Sep 19 14:30:48 2018 -0700 +++ b/source/x265cli.h Thu Sep 20 10:28:00 2018 -0700 @@ -501,7 +501,7 @@ H0(" --analysis-load <filename> Load analysis buffers from the file specified. Default Disabled\n"); H0(" --analysis-reuse-file <filename> Specify file name used for either dumping or reading analysis data. Deault x265_analysis.dat\n"); H0(" --analysis-reuse-level <1..10> Level of analysis reuse indicates amount of info stored/reused in save/load mode, 1:least..10:most. Default %d\n", param->analysisReuseLevel); - H0(" --refine-analysis-type <string> Reuse anlaysis information received through API call. Supported options are avc. Default disabled - %d\n", param->bAnalysisType); + H0(" --refine-analysis-type <string> Reuse anlaysis information received through API call. Supported options are avc and hevc. Default disabled - %d\n", param->bAnalysisType); H0(" --scale-factor <int> Specify factor by which input video is scaled down for analysis save mode. Default %d\n", param->scaleFactor); H0(" --refine-intra <0..4> Enable intra refinement for encode that uses analysis-load.\n" " - 0 : Forces both mode and depth from the save encode.\n"
_______________________________________________ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel