[x265] [PATCH 1 of 3] De-couple analysis reuse levels of --analysis-save and --analysis-load
Aruna Matheswaran
aruna at multicorewareinc.com
Fri Jan 10 12:54:17 CET 2020
Resent the patch after re-basing on default tip; Please ignore this.
On Tue, Jan 7, 2020 at 2:25 PM Aruna Matheswaran <aruna at multicorewareinc.com>
wrote:
> # HG changeset patch
> # User Aruna Matheswaran <aruna at multicorewareinc.com>
> # Date 1576499107 -19800
> # Mon Dec 16 17:55:07 2019 +0530
> # Node ID 4d870dd7c314334b27413de922d08d9c01d5860b
> # Parent 52135ffd9bcdd32b944311e9e66c473894c0a2bd
> De-couple analysis reuse levels of --analysis-save and --analysis-load.
>
> Currently, analysis reuse level of the load encode has to be the same as
> that of
> the reuse level of the save encode. This commit de-couples the reuse level
> constraints and let the load encode re-use a subset of the available
> analysis
> info.
>
> Two CLI and x265_param options are introduced to get the desired reuse
> level
> during save and load.
>
> The existing option --analysis-reuse-level is deprecated.
>
> diff -r 52135ffd9bcd -r 4d870dd7c314 doc/reST/cli.rst
> --- a/doc/reST/cli.rst Mon Dec 23 14:40:32 2019 +0530
> +++ b/doc/reST/cli.rst Mon Dec 16 17:55:07 2019 +0530
> @@ -918,12 +918,14 @@
> Specify a filename for `multi-pass-opt-analysis` and
> `multi-pass-opt-distortion`.
> If no filename is specified, x265_analysis.dat is used.
>
> -.. option:: --analysis-reuse-level <1..10>
> -
> - Amount of information stored/reused in
> :option:`--analysis-reuse-mode` is distributed across levels.
> +.. option:: --analysis-save-reuse-level <1..10>,
> --analysis-load-reuse-level <1..10>
> +
> + :option:`--analysis-save-reuse-level` denotes the amount of
> information stored during :option:`--analysis-save` and
> + :option:`--analysis-load-reuse-level` denotes the amount of
> information reused during :option:`--analysis-load`.
> Higher the value, higher the information stored/reused, faster the
> encode. Default 5.
>
> - Note that --analysis-reuse-level must be paired with
> analysis-reuse-mode.
> + Note that :option:`--analysis-save-reuse-level` and
> :option:`--analysis-load-reuse-level` must be paired
> + with :option:`--analysis-save` and :option:`--analysis-load`
> respectively.
>
> +--------------+------------------------------------------+
> | Level | Description |
> diff -r 52135ffd9bcd -r 4d870dd7c314 source/CMakeLists.txt
> --- a/source/CMakeLists.txt Mon Dec 23 14:40:32 2019 +0530
> +++ b/source/CMakeLists.txt Mon Dec 16 17:55:07 2019 +0530
> @@ -29,7 +29,7 @@
> option(STATIC_LINK_CRT "Statically link C runtime for release builds" OFF)
> mark_as_advanced(FPROFILE_USE FPROFILE_GENERATE NATIVE_BUILD)
> # X265_BUILD must be incremented each time the public API is changed
> -set(X265_BUILD 184)
> +set(X265_BUILD 185)
> configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
> "${PROJECT_BINARY_DIR}/x265.def")
> configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
> diff -r 52135ffd9bcd -r 4d870dd7c314 source/common/param.cpp
> --- a/source/common/param.cpp Mon Dec 23 14:40:32 2019 +0530
> +++ b/source/common/param.cpp Mon Dec 16 17:55:07 2019 +0530
> @@ -319,7 +319,9 @@
> param->bOptCUDeltaQP = 0;
> param->bAQMotion = 0;
> param->bHDROpt = 0;
> - param->analysisReuseLevel = 5;
> + param->analysisReuseLevel = 0; /*DEPRECATED*/
> + param->analysisSaveReuseLevel = 0;
> + param->analysisLoadReuseLevel = 0;
> param->toneMapFile = NULL;
> param->bDhdr10opt = 0;
> param->dolbyProfile = 0;
> @@ -1219,7 +1221,14 @@
> OPT("multi-pass-opt-distortion") p->analysisMultiPassDistortion =
> atobool(value);
> OPT("aq-motion") p->bAQMotion = atobool(value);
> OPT("dynamic-rd") p->dynamicRd = atof(value);
> - OPT("analysis-reuse-level") p->analysisReuseLevel = atoi(value);
> + OPT("analysis-reuse-level")
> + {
> + p->analysisReuseLevel = atoi(value);
> + p->analysisSaveReuseLevel = atoi(value);
> + p->analysisLoadReuseLevel = atoi(value);
> + }
> + OPT("analysis-save-reuse-level") p->analysisSaveReuseLevel =
> atoi(value);
> + OPT("analysis-load-reuse-level") p->analysisLoadReuseLevel =
> atoi(value);
> OPT("ssim-rd")
> {
> int bval = atobool(value);
> @@ -1260,7 +1269,7 @@
> }
> else if (strcmp(strdup(value), "off") == 0)
> {
> - p->bAnalysisType = NO_INFO;
> + p->bAnalysisType = DEFAULT;
> }
> else
> {
> @@ -1696,8 +1705,10 @@
> "Constant QP is incompatible with 2pass");
> CHECK(param->rc.bStrictCbr && (param->rc.bitrate <= 0 ||
> param->rc.vbvBufferSize <=0),
> "Strict-cbr cannot be applied without specifying target bitrate
> or vbv bufsize");
> - CHECK((param->analysisSave || param->analysisLoad) &&
> (param->analysisReuseLevel < 1 || param->analysisReuseLevel > 10),
> - "Invalid analysis refine level. Value must be between 1 and 10
> (inclusive)");
> + CHECK(param->analysisSave && (param->analysisSaveReuseLevel < 1 ||
> param->analysisSaveReuseLevel > 10),
> + "Invalid analysis save refine level. Value must be between 1 and
> 10 (inclusive)");
> + CHECK(param->analysisLoad && (param->analysisLoadReuseLevel < 1 ||
> param->analysisLoadReuseLevel > 10),
> + "Invalid analysis load refine level. Value must be between 1 and
> 10 (inclusive)");
> CHECK(param->analysisLoad && (param->mvRefine < 1 || param->mvRefine
> > 3),
> "Invalid mv refinement level. Value must be between 1 and 3
> (inclusive)");
> CHECK(param->scaleFactor > 2, "Invalid scale-factor. Supports factor
> <= 2");
> @@ -2160,6 +2171,8 @@
> if (p->analysisLoad)
> s += sprintf(s, " analysis-load");
> s += sprintf(s, " analysis-reuse-level=%d", p->analysisReuseLevel);
> + s += sprintf(s, " analysis-save-reuse-level=%d",
> p->analysisSaveReuseLevel);
> + s += sprintf(s, " analysis-load-reuse-level=%d",
> p->analysisLoadReuseLevel);
> s += sprintf(s, " scale-factor=%d", p->scaleFactor);
> s += sprintf(s, " refine-intra=%d", p->intraRefine);
> s += sprintf(s, " refine-inter=%d", p->interRefine);
> @@ -2477,6 +2490,8 @@
> dst->bEmitHRDSEI = src->bEmitHRDSEI;
> dst->bHDROpt = src->bHDROpt;
> dst->analysisReuseLevel = src->analysisReuseLevel;
> + dst->analysisSaveReuseLevel = src->analysisSaveReuseLevel;
> + dst->analysisLoadReuseLevel = src->analysisLoadReuseLevel;
> dst->bLimitSAO = src->bLimitSAO;
> if (src->toneMapFile) dst->toneMapFile = strdup(src->toneMapFile);
> else dst->toneMapFile = NULL;
> diff -r 52135ffd9bcd -r 4d870dd7c314 source/encoder/analysis.cpp
> --- a/source/encoder/analysis.cpp Mon Dec 23 14:40:32 2019 +0530
> +++ b/source/encoder/analysis.cpp Mon Dec 16 17:55:07 2019 +0530
> @@ -202,14 +202,17 @@
> m_reuseDepth = &m_reuseInterDataCTU->depth[ctu.m_cuAddr *
> ctu.m_numPartitions];
> }
>
> - if ((m_param->analysisSave || m_param->analysisLoad) &&
> m_slice->m_sliceType != I_SLICE && m_param->analysisReuseLevel > 1 &&
> m_param->analysisReuseLevel < 10)
> + int reuseLevel = X265_MAX(m_param->analysisSaveReuseLevel,
> m_param->analysisLoadReuseLevel);
> + if ((m_param->analysisSave || m_param->analysisLoad) &&
> m_slice->m_sliceType != I_SLICE && reuseLevel > 1 && reuseLevel < 10)
> {
> int numPredDir = m_slice->isInterP() ? 1 : 2;
> m_reuseInterDataCTU = m_frame->m_analysisData.interData;
> - m_reuseRef = &m_reuseInterDataCTU->ref [ctu.m_cuAddr *
> X265_MAX_PRED_MODE_PER_CTU * numPredDir];
> + if (((m_param->analysisSaveReuseLevel > 1) &&
> (m_param->analysisSaveReuseLevel < 7)) ||
> + ((m_param->analysisLoadReuseLevel > 1) &&
> (m_param->analysisLoadReuseLevel < 7)))
> + m_reuseRef = &m_reuseInterDataCTU->ref[ctu.m_cuAddr *
> X265_MAX_PRED_MODE_PER_CTU * numPredDir];
> m_reuseDepth = &m_reuseInterDataCTU->depth[ctu.m_cuAddr *
> ctu.m_numPartitions];
> m_reuseModes = &m_reuseInterDataCTU->modes[ctu.m_cuAddr *
> ctu.m_numPartitions];
> - if (m_param->analysisReuseLevel > 4)
> + if (reuseLevel > 4)
> {
> m_reusePartSize = &m_reuseInterDataCTU->partSize[ctu.m_cuAddr
> * ctu.m_numPartitions];
> m_reuseMergeFlag =
> &m_reuseInterDataCTU->mergeFlag[ctu.m_cuAddr * ctu.m_numPartitions];
> @@ -223,7 +226,7 @@
> if (m_slice->m_sliceType == I_SLICE)
> {
> x265_analysis_intra_data* intraDataCTU =
> m_frame->m_analysisData.intraData;
> - if (m_param->analysisLoad && m_param->analysisReuseLevel > 1)
> + if (m_param->analysisLoadReuseLevel > 1)
> {
> memcpy(ctu.m_cuDepth, &intraDataCTU->depth[ctu.m_cuAddr *
> numPartition], sizeof(uint8_t) * numPartition);
> memcpy(ctu.m_lumaIntraDir, &intraDataCTU->modes[ctu.m_cuAddr
> * numPartition], sizeof(uint8_t) * numPartition);
> @@ -234,9 +237,9 @@
> }
> else
> {
> - bool bCopyAnalysis = ((m_param->analysisLoad &&
> m_param->analysisReuseLevel == 10) || (m_param->bAnalysisType == AVC_INFO
> && m_param->analysisReuseLevel >= 7 && ctu.m_numPartitions <= 16));
> - bool BCompressInterCUrd0_4 = (m_param->bAnalysisType == AVC_INFO
> && m_param->analysisReuseLevel >= 7 && m_param->rdLevel <= 4);
> - bool BCompressInterCUrd5_6 = (m_param->bAnalysisType == AVC_INFO
> && m_param->analysisReuseLevel >= 7 && m_param->rdLevel >= 5 &&
> m_param->rdLevel <= 6);
> + bool bCopyAnalysis = ((m_param->analysisLoadReuseLevel == 10) ||
> (m_param->bAnalysisType == AVC_INFO && m_param->analysisLoadReuseLevel >= 7
> && ctu.m_numPartitions <= 16));
> + bool BCompressInterCUrd0_4 = (m_param->bAnalysisType == AVC_INFO
> && m_param->analysisLoadReuseLevel >= 7 && m_param->rdLevel <= 4);
> + bool BCompressInterCUrd5_6 = (m_param->bAnalysisType == AVC_INFO
> && m_param->analysisLoadReuseLevel >= 7 && m_param->rdLevel >= 5 &&
> m_param->rdLevel <= 6);
> bCopyAnalysis = bCopyAnalysis || BCompressInterCUrd0_4 ||
> BCompressInterCUrd5_6;
>
> if (bCopyAnalysis)
> @@ -275,8 +278,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 == HEVC_INFO) || m_slice->m_sliceType !=
> P_SLICE)) ||
> - ((m_param->bAnalysisType == AVC_INFO) &&
> m_param->analysisReuseLevel >= 7 && ctu.m_numPartitions <= 16))
> + else if ((m_param->analysisLoadReuseLevel == 10 &&
> (!(m_param->bAnalysisType == HEVC_INFO) || m_slice->m_sliceType !=
> P_SLICE)) ||
> + ((m_param->bAnalysisType == AVC_INFO) &&
> m_param->analysisLoadReuseLevel >= 7 && ctu.m_numPartitions <= 16))
> {
> x265_analysis_inter_data* interDataCTU =
> m_frame->m_analysisData.interData;
> int posCTU = ctu.m_cuAddr * numPartition;
> @@ -456,7 +459,7 @@
> int bestCUQP = qp;
> int lambdaQP = lqp;
> bool doQPRefine = (bDecidedDepth && depth <=
> m_slice->m_pps->maxCuDQPDepth) || (!bDecidedDepth && depth ==
> m_slice->m_pps->maxCuDQPDepth);
> - if (m_param->analysisReuseLevel >= 7)
> + if (m_param->analysisLoadReuseLevel >= 7)
> doQPRefine = false;
> if (doQPRefine)
> {
> @@ -1164,7 +1167,7 @@
> SplitData splitCUData;
>
> bool bHEVCBlockAnalysis = (m_param->bAnalysisType == AVC_INFO &&
> cuGeom.numPartitions > 16);
> - bool bRefineAVCAnalysis = (m_param->analysisReuseLevel == 7 &&
> (m_modeFlag[0] || m_modeFlag[1]));
> + bool bRefineAVCAnalysis = (m_param->analysisLoadReuseLevel == 7 &&
> (m_modeFlag[0] || m_modeFlag[1]));
> bool bNooffloading = !(m_param->bAnalysisType == AVC_INFO);
>
> if (bHEVCBlockAnalysis || bRefineAVCAnalysis || bNooffloading)
> @@ -1259,7 +1262,7 @@
> mightSplit &= !bDecidedDepth;
> }
> }
> - if ((m_param->analysisLoad && m_param->analysisReuseLevel > 1 &&
> m_param->analysisReuseLevel != 10))
> + if ((m_param->analysisLoadReuseLevel > 1 &&
> m_param->analysisLoadReuseLevel != 10))
> {
> if (mightNotSplit && depth == m_reuseDepth[cuGeom.absPartIdx])
> {
> @@ -1273,7 +1276,7 @@
> if (m_param->rdLevel)
> skipModes = m_param->bEnableEarlySkip &&
> md.bestMode;
> }
> - if (m_param->analysisReuseLevel > 4 &&
> m_reusePartSize[cuGeom.absPartIdx] == SIZE_2Nx2N)
> + if (m_param->analysisLoadReuseLevel > 4 &&
> m_reusePartSize[cuGeom.absPartIdx] == SIZE_2Nx2N)
> {
> if (m_reuseModes[cuGeom.absPartIdx] != MODE_INTRA &&
> m_reuseModes[cuGeom.absPartIdx] != 4)
> {
> @@ -1300,7 +1303,8 @@
> }
> }
> /* Step 1. Evaluate Merge/Skip candidates for likely early-outs,
> if skip mode was not set above */
> - if ((mightNotSplit && depth >= minDepth && !md.bestMode &&
> !bCtuInfoCheck) || (m_param->bAnalysisType == AVC_INFO &&
> m_param->analysisReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1]))) /*
> TODO: Re-evaluate if analysis load/save still works */
> + if ((mightNotSplit && depth >= minDepth && !md.bestMode &&
> !bCtuInfoCheck) || (m_param->bAnalysisType == AVC_INFO &&
> m_param->analysisLoadReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1])))
> + /* TODO: Re-evaluate if analysis load/save still works */
> {
> /* Compute Merge Cost */
> md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom, qp);
> @@ -1310,7 +1314,7 @@
> skipModes = (m_param->bEnableEarlySkip || m_refineLevel
> == 2)
> && md.bestMode && md.bestMode->cu.isSkipped(0); // TODO:
> sa8d threshold per depth
> }
> - if (md.bestMode && m_param->bEnableRecursionSkip &&
> !bCtuInfoCheck && !(m_param->bAnalysisType == AVC_INFO &&
> m_param->analysisReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1])))
> + if (md.bestMode && m_param->bEnableRecursionSkip &&
> !bCtuInfoCheck && !(m_param->bAnalysisType == AVC_INFO &&
> m_param->analysisLoadReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1])))
> {
> skipRecursion = md.bestMode->cu.isSkipped(0);
> if (mightSplit && depth >= minDepth && !skipRecursion)
> @@ -1321,7 +1325,7 @@
> skipRecursion = complexityCheckCU(*md.bestMode);
> }
> }
> - if (m_param->bAnalysisType == AVC_INFO && md.bestMode &&
> cuGeom.numPartitions <= 16 && m_param->analysisReuseLevel == 7)
> + if (m_param->bAnalysisType == AVC_INFO && md.bestMode &&
> cuGeom.numPartitions <= 16 && m_param->analysisLoadReuseLevel == 7)
> skipRecursion = true;
> /* Step 2. Evaluate each of the 4 split sub-blocks in series */
> if (mightSplit && !skipRecursion)
> @@ -1378,7 +1382,7 @@
> splitPred->sa8dCost =
> m_rdCost.calcRdSADCost((uint32_t)splitPred->distortion,
> splitPred->sa8dBits);
> }
> /* If analysis mode is simple do not Evaluate other modes */
> - if (m_param->bAnalysisType == AVC_INFO &&
> m_param->analysisReuseLevel == 7)
> + if (m_param->bAnalysisType == AVC_INFO &&
> m_param->analysisLoadReuseLevel == 7)
> {
> if (m_slice->m_sliceType == P_SLICE)
> {
> @@ -1857,7 +1861,7 @@
> SplitData splitCUData;
>
> bool bHEVCBlockAnalysis = (m_param->bAnalysisType == AVC_INFO &&
> cuGeom.numPartitions > 16);
> - bool bRefineAVCAnalysis = (m_param->analysisReuseLevel == 7 &&
> (m_modeFlag[0] || m_modeFlag[1]));
> + bool bRefineAVCAnalysis = (m_param->analysisLoadReuseLevel == 7 &&
> (m_modeFlag[0] || m_modeFlag[1]));
> bool bNooffloading = !(m_param->bAnalysisType == AVC_INFO);
>
> if (bHEVCBlockAnalysis || bRefineAVCAnalysis || bNooffloading)
> @@ -1953,7 +1957,7 @@
> mightSplit &= !bDecidedDepth;
> }
> }
> - if (m_param->analysisLoad && m_param->analysisReuseLevel > 1 &&
> m_param->analysisReuseLevel != 10)
> + if (m_param->analysisLoadReuseLevel > 1 &&
> m_param->analysisLoadReuseLevel != 10)
> {
> if (mightNotSplit && depth == m_reuseDepth[cuGeom.absPartIdx])
> {
> @@ -1971,7 +1975,7 @@
> if (m_param->bEnableRecursionSkip && depth &&
> m_modeDepth[depth - 1].bestMode)
> skipRecursion = md.bestMode &&
> !md.bestMode->cu.getQtRootCbf(0);
> }
> - if (m_param->analysisReuseLevel > 4 &&
> m_reusePartSize[cuGeom.absPartIdx] == SIZE_2Nx2N)
> + if (m_param->analysisLoadReuseLevel > 4 &&
> m_reusePartSize[cuGeom.absPartIdx] == SIZE_2Nx2N)
> skipRectAmp = true && !!md.bestMode;
> }
> }
> @@ -1999,7 +2003,7 @@
> }
> /* Step 1. Evaluate Merge/Skip candidates for likely early-outs */
> if ((mightNotSplit && !md.bestMode && !bCtuInfoCheck) ||
> - (m_param->bAnalysisType == AVC_INFO &&
> m_param->analysisReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1])))
> + (m_param->bAnalysisType == AVC_INFO &&
> m_param->analysisLoadReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1])))
> {
> md.pred[PRED_SKIP].cu.initSubCU(parentCTU, cuGeom, qp);
> md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom, qp);
> @@ -2014,7 +2018,7 @@
> if (m_param->bEnableRecursionSkip && depth &&
> m_modeDepth[depth - 1].bestMode)
> skipRecursion = md.bestMode &&
> !md.bestMode->cu.getQtRootCbf(0);
> }
> - if (m_param->bAnalysisType == AVC_INFO && md.bestMode &&
> cuGeom.numPartitions <= 16 && m_param->analysisReuseLevel == 7)
> + if (m_param->bAnalysisType == AVC_INFO && md.bestMode &&
> cuGeom.numPartitions <= 16 && m_param->analysisLoadReuseLevel == 7)
> skipRecursion = true;
> // estimate split cost
> /* Step 2. Evaluate each of the 4 split sub-blocks in series */
> @@ -2068,7 +2072,7 @@
> checkDQPForSplitPred(*splitPred, cuGeom);
> }
> /* If analysis mode is simple do not Evaluate other modes */
> - if (m_param->bAnalysisType == AVC_INFO &&
> m_param->analysisReuseLevel == 7)
> + if (m_param->bAnalysisType == AVC_INFO &&
> m_param->analysisLoadReuseLevel == 7)
> {
> if (m_slice->m_sliceType == P_SLICE)
> {
> @@ -2461,7 +2465,7 @@
> for (uint32_t part = 0; part < numPU; part++)
> {
> PredictionUnit pu(mode.cu, cuGeom, part);
> - if ((m_param->analysisLoad && m_param->analysisReuseLevel
> == 10) || (m_param->bAnalysisType == AVC_INFO &&
> m_param->analysisReuseLevel >= 7))
> + if (m_param->analysisLoadReuseLevel == 10 ||
> (m_param->bAnalysisType == AVC_INFO && m_param->analysisLoadReuseLevel >=
> 7))
> {
> x265_analysis_inter_data* interDataCTU =
> m_frame->m_analysisData.interData;
> int cuIdx = (mode.cu.m_cuAddr *
> parentCTU.m_numPartitions) + cuGeom.absPartIdx;
> @@ -2552,7 +2556,7 @@
> checkDQPForSplitPred(*md.bestMode, cuGeom);
> }
>
> - if (m_param->bAnalysisType == AVC_INFO &&
> m_param->analysisReuseLevel == 7)
> + if (m_param->bAnalysisType == AVC_INFO &&
> m_param->analysisLoadReuseLevel == 7)
> {
> for (int list = 0; list < m_slice->isInterB() + 1; list++)
> {
> @@ -2607,7 +2611,7 @@
> if (m_slice->m_pps->bUseDQP && nextDepth <=
> m_slice->m_pps->maxCuDQPDepth)
> nextQP = setLambdaFromQP(parentCTU,
> calculateQpforCuSize(parentCTU, childGeom));
>
> - int lamdaQP = (m_param->analysisReuseLevel >= 7) ? nextQP
> : lqp;
> + int lamdaQP = (m_param->analysisLoadReuseLevel >= 7) ?
> nextQP : lqp;
>
> if (split)
> m_param->rdLevel > 4 ?
> compressInterCU_rd5_6(parentCTU, childGeom, nextQP) :
> compressInterCU_rd0_4(parentCTU, childGeom, nextQP);
> @@ -3013,7 +3017,7 @@
> interMode.cu.setPredModeSubParts(MODE_INTER);
> int numPredDir = m_slice->isInterP() ? 1 : 2;
>
> - if (m_param->analysisLoad && m_reuseInterDataCTU &&
> m_param->analysisReuseLevel > 1 && m_param->analysisReuseLevel != 10)
> + if (m_param->analysisLoadReuseLevel > 1 &&
> m_param->analysisLoadReuseLevel != 10 && m_reuseInterDataCTU)
> {
> int refOffset = cuGeom.geomRecurId * 16 * numPredDir + partSize *
> numPredDir * 2;
> int index = 0;
> @@ -3056,7 +3060,7 @@
> }
> interMode.sa8dCost =
> m_rdCost.calcRdSADCost((uint32_t)interMode.distortion, interMode.sa8dBits);
>
> - if (m_param->analysisSave && m_reuseInterDataCTU &&
> m_param->analysisReuseLevel > 1)
> + if (m_param->analysisSaveReuseLevel > 1 && m_reuseInterDataCTU)
> {
> int refOffset = cuGeom.geomRecurId * 16 * numPredDir + partSize *
> numPredDir * 2;
> int index = 0;
> @@ -3078,7 +3082,7 @@
> interMode.cu.setPredModeSubParts(MODE_INTER);
> int numPredDir = m_slice->isInterP() ? 1 : 2;
>
> - if (m_param->analysisLoad && m_reuseInterDataCTU &&
> m_param->analysisReuseLevel > 1 && m_param->analysisReuseLevel != 10)
> + if (m_param->analysisLoadReuseLevel > 1 &&
> m_param->analysisLoadReuseLevel != 10 && m_reuseInterDataCTU)
> {
> int refOffset = cuGeom.geomRecurId * 16 * numPredDir + partSize *
> numPredDir * 2;
> int index = 0;
> @@ -3113,7 +3117,7 @@
> /* predInterSearch sets interMode.sa8dBits, but this is ignored */
> encodeResAndCalcRdInterCU(interMode, cuGeom);
>
> - if (m_param->analysisSave && m_reuseInterDataCTU &&
> m_param->analysisReuseLevel > 1)
> + if (m_param->analysisSaveReuseLevel > 1 && m_reuseInterDataCTU)
> {
> int refOffset = cuGeom.geomRecurId * 16 * numPredDir + partSize *
> numPredDir * 2;
> int index = 0;
> @@ -3612,7 +3616,7 @@
> qp += distortionData->offset[ctu.m_cuAddr];
> }
>
> - if (m_param->analysisLoad && m_param->analysisReuseLevel == 10 &&
> m_param->rc.cuTree)
> + if (m_param->analysisLoadReuseLevel == 10 && m_param->rc.cuTree)
> {
> int cuIdx = (ctu.m_cuAddr * ctu.m_numPartitions) +
> cuGeom.absPartIdx;
> if (ctu.m_slice->m_sliceType == I_SLICE)
> diff -r 52135ffd9bcd -r 4d870dd7c314 source/encoder/api.cpp
> --- a/source/encoder/api.cpp Mon Dec 23 14:40:32 2019 +0530
> +++ b/source/encoder/api.cpp Mon Dec 16 17:55:07 2019 +0530
> @@ -771,6 +771,12 @@
> int numDir = 2; //irrespective of P or B slices set direction as 2
> uint32_t numPlanes = param->internalCsp == X265_CSP_I400 ? 1 : 3;
>
> + int maxReuseLevel = X265_MAX(param->analysisSaveReuseLevel,
> param->analysisLoadReuseLevel);
> + int minReuseLevel = (param->analysisSaveReuseLevel &&
> param->analysisLoadReuseLevel) ?
> + X265_MIN(param->analysisSaveReuseLevel,
> param->analysisLoadReuseLevel) : maxReuseLevel;
> +
> + bool isMultiPassOpt = param->analysisMultiPassRefine ||
> param->analysisMultiPassDistortion;
> +
> #if X265_DEPTH < 10 && (LINKED_10BIT || LINKED_12BIT)
> uint32_t numCUs_sse_t = param->internalBitDepth > 8 ?
> analysis->numCUsInFrame << 1 : analysis->numCUsInFrame;
> #elif X265_DEPTH >= 10 && LINKED_8BIT
> @@ -778,7 +784,7 @@
> #else
> uint32_t numCUs_sse_t = analysis->numCUsInFrame;
> #endif
> - if (param->analysisMultiPassRefine ||
> param->analysisMultiPassDistortion || param->ctuDistortionRefine)
> + if (isMultiPassOpt || param->ctuDistortionRefine)
> {
> //Allocate memory for distortionData pointer
> CHECKED_MALLOC_ZERO(distortionData,
> x265_analysis_distortion_data, 1);
> @@ -792,7 +798,7 @@
> analysis->distortionData = distortionData;
> }
>
> - if (param->bDisableLookahead && isVbv)
> + if (!isMultiPassOpt && param->bDisableLookahead && isVbv)
> {
> CHECKED_MALLOC_ZERO(analysis->lookahead.intraSatdForVbv,
> uint32_t, analysis->numCuInHeight);
> CHECKED_MALLOC_ZERO(analysis->lookahead.satdForVbv, uint32_t,
> analysis->numCuInHeight);
> @@ -801,20 +807,23 @@
> }
>
> //Allocate memory for weightParam pointer
> - if (!(param->bAnalysisType == AVC_INFO))
> + if (!isMultiPassOpt && !(param->bAnalysisType == AVC_INFO))
> CHECKED_MALLOC_ZERO(analysis->wt, x265_weight_param, numPlanes *
> numDir);
>
> - if (param->analysisReuseLevel < 2)
> + if (maxReuseLevel < 2)
> return;
>
> //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_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_ZERO(intraData->cuQPOff, int8_t,
> analysis->numPartitions * analysis->numCUsInFrame);
> + if (!isMultiPassOpt)
> + {
> + 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_ZERO(intraData->cuQPOff, int8_t,
> analysis->numPartitions * analysis->numCUsInFrame);
> + }
> analysis->intraData = intraData;
>
> //Allocate memory for interData pointer based on ReuseLevels
> @@ -822,19 +831,19 @@
> CHECKED_MALLOC(interData->depth, uint8_t, analysis->numPartitions *
> analysis->numCUsInFrame);
> CHECKED_MALLOC_ZERO(interData->modes, uint8_t,
> analysis->numPartitions * analysis->numCUsInFrame);
>
> - if (param->rc.cuTree)
> + if (param->rc.cuTree && !isMultiPassOpt)
> 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);
> CHECKED_MALLOC_ZERO(interData->mv[1], x265_analysis_MV,
> analysis->numPartitions * analysis->numCUsInFrame);
>
> - if (param->analysisReuseLevel > 4)
> + if (maxReuseLevel > 4)
> {
> 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)
> + if (maxReuseLevel >= 7)
> {
> CHECKED_MALLOC_ZERO(interData->interDir, uint8_t,
> analysis->numPartitions * analysis->numCUsInFrame);
> CHECKED_MALLOC_ZERO(interData->sadCost, int64_t,
> analysis->numPartitions * analysis->numCUsInFrame);
> @@ -844,14 +853,13 @@
> CHECKED_MALLOC_ZERO(analysis->modeFlag[dir], uint8_t,
> analysis->numPartitions * analysis->numCUsInFrame);
> }
> }
> - else
> + if ((minReuseLevel >= 2) && (minReuseLevel <= 6))
> {
> - if (param->analysisMultiPassRefine ||
> param->analysisMultiPassDistortion){
> - CHECKED_MALLOC_ZERO(interData->ref, int32_t, 2 *
> analysis->numPartitions * analysis->numCUsInFrame);
> - }
> - else
> - CHECKED_MALLOC_ZERO(interData->ref, int32_t,
> analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU * numDir);
> + CHECKED_MALLOC_ZERO(interData->ref, int32_t,
> analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU * numDir);
> }
> + if (isMultiPassOpt)
> + CHECKED_MALLOC_ZERO(interData->ref, int32_t, 2 *
> analysis->numPartitions * analysis->numCUsInFrame);
> +
> analysis->interData = interData;
>
> return;
> @@ -862,10 +870,15 @@
>
> void x265_free_analysis_data(x265_param *param, x265_analysis_data*
> analysis)
> {
> + int maxReuseLevel = X265_MAX(param->analysisSaveReuseLevel,
> param->analysisLoadReuseLevel);
> + int minReuseLevel = (param->analysisSaveReuseLevel &&
> param->analysisLoadReuseLevel) ?
> + X265_MIN(param->analysisSaveReuseLevel,
> param->analysisLoadReuseLevel) : maxReuseLevel;
> +
> bool isVbv = param->rc.vbvMaxBitrate > 0 && param->rc.vbvBufferSize >
> 0;
> + bool isMultiPassOpt = param->analysisMultiPassRefine ||
> param->analysisMultiPassDistortion;
>
> //Free memory for Lookahead pointers
> - if (param->bDisableLookahead && isVbv)
> + if (!isMultiPassOpt && param->bDisableLookahead && isVbv)
> {
> X265_FREE(analysis->lookahead.satdForVbv);
> X265_FREE(analysis->lookahead.intraSatdForVbv);
> @@ -887,21 +900,24 @@
> }
>
> /* Early exit freeing weights alone if level is 1 (when there is no
> analysis inter/intra) */
> - if (analysis->wt && !(param->bAnalysisType == AVC_INFO))
> + if (!isMultiPassOpt && analysis->wt && !(param->bAnalysisType ==
> AVC_INFO))
> X265_FREE(analysis->wt);
>
> - if (param->analysisReuseLevel < 2)
> + if (maxReuseLevel < 2)
> return;
>
> //Free memory for intraData pointers
> if (analysis->intraData)
> {
> X265_FREE((analysis->intraData)->depth);
> - X265_FREE((analysis->intraData)->modes);
> - X265_FREE((analysis->intraData)->partSizes);
> - X265_FREE((analysis->intraData)->chromaModes);
> - if (param->rc.cuTree)
> - X265_FREE((analysis->intraData)->cuQPOff);
> + if (!isMultiPassOpt)
> + {
> + X265_FREE((analysis->intraData)->modes);
> + X265_FREE((analysis->intraData)->partSizes);
> + X265_FREE((analysis->intraData)->chromaModes);
> + if (param->rc.cuTree)
> + X265_FREE((analysis->intraData)->cuQPOff);
> + }
> X265_FREE(analysis->intraData);
> analysis->intraData = NULL;
> }
> @@ -911,19 +927,19 @@
> {
> X265_FREE((analysis->interData)->depth);
> X265_FREE((analysis->interData)->modes);
> - if (param->rc.cuTree)
> + if (!isMultiPassOpt && param->rc.cuTree)
> X265_FREE((analysis->interData)->cuQPOff);
> X265_FREE((analysis->interData)->mvpIdx[0]);
> X265_FREE((analysis->interData)->mvpIdx[1]);
> X265_FREE((analysis->interData)->mv[0]);
> X265_FREE((analysis->interData)->mv[1]);
>
> - if (param->analysisReuseLevel > 4)
> + if (maxReuseLevel > 4)
> {
> X265_FREE((analysis->interData)->mergeFlag);
> X265_FREE((analysis->interData)->partSize);
> }
> - if (param->analysisReuseLevel >= 7)
> + if (maxReuseLevel >= 7)
> {
> int numDir = 2;
> X265_FREE((analysis->interData)->interDir);
> @@ -932,13 +948,13 @@
> {
> X265_FREE((analysis->interData)->refIdx[dir]);
> if (analysis->modeFlag[dir] != NULL)
> - {
> + {
> X265_FREE(analysis->modeFlag[dir]);
> analysis->modeFlag[dir] = NULL;
> }
> }
> }
> - else
> + if (((minReuseLevel >= 2) && (minReuseLevel <= 6)) ||
> isMultiPassOpt)
> X265_FREE((analysis->interData)->ref);
> X265_FREE(analysis->interData);
> analysis->interData = NULL;
> diff -r 52135ffd9bcd -r 4d870dd7c314 source/encoder/encoder.cpp
> --- a/source/encoder/encoder.cpp Mon Dec 23 14:40:32 2019 +0530
> +++ b/source/encoder/encoder.cpp Mon Dec 16 17:55:07 2019 +0530
> @@ -650,7 +650,7 @@
> if (analysis_data->sliceType == X265_TYPE_IDR ||
> analysis_data->sliceType == X265_TYPE_I)
> {
> curFrame->m_analysisData.sliceType = X265_TYPE_I;
> - if (m_param->analysisReuseLevel < 7)
> + if (m_param->analysisLoadReuseLevel < 7)
> return -1;
> curFrame->m_analysisData.numPartitions =
> m_param->num4x4Partitions;
> int num16x16inCUWidth = m_param->maxCUSize >> 4;
> @@ -680,7 +680,7 @@
> else
> {
> uint32_t numDir = analysis_data->sliceType == X265_TYPE_P ? 1 : 2;
> - if (m_param->analysisReuseLevel < 7)
> + if (m_param->analysisLoadReuseLevel < 7)
> return -1;
> curFrame->m_analysisData.numPartitions =
> m_param->num4x4Partitions;
> int num16x16inCUWidth = m_param->maxCUSize >> 4;
> @@ -722,7 +722,7 @@
> (interData)->mvpIdx[k][cuPos + cuOffset] =
> (srcInterData)->mvpIdx[k][(mbIndex * 16) + cuOffset];
> (interData)->refIdx[k][cuPos + cuOffset] =
> (srcInterData)->refIdx[k][(mbIndex * 16) + cuOffset];
> memcpy(&(interData)->mv[k][cuPos + cuOffset],
> &(srcInterData)->mv[k][(mbIndex * 16) + cuOffset], sizeof(MV));
> - if (m_param->analysisReuseLevel == 7 && numPU
> == PU_2Nx2N &&
> + if (m_param->analysisLoadReuseLevel == 7 &&
> numPU == PU_2Nx2N &&
> ((interData)->depth[cuPos + cuOffset] ==
> (m_param->maxCUSize >> 5)))
> {
> int mv_x = (interData)->mv[k][cuPos +
> cuOffset].x;
> @@ -756,7 +756,7 @@
> if (analysis_data->sliceType == X265_TYPE_IDR ||
> analysis_data->sliceType == X265_TYPE_I)
> {
> curFrame->m_analysisData.sliceType = X265_TYPE_I;
> - if (m_param->analysisReuseLevel < 2)
> + if (m_param->analysisLoadReuseLevel < 2)
> return -1;
>
> curFrame->m_analysisData.numPartitions =
> m_param->num4x4Partitions;
> @@ -777,7 +777,7 @@
> else
> {
> uint32_t numDir = analysis_data->sliceType == X265_TYPE_P
> ? 1 : 2;
> - if (m_param->analysisReuseLevel < 2)
> + if (m_param->analysisLoadReuseLevel < 2)
> return -1;
>
> curFrame->m_analysisData.numPartitions =
> m_param->num4x4Partitions;
> @@ -790,7 +790,7 @@
> memset(&(currInterData)->depth[count],
> (interData)->depth[d], bytes);
> memset(&(currInterData)->modes[count],
> (interData)->modes[d], bytes);
> memcpy(&(currInterData)->sadCost[count],
> &(analysis_data->interData)->sadCost[d], bytes);
> - if (m_param->analysisReuseLevel > 4)
> + if (m_param->analysisLoadReuseLevel > 4)
> {
> memset(&(currInterData)->partSize[count],
> (interData)->partSize[d], bytes);
> int numPU =
> nbPartsTable[(interData)->partSize[d]];
> @@ -798,7 +798,7 @@
> {
> if (pu) d++;
> (currInterData)->mergeFlag[count + pu] =
> (interData)->mergeFlag[d];
> - if (m_param->analysisReuseLevel >= 7)
> + if (m_param->analysisLoadReuseLevel >= 7)
> {
> (currInterData)->interDir[count + pu] =
> (interData)->interDir[d];
> for (uint32_t i = 0; i < numDir; i++)
> @@ -806,7 +806,7 @@
> (currInterData)->mvpIdx[i][count +
> pu] = (interData)->mvpIdx[i][d];
> (currInterData)->refIdx[i][count +
> pu] = (interData)->refIdx[i][d];
> memcpy(&(currInterData)->mv[i][count
> + pu], &(interData)->mv[i][d], sizeof(MV));
> - if (m_param->analysisReuseLevel == 7
> && numPU == PU_2Nx2N && m_param->num4x4Partitions <= 16)
> + if (m_param->analysisLoadReuseLevel
> == 7 && numPU == PU_2Nx2N && m_param->num4x4Partitions <= 16)
> {
> int mv_x =
> (currInterData)->mv[i][count + pu].x;
> int mv_y =
> (currInterData)->mv[i][count + pu].y;
> @@ -3577,10 +3577,46 @@
> p->rc.rfConstantMin = 0;
> }
>
> - 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;
> + if (p->analysisSaveReuseLevel && !p->analysisSave)
> + {
> + x265_log(p, X265_LOG_WARNING, "analysis-save-reuse-level can be
> set only when analysis-save is enabled."
> + " Resetting analysis-save-reuse-level to 0.\n");
> + p->analysisSaveReuseLevel = 0;
> + }
> +
> + if (p->analysisLoadReuseLevel && !p->analysisLoad)
> + {
> + x265_log(p, X265_LOG_WARNING, "analysis-load-reuse-level can be
> set only when analysis-load is enabled."
> + " Resetting analysis-load-reuse-level to 0.\n");
> + p->analysisLoadReuseLevel = 0;
> + }
> +
> + if (p->analysisSave && !p->analysisSaveReuseLevel)
> + {
> + x265_log(p, X265_LOG_WARNING, "analysis-save-reuse-level must be
> set when analysis-save is enabled."
> + " Setting analysis-save-reuse-level to 5.\n");
> + p->analysisSaveReuseLevel = 5;
> + }
> +
> + if (p->analysisLoad && !p->analysisLoadReuseLevel)
> + {
> + x265_log(p, X265_LOG_WARNING, "analysis-load-reuse-level must be
> set when analysis-load is enabled."
> + " Setting analysis-load-reuse-level to 5.\n");
> + p->analysisLoadReuseLevel = 5;
> + }
> +
> + if ((p->bAnalysisType == DEFAULT) && p->rc.cuTree)
> + {
> + if (p->analysisSaveReuseLevel && p->analysisSaveReuseLevel < 10)
> + {
> + x265_log(p, X265_LOG_WARNING, "cu-tree works only with
> analysis-save-reuse-level 10, Disabling cu-tree\n");
> + p->rc.cuTree = 0;
> + }
> + if (p->analysisLoadReuseLevel && p->analysisLoadReuseLevel < 10)
> + {
> + x265_log(p, X265_LOG_WARNING, "cu-tree works only with
> analysis-load-reuse-level 10, Disabling cu-tree\n");
> + p->rc.cuTree = 0;
> + }
> }
>
> if ((p->analysisLoad || p->analysisSave) &&
> (p->bDistributeModeAnalysis || p->bDistributeMotionEstimation))
> @@ -3602,45 +3638,37 @@
> {
> p->scaleFactor = 0;
> }
> - else if ((!p->analysisLoad && !p->analysisSave) ||
> (p->analysisReuseLevel > 6 && p->analysisReuseLevel != 10))
> + else if ((p->analysisSaveReuseLevel > 6 &&
> p->analysisSaveReuseLevel != 10) || (p->analysisLoadReuseLevel > 6 &&
> p->analysisLoadReuseLevel != 10))
> {
> - x265_log(p, X265_LOG_WARNING, "Input scaling works with
> analysis load/save and analysis-reuse-level 1-6 and 10. Disabling
> scale-factor.\n");
> + x265_log(p, X265_LOG_WARNING, "Input scaling works with
> analysis-save/load and analysis-save/load-reuse-level 1-6 and 10. Disabling
> scale-factor.\n");
> p->scaleFactor = 0;
> }
> }
>
> - if (p->intraRefine)
> - {
> - if (!p->analysisLoad || p->analysisReuseLevel < 10)
> - {
> - x265_log(p, X265_LOG_WARNING, "Intra refinement requires
> analysis load, analysis-reuse-level 10. Disabling intra refine.\n");
> - p->intraRefine = 0;
> - }
> - }
> -
> - if (p->interRefine)
> - {
> - if (!p->analysisLoad || p->analysisReuseLevel < 10)
> - {
> - x265_log(p, X265_LOG_WARNING, "Inter refinement requires
> analysis load, analysis-reuse-level 10. Disabling inter refine.\n");
> - p->interRefine = 0;
> - }
> - }
> -
> - if (p->bDynamicRefine)
> - {
> - if (!p->analysisLoad || p->analysisReuseLevel < 10)
> - {
> - x265_log(p, X265_LOG_WARNING, "Dynamic refinement requires
> analysis load, analysis-reuse-level 10. Disabling dynamic refine.\n");
> - p->bDynamicRefine = 0;
> - }
> + if (p->intraRefine && p->analysisLoadReuseLevel &&
> p->analysisLoadReuseLevel < 10)
> + {
> + x265_log(p, X265_LOG_WARNING, "Intra refinement requires analysis
> load, analysis-load-reuse-level 10. Disabling intra refine.\n");
> + p->intraRefine = 0;
> + }
> +
> + if (p->interRefine && p->analysisLoadReuseLevel &&
> p->analysisLoadReuseLevel < 10)
> + {
> + x265_log(p, X265_LOG_WARNING, "Inter refinement requires analysis
> load, analysis-load-reuse-level 10. Disabling inter refine.\n");
> + p->interRefine = 0;
> + }
> +
> + if (p->bDynamicRefine && p->analysisLoadReuseLevel &&
> p->analysisLoadReuseLevel < 10)
> + {
> + x265_log(p, X265_LOG_WARNING, "Dynamic refinement requires
> analysis load, analysis-load-reuse-level 10. Disabling dynamic refine.\n");
> + p->bDynamicRefine = 0;
> +
> if (p->interRefine)
> {
> x265_log(p, X265_LOG_WARNING, "Inter refine cannot be used
> with dynamic refine. Disabling refine-inter.\n");
> p->interRefine = 0;
> }
> }
> - if (p->scaleFactor && p->analysisLoad && !p->interRefine &&
> !p->bDynamicRefine && p->analysisReuseLevel == 10)
> + if (p->scaleFactor && !p->interRefine && !p->bDynamicRefine &&
> p->analysisLoadReuseLevel == 10)
> {
> x265_log(p, X265_LOG_WARNING, "Inter refinement 0 is not
> supported with scaling and analysis-reuse-level=10. Enabling refine-inter
> 1.\n");
> p->interRefine = 1;
> @@ -4205,7 +4233,7 @@
> {
> if (m_param->bAnalysisType == HEVC_INFO)
> return;
> - if (m_param->analysisReuseLevel < 2)
> + if (m_param->analysisLoadReuseLevel < 2)
> return;
>
> uint8_t *tempBuf = NULL, *depthBuf = NULL, *modeBuf = NULL,
> *partSizes = NULL;
> @@ -4265,7 +4293,7 @@
> uint32_t numDir = analysis->sliceType == X265_TYPE_P ? 1 : 2;
> uint32_t numPlanes = m_param->internalCsp == X265_CSP_I400 ? 1 :
> 3;
> X265_FREAD((WeightParam*)analysis->wt, sizeof(WeightParam),
> numPlanes * numDir, m_analysisFileIn, (picIn->analysisData.wt));
> - if (m_param->analysisReuseLevel < 2)
> + if (m_param->analysisLoadReuseLevel < 2)
> return;
>
> uint8_t *tempBuf = NULL, *depthBuf = NULL, *modeBuf = NULL,
> *partSize = NULL, *mergeFlag = NULL;
> @@ -4274,9 +4302,9 @@
> int8_t* refIdx[2];
> int8_t* cuQPBuf = NULL;
>
> - int numBuf = m_param->analysisReuseLevel > 4 ? 4 : 2;
> + int numBuf = m_param->analysisLoadReuseLevel > 4 ? 4 : 2;
> bool bIntraInInter = false;
> - if (m_param->analysisReuseLevel == 10)
> + if (m_param->analysisLoadReuseLevel == 10)
> {
> numBuf++;
> bIntraInInter = (analysis->sliceType == X265_TYPE_P ||
> m_param->bIntraInBFrames);
> @@ -4299,14 +4327,14 @@
> 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->analysisLoadReuseLevel > 4)
> {
> 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)
> + if (m_param->analysisLoadReuseLevel == 10)
> {
> interDir = mergeFlag + depthBytes;
> X265_FREAD(interDir, sizeof(uint8_t), depthBytes,
> m_analysisFileIn, interPic->interDir);
> @@ -4337,7 +4365,7 @@
> 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 (m_param->analysisLoadReuseLevel > 4)
> {
> if (m_param->scaleFactor && modeBuf[d] == MODE_INTRA
> && partSize[d] == SIZE_NxN)
> partSize[d] = SIZE_2Nx2N;
> @@ -4347,7 +4375,7 @@
> {
> if (pu) d++;
> (analysis->interData)->mergeFlag[count + pu] =
> mergeFlag[d];
> - if (m_param->analysisReuseLevel == 10)
> + if (m_param->analysisLoadReuseLevel == 10)
> {
> (analysis->interData)->interDir[count + pu] =
> interDir[d];
> for (uint32_t i = 0; i < numDir; i++)
> @@ -4363,7 +4391,7 @@
> }
> }
> }
> - if (m_param->analysisReuseLevel == 10 &&
> bIntraInInter)
> + if (m_param->analysisLoadReuseLevel == 10 &&
> bIntraInInter)
>
> memset(&(analysis->intraData)->chromaModes[count], chromaDir[d], bytes);
> }
> count += bytes;
> @@ -4373,7 +4401,7 @@
> X265_FREE(cuQPBuf);
> X265_FREE(tempBuf);
> }
> - if (m_param->analysisReuseLevel == 10)
> + if (m_param->analysisLoadReuseLevel == 10)
> {
> if (m_param->bAnalysisType != HEVC_INFO)
> {
> @@ -4556,7 +4584,7 @@
>
> if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType ==
> X265_TYPE_I)
> {
> - if (m_param->analysisReuseLevel < 2)
> + if (m_param->analysisLoadReuseLevel < 2)
> return;
>
> uint8_t *tempBuf = NULL, *depthBuf = NULL, *modeBuf = NULL,
> *partSizes = NULL;
> @@ -4625,7 +4653,7 @@
> uint32_t numDir = analysis->sliceType == X265_TYPE_P ? 1 : 2;
> uint32_t numPlanes = m_param->internalCsp == X265_CSP_I400 ? 1 :
> 3;
> X265_FREAD((WeightParam*)analysis->wt, sizeof(WeightParam),
> numPlanes * numDir, m_analysisFileIn, (picIn->analysisData.wt));
> - if (m_param->analysisReuseLevel < 2)
> + if (m_param->analysisLoadReuseLevel < 2)
> return;
>
> uint8_t *tempBuf = NULL, *depthBuf = NULL, *modeBuf = NULL,
> *partSize = NULL, *mergeFlag = NULL;
> @@ -4634,9 +4662,9 @@
> int8_t* refIdx[2];
> int8_t* cuQPBuf = NULL;
>
> - int numBuf = m_param->analysisReuseLevel > 4 ? 4 : 2;
> + int numBuf = m_param->analysisLoadReuseLevel > 4 ? 4 : 2;
> bool bIntraInInter = false;
> - if (m_param->analysisReuseLevel == 10)
> + if (m_param->analysisLoadReuseLevel == 10)
> {
> numBuf++;
> bIntraInInter = (analysis->sliceType == X265_TYPE_P ||
> m_param->bIntraInBFrames);
> @@ -4652,13 +4680,13 @@
> 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->analysisLoadReuseLevel > 4)
> {
> 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)
> + if (m_param->analysisLoadReuseLevel == 10)
> {
> interDir = mergeFlag + depthBytes;
> X265_FREAD(interDir, sizeof(uint8_t), depthBytes,
> m_analysisFileIn, interPic->interDir);
> @@ -4702,10 +4730,10 @@
> 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 == 10 && bIntraInInter)
> + if (m_param->analysisLoadReuseLevel == 10 &&
> bIntraInInter)
> memset(&(analysis->intraData)->chromaModes[count],
> chromaDir[d], bytes);
>
> - if (m_param->analysisReuseLevel > 4)
> + if (m_param->analysisLoadReuseLevel > 4)
> {
> puOrientation puOrient;
> puOrient.init();
> @@ -4731,7 +4759,7 @@
> d++;
>
> (analysis->interData)->mergeFlag[count + pu] =
> mergeFlag[d];
> - if (m_param->analysisReuseLevel == 10)
> + if (m_param->analysisLoadReuseLevel == 10)
> {
> (analysis->interData)->interDir[count + pu] =
> interDir[d];
> MV mvCopy[2];
> @@ -4766,7 +4794,7 @@
> X265_FREE(cuQPBuf);
> X265_FREE(tempBuf);
>
> - if (m_param->analysisReuseLevel == 10)
> + if (m_param->analysisLoadReuseLevel == 10)
> {
> for (uint32_t i = 0; i < numDir; i++)
> {
> @@ -4855,7 +4883,6 @@
>
> X265_PARAM_VALIDATE(saveParam->intraRefresh, sizeof(int), 1,
> &m_param->bIntraRefresh, intra-refresh);
> X265_PARAM_VALIDATE(saveParam->maxNumReferences, sizeof(int), 1,
> &m_param->maxNumReferences, ref);
> - X265_PARAM_VALIDATE(saveParam->analysisReuseLevel, sizeof(int), 1,
> &m_param->analysisReuseLevel, analysis-reuse-level);
> X265_PARAM_VALIDATE(saveParam->keyframeMax, sizeof(int), 1,
> &m_param->keyframeMax, keyint);
> X265_PARAM_VALIDATE(saveParam->keyframeMin, sizeof(int), 1,
> &m_param->keyframeMin, min-keyint);
> X265_PARAM_VALIDATE(saveParam->openGOP, sizeof(int), 1,
> &m_param->bOpenGOP, open-gop);
> @@ -4871,6 +4898,7 @@
> int sourceHeight, sourceWidth;
> if (writeFlag)
> {
> + X265_PARAM_VALIDATE(saveParam->analysisReuseLevel, sizeof(int),
> 1, &m_param->analysisSaveReuseLevel, analysis - save - reuse - level);
> sourceHeight = m_param->sourceHeight -
> m_conformanceWindow.bottomOffset;
> sourceWidth = m_param->sourceWidth -
> m_conformanceWindow.rightOffset;
> X265_PARAM_VALIDATE(saveParam->sourceWidth, sizeof(int), 1,
> &sourceWidth, res-width);
> @@ -4880,10 +4908,35 @@
> else
> {
> fileOffset = m_analysisFileIn;
> +
> + int saveLevel = 0;
> + bool isIncompatibleReuseLevel = false;
> + int loadLevel = m_param->analysisLoadReuseLevel;
> +
> + X265_FREAD(&saveLevel, sizeof(int), 1, m_analysisFileIn,
> &(saveParam->analysisReuseLevel));
> +
> + if (loadLevel == 10 && saveLevel != 10)
> + isIncompatibleReuseLevel = true;
> + else if (((loadLevel >= 7) && (loadLevel <= 9)) && ((saveLevel <
> 7) || (saveLevel > 9)))
> + isIncompatibleReuseLevel = true;
> + else if ((loadLevel == 5 || loadLevel == 6) && ((saveLevel != 5)
> && (saveLevel != 6)))
> + isIncompatibleReuseLevel = true;
> + else if ((loadLevel >= 2 && loadLevel <= 4) && (saveLevel < 2 ||
> saveLevel > 6))
> + isIncompatibleReuseLevel = true;
> + else if (!saveLevel)
> + isIncompatibleReuseLevel = true;
> +
> + if (isIncompatibleReuseLevel)
> + {
> + x265_log(NULL, X265_LOG_ERROR, "Error reading analysis data.
> Incompatible reuse-levels.\n");
> + m_aborted = true;
> + return -1;
> + }
> +
> bool error = false;
> int curSourceHeight = m_param->sourceHeight -
> m_conformanceWindow.bottomOffset;
> int curSourceWidth = m_param->sourceWidth -
> m_conformanceWindow.rightOffset;
> -
> +
> X265_FREAD(&sourceWidth, sizeof(int), 1, m_analysisFileIn,
> &(saveParam->sourceWidth));
> X265_FREAD(&sourceHeight, sizeof(int), 1, m_analysisFileIn,
> &(saveParam->sourceHeight));
> X265_FREAD(&readValue, sizeof(int), 1, m_analysisFileIn,
> &(saveParam->maxCUSize));
> @@ -5205,7 +5258,7 @@
> analysis->frameRecordSize += analysis->numCUsInFrame *
> sizeof(sse_t);
> }
>
> - if (m_param->analysisReuseLevel > 1)
> + if (m_param->analysisSaveReuseLevel > 1)
> {
>
> if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType
> == X265_TYPE_I)
> @@ -5258,14 +5311,14 @@
> interDataCTU->depth[depthBytes] = depth;
>
> predMode = ctu->m_predMode[absPartIdx];
> - if (m_param->analysisReuseLevel != 10 &&
> ctu->m_refIdx[1][absPartIdx] != -1)
> + if (m_param->analysisSaveReuseLevel != 10 &&
> ctu->m_refIdx[1][absPartIdx] != -1)
> predMode = 4; // used as indicator if the block
> is coded as bidir
>
> interDataCTU->modes[depthBytes] = predMode;
> if (m_param->rc.cuTree)
> interDataCTU->cuQPOff[depthBytes] =
> (int8_t)(ctu->m_qpAnalysis[absPartIdx] - baseQP);
>
> - if (m_param->analysisReuseLevel > 4)
> + if (m_param->analysisSaveReuseLevel > 4)
> {
> partSize = ctu->m_partSize[absPartIdx];
> interDataCTU->partSize[depthBytes] = partSize;
> @@ -5278,7 +5331,7 @@
> if (puIdx) depthBytes++;
> interDataCTU->mergeFlag[depthBytes] =
> ctu->m_mergeFlag[puabsPartIdx];
>
> - if (m_param->analysisReuseLevel == 10)
> + if (m_param->analysisSaveReuseLevel == 10)
> {
> interDataCTU->interDir[depthBytes] =
> ctu->m_interDir[puabsPartIdx];
> for (uint32_t dir = 0; dir < numDir;
> dir++)
> @@ -5289,12 +5342,12 @@
> }
> }
> }
> - if (m_param->analysisReuseLevel == 10 &&
> bIntraInInter)
> + if (m_param->analysisSaveReuseLevel == 10 &&
> bIntraInInter)
> intraDataCTU->chromaModes[depthBytes] =
> ctu->m_chromaIntraDir[absPartIdx];
> }
> absPartIdx += ctu->m_numPartitions >> (depth * 2);
> }
> - if (m_param->analysisReuseLevel == 10 && bIntraInInter)
> + if (m_param->analysisSaveReuseLevel == 10 &&
> bIntraInInter)
> memcpy(&intraDataCTU->modes[ctu->m_cuAddr *
> ctu->m_numPartitions], ctu->m_lumaIntraDir, sizeof(uint8_t)*
> ctu->m_numPartitions);
> }
> }
> @@ -5309,10 +5362,10 @@
> analysis->frameRecordSize += depthBytes * 2;
> if (m_param->rc.cuTree)
> analysis->frameRecordSize += (sizeof(int8_t) * depthBytes);
> - if (m_param->analysisReuseLevel > 4)
> + if (m_param->analysisSaveReuseLevel > 4)
> analysis->frameRecordSize += (depthBytes * 2);
>
> - if (m_param->analysisReuseLevel == 10)
> + if (m_param->analysisSaveReuseLevel == 10)
> {
> /* Add Size of interDir, mvpIdx, refIdx, mv, luma and
> chroma modes */
> analysis->frameRecordSize += depthBytes;
> @@ -5344,7 +5397,7 @@
> if (analysis->sliceType > X265_TYPE_I)
> X265_FWRITE((WeightParam*)analysis->wt, sizeof(WeightParam),
> numPlanes * numDir, m_analysisFileOut);
>
> - if (m_param->analysisReuseLevel < 2)
> + if (m_param->analysisSaveReuseLevel < 2)
> return;
>
> if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType ==
> X265_TYPE_I)
> @@ -5362,11 +5415,11 @@
> X265_FWRITE((analysis->interData)->modes, sizeof(uint8_t),
> depthBytes, m_analysisFileOut);
> if (m_param->rc.cuTree)
> X265_FWRITE((analysis->interData)->cuQPOff, sizeof(int8_t),
> depthBytes, m_analysisFileOut);
> - if (m_param->analysisReuseLevel > 4)
> + if (m_param->analysisSaveReuseLevel > 4)
> {
> X265_FWRITE((analysis->interData)->partSize, sizeof(uint8_t),
> depthBytes, m_analysisFileOut);
> X265_FWRITE((analysis->interData)->mergeFlag,
> sizeof(uint8_t), depthBytes, m_analysisFileOut);
> - if (m_param->analysisReuseLevel == 10)
> + if (m_param->analysisSaveReuseLevel == 10)
> {
> X265_FWRITE((analysis->interData)->interDir,
> sizeof(uint8_t), depthBytes, m_analysisFileOut);
> if (bIntraInInter)
> X265_FWRITE((analysis->intraData)->chromaModes, sizeof(uint8_t),
> depthBytes, m_analysisFileOut);
> @@ -5380,7 +5433,7 @@
> X265_FWRITE((analysis->intraData)->modes,
> sizeof(uint8_t), analysis->numCUsInFrame * analysis->numPartitions,
> m_analysisFileOut);
> }
> }
> - if (m_param->analysisReuseLevel != 10)
> + if (m_param->analysisSaveReuseLevel != 10)
> X265_FWRITE((analysis->interData)->ref, sizeof(int32_t),
> analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU * numDir,
> m_analysisFileOut);
>
> }
> diff -r 52135ffd9bcd -r 4d870dd7c314 source/encoder/search.cpp
> --- a/source/encoder/search.cpp Mon Dec 23 14:40:32 2019 +0530
> +++ b/source/encoder/search.cpp Mon Dec 16 17:55:07 2019 +0530
> @@ -2208,7 +2208,7 @@
> x265_analysis_inter_data* interDataCTU = NULL;
> int cuIdx;
> cuIdx = (interMode.cu.m_cuAddr * m_param->num4x4Partitions) +
> cuGeom.absPartIdx;
> - if (m_param->analysisReuseLevel == 10 && m_param->interRefine > 1)
> + if (m_param->analysisLoadReuseLevel == 10 && m_param->interRefine
> > 1)
> {
> interDataCTU = m_frame->m_analysisData.interData;
> if ((cu.m_predMode[pu.puAbsPartIdx] ==
> interDataCTU->modes[cuIdx + pu.puAbsPartIdx])
> @@ -2227,7 +2227,7 @@
>
> cu.getNeighbourMV(puIdx, pu.puAbsPartIdx,
> interMode.interNeighbours);
> /* Uni-directional prediction */
> - if ((m_param->analysisLoad && m_param->analysisReuseLevel > 1 &&
> m_param->analysisReuseLevel != 10)
> + if ((m_param->analysisLoadReuseLevel > 1 &&
> m_param->analysisLoadReuseLevel != 10)
> || (m_param->analysisMultiPassRefine &&
> m_param->rc.bStatRead) || (m_param->bAnalysisType == AVC_INFO) ||
> (useAsMVP))
> {
> for (int list = 0; list < numPredDir; list++)
> diff -r 52135ffd9bcd -r 4d870dd7c314 source/x265.h
> --- a/source/x265.h Mon Dec 23 14:40:32 2019 +0530
> +++ b/source/x265.h Mon Dec 16 17:55:07 2019 +0530
> @@ -320,7 +320,7 @@
>
> typedef enum
> {
> - NO_INFO = 0,
> + DEFAULT = 0,
> AVC_INFO = 1,
> HEVC_INFO = 2,
> }AnalysisRefineType;
> @@ -1656,7 +1656,7 @@
>
> /* A value between 1 and 10 (both inclusive) determines the level of
> * information stored/reused in analysis save/load. Higher the refine
> - * level higher the information stored/reused. Default is 5 */
> + * level higher the information stored/reused. Default is 5. Now
> deprecated. */
> int analysisReuseLevel;
>
> /* Limit Sample Adaptive Offset filter computation by early
> terminating SAO
> @@ -1859,6 +1859,16 @@
>
> /* Enable HME search ranges for L0, L1 and L2 respectively. */
> int hmeRange[3];
> +
> + /* A value between 1 and 10 (both inclusive) determines the level of
> + * analysis information stored in analysis-save. Higher the refine
> level higher
> + * the information stored. Default is 5 */
> + int analysisSaveReuseLevel;
> +
> + /* A value between 1 and 10 (both inclusive) determines the level of
> + * analysis information reused in analysis-load. Higher the refine
> level higher
> + * the information reused. Default is 5 */
> + int analysisLoadReuseLevel;
> } x265_param;
>
> /* x265_param_alloc:
> diff -r 52135ffd9bcd -r 4d870dd7c314 source/x265cli.h
> --- a/source/x265cli.h Mon Dec 23 14:40:32 2019 +0530
> +++ b/source/x265cli.h Mon Dec 16 17:55:07 2019 +0530
> @@ -275,7 +275,9 @@
> { "no-multi-pass-opt-rps", no_argument, NULL, 0 },
> { "analysis-reuse-mode", required_argument, NULL, 0 }, /* DEPRECATED
> */
> { "analysis-reuse-file", required_argument, NULL, 0 },
> - { "analysis-reuse-level", required_argument, NULL, 0 },
> + { "analysis-reuse-level", required_argument, NULL, 0 }, /* DEPRECATED
> */
> + { "analysis-save-reuse-level", required_argument, NULL, 0 },
> + { "analysis-load-reuse-level", required_argument, NULL, 0 },
> { "analysis-save", required_argument, NULL, 0 },
> { "analysis-load", required_argument, NULL, 0 },
> { "scale-factor", required_argument, NULL, 0 },
> @@ -549,7 +551,9 @@
> H0(" --analysis-save <filename> Dump analysis info into the
> specified file. Default Disabled\n");
> 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(" --analysis-reuse-level <1..10> Level of analysis reuse
> indicates amount of info stored/reused in save/load mode, 1:least..10:most.
> Now deprecated. Default %d\n", param->analysisReuseLevel);
> + H0(" --analysis-save-reuse-level <1..10> Indicates the amount of
> analysis info stored in save mode, 1:least..10:most. Default %d\n",
> param->analysisSaveReuseLevel);
> + H0(" --analysis-load-reuse-level <1..10> Indicates the amount of
> analysis info reused in load mode, 1:least..10:most. Default %d\n",
> param->analysisLoadReuseLevel);
> 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"
>
--
Regards,
*Aruna Matheswaran,*
Video Codec Engineer,
Media & AI analytics BU,
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20200110/7e333674/attachment-0001.html>
More information about the x265-devel
mailing list