Pushed to the master branch On Fri, Jan 13, 2023 at 3:02 PM Kirithika Kalirathnam < [email protected]> wrote:
> From e3402211edcd19acf172d2597ff65890d7fc227e Mon Sep 17 00:00:00 2001 > From: Kirithika <[email protected]> > Date: Thu, 12 Jan 2023 15:50:58 +0530 > Subject: [PATCH] Add command line support for scene cut aware qp feature > > This commit enables the scene cut aware qp feature through the command > line parameters > --scenecut-aware-qp and --masking-strength.It doesn't disable the scenecut > aware qp configuration via config file. > User can choose between either of these two ways to configure > scenecut-aware-qp. > --- > doc/reST/cli.rst | 3 +- > source/CMakeLists.txt | 2 +- > source/common/param.cpp | 290 ++++++++++++++++++++-------------------- > source/common/param.h | 1 + > 4 files changed, 151 insertions(+), 145 deletions(-) > > diff --git a/doc/reST/cli.rst b/doc/reST/cli.rst > index f1d9fa36c..a98c860d0 100755 > --- a/doc/reST/cli.rst > +++ b/doc/reST/cli.rst > @@ -1987,7 +1987,6 @@ Quality, rate control and rate distortion options > It reduces the bits spent on the inter-frames within the scenecut window > before and after a scenecut by increasing their QP in ratecontrol pass2 > algorithm > without any deterioration in visual quality. > - It is mentioned inside :option:`--scenecut-qp-config` file. > :option:`--scenecut-aware-qp` works only with --pass 2. Default 0. > > +-------+---------------------------------------------------------------+ > @@ -2010,7 +2009,7 @@ Quality, rate control and rate distortion options > > Comma separated list of values which specifies the duration and offset > for the QP increment for inter-frames when :option:`--scenecut-aware-qp` > - is enabled. It is mentioned inside :option:`--scenecut-qp-config` file. > + is enabled. > > When :option:`--scenecut-aware-qp` is: > > diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt > index 04ceea0ec..4c3274f63 100755 > --- a/source/CMakeLists.txt > +++ b/source/CMakeLists.txt > @@ -29,7 +29,7 @@ option(NATIVE_BUILD "Target the build CPU" OFF) > 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 206) > +set(X265_BUILD 207) > configure_file("${PROJECT_SOURCE_DIR}/x265.def.in" > "${PROJECT_BINARY_DIR}/x265.def") > configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in" > diff --git a/source/common/param.cpp b/source/common/param.cpp > index fe85d8726..8c32fafa2 100755 > --- a/source/common/param.cpp > +++ b/source/common/param.cpp > @@ -711,148 +711,7 @@ int x265_scenecut_aware_qp_param_parse(x265_param* > p, const char* name, const ch > #define OPT(STR) else if (!strcmp(name, STR)) > if (0); > OPT("scenecut-aware-qp") p->bEnableSceneCutAwareQp = x265_atoi(value, > bError); > - OPT("masking-strength") > - { > - int window1[6]; > - double refQpDelta1[6], nonRefQpDelta1[6]; > - if (p->bEnableSceneCutAwareQp == FORWARD) > - { > - if (3 == sscanf(value, "%d,%lf,%lf", &window1[0], > &refQpDelta1[0], &nonRefQpDelta1[0])) > - { > - if (window1[0] > 0) > - p->fwdMaxScenecutWindow = window1[0]; > - if (refQpDelta1[0] > 0) > - p->fwdRefQpDelta[0] = refQpDelta1[0]; > - if (nonRefQpDelta1[0] > 0) > - p->fwdNonRefQpDelta[0] = nonRefQpDelta1[0]; > - > - p->fwdScenecutWindow[0] = p->fwdMaxScenecutWindow / 6; > - for (int i = 1; i < 6; i++) > - { > - p->fwdScenecutWindow[i] = p->fwdMaxScenecutWindow / 6; > - p->fwdRefQpDelta[i] = p->fwdRefQpDelta[i - 1] - (0.15 > * p->fwdRefQpDelta[i - 1]); > - p->fwdNonRefQpDelta[i] = p->fwdNonRefQpDelta[i - 1] - > (0.15 * p->fwdNonRefQpDelta[i - 1]); > - } > - } > - else if (18 == sscanf(value, > "%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf" > - , &window1[0], &refQpDelta1[0], &nonRefQpDelta1[0], > &window1[1], &refQpDelta1[1], &nonRefQpDelta1[1] > - , &window1[2], &refQpDelta1[2], &nonRefQpDelta1[2], > &window1[3], &refQpDelta1[3], &nonRefQpDelta1[3] > - , &window1[4], &refQpDelta1[4], &nonRefQpDelta1[4], > &window1[5], &refQpDelta1[5], &nonRefQpDelta1[5])) > - { > - p->fwdMaxScenecutWindow = 0; > - for (int i = 0; i < 6; i++) > - { > - p->fwdScenecutWindow[i] = window1[i]; > - p->fwdRefQpDelta[i] = refQpDelta1[i]; > - p->fwdNonRefQpDelta[i] = nonRefQpDelta1[i]; > - p->fwdMaxScenecutWindow += p->fwdScenecutWindow[i]; > - } > - } > - else > - { > - x265_log(NULL, X265_LOG_ERROR, "Specify all the necessary > offsets for masking-strength \n"); > - bError = true; > - } > - } > - else if (p->bEnableSceneCutAwareQp == BACKWARD) > - { > - if (3 == sscanf(value, "%d,%lf,%lf", &window1[0], > &refQpDelta1[0], &nonRefQpDelta1[0])) > - { > - if (window1[0] > 0) > - p->bwdMaxScenecutWindow = window1[0]; > - if (refQpDelta1[0] > 0) > - p->bwdRefQpDelta[0] = refQpDelta1[0]; > - if (nonRefQpDelta1[0] > 0) > - p->bwdNonRefQpDelta[0] = nonRefQpDelta1[0]; > - > - p->bwdScenecutWindow[0] = p->bwdMaxScenecutWindow / 6; > - for (int i = 1; i < 6; i++) > - { > - p->bwdScenecutWindow[i] = p->bwdMaxScenecutWindow / 6; > - p->bwdRefQpDelta[i] = p->bwdRefQpDelta[i - 1] - (0.15 > * p->bwdRefQpDelta[i - 1]); > - p->bwdNonRefQpDelta[i] = p->bwdNonRefQpDelta[i - 1] - > (0.15 * p->bwdNonRefQpDelta[i - 1]); > - } > - } > - else if (18 == sscanf(value, > "%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf" > - , &window1[0], &refQpDelta1[0], &nonRefQpDelta1[0], > &window1[1], &refQpDelta1[1], &nonRefQpDelta1[1] > - , &window1[2], &refQpDelta1[2], &nonRefQpDelta1[2], > &window1[3], &refQpDelta1[3], &nonRefQpDelta1[3] > - , &window1[4], &refQpDelta1[4], &nonRefQpDelta1[4], > &window1[5], &refQpDelta1[5], &nonRefQpDelta1[5])) > - { > - p->bwdMaxScenecutWindow = 0; > - for (int i = 0; i < 6; i++) > - { > - p->bwdScenecutWindow[i] = window1[i]; > - p->bwdRefQpDelta[i] = refQpDelta1[i]; > - p->bwdNonRefQpDelta[i] = nonRefQpDelta1[i]; > - p->bwdMaxScenecutWindow += p->bwdScenecutWindow[i]; > - } > - } > - else > - { > - x265_log(NULL, X265_LOG_ERROR, "Specify all the necessary > offsets for masking-strength \n"); > - bError = true; > - } > - } > - else if (p->bEnableSceneCutAwareQp == BI_DIRECTIONAL) > - { > - int window2[6]; > - double refQpDelta2[6], nonRefQpDelta2[6]; > - if (6 == sscanf(value, "%d,%lf,%lf,%d,%lf,%lf", &window1[0], > &refQpDelta1[0], &nonRefQpDelta1[0], &window2[0], &refQpDelta2[0], > &nonRefQpDelta2[0])) > - { > - if (window1[0] > 0) > - p->fwdMaxScenecutWindow = window1[0]; > - if (refQpDelta1[0] > 0) > - p->fwdRefQpDelta[0] = refQpDelta1[0]; > - if (nonRefQpDelta1[0] > 0) > - p->fwdNonRefQpDelta[0] = nonRefQpDelta1[0]; > - if (window2[0] > 0) > - p->bwdMaxScenecutWindow = window2[0]; > - if (refQpDelta2[0] > 0) > - p->bwdRefQpDelta[0] = refQpDelta2[0]; > - if (nonRefQpDelta2[0] > 0) > - p->bwdNonRefQpDelta[0] = nonRefQpDelta2[0]; > - > - p->fwdScenecutWindow[0] = p->fwdMaxScenecutWindow / 6; > - p->bwdScenecutWindow[0] = p->bwdMaxScenecutWindow / 6; > - for (int i = 1; i < 6; i++) > - { > - p->fwdScenecutWindow[i] = p->fwdMaxScenecutWindow / 6; > - p->bwdScenecutWindow[i] = p->bwdMaxScenecutWindow / 6; > - p->fwdRefQpDelta[i] = p->fwdRefQpDelta[i - 1] - (0.15 > * p->fwdRefQpDelta[i - 1]); > - p->fwdNonRefQpDelta[i] = p->fwdNonRefQpDelta[i - 1] - > (0.15 * p->fwdNonRefQpDelta[i - 1]); > - p->bwdRefQpDelta[i] = p->bwdRefQpDelta[i - 1] - (0.15 > * p->bwdRefQpDelta[i - 1]); > - p->bwdNonRefQpDelta[i] = p->bwdNonRefQpDelta[i - 1] - > (0.15 * p->bwdNonRefQpDelta[i - 1]); > - } > - } > - else if (36 == sscanf(value, > "%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf" > - , &window1[0], &refQpDelta1[0], &nonRefQpDelta1[0], > &window1[1], &refQpDelta1[1], &nonRefQpDelta1[1] > - , &window1[2], &refQpDelta1[2], &nonRefQpDelta1[2], > &window1[3], &refQpDelta1[3], &nonRefQpDelta1[3] > - , &window1[4], &refQpDelta1[4], &nonRefQpDelta1[4], > &window1[5], &refQpDelta1[5], &nonRefQpDelta1[5] > - , &window2[0], &refQpDelta2[0], &nonRefQpDelta2[0], > &window2[1], &refQpDelta2[1], &nonRefQpDelta2[1] > - , &window2[2], &refQpDelta2[2], &nonRefQpDelta2[2], > &window2[3], &refQpDelta2[3], &nonRefQpDelta2[3] > - , &window2[4], &refQpDelta2[4], &nonRefQpDelta2[4], > &window2[5], &refQpDelta2[5], &nonRefQpDelta2[5])) > - { > - p->fwdMaxScenecutWindow = 0; > - p->bwdMaxScenecutWindow = 0; > - for (int i = 0; i < 6; i++) > - { > - p->fwdScenecutWindow[i] = window1[i]; > - p->fwdRefQpDelta[i] = refQpDelta1[i]; > - p->fwdNonRefQpDelta[i] = nonRefQpDelta1[i]; > - p->bwdScenecutWindow[i] = window2[i]; > - p->bwdRefQpDelta[i] = refQpDelta2[i]; > - p->bwdNonRefQpDelta[i] = nonRefQpDelta2[i]; > - p->fwdMaxScenecutWindow += p->fwdScenecutWindow[i]; > - p->bwdMaxScenecutWindow += p->bwdScenecutWindow[i]; > - } > - } > - else > - { > - x265_log(NULL, X265_LOG_ERROR, "Specify all the necessary > offsets for masking-strength \n"); > - bError = true; > - } > - } > - } > + OPT("masking-strength") bError = parseMaskingStrength(p, value); > else > return X265_PARAM_BAD_NAME; > #undef OPT > @@ -1534,6 +1393,8 @@ int x265_param_parse(x265_param* p, const char* > name, const char* value) > p->selectiveSAO = atoi(value); > } > OPT("fades") p->bEnableFades = atobool(value); > + OPT("scenecut-aware-qp") p->bEnableSceneCutAwareQp = atoi(value); > + OPT("masking-strength") bError |= parseMaskingStrength(p, value); > OPT("field") p->bField = atobool( value ); > OPT("cll") p->bEmitCLL = atobool(value); > OPT("frame-dup") p->bEnableFrameDuplication = atobool(value); > @@ -2548,6 +2409,151 @@ bool parseLambdaFile(x265_param* param) > return false; > } > > +bool parseMaskingStrength(x265_param* p, const char* value) > +{ > + bool bError = false; > + int window1[6]; > + double refQpDelta1[6], nonRefQpDelta1[6]; > + if (p->bEnableSceneCutAwareQp == FORWARD) > + { > + if (3 == sscanf(value, "%d,%lf,%lf", &window1[0], > &refQpDelta1[0], &nonRefQpDelta1[0])) > + { > + if (window1[0] > 0) > + p->fwdMaxScenecutWindow = window1[0]; > + if (refQpDelta1[0] > 0) > + p->fwdRefQpDelta[0] = refQpDelta1[0]; > + if (nonRefQpDelta1[0] > 0) > + p->fwdNonRefQpDelta[0] = nonRefQpDelta1[0]; > + > + p->fwdScenecutWindow[0] = p->fwdMaxScenecutWindow / 6; > + for (int i = 1; i < 6; i++) > + { > + p->fwdScenecutWindow[i] = p->fwdMaxScenecutWindow / 6; > + p->fwdRefQpDelta[i] = p->fwdRefQpDelta[i - 1] - (0.15 * > p->fwdRefQpDelta[i - 1]); > + p->fwdNonRefQpDelta[i] = p->fwdNonRefQpDelta[i - 1] - > (0.15 * p->fwdNonRefQpDelta[i - 1]); > + } > + } > + else if (18 == sscanf(value, > "%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf" > + , &window1[0], &refQpDelta1[0], &nonRefQpDelta1[0], > &window1[1], &refQpDelta1[1], &nonRefQpDelta1[1] > + , &window1[2], &refQpDelta1[2], &nonRefQpDelta1[2], > &window1[3], &refQpDelta1[3], &nonRefQpDelta1[3] > + , &window1[4], &refQpDelta1[4], &nonRefQpDelta1[4], > &window1[5], &refQpDelta1[5], &nonRefQpDelta1[5])) > + { > + p->fwdMaxScenecutWindow = 0; > + for (int i = 0; i < 6; i++) > + { > + p->fwdScenecutWindow[i] = window1[i]; > + p->fwdRefQpDelta[i] = refQpDelta1[i]; > + p->fwdNonRefQpDelta[i] = nonRefQpDelta1[i]; > + p->fwdMaxScenecutWindow += p->fwdScenecutWindow[i]; > + } > + } > + else > + { > + x265_log(NULL, X265_LOG_ERROR, "Specify all the necessary > offsets for masking-strength \n"); > + bError = true; > + } > + } > + else if (p->bEnableSceneCutAwareQp == BACKWARD) > + { > + if (3 == sscanf(value, "%d,%lf,%lf", &window1[0], > &refQpDelta1[0], &nonRefQpDelta1[0])) > + { > + if (window1[0] > 0) > + p->bwdMaxScenecutWindow = window1[0]; > + if (refQpDelta1[0] > 0) > + p->bwdRefQpDelta[0] = refQpDelta1[0]; > + if (nonRefQpDelta1[0] > 0) > + p->bwdNonRefQpDelta[0] = nonRefQpDelta1[0]; > + > + p->bwdScenecutWindow[0] = p->bwdMaxScenecutWindow / 6; > + for (int i = 1; i < 6; i++) > + { > + p->bwdScenecutWindow[i] = p->bwdMaxScenecutWindow / 6; > + p->bwdRefQpDelta[i] = p->bwdRefQpDelta[i - 1] - (0.15 * > p->bwdRefQpDelta[i - 1]); > + p->bwdNonRefQpDelta[i] = p->bwdNonRefQpDelta[i - 1] - > (0.15 * p->bwdNonRefQpDelta[i - 1]); > + } > + } > + else if (18 == sscanf(value, > "%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf" > + , &window1[0], &refQpDelta1[0], &nonRefQpDelta1[0], > &window1[1], &refQpDelta1[1], &nonRefQpDelta1[1] > + , &window1[2], &refQpDelta1[2], &nonRefQpDelta1[2], > &window1[3], &refQpDelta1[3], &nonRefQpDelta1[3] > + , &window1[4], &refQpDelta1[4], &nonRefQpDelta1[4], > &window1[5], &refQpDelta1[5], &nonRefQpDelta1[5])) > + { > + p->bwdMaxScenecutWindow = 0; > + for (int i = 0; i < 6; i++) > + { > + p->bwdScenecutWindow[i] = window1[i]; > + p->bwdRefQpDelta[i] = refQpDelta1[i]; > + p->bwdNonRefQpDelta[i] = nonRefQpDelta1[i]; > + p->bwdMaxScenecutWindow += p->bwdScenecutWindow[i]; > + } > + } > + else > + { > + x265_log(NULL, X265_LOG_ERROR, "Specify all the necessary > offsets for masking-strength \n"); > + bError = true; > + } > + } > + else if (p->bEnableSceneCutAwareQp == BI_DIRECTIONAL) > + { > + int window2[6]; > + double refQpDelta2[6], nonRefQpDelta2[6]; > + if (6 == sscanf(value, "%d,%lf,%lf,%d,%lf,%lf", &window1[0], > &refQpDelta1[0], &nonRefQpDelta1[0], &window2[0], &refQpDelta2[0], > &nonRefQpDelta2[0])) > + { > + if (window1[0] > 0) > + p->fwdMaxScenecutWindow = window1[0]; > + if (refQpDelta1[0] > 0) > + p->fwdRefQpDelta[0] = refQpDelta1[0]; > + if (nonRefQpDelta1[0] > 0) > + p->fwdNonRefQpDelta[0] = nonRefQpDelta1[0]; > + if (window2[0] > 0) > + p->bwdMaxScenecutWindow = window2[0]; > + if (refQpDelta2[0] > 0) > + p->bwdRefQpDelta[0] = refQpDelta2[0]; > + if (nonRefQpDelta2[0] > 0) > + p->bwdNonRefQpDelta[0] = nonRefQpDelta2[0]; > + > + p->fwdScenecutWindow[0] = p->fwdMaxScenecutWindow / 6; > + p->bwdScenecutWindow[0] = p->bwdMaxScenecutWindow / 6; > + for (int i = 1; i < 6; i++) > + { > + p->fwdScenecutWindow[i] = p->fwdMaxScenecutWindow / 6; > + p->bwdScenecutWindow[i] = p->bwdMaxScenecutWindow / 6; > + p->fwdRefQpDelta[i] = p->fwdRefQpDelta[i - 1] - (0.15 * > p->fwdRefQpDelta[i - 1]); > + p->fwdNonRefQpDelta[i] = p->fwdNonRefQpDelta[i - 1] - > (0.15 * p->fwdNonRefQpDelta[i - 1]); > + p->bwdRefQpDelta[i] = p->bwdRefQpDelta[i - 1] - (0.15 * > p->bwdRefQpDelta[i - 1]); > + p->bwdNonRefQpDelta[i] = p->bwdNonRefQpDelta[i - 1] - > (0.15 * p->bwdNonRefQpDelta[i - 1]); > + } > + } > + else if (36 == sscanf(value, > "%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf,%d,%lf,%lf" > + , &window1[0], &refQpDelta1[0], &nonRefQpDelta1[0], > &window1[1], &refQpDelta1[1], &nonRefQpDelta1[1] > + , &window1[2], &refQpDelta1[2], &nonRefQpDelta1[2], > &window1[3], &refQpDelta1[3], &nonRefQpDelta1[3] > + , &window1[4], &refQpDelta1[4], &nonRefQpDelta1[4], > &window1[5], &refQpDelta1[5], &nonRefQpDelta1[5] > + , &window2[0], &refQpDelta2[0], &nonRefQpDelta2[0], > &window2[1], &refQpDelta2[1], &nonRefQpDelta2[1] > + , &window2[2], &refQpDelta2[2], &nonRefQpDelta2[2], > &window2[3], &refQpDelta2[3], &nonRefQpDelta2[3] > + , &window2[4], &refQpDelta2[4], &nonRefQpDelta2[4], > &window2[5], &refQpDelta2[5], &nonRefQpDelta2[5])) > + { > + p->fwdMaxScenecutWindow = 0; > + p->bwdMaxScenecutWindow = 0; > + for (int i = 0; i < 6; i++) > + { > + p->fwdScenecutWindow[i] = window1[i]; > + p->fwdRefQpDelta[i] = refQpDelta1[i]; > + p->fwdNonRefQpDelta[i] = nonRefQpDelta1[i]; > + p->bwdScenecutWindow[i] = window2[i]; > + p->bwdRefQpDelta[i] = refQpDelta2[i]; > + p->bwdNonRefQpDelta[i] = nonRefQpDelta2[i]; > + p->fwdMaxScenecutWindow += p->fwdScenecutWindow[i]; > + p->bwdMaxScenecutWindow += p->bwdScenecutWindow[i]; > + } > + } > + else > + { > + x265_log(NULL, X265_LOG_ERROR, "Specify all the necessary > offsets for masking-strength \n"); > + bError = true; > + } > + } > + return bError; > +} > + > void x265_copy_params(x265_param* dst, x265_param* src) > { > dst->cpuid = src->cpuid; > diff --git a/source/common/param.h b/source/common/param.h > index 7808947f6..f504ec9e4 100644 > --- a/source/common/param.h > +++ b/source/common/param.h > @@ -38,6 +38,7 @@ void setParamAspectRatio(x265_param *p, int width, int > height); > void getParamAspectRatio(x265_param *p, int& width, int& height); > bool parseLambdaFile(x265_param *param); > void x265_copy_params(x265_param* dst, x265_param* src); > +bool parseMaskingStrength(x265_param* p, const char* value); > > /* this table is kept internal to avoid confusion, since log level > indices start at -1 */ > static const char * const logLevelNames[] = { "none", "error", "warning", > "info", "debug", "full", 0 }; > -- > 2.28.0.windows.1 > > *Thanks,* > *Kirithika* > _______________________________________________ > x265-devel mailing list > [email protected] > https://mailman.videolan.org/listinfo/x265-devel >
_______________________________________________ x265-devel mailing list [email protected] https://mailman.videolan.org/listinfo/x265-devel
