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