[x265] [PATCH 1 of 2] Add option to enable slice-based SAO filter

Aruna Matheswaran aruna at multicorewareinc.com
Thu Sep 12 08:10:10 CEST 2019


Pushed to default.

On Wed, Sep 11, 2019 at 10:48 PM <pooja at multicorewareinc.com> wrote:

> # HG changeset patch
> # User Pooja Venkatesan <pooja at multicorewareinc.com>
> # Date 1567500944 -19800
> #      Tue Sep 03 14:25:44 2019 +0530
> # Node ID 5e791399ec4a0a788f880a9967c9e21fbaa22fa3
> # Parent  a092e82e6acfe7afe6a9a381e9ef52323e4e2467
> Add option to enable slice-based SAO filter.
>
> diff -r a092e82e6acf -r 5e791399ec4a doc/reST/cli.rst
> --- a/doc/reST/cli.rst  Thu Aug 01 22:55:21 2019 +0200
> +++ b/doc/reST/cli.rst  Tue Sep 03 14:25:44 2019 +0530
> @@ -1996,6 +1996,24 @@
>         on inter prediction mode, CTU spatial-domain correlations, and
> relations
>         between luma and chroma.
>         Default disabled
> +
> +.. option:: --selective-sao <0..4>
> +
> +       Toggles SAO at slice level. Default 4.
> +
> +       +--------------+---------------------------------------+
> +       |     Level    |              Description              |
> +       +==============+=======================================+
> +       |      0       | Disable SAO for all slices            |
> +       +--------------+---------------------------------------+
> +       |      1       | Enable SAO only for I-slices          |
> +       +--------------+---------------------------------------+
> +       |      2       | Enable SAO for I-slices & P-slices    |
>                         |
> +       +--------------+---------------------------------------+
> +       |      3       | Enable SAO for all reference slices   |
> +       +--------------+---------------------------------------+
> +       |      4       | Enable SAO for all slices             |
> +       +--------------+---------------------------------------+
>
>  VUI (Video Usability Information) options
>  =========================================
> diff -r a092e82e6acf -r 5e791399ec4a source/CMakeLists.txt
> --- a/source/CMakeLists.txt     Thu Aug 01 22:55:21 2019 +0200
> +++ b/source/CMakeLists.txt     Tue Sep 03 14:25:44 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 178)
> +set(X265_BUILD 179)
>  configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
>                 "${PROJECT_BINARY_DIR}/x265.def")
>  configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
> diff -r a092e82e6acf -r 5e791399ec4a source/common/param.cpp
> --- a/source/common/param.cpp   Thu Aug 01 22:55:21 2019 +0200
> +++ b/source/common/param.cpp   Tue Sep 03 14:25:44 2019 +0530
> @@ -215,6 +215,7 @@
>      param->bEnableSAO = 1;
>      param->bSaoNonDeblocked = 0;
>      param->bLimitSAO = 0;
> +    param->selectiveSAO = 4;
>
>      /* Coding Quality */
>      param->cbQpOffset = 0;
> @@ -375,6 +376,7 @@
>              param->subpelRefine = 0;
>              param->searchMethod = X265_DIA_SEARCH;
>              param->bEnableSAO = 0;
> +            param->selectiveSAO = 0;
>              param->bEnableSignHiding = 0;
>              param->bEnableWeightedPred = 0;
>              param->rdLevel = 2;
> @@ -404,6 +406,7 @@
>              param->rc.hevcAq = 0;
>              param->rc.qgSize = 32;
>              param->bEnableSAO = 0;
> +            param->selectiveSAO = 0;
>              param->bEnableFastIntra = 1;
>          }
>          else if (!strcmp(preset, "veryfast"))
> @@ -551,6 +554,7 @@
>          {
>              param->bEnableLoopFilter = 0;
>              param->bEnableSAO = 0;
> +            param->selectiveSAO = 0;
>              param->bEnableWeightedPred = 0;
>              param->bEnableWeightedBiPred = 0;
>              param->bIntraInBFrames = 0;
> @@ -578,6 +582,7 @@
>              param->psyRd = 4.0;
>              param->psyRdoq = 10.0;
>              param->bEnableSAO = 0;
> +            param->selectiveSAO = 0;
>              param->rc.bEnableConstVbv = 1;
>          }
>          else if (!strcmp(tune, "animation"))
> @@ -1282,6 +1287,10 @@
>          OPT("svt-pred-struct") x265_log(p, X265_LOG_WARNING, "Option %s
> is SVT-HEVC Encoder specific; Disabling it here \n", name);
>          OPT("svt-fps-in-vps") x265_log(p, X265_LOG_WARNING, "Option %s is
> SVT-HEVC Encoder specific; Disabling it here \n", name);
>  #endif
> +        OPT("selective-sao")
> +        {
> +            p->selectiveSAO = atoi(value);
> +        }
>          OPT("fades") p->bEnableFades = atobool(value);
>          OPT("field") p->bField = atobool( value );
>          OPT("cll") p->bEmitCLL = atobool(value);
> @@ -1686,6 +1695,8 @@
>          CHECK( (param->bFrameAdaptive==0), "Adaptive B-frame decision
> method should be closed for field feature.\n" );
>          // to do
>      }
> +    CHECK(param->selectiveSAO < 0 || param->selectiveSAO > 4,
> +        "Invalid SAO tune level. Value must be between 0 and 4
> (inclusive)");
>  #if !X86_64
>      CHECK(param->searchMethod == X265_SEA && (param->sourceWidth > 840 ||
> param->sourceHeight > 480),
>          "SEA motion search does not support resolutions greater than 480p
> in 32 bit build");
> @@ -1862,6 +1873,8 @@
>      }
>      TOOLOPT(param->bSaoNonDeblocked, "sao-non-deblock");
>      TOOLOPT(!param->bSaoNonDeblocked && param->bEnableSAO, "sao");
> +    if (param->selectiveSAO != 4)
> +        TOOLOPT(param->selectiveSAO, "selective-sao");
>      TOOLOPT(param->rc.bStatWrite, "stats-write");
>      TOOLOPT(param->rc.bStatRead,  "stats-read");
>      TOOLOPT(param->bSingleSeiNal, "single-sei");
> @@ -1971,6 +1984,7 @@
>      BOOL(p->bEnableSAO, "sao");
>      BOOL(p->bSaoNonDeblocked, "sao-non-deblock");
>      s += sprintf(s, " rd=%d", p->rdLevel);
> +    s += sprintf(s, "selective-sao=%d", p->selectiveSAO);
>      BOOL(p->bEnableEarlySkip, "early-skip");
>      BOOL(p->bEnableRecursionSkip, "rskip");
>      BOOL(p->bEnableFastIntra, "fast-intra");
> @@ -2420,6 +2434,7 @@
>      else dst->analysisLoad = NULL;
>      dst->gopLookahead = src->gopLookahead;
>      dst->radl = src->radl;
> +    dst->selectiveSAO = src->selectiveSAO;
>      dst->maxAUSizeFactor = src->maxAUSizeFactor;
>      dst->bEmitIDRRecoverySEI = src->bEmitIDRRecoverySEI;
>      dst->bDynamicRefine = src->bDynamicRefine;
> diff -r a092e82e6acf -r 5e791399ec4a source/common/slice.h
> --- a/source/common/slice.h     Thu Aug 01 22:55:21 2019 +0200
> +++ b/source/common/slice.h     Tue Sep 03 14:25:44 2019 +0530
> @@ -356,6 +356,7 @@
>      bool        m_bCheckLDC;       // TODO: is this necessary?
>      bool        m_sLFaseFlag;      // loop filter boundary flag
>      bool        m_colFromL0Flag;   // collocated picture from List0 or
> List1 flag
> +    int         m_bUseSao;
>
>      int         m_iPPSQpMinus26;
>      int         numRefIdxDefault[2];
> diff -r a092e82e6acf -r 5e791399ec4a source/encoder/encoder.cpp
> --- a/source/encoder/encoder.cpp        Thu Aug 01 22:55:21 2019 +0200
> +++ b/source/encoder/encoder.cpp        Tue Sep 03 14:25:44 2019 +0530
> @@ -1621,6 +1621,28 @@
>              }
>              /* determine references, setup RPS, etc */
>              m_dpb->prepareEncode(frameEnc);
> +            if (!!m_param->selectiveSAO)
> +            {
> +                Slice* slice = frameEnc->m_encData->m_slice;
> +                slice->m_bUseSao = curEncoder->m_frameFilter.m_useSao = 1;
> +                switch (m_param->selectiveSAO)
> +                {
> +                case 3: if (!IS_REFERENCED(frameEnc))
> +                            slice->m_bUseSao =
> curEncoder->m_frameFilter.m_useSao = 0;
> +                        break;
> +                case 2: if (!!m_param->bframes && slice->m_sliceType ==
> B_SLICE)
> +                            slice->m_bUseSao =
> curEncoder->m_frameFilter.m_useSao = 0;
> +                        break;
> +                case 1: if (slice->m_sliceType != I_SLICE)
> +                            slice->m_bUseSao =
> curEncoder->m_frameFilter.m_useSao = 0;
> +                        break;
> +                }
> +            }
> +            else
> +            {
> +                Slice* slice = frameEnc->m_encData->m_slice;
> +                slice->m_bUseSao = curEncoder->m_frameFilter.m_useSao = 0;
> +            }
>
>              if (m_param->rc.rateControlMode != X265_RC_CQP)
>                  m_lookahead->getEstimatedPictureCost(frameEnc);
> @@ -2891,6 +2913,14 @@
>
>      }
>
> +    if (p->selectiveSAO && !p->bEnableSAO)
> +    {
> +        p->bEnableSAO = 1;
> +        x265_log(p, X265_LOG_WARNING, "SAO turned ON when selective-sao
> is ON\n");
> +    }
> +
> +    if (!p->selectiveSAO && p->bEnableSAO)
> +        p->selectiveSAO = 4;
>
>      if (p->interlaceMode)
>          x265_log(p, X265_LOG_WARNING, "Support for interlaced video is
> experimental\n");
> diff -r a092e82e6acf -r 5e791399ec4a source/encoder/entropy.cpp
> --- a/source/encoder/entropy.cpp        Thu Aug 01 22:55:21 2019 +0200
> +++ b/source/encoder/entropy.cpp        Tue Sep 03 14:25:44 2019 +0530
> @@ -641,12 +641,18 @@
>              WRITE_FLAG(1, "slice_temporal_mvp_enable_flag");
>      }
>      const SAOParam *saoParam = encData.m_saoParam;
> -    if (slice.m_sps->bUseSAO)
> +    if (slice.m_bUseSao)
>      {
>          WRITE_FLAG(saoParam->bSaoFlag[0], "slice_sao_luma_flag");
>          if (encData.m_param->internalCsp != X265_CSP_I400)
>              WRITE_FLAG(saoParam->bSaoFlag[1], "slice_sao_chroma_flag");
>      }
> +    else if(encData.m_param->selectiveSAO)
> +    {
> +        WRITE_FLAG(0, "slice_sao_luma_flag");
> +        if (encData.m_param->internalCsp != X265_CSP_I400)
> +            WRITE_FLAG(0, "slice_sao_chroma_flag");
> +    }
>
>      // check if numRefIdx match the defaults (1, hard-coded in PPS). If
> not, override
>      // TODO: this might be a place to optimize a few bits per slice, by
> using param->refs for L0 default
> @@ -706,7 +712,7 @@
>
>      if (encData.m_param->maxSlices <= 1)
>      {
> -        bool isSAOEnabled = slice.m_sps->bUseSAO ? saoParam->bSaoFlag[0]
> || saoParam->bSaoFlag[1] : false;
> +        bool isSAOEnabled = slice.m_sps->bUseSAO && slice.m_bUseSao ?
> saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1] : false;
>          bool isDBFEnabled = !slice.m_pps->bPicDisableDeblockingFilter;
>
>          if (isSAOEnabled || isDBFEnabled)
> diff -r a092e82e6acf -r 5e791399ec4a source/encoder/framefilter.cpp
> --- a/source/encoder/framefilter.cpp    Thu Aug 01 22:55:21 2019 +0200
> +++ b/source/encoder/framefilter.cpp    Tue Sep 03 14:25:44 2019 +0530
> @@ -163,7 +163,7 @@
>
>      if (m_parallelFilter)
>      {
> -        if (m_param->bEnableSAO)
> +        if (m_useSao)
>          {
>              for(int row = 0; row < m_numRows; row++)
>                  m_parallelFilter[row].m_sao.destroy((row == 0 ? 1 : 0));
> @@ -178,6 +178,7 @@
>  {
>      m_param = frame->m_param;
>      m_frameEncoder = frame;
> +    m_useSao = 1;
>      m_numRows = numRows;
>      m_numCols = numCols;
>      m_hChromaShift = CHROMA_H_SHIFT(m_param->internalCsp);
> @@ -196,12 +197,12 @@
>
>      if (m_parallelFilter)
>      {
> -        if (m_param->bEnableSAO)
> +        if (m_useSao)
>          {
>              for(int row = 0; row < numRows; row++)
>              {
>                  if (!m_parallelFilter[row].m_sao.create(m_param, (row ==
> 0 ? 1 : 0)))
> -                    m_param->bEnableSAO = 0;
> +                    m_useSao = 0;
>                  else
>                  {
>                      if (row != 0)
> @@ -235,7 +236,7 @@
>      {
>          for(int row = 0; row < m_numRows; row++)
>          {
> -            if (m_param->bEnableSAO)
> +            if (m_useSao)
>                  m_parallelFilter[row].m_sao.startSlice(frame, initState);
>
>              m_parallelFilter[row].m_lastCol.set(0);
> @@ -245,7 +246,7 @@
>          }
>
>          // Reset SAO common statistics
> -        if (m_param->bEnableSAO)
> +        if (m_useSao)
>              m_parallelFilter[0].m_sao.resetStats();
>      }
>  }
> @@ -472,11 +473,11 @@
>                  deblockCTU(ctuPrev, cuGeoms[ctuGeomMap[cuAddr - 1]],
> Deblock::EDGE_HOR);
>
>                  // When SAO Disable, setting column counter here
> -                if (!m_frameFilter->m_param->bEnableSAO &
> !ctuPrev->m_bFirstRowInSlice)
> +                if (!m_frameFilter->m_useSao &
> !ctuPrev->m_bFirstRowInSlice)
>                      m_prevRow->processPostCu(col - 1);
>              }
>
> -            if (m_frameFilter->m_param->bEnableSAO)
> +            if (m_frameFilter->m_useSao)
>              {
>                  // Save SAO bottom row reference pixels
>                  copySaoAboveRef(ctuPrev, reconPic, cuAddr - 1, col - 1);
> @@ -514,12 +515,12 @@
>              deblockCTU(ctuPrev, cuGeoms[ctuGeomMap[cuAddr]],
> Deblock::EDGE_HOR);
>
>              // When SAO Disable, setting column counter here
> -            if (!m_frameFilter->m_param->bEnableSAO &
> !ctuPrev->m_bFirstRowInSlice)
> +            if (!m_frameFilter->m_useSao & !ctuPrev->m_bFirstRowInSlice)
>                  m_prevRow->processPostCu(numCols - 1);
>          }
>
>          // TODO: move processPostCu() into processSaoUnitCu()
> -        if (m_frameFilter->m_param->bEnableSAO)
> +        if (m_frameFilter->m_useSao)
>          {
>              const CUData* ctu = m_encData->getPicCTU(m_rowAddr + numCols
> - 2);
>
> @@ -570,7 +571,7 @@
>      m_frameEncoder->m_cuStats.countLoopFilter++;
>  #endif
>
> -    if (!m_param->bEnableLoopFilter && !m_param->bEnableSAO)
> +    if (!m_param->bEnableLoopFilter && !m_useSao)
>      {
>          processPostRow(row);
>          return;
> @@ -596,7 +597,7 @@
>                  x265_log(m_param, X265_LOG_WARNING, "detected
> ParallelFilter race condition on last row\n");
>
>              /* Apply SAO on last row of CUs, because we always apply SAO
> on row[X-1] */
> -            if (m_param->bEnableSAO)
> +            if (m_useSao)
>              {
>                  for(int col = 0; col < m_numCols; col++)
>                  {
> @@ -634,7 +635,7 @@
>
>      if (numRowFinished == m_numRows)
>      {
> -        if (m_param->bEnableSAO)
> +        if (m_useSao)
>          {
>              // Merge numNoSao into RootNode (Node0)
>              for(int i = 1; i < m_numRows; i++)
> diff -r a092e82e6acf -r 5e791399ec4a source/encoder/framefilter.h
> --- a/source/encoder/framefilter.h      Thu Aug 01 22:55:21 2019 +0200
> +++ b/source/encoder/framefilter.h      Tue Sep 03 14:25:44 2019 +0530
> @@ -46,6 +46,7 @@
>
>      x265_param*   m_param;
>      Frame*        m_frame;
> +    int           m_useSao;
>      FrameEncoder* m_frameEncoder;
>      int           m_hChromaShift;
>      int           m_vChromaShift;
> diff -r a092e82e6acf -r 5e791399ec4a source/test/regression-tests.txt
> --- a/source/test/regression-tests.txt  Thu Aug 01 22:55:21 2019 +0200
> +++ b/source/test/regression-tests.txt  Tue Sep 03 14:25:44 2019 +0530
> @@ -155,6 +155,7 @@
>  big_buck_bunny_360p24.y4m, --bitrate 500 --fades
>  720p50_parkrun_ter.y4m,--preset medium --bitrate 400 --hme
>  ducks_take_off_420_1_720p50.y4m,--preset medium --aq-mode 4 --crf 22
> --no-cutree
> +ducks_take_off_420_1_720p50.y4m,--preset medium --selective-sao 4 --sao
> --crf 20
>
>  # Main12 intraCost overflow bug test
>  720p50_parkrun_ter.y4m,--preset medium
> diff -r a092e82e6acf -r 5e791399ec4a source/x265.h
> --- a/source/x265.h     Thu Aug 01 22:55:21 2019 +0200
> +++ b/source/x265.h     Tue Sep 03 14:25:44 2019 +0530
> @@ -1223,6 +1223,12 @@
>       * non-deblocked pixels are used entirely. Default is disabled */
>      int       bSaoNonDeblocked;
>
> +    /* Select tune rate in which SAO has to be applied.
> +    1 - Filtering applied only on I-frames(I) [Light tune]
> +    2 - No Filtering on B frames (I, P) [Medium tune]
> +    3 - No Filtering on non-ref b frames  (I, P, B) [Strong tune] */
> +    int       selectiveSAO;
> +
>      /*== Analysis tools ==*/
>
>      /* A value between 1 and 6 (both inclusive) which determines the
> level of
> diff -r a092e82e6acf -r 5e791399ec4a source/x265cli.h
> --- a/source/x265cli.h  Thu Aug 01 22:55:21 2019 +0200
> +++ b/source/x265cli.h  Tue Sep 03 14:25:44 2019 +0530
> @@ -200,6 +200,7 @@
>      { "no-deblock",           no_argument, NULL, 0 },
>      { "deblock",        required_argument, NULL, 0 },
>      { "no-sao",               no_argument, NULL, 0 },
> +    { "selective-sao",  required_argument, NULL, 0 },
>      { "sao",                  no_argument, NULL, 0 },
>      { "no-sao-non-deblock",   no_argument, NULL, 0 },
>      { "sao-non-deblock",      no_argument, NULL, 0 },
> @@ -589,6 +590,7 @@
>      H0("   --[no-]sao                    Enable Sample Adaptive Offset.
> Default %s\n", OPT(param->bEnableSAO));
>      H1("   --[no-]sao-non-deblock        Use non-deblocked pixels, else
> right/bottom boundary areas skipped. Default %s\n",
> OPT(param->bSaoNonDeblocked));
>      H0("   --[no-]limit-sao              Limit Sample Adaptive Offset
> types. Default %s\n", OPT(param->bLimitSAO));
> +    H0("   --selective-sao <int>         Enable slice-level SAO filter.
> Default %d\n", param->selectiveSAO);
>      H0("\nVUI options:\n");
>      H0("   --sar <width:height|int>      Sample Aspect Ratio, the ratio
> of width to height of an individual pixel.\n");
>      H0("                                 Choose from 0=undef,
> 1=1:1(\"square\"), 2=12:11, 3=10:11, 4=16:11,\n");
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
>


-- 
Regards,
Aruna
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20190912/0a08ef98/attachment-0001.html>


More information about the x265-devel mailing list