[x265] [PATCH] Increase BBAQ windows and enable masking after I frames

Mahesh Pittala mahesh at multicorewareinc.com
Thu Dec 15 07:12:31 UTC 2022


Pushed BBAQ 3 patches to master branch

On Sun, Dec 11, 2022 at 9:46 PM Niranjan Bala <niranjan at multicorewareinc.com>
wrote:

> From d6b6c195aca2037c0e141efda899f22368ec7555 Mon Sep 17 00:00:00 2001
> From: Niranjan Kumar <niranjan at multicorewareinc.com>
> Date: Fri, 4 Nov 2022 14:56:35 +0530
> Subject: [PATCH] Increase BBAQ windows and enable masking after I frames
>
> ---
>  doc/reST/cli.rst               |  66 ++++++++---
>  source/common/param.cpp        | 208 ++++++++++++++++++++++++---------
>  source/encoder/encoder.cpp     |   4 +-
>  source/encoder/ratecontrol.cpp | 184 ++++++++++++++++++-----------
>  source/encoder/ratecontrol.h   |   8 --
>  source/x265.h                  |  15 ++-
>  6 files changed, 326 insertions(+), 159 deletions(-)
>
> diff --git a/doc/reST/cli.rst b/doc/reST/cli.rst
> index 2437a09da..c7ff17ff8 100755
> --- a/doc/reST/cli.rst
> +++ b/doc/reST/cli.rst
> @@ -1974,12 +1974,17 @@ Quality, rate control and rate distortion options
>
>   **CLI ONLY**
>
> +.. option:: --scenecut-qp-config <filename>
> + Specify a text file which contains the scenecut aware QP options.
> + The options include :option:`--scenecut-aware-qp` and
> :option:`--masking-strength`
> + **CLI ONLY**
> +
>  .. option:: --scenecut-aware-qp <integer>
>
>   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. If a scenecut falls within
> the window,
> - the QP of the inter-frames after this scenecut will not be modified.
> + 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.
>
>   +-------+---------------------------------------------------------------+
> @@ -2002,47 +2007,72 @@ 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.
> + is enabled. It is mentioned inside :option:`--scenecut-qp-config` file.
>
>   When :option:`--scenecut-aware-qp` is::
>   * 1 (Forward masking):
> - --masking-strength <fwdWindow,fwdRefQPDelta,fwdNonRefQPDelta>
> + --masking-strength <fwdMaxWindow,fwdRefQPDelta,fwdNonRefQPDelta>
> + or
> + --masking-strength
> <fwdWindow1,fwdRefQPDelta1,fwdNonRefQPDelta1,fwdWindow2,fwdRefQPDelta2,fwdNonRefQPDelta2,
> +
> fwdWindow3,fwdRefQPDelta3,fwdNonRefQPDelta3,fwdWindow4,fwdRefQPDelta4,fwdNonRefQPDelta4,
> +
> fwdWindow5,fwdRefQPDelta5,fwdNonRefQPDelta5,fwdWindow6,fwdRefQPDelta6,fwdNonRefQPDelta6>
>   * 2 (Backward masking):
> - --masking-strength <bwdWindow,bwdRefQPDelta,bwdNonRefQPDelta>
> + --masking-strength <bwdMaxWindow,bwdRefQPDelta,bwdNonRefQPDelta>
> + or
> + --masking-strength
> <bwdWindow1,bwdRefQPDelta1,bwdNonRefQPDelta1,bwdWindow2,bwdRefQPDelta2,bwdNonRefQPDelta2,
> +
> bwdWindow3,bwdRefQPDelta3,bwdNonRefQPDelta3,bwdWindow4,bwdRefQPDelta4,bwdNonRefQPDelta4,
> +
> bwdWindow5,bwdRefQPDelta5,bwdNonRefQPDelta5,bwdWindow6,bwdRefQPDelta6,bwdNonRefQPDelta6>
>   * 3 (Bi-directional masking):
> - --masking-strength
> <fwdWindow,fwdRefQPDelta,fwdNonRefQPDelta,bwdWindow,bwdRefQPDelta,bwdNonRefQPDelta>
> + --masking-strength
> <fwdMaxWindow,fwdRefQPDelta,fwdNonRefQPDelta,bwdMaxWindow,bwdRefQPDelta,bwdNonRefQPDelta>
> + or
> + --masking-strength
> <fwdWindow1,fwdRefQPDelta1,fwdNonRefQPDelta1,fwdWindow2,fwdRefQPDelta2,fwdNonRefQPDelta2,
> +
> fwdWindow3,fwdRefQPDelta3,fwdNonRefQPDelta3,fwdWindow4,fwdRefQPDelta4,fwdNonRefQPDelta4,
> +
> fwdWindow5,fwdRefQPDelta5,fwdNonRefQPDelta5,fwdWindow6,fwdRefQPDelta6,fwdNonRefQPDelta6,
> +
> bwdWindow1,bwdRefQPDelta1,bwdNonRefQPDelta1,bwdWindow2,bwdRefQPDelta2,bwdNonRefQPDelta2,
> +
> bwdWindow3,bwdRefQPDelta3,bwdNonRefQPDelta3,bwdWindow4,bwdRefQPDelta4,bwdNonRefQPDelta4,
> +
> bwdWindow5,bwdRefQPDelta5,bwdNonRefQPDelta5,bwdWindow6,bwdRefQPDelta6,bwdNonRefQPDelta6>
>
>
> +-----------------+---------------------------------------------------------------+
>   | Parameter       | Description
>           |
>
> +=================+===============================================================+
> - | fwdWindow       | The duration(in milliseconds) for which there is a
> reduction  |
> - |                 | in the bits spent on the inter-frames after a
> scenecut by     |
> - |                 | increasing their QP. Default 500ms.
>           |
> - |                 | **Range of values:** 0 to 1000
>          |
> + | fwdMaxWindow    | The maximum duration(in milliseconds) for which
> there is a    |
> + |                 | reduction in the bits spent on the inter-frames
> after a       |
> + |                 | scenecut by increasing their QP. Default 500ms.
>           |
> + |                 | **Range of values:** 0 to 2000
>          |
> +
> +-----------------+---------------------------------------------------------------+
> + | fwdWindow       | The duration of a sub-window(in milliseconds) for
> which there |
> + |                 | is a reduction in the bits spent on the inter-frames
> after a  |
> + |                 | scenecut by increasing their QP. Default 500ms.
>           |
> + |                 | **Range of values:** 0 to 2000
>          |
>
> +-----------------+---------------------------------------------------------------+
>   | fwdRefQPDelta   | The offset by which QP is incremented for
> inter-frames        |
>   |                 | after a scenecut. Default 5.
>          |
> - |                 | **Range of values:** 0 to 10
>          |
> + |                 | **Range of values:** 0 to 20
>          |
>
> +-----------------+---------------------------------------------------------------+
>   | fwdNonRefQPDelta| The offset by which QP is incremented for
> non-referenced      |
>   |                 | inter-frames after a scenecut. The offset is
> computed from    |
>   |                 | fwdRefQPDelta when it is not explicitly specified.
>          |
> - |                 | **Range of values:** 0 to 10
>          |
> + |                 | **Range of values:** 0 to 20
>          |
> +
> +-----------------+---------------------------------------------------------------+
> + | bwdMaxWindow    | The maximum duration(in milliseconds) for which
> there is a    |
> + |                 | reduction in the bits spent on the inter-frames
> before a      |
> + |                 | scenecut by increasing their QP. Default 100ms.
>           |
> + |                 | **Range of values:** 0 to 2000
>          |
>
> +-----------------+---------------------------------------------------------------+
> - | bwdWindow       | The duration(in milliseconds) for which there is a
> reduction  |
> - |                 | in the bits spent on the inter-frames before a
> scenecut by    |
> - |                 | increasing their QP. Default 100ms.
>           |
> - |                 | **Range of values:** 0 to 1000
>          |
> + | bwdWindow       | The duration of a sub-window(in milliseconds) for
> which there |
> + |                 | is a reduction in the bits spent on the inter-frames
> before a |
> + |                 | scenecut by increasing their QP. Default 100ms.
>           |
> + |                 | **Range of values:** 0 to 2000
>          |
>
> +-----------------+---------------------------------------------------------------+
>   | bwdRefQPDelta   | The offset by which QP is incremented for
> inter-frames        |
>   |                 | before a scenecut. The offset is computed from
>          |
>   |                 | fwdRefQPDelta when it is not explicitly specified.
>          |
> - |                 | **Range of values:** 0 to 10
>          |
> + |                 | **Range of values:** 0 to 20
>          |
>
> +-----------------+---------------------------------------------------------------+
>   | bwdNonRefQPDelta| The offset by which QP is incremented for
> non-referenced      |
>   |                 | inter-frames before a scenecut. The offset is
> computed from   |
>   |                 | bwdRefQPDelta when it is not explicitly specified.
>          |
> - |                 | **Range of values:** 0 to 10
>          |
> + |                 | **Range of values:** 0 to 20
>          |
>
> +-----------------+---------------------------------------------------------------+
>
>   **CLI ONLY**
> diff --git a/source/common/param.cpp b/source/common/param.cpp
> index ccadcd2cc..d44693e56 100755
> --- a/source/common/param.cpp
> +++ b/source/common/param.cpp
> @@ -180,12 +180,20 @@ void x265_param_default(x265_param* param)
>      param->bEnableHRDConcatFlag = 0;
>      param->bEnableFades = 0;
>      param->bEnableSceneCutAwareQp = 0;
> -    param->fwdScenecutWindow = 500;
> -    param->fwdRefQpDelta = 5;
> -    param->fwdNonRefQpDelta = param->fwdRefQpDelta + (SLICE_TYPE_DELTA *
> param->fwdRefQpDelta);
> -    param->bwdScenecutWindow = 100;
> -    param->bwdRefQpDelta = -1;
> -    param->bwdNonRefQpDelta = -1;
> +    param->fwdMaxScenecutWindow = 1200;
> +    param->bwdMaxScenecutWindow = 600;
> +    for (int i = 0; i < 6; i++)
> +    {
> +        int deltas[6] = { 5, 4, 3, 2, 1, 0 };
> +
> +        param->fwdScenecutWindow[i] = 200;
> +        param->fwdRefQpDelta[i] = deltas[i];
> +        param->fwdNonRefQpDelta[i] = param->fwdRefQpDelta[i] +
> (SLICE_TYPE_DELTA * param->fwdRefQpDelta[i]);
> +
> +        param->bwdScenecutWindow[i] = 100;
> +        param->bwdRefQpDelta[i] = -1;
> +        param->bwdNonRefQpDelta[i] = -1;
> +    }
>
>      /* Intra Coding Tools */
>      param->bEnableConstrainedIntra = 0;
> @@ -705,18 +713,40 @@ int x265_scenecut_aware_qp_param_parse(x265_param*
> p, const char* name, const ch
>      OPT("scenecut-aware-qp") p->bEnableSceneCutAwareQp = x265_atoi(value,
> bError);
>      OPT("masking-strength")
>      {
> -        int window1;
> -        double refQpDelta1, nonRefQpDelta1;
> +        int window1[6];
> +        double refQpDelta1[6], nonRefQpDelta1[6];
>          if (p->bEnableSceneCutAwareQp == FORWARD)
>          {
> -            if (3 == sscanf(value, "%d,%lf,%lf", &window1, &refQpDelta1,
> &nonRefQpDelta1))
> +            if (3 == sscanf(value, "%d,%lf,%lf", &window1[0],
> &refQpDelta1[0], &nonRefQpDelta1[0]))
>              {
> -                if (window1 > 0)
> -                    p->fwdScenecutWindow = window1;
> -                if (refQpDelta1 > 0)
> -                    p->fwdRefQpDelta = refQpDelta1;
> -                if (nonRefQpDelta1 > 0)
> -                    p->fwdNonRefQpDelta = nonRefQpDelta1;
> +                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
>              {
> @@ -726,14 +756,36 @@ int x265_scenecut_aware_qp_param_parse(x265_param*
> p, const char* name, const ch
>          }
>          else if (p->bEnableSceneCutAwareQp == BACKWARD)
>          {
> -            if (3 == sscanf(value, "%d,%lf,%lf", &window1, &refQpDelta1,
> &nonRefQpDelta1))
> +            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]))
>              {
> -                if (window1 > 0)
> -                    p->bwdScenecutWindow = window1;
> -                if (refQpDelta1 > 0)
> -                    p->bwdRefQpDelta = refQpDelta1;
> -                if (nonRefQpDelta1 > 0)
> -                    p->bwdNonRefQpDelta = nonRefQpDelta1;
> +                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
>              {
> @@ -743,22 +795,56 @@ int x265_scenecut_aware_qp_param_parse(x265_param*
> p, const char* name, const ch
>          }
>          else if (p->bEnableSceneCutAwareQp == BI_DIRECTIONAL)
>          {
> -            int window2;
> -            double refQpDelta2, nonRefQpDelta2;
> -            if (6 == sscanf(value, "%d,%lf,%lf,%d,%lf,%lf", &window1,
> &refQpDelta1, &nonRefQpDelta1, &window2, &refQpDelta2, &nonRefQpDelta2))
> +            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)
> -                    p->fwdScenecutWindow = window1;
> -                if (refQpDelta1 > 0)
> -                    p->fwdRefQpDelta = refQpDelta1;
> -                if (nonRefQpDelta1 > 0)
> -                    p->fwdNonRefQpDelta = nonRefQpDelta1;
> -                if (window2 > 0)
> -                    p->bwdScenecutWindow = window2;
> -                if (refQpDelta2 > 0)
> -                    p->bwdRefQpDelta = refQpDelta2;
> -                if (nonRefQpDelta2 > 0)
> -                    p->bwdNonRefQpDelta = nonRefQpDelta2;
> +                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"
> +                , &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
>              {
> @@ -1894,19 +1980,22 @@ int x265_check_params(x265_param* param)
>          {
>              CHECK(param->bEnableSceneCutAwareQp < 0 ||
> param->bEnableSceneCutAwareQp > 3,
>              "Invalid masking direction. Value must be between 0 and
> 3(inclusive)");
> -            CHECK(param->fwdScenecutWindow < 0 ||
> param->fwdScenecutWindow > 1000,
> -            "Invalid forward scenecut Window duration. Value must be
> between 0 and 1000(inclusive)");
> -            CHECK(param->fwdRefQpDelta < 0 || param->fwdRefQpDelta > 20,
> -            "Invalid fwdRefQpDelta value. Value must be between 0 and 20
> (inclusive)");
> -            CHECK(param->fwdNonRefQpDelta < 0 || param->fwdNonRefQpDelta
> > 20,
> -            "Invalid fwdNonRefQpDelta value. Value must be between 0 and
> 20 (inclusive)");
> -
> -            CHECK(param->bwdScenecutWindow < 0 ||
> param->bwdScenecutWindow > 1000,
> -                "Invalid backward scenecut Window duration. Value must be
> between 0 and 1000(inclusive)");
> -            CHECK(param->bwdRefQpDelta < -1 || param->bwdRefQpDelta > 20,
> -                "Invalid bwdRefQpDelta value. Value must be between 0 and
> 20 (inclusive)");
> -            CHECK(param->bwdNonRefQpDelta < -1 || param->bwdNonRefQpDelta
> > 20,
> -                "Invalid bwdNonRefQpDelta value. Value must be between 0
> and 20 (inclusive)");
> +            for (int i = 0; i < 6; i++)
> +            {
> +                CHECK(param->fwdScenecutWindow[i] < 0 ||
> param->fwdScenecutWindow[i] > 1000,
> +                    "Invalid forward scenecut Window duration. Value must
> be between 0 and 1000(inclusive)");
> +                CHECK(param->fwdRefQpDelta[i] < 0 ||
> param->fwdRefQpDelta[i] > 20,
> +                    "Invalid fwdRefQpDelta value. Value must be between 0
> and 20 (inclusive)");
> +                CHECK(param->fwdNonRefQpDelta[i] < 0 ||
> param->fwdNonRefQpDelta[i] > 20,
> +                    "Invalid fwdNonRefQpDelta value. Value must be
> between 0 and 20 (inclusive)");
> +
> +                CHECK(param->bwdScenecutWindow[i] < 0 ||
> param->bwdScenecutWindow[i] > 1000,
> +                    "Invalid backward scenecut Window duration. Value
> must be between 0 and 1000(inclusive)");
> +                CHECK(param->bwdRefQpDelta[i] < -1 ||
> param->bwdRefQpDelta[i] > 20,
> +                    "Invalid bwdRefQpDelta value. Value must be between 0
> and 20 (inclusive)");
> +                CHECK(param->bwdNonRefQpDelta[i] < -1 ||
> param->bwdNonRefQpDelta[i] > 20,
> +                    "Invalid bwdNonRefQpDelta value. Value must be
> between 0 and 20 (inclusive)");
> +            }
>          }
>      }
>      if (param->bEnableHME)
> @@ -2380,7 +2469,7 @@ char *x265_param2string(x265_param* p, int padx, int
> pady)
>      s += sprintf(s, " qp-adaptation-range=%.2f", p->rc.qpAdaptationRange);
>      s += sprintf(s, " scenecut-aware-qp=%d", p->bEnableSceneCutAwareQp);
>      if (p->bEnableSceneCutAwareQp)
> -        s += sprintf(s, " fwd-scenecut-window=%d fwd-ref-qp-delta=%f
> fwd-nonref-qp-delta=%f bwd-scenecut-window=%d bwd-ref-qp-delta=%f
> bwd-nonref-qp-delta=%f", p->fwdScenecutWindow, p->fwdRefQpDelta,
> p->fwdNonRefQpDelta, p->bwdScenecutWindow, p->bwdRefQpDelta,
> p->bwdNonRefQpDelta);
> +        s += sprintf(s, " fwd-scenecut-window=%d fwd-ref-qp-delta=%f
> fwd-nonref-qp-delta=%f bwd-scenecut-window=%d bwd-ref-qp-delta=%f
> bwd-nonref-qp-delta=%f", p->fwdMaxScenecutWindow, p->fwdRefQpDelta[0],
> p->fwdNonRefQpDelta[0], p->bwdMaxScenecutWindow, p->bwdRefQpDelta[0],
> p->bwdNonRefQpDelta[0]);
>      s += sprintf(s, "conformance-window-offsets right=%d bottom=%d",
> p->confWinRightOffset, p->confWinBottomOffset);
>      s += sprintf(s, " decoder-max-rate=%d", p->decoderVbvMaxRate);
>      BOOL(p->bliveVBV2pass, "vbv-live-multi-pass");
> @@ -2742,12 +2831,17 @@ void x265_copy_params(x265_param* dst, x265_param*
> src)
>      dst->bEnableSvtHevc = src->bEnableSvtHevc;
>      dst->bEnableFades = src->bEnableFades;
>      dst->bEnableSceneCutAwareQp = src->bEnableSceneCutAwareQp;
> -    dst->fwdScenecutWindow = src->fwdScenecutWindow;
> -    dst->fwdRefQpDelta = src->fwdRefQpDelta;
> -    dst->fwdNonRefQpDelta = src->fwdNonRefQpDelta;
> -    dst->bwdScenecutWindow = src->bwdScenecutWindow;
> -    dst->bwdRefQpDelta = src->bwdRefQpDelta;
> -    dst->bwdNonRefQpDelta = src->bwdNonRefQpDelta;
> +    dst->fwdMaxScenecutWindow = src->fwdMaxScenecutWindow;
> +    dst->bwdMaxScenecutWindow = src->bwdMaxScenecutWindow;
> +    for (int i = 0; i < 6; i++)
> +    {
> +        dst->fwdScenecutWindow[i] = src->fwdScenecutWindow[i];
> +        dst->fwdRefQpDelta[i] = src->fwdRefQpDelta[i];
> +        dst->fwdNonRefQpDelta[i] = src->fwdNonRefQpDelta[i];
> +        dst->bwdScenecutWindow[i] = src->bwdScenecutWindow[i];
> +        dst->bwdRefQpDelta[i] = src->bwdRefQpDelta[i];
> +        dst->bwdNonRefQpDelta[i] = src->bwdNonRefQpDelta[i];
> +    }
>      dst->bField = src->bField;
>      dst->bEnableTemporalFilter = src->bEnableTemporalFilter;
>      dst->temporalFilterStrength = src->temporalFilterStrength;
> diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp
> index 0fea6553c..38e1e56eb 100644
> --- a/source/encoder/encoder.cpp
> +++ b/source/encoder/encoder.cpp
> @@ -1652,7 +1652,7 @@ int Encoder::encode(const x265_picture* pic_in,
> x265_picture* pic_out)
>              rcEntry = &(m_rateControl->m_rce2Pass[inFrame->m_poc]);
>              if(rcEntry->scenecut)
>              {
> -                int backwardWindow =
> X265_MIN(int((m_param->bwdScenecutWindow / 1000.0) * (m_param->fpsNum /
> m_param->fpsDenom)), p->lookaheadDepth);
> +                int backwardWindow =
> X265_MIN(int((m_param->bwdMaxScenecutWindow / 1000.0) * (m_param->fpsNum /
> m_param->fpsDenom)), p->lookaheadDepth);
>                  for (int i = 1; i <= backwardWindow; i++)
>                  {
>                      int frameNum = inFrame->m_poc - i;
> @@ -2137,7 +2137,7 @@ int Encoder::encode(const x265_picture* pic_in,
> x265_picture* pic_out)
>                          m_rateControl->m_lastScenecut = frameEnc->m_poc;
>                      else
>                      {
> -                        int maxWindowSize =
> int((m_param->fwdScenecutWindow / 1000.0) * (m_param->fpsNum /
> m_param->fpsDenom) + 0.5);
> +                        int maxWindowSize =
> int((m_param->fwdMaxScenecutWindow / 1000.0) * (m_param->fpsNum /
> m_param->fpsDenom) + 0.5);
>                          if (frameEnc->m_poc >
> (m_rateControl->m_lastScenecut + maxWindowSize))
>                              m_rateControl->m_lastScenecut =
> frameEnc->m_poc;
>                      }
> diff --git a/source/encoder/ratecontrol.cpp
> b/source/encoder/ratecontrol.cpp
> index 3defaf8bf..17d8c1e0d 100644
> --- a/source/encoder/ratecontrol.cpp
> +++ b/source/encoder/ratecontrol.cpp
> @@ -3344,13 +3344,21 @@ void RateControl::splitbUsed(char bused[],
> RateControlEntry *rce)
>  double RateControl::forwardMasking(Frame* curFrame, double q)
>  {
>      double qp = x265_qScale2qp(q);
> -    uint32_t maxWindowSize = uint32_t((m_param->fwdScenecutWindow /
> 1000.0) * (m_param->fpsNum / m_param->fpsDenom) + 0.5);
> -    uint32_t windowSize = maxWindowSize / 6;
> +    uint32_t maxWindowSize = uint32_t((m_param->fwdMaxScenecutWindow /
> 1000.0) * (m_param->fpsNum / m_param->fpsDenom) + 0.5);
> +    uint32_t windowSize[6], prevWindow = 0;
>      int lastScenecut = m_top->m_rateControl->m_lastScenecut;
>      int lastIFrame = m_top->m_rateControl->m_lastScenecutAwareIFrame;
> -    double fwdRefQpDelta = double(m_param->fwdRefQpDelta);
> -    double fwdNonRefQpDelta = double(m_param->fwdNonRefQpDelta);
> -    double sliceTypeDelta = SLICE_TYPE_DELTA * fwdRefQpDelta;
> +
> +    double fwdRefQpDelta[6], fwdNonRefQpDelta[6], sliceTypeDelta[6];
> +    for (int i = 0; i < 6; i++)
> +    {
> +        windowSize[i] = prevWindow +
> (uint32_t((m_param->fwdScenecutWindow[i] / 1000.0) * (m_param->fpsNum /
> m_param->fpsDenom) + 0.5));
> +        fwdRefQpDelta[i] = double(m_param->fwdRefQpDelta[i]);
> +        fwdNonRefQpDelta[i] = double(m_param->fwdNonRefQpDelta[i]);
> +        sliceTypeDelta[i] = SLICE_TYPE_DELTA * fwdRefQpDelta[i];
> +        prevWindow = windowSize[i];
> +    }
> +
>
>      //Check whether the current frame is within the forward window
>      if (curFrame->m_poc > lastScenecut && curFrame->m_poc <=
> (lastScenecut + int(maxWindowSize)))
> @@ -3363,63 +3371,51 @@ double RateControl::forwardMasking(Frame*
> curFrame, double q)
>          }
>          else if (curFrame->m_lowres.sliceType == X265_TYPE_P)
>          {
> -            if (!(lastIFrame > lastScenecut && lastIFrame <=
> (lastScenecut + int(maxWindowSize))
> -                && curFrame->m_poc >= lastIFrame))
> -            {
> -                //Add offsets corresponding to the window in which the
> P-frame occurs
> -                if (curFrame->m_poc <= (lastScenecut + int(windowSize)))
> -                    qp += WINDOW1_DELTA * (fwdRefQpDelta -
> sliceTypeDelta);
> -                else if (((curFrame->m_poc) > (lastScenecut +
> int(windowSize))) && ((curFrame->m_poc) <= (lastScenecut + 2 *
> int(windowSize))))
> -                    qp += WINDOW2_DELTA * (fwdRefQpDelta -
> sliceTypeDelta);
> -                else if (((curFrame->m_poc) > (lastScenecut + 2 *
> int(windowSize))) && ((curFrame->m_poc) <= (lastScenecut + 3 *
> int(windowSize))))
> -                    qp += WINDOW3_DELTA * (fwdRefQpDelta -
> sliceTypeDelta);
> -                else if (((curFrame->m_poc) > (lastScenecut + 3 *
> int(windowSize))) && ((curFrame->m_poc) <= (lastScenecut + 4 *
> int(windowSize))))
> -                    qp += WINDOW4_DELTA * (fwdRefQpDelta -
> sliceTypeDelta);
> -                else if (((curFrame->m_poc) > (lastScenecut + 4 *
> int(windowSize))) && ((curFrame->m_poc) <= (lastScenecut + 5 *
> int(windowSize))))
> -                    qp += WINDOW5_DELTA * (fwdRefQpDelta -
> sliceTypeDelta);
> -                else if (curFrame->m_poc > lastScenecut + 5 *
> int(windowSize))
> -                    qp += WINDOW6_DELTA * (fwdRefQpDelta -
> sliceTypeDelta);
> -            }
> +            //Add offsets corresponding to the window in which the
> P-frame occurs
> +            if (curFrame->m_poc <= (lastScenecut + int(windowSize[0])))
> +                qp += fwdRefQpDelta[0] - sliceTypeDelta[0];
> +            else if (((curFrame->m_poc) > (lastScenecut +
> int(windowSize[0]))) && ((curFrame->m_poc) <= (lastScenecut +
> int(windowSize[1]))))
> +                qp += fwdRefQpDelta[1] - sliceTypeDelta[1];
> +            else if (((curFrame->m_poc) > (lastScenecut +
> int(windowSize[1]))) && ((curFrame->m_poc) <= (lastScenecut +
> int(windowSize[2]))))
> +                qp += fwdRefQpDelta[2] - sliceTypeDelta[2];
> +            else if (((curFrame->m_poc) > (lastScenecut +
> int(windowSize[2]))) && ((curFrame->m_poc) <= (lastScenecut +
> int(windowSize[3]))))
> +                qp += fwdRefQpDelta[3] - sliceTypeDelta[3];
> +            else if (((curFrame->m_poc) > (lastScenecut +
> int(windowSize[3]))) && ((curFrame->m_poc) <= (lastScenecut +
> int(windowSize[4]))))
> +                qp += fwdRefQpDelta[4] - sliceTypeDelta[4];
> +            else if (curFrame->m_poc > lastScenecut + int(windowSize[4]))
> +                qp += fwdRefQpDelta[5] - sliceTypeDelta[5];
>          }
>          else if (curFrame->m_lowres.sliceType == X265_TYPE_BREF)
>          {
> -            if (!(lastIFrame > lastScenecut && lastIFrame <=
> (lastScenecut + int(maxWindowSize))
> -                && curFrame->m_poc >= lastIFrame))
> -            {
> -                //Add offsets corresponding to the window in which the
> B-frame occurs
> -                if (curFrame->m_poc <= (lastScenecut + int(windowSize)))
> -                    qp += WINDOW1_DELTA * fwdRefQpDelta;
> -                else if (((curFrame->m_poc) > (lastScenecut +
> int(windowSize))) && ((curFrame->m_poc) <= (lastScenecut + 2 *
> int(windowSize))))
> -                    qp += WINDOW2_DELTA * fwdRefQpDelta;
> -                else if (((curFrame->m_poc) > (lastScenecut + 2 *
> int(windowSize))) && ((curFrame->m_poc) <= (lastScenecut + 3 *
> int(windowSize))))
> -                    qp += WINDOW3_DELTA * fwdRefQpDelta;
> -                else if (((curFrame->m_poc) > (lastScenecut + 3 *
> int(windowSize))) && ((curFrame->m_poc) <= (lastScenecut + 4 *
> int(windowSize))))
> -                    qp += WINDOW4_DELTA * fwdRefQpDelta;
> -                else if (((curFrame->m_poc) > (lastScenecut + 4 *
> int(windowSize))) && ((curFrame->m_poc) <= (lastScenecut + 5 *
> int(windowSize))))
> -                    qp += WINDOW5_DELTA * fwdRefQpDelta;
> -                else if (curFrame->m_poc > lastScenecut + 5 *
> int(windowSize))
> -                    qp += WINDOW6_DELTA * fwdRefQpDelta;
> -            }
> +            //Add offsets corresponding to the window in which the
> B-frame occurs
> +            if (curFrame->m_poc <= (lastScenecut + int(windowSize[0])))
> +                qp += fwdRefQpDelta[0];
> +            else if (((curFrame->m_poc) > (lastScenecut +
> int(windowSize[0]))) && ((curFrame->m_poc) <= (lastScenecut +
> int(windowSize[1]))))
> +                qp += fwdRefQpDelta[1];
> +            else if (((curFrame->m_poc) > (lastScenecut +
> int(windowSize[1]))) && ((curFrame->m_poc) <= (lastScenecut +
> int(windowSize[2]))))
> +                qp += fwdRefQpDelta[2];
> +            else if (((curFrame->m_poc) > (lastScenecut +
> int(windowSize[2]))) && ((curFrame->m_poc) <= (lastScenecut +
> int(windowSize[3]))))
> +                qp += fwdRefQpDelta[3];
> +            else if (((curFrame->m_poc) > (lastScenecut +
> int(windowSize[3]))) && ((curFrame->m_poc) <= (lastScenecut +
> int(windowSize[4]))))
> +                qp += fwdRefQpDelta[4];
> +            else if (curFrame->m_poc > lastScenecut + int(windowSize[4]))
> +                qp += fwdRefQpDelta[5];
>          }
>          else if (curFrame->m_lowres.sliceType == X265_TYPE_B)
>          {
> -            if (!(lastIFrame > lastScenecut && lastIFrame <=
> (lastScenecut + int(maxWindowSize))
> -                && curFrame->m_poc >= lastIFrame))
> -            {
> -                //Add offsets corresponding to the window in which the
> b-frame occurs
> -                if (curFrame->m_poc <= (lastScenecut + int(windowSize)))
> -                    qp += WINDOW1_DELTA * fwdNonRefQpDelta;
> -                else if (((curFrame->m_poc) > (lastScenecut +
> int(windowSize))) && ((curFrame->m_poc) <= (lastScenecut + 2 *
> int(windowSize))))
> -                    qp += WINDOW2_DELTA * fwdNonRefQpDelta;
> -                else if (((curFrame->m_poc) > (lastScenecut + 2 *
> int(windowSize))) && ((curFrame->m_poc) <= (lastScenecut + 3 *
> int(windowSize))))
> -                    qp += WINDOW3_DELTA * fwdNonRefQpDelta;
> -                else if (((curFrame->m_poc) > (lastScenecut + 3 *
> int(windowSize))) && ((curFrame->m_poc) <= (lastScenecut + 4 *
> int(windowSize))))
> -                    qp += WINDOW4_DELTA * fwdNonRefQpDelta;
> -                else if (((curFrame->m_poc) > (lastScenecut + 4 *
> int(windowSize))) && ((curFrame->m_poc) <= (lastScenecut + 5 *
> int(windowSize))))
> -                    qp += WINDOW5_DELTA * fwdNonRefQpDelta;
> -                else if (curFrame->m_poc > lastScenecut + 5 *
> int(windowSize))
> -                    qp += WINDOW6_DELTA * fwdNonRefQpDelta;
> -            }
> +            //Add offsets corresponding to the window in which the
> b-frame occurs
> +            if (curFrame->m_poc <= (lastScenecut + int(windowSize[0])))
> +                qp += fwdNonRefQpDelta[0];
> +            else if (((curFrame->m_poc) > (lastScenecut +
> int(windowSize[0]))) && ((curFrame->m_poc) <= (lastScenecut +
> int(windowSize[1]))))
> +                qp += fwdNonRefQpDelta[1];
> +            else if (((curFrame->m_poc) > (lastScenecut +
> int(windowSize[1]))) && ((curFrame->m_poc) <= (lastScenecut +
> int(windowSize[2]))))
> +                qp += fwdNonRefQpDelta[2];
> +            else if (((curFrame->m_poc) > (lastScenecut +
> int(windowSize[2]))) && ((curFrame->m_poc) <= (lastScenecut +
> int(windowSize[3]))))
> +                qp += fwdNonRefQpDelta[3];
> +            else if (((curFrame->m_poc) > (lastScenecut +
> int(windowSize[3]))) && ((curFrame->m_poc) <= (lastScenecut +
> int(windowSize[4]))))
> +                qp += fwdNonRefQpDelta[4];
> +            else if (curFrame->m_poc > lastScenecut + int(windowSize[4]))
> +                qp += fwdNonRefQpDelta[5];
>          }
>      }
>
> @@ -3428,24 +3424,76 @@ double RateControl::forwardMasking(Frame*
> curFrame, double q)
>  double RateControl::backwardMasking(Frame* curFrame, double q)
>  {
>      double qp = x265_qScale2qp(q);
> -    double fwdRefQpDelta = double(m_param->fwdRefQpDelta);
> -    double bwdRefQpDelta = double(m_param->bwdRefQpDelta);
> -    double bwdNonRefQpDelta = double(m_param->bwdNonRefQpDelta);
> +    uint32_t maxWindowSize = uint32_t((m_param->bwdMaxScenecutWindow /
> 1000.0) * (m_param->fpsNum / m_param->fpsDenom) + 0.5);
> +    uint32_t windowSize[6], prevWindow = 0;
> +    int lastScenecut = m_top->m_rateControl->m_lastScenecut;
>
> -    if (curFrame->m_isInsideWindow == BACKWARD_WINDOW)
> +    double bwdRefQpDelta[6], bwdNonRefQpDelta[6], sliceTypeDelta[6];
> +    for (int i = 0; i < 6; i++)
>      {
> -        if (bwdRefQpDelta < 0)
> -            bwdRefQpDelta = WINDOW3_DELTA * fwdRefQpDelta;
> -        double sliceTypeDelta = SLICE_TYPE_DELTA * bwdRefQpDelta;
> -        if (bwdNonRefQpDelta < 0)
> -            bwdNonRefQpDelta = bwdRefQpDelta + sliceTypeDelta;
> +        windowSize[i] = prevWindow +
> (uint32_t((m_param->bwdScenecutWindow[i] / 1000.0) * (m_param->fpsNum /
> m_param->fpsDenom) + 0.5));
> +        prevWindow = windowSize[i];
> +        bwdRefQpDelta[i] = double(m_param->bwdRefQpDelta[i]);
> +        bwdNonRefQpDelta[i] = double(m_param->bwdNonRefQpDelta[i]);
>
> +        if (bwdRefQpDelta[i] < 0)
> +            bwdRefQpDelta[i] = BWD_WINDOW_DELTA *
> m_param->fwdRefQpDelta[i];
> +        sliceTypeDelta[i] = SLICE_TYPE_DELTA * bwdRefQpDelta[i];
> +
> +        if (bwdNonRefQpDelta[i] < 0)
> +            bwdNonRefQpDelta[i] = bwdRefQpDelta[i] + sliceTypeDelta[i];
> +    }
> +
> +    if (curFrame->m_isInsideWindow == BACKWARD_WINDOW)
> +    {
>          if (curFrame->m_lowres.sliceType == X265_TYPE_P)
> -            qp += bwdRefQpDelta - sliceTypeDelta;
> +        {
> +            //Add offsets corresponding to the window in which the
> P-frame occurs
> +            if (curFrame->m_poc >= (lastScenecut - int(windowSize[0])))
> +                qp += bwdRefQpDelta[0] - sliceTypeDelta[0];
> +            else if (((curFrame->m_poc) < (lastScenecut -
> int(windowSize[0]))) && ((curFrame->m_poc) >= (lastScenecut -
> int(windowSize[1]))))
> +                qp += bwdRefQpDelta[1] - sliceTypeDelta[1];
> +            else if (((curFrame->m_poc) < (lastScenecut -
> int(windowSize[1]))) && ((curFrame->m_poc) >= (lastScenecut -
> int(windowSize[2]))))
> +                qp += bwdRefQpDelta[2] - sliceTypeDelta[2];
> +            else if (((curFrame->m_poc) < (lastScenecut -
> int(windowSize[2]))) && ((curFrame->m_poc) >= (lastScenecut -
> int(windowSize[3]))))
> +                qp += bwdRefQpDelta[3] - sliceTypeDelta[3];
> +            else if (((curFrame->m_poc) < (lastScenecut -
> int(windowSize[3]))) && ((curFrame->m_poc) >= (lastScenecut -
> int(windowSize[4]))))
> +                qp += bwdRefQpDelta[4] - sliceTypeDelta[4];
> +            else if (curFrame->m_poc < lastScenecut - int(windowSize[4]))
> +                qp += bwdRefQpDelta[5] - sliceTypeDelta[5];
> +        }
>          else if (curFrame->m_lowres.sliceType == X265_TYPE_BREF)
> -            qp += bwdRefQpDelta;
> +        {
> +            //Add offsets corresponding to the window in which the
> B-frame occurs
> +            if (curFrame->m_poc >= (lastScenecut - int(windowSize[0])))
> +                qp += bwdRefQpDelta[0];
> +            else if (((curFrame->m_poc) < (lastScenecut -
> int(windowSize[0]))) && ((curFrame->m_poc) >= (lastScenecut -
> int(windowSize[1]))))
> +                qp += bwdRefQpDelta[1];
> +            else if (((curFrame->m_poc) < (lastScenecut -
> int(windowSize[1]))) && ((curFrame->m_poc) >= (lastScenecut -
> int(windowSize[2]))))
> +                qp += bwdRefQpDelta[2];
> +            else if (((curFrame->m_poc) < (lastScenecut -
> int(windowSize[2]))) && ((curFrame->m_poc) >= (lastScenecut -
> int(windowSize[3]))))
> +                qp += bwdRefQpDelta[3];
> +            else if (((curFrame->m_poc) < (lastScenecut -
> int(windowSize[3]))) && ((curFrame->m_poc) >= (lastScenecut -
> int(windowSize[4]))))
> +                qp += bwdRefQpDelta[4];
> +            else if (curFrame->m_poc < lastScenecut - int(windowSize[4]))
> +                qp += bwdRefQpDelta[5];
> +        }
>          else if (curFrame->m_lowres.sliceType == X265_TYPE_B)
> -            qp += bwdNonRefQpDelta;
> +        {
> +            //Add offsets corresponding to the window in which the
> b-frame occurs
> +            if (curFrame->m_poc >= (lastScenecut - int(windowSize[0])))
> +                qp += bwdNonRefQpDelta[0];
> +            else if (((curFrame->m_poc) < (lastScenecut -
> int(windowSize[0]))) && ((curFrame->m_poc) >= (lastScenecut -
> int(windowSize[1]))))
> +                qp += bwdNonRefQpDelta[1];
> +            else if (((curFrame->m_poc) < (lastScenecut -
> int(windowSize[1]))) && ((curFrame->m_poc) >= (lastScenecut -
> int(windowSize[2]))))
> +                qp += bwdNonRefQpDelta[2];
> +            else if (((curFrame->m_poc) < (lastScenecut -
> int(windowSize[2]))) && ((curFrame->m_poc) >= (lastScenecut -
> int(windowSize[3]))))
> +                qp += bwdNonRefQpDelta[3];
> +            else if (((curFrame->m_poc) < (lastScenecut -
> int(windowSize[3]))) && ((curFrame->m_poc) >= (lastScenecut -
> int(windowSize[4]))))
> +                qp += bwdNonRefQpDelta[4];
> +            else if (curFrame->m_poc < lastScenecut - int(windowSize[4]))
> +                qp += bwdNonRefQpDelta[5];
> +        }
>      }
>
>      return x265_qp2qScale(qp);
> diff --git a/source/encoder/ratecontrol.h b/source/encoder/ratecontrol.h
> index d1734f8ff..e9fd0e182 100644
> --- a/source/encoder/ratecontrol.h
> +++ b/source/encoder/ratecontrol.h
> @@ -47,14 +47,6 @@ struct SPS;
>  #define MIN_AMORTIZE_FRACTION 0.2
>  #define CLIP_DURATION(f) x265_clip3(MIN_FRAME_DURATION,
> MAX_FRAME_DURATION, f)
>
> -/*Scenecut Aware QP*/
> -#define WINDOW1_DELTA           1.0 /* The offset for the frames coming
> in the window-1*/
> -#define WINDOW2_DELTA           0.85 /* The offset for the frames coming
> in the window-2*/
> -#define WINDOW3_DELTA           0.7 /* The offset for the frames coming
> in the window-3*/
> -#define WINDOW4_DELTA           0.55 /* The offset for the frames coming
> in the window-4*/
> -#define WINDOW5_DELTA           0.4 /* The offset for the frames coming
> in the window-5*/
> -#define WINDOW6_DELTA           0.25 /* The offset for the frames coming
> in the window-6*/
> -
>  struct Predictor
>  {
>      double coeffMin;
> diff --git a/source/x265.h b/source/x265.h
> index 25efb17f1..0f092c5c4 100644
> --- a/source/x265.h
> +++ b/source/x265.h
> @@ -614,6 +614,7 @@ typedef enum
>  #define SLICE_TYPE_DELTA        0.3 /* The offset decremented or
> incremented for P-frames or b-frames respectively*/
>  #define BACKWARD_WINDOW         1 /* Scenecut window before a scenecut */
>  #define FORWARD_WINDOW          2 /* Scenecut window after a scenecut */
> +#define BWD_WINDOW_DELTA        0.4
>
>  typedef struct x265_cli_csp
>  {
> @@ -1886,14 +1887,15 @@ typedef struct x265_param
>
>      /* The duration(in milliseconds) for which there is a reduction in
> the bits spent on the inter-frames after a scenecut
>       * by increasing their QP, when bEnableSceneCutAwareQp is 1 or 3.
> Default is 500ms.*/
> -    int       fwdScenecutWindow;
> +    int       fwdMaxScenecutWindow;
> +    int       fwdScenecutWindow[6];
>
>      /* The offset by which QP is incremented for inter-frames after a
> scenecut when bEnableSceneCutAwareQp is 1 or 3.
>       * Default is +5. */
> -    double    fwdRefQpDelta;
> +    double    fwdRefQpDelta[6];
>
>      /* The offset by which QP is incremented for non-referenced
> inter-frames after a scenecut when bEnableSceneCutAwareQp is 1 or 3. */
> -    double    fwdNonRefQpDelta;
> +    double    fwdNonRefQpDelta[6];
>
>      /* Enables histogram based scenecut detection algorithm to detect
> scenecuts. Default disabled */
>      int       bHistBasedSceneCut;
> @@ -1961,13 +1963,14 @@ typedef struct x265_param
>
>      /* The duration(in milliseconds) for which there is a reduction in
> the bits spent on the inter-frames before a scenecut
>       * by increasing their QP, when bEnableSceneCutAwareQp is 2 or 3.
> Default is 100ms.*/
> -    int       bwdScenecutWindow;
> +    int       bwdMaxScenecutWindow;
> +    int       bwdScenecutWindow[6];
>
>      /* The offset by which QP is incremented for inter-frames before a
> scenecut when bEnableSceneCutAwareQp is 2 or 3. */
> -    double    bwdRefQpDelta;
> +    double    bwdRefQpDelta[6];
>
>      /* The offset by which QP is incremented for non-referenced
> inter-frames before a scenecut when bEnableSceneCutAwareQp is 2 or 3. */
> -    double    bwdNonRefQpDelta;
> +    double    bwdNonRefQpDelta[6];
>
>      /* Specify combinations of color primaries, transfer characteristics,
> color matrix,
>      * range of luma and chroma signals, and chroma sample location. This
> has higher
> --
> 2.18.0.windows.1
>
>
> --
>
> Thanks & Regards
> *Niranjan Kumar B*
> Video Codec Engineer
> Media & AI Analytics
> +91 958 511 1449
> <https://multicorewareinc.com/>
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20221215/6f2a6cf3/attachment-0001.htm>


More information about the x265-devel mailing list