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

pooja at multicorewareinc.com pooja at multicorewareinc.com
Tue Sep 10 07:38:13 CEST 2019


# HG changeset patch
# User Pooja Venkatesan <pooja at multicorewareinc.com>
# Date 1567500944 -19800
#      Tue Sep 03 14:25:44 2019 +0530
# Node ID f6d9a0145c4fcd7ac0a2a776a4f99fc431f8fd4a
# Parent  a092e82e6acfe7afe6a9a381e9ef52323e4e2467
Add option to enable slicetype based SAO filter.

diff -r a092e82e6acf -r f6d9a0145c4f 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
@@ -1979,9 +1979,22 @@
 	If deblocking is disabled, or the offsets are non-zero, these
 	changes from the default configuration are signaled in the PPS.
 
-.. option:: --sao, --no-sao
-
-	Toggle Sample Adaptive Offset loop filter, default enabled
+.. option:: --sao <0..4>
+
+	Toggle Sample Adaptive Offset loop filter 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             |
+	+--------------+---------------------------------------+
 
 .. option:: --sao-non-deblock, --no-sao-non-deblock
 
diff -r a092e82e6acf -r f6d9a0145c4f 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
@@ -212,7 +212,7 @@
     param->bEnableLoopFilter = 1;
 
     /* SAO Loop Filter */
-    param->bEnableSAO = 1;
+    param->enableSAO = 4;
     param->bSaoNonDeblocked = 0;
     param->bLimitSAO = 0;
 
@@ -374,7 +374,7 @@
             param->bFrameAdaptive = 0;
             param->subpelRefine = 0;
             param->searchMethod = X265_DIA_SEARCH;
-            param->bEnableSAO = 0;
+            param->enableSAO = 0;
             param->bEnableSignHiding = 0;
             param->bEnableWeightedPred = 0;
             param->rdLevel = 2;
@@ -403,7 +403,7 @@
             param->rc.aqMode = X265_AQ_NONE;
             param->rc.hevcAq = 0;
             param->rc.qgSize = 32;
-            param->bEnableSAO = 0;
+            param->enableSAO = 0;
             param->bEnableFastIntra = 1;
         }
         else if (!strcmp(preset, "veryfast"))
@@ -550,7 +550,7 @@
                  !strcmp(tune, "fast-decode"))
         {
             param->bEnableLoopFilter = 0;
-            param->bEnableSAO = 0;
+            param->enableSAO = 0;
             param->bEnableWeightedPred = 0;
             param->bEnableWeightedBiPred = 0;
             param->bIntraInBFrames = 0;
@@ -577,7 +577,7 @@
             param->bEnableRecursionSkip = 0;
             param->psyRd = 4.0;
             param->psyRdoq = 10.0;
-            param->bEnableSAO = 0;
+            param->enableSAO = 0;
             param->rc.bEnableConstVbv = 1;
         }
         else if (!strcmp(tune, "animation"))
@@ -1001,7 +1001,7 @@
         else
             p->bEnableLoopFilter = atobool(value);
     }
-    OPT("sao") p->bEnableSAO = atobool(value);
+    OPT("sao") p->enableSAO = atoi(value);
     OPT("sao-non-deblock") p->bSaoNonDeblocked = atobool(value);
     OPT("ssim") p->bEnableSsim = atobool(value);
     OPT("psnr") p->bEnablePsnr = atobool(value);
@@ -1861,7 +1861,7 @@
             TOOLOPT(param->bEnableLoopFilter, "deblock");
     }
     TOOLOPT(param->bSaoNonDeblocked, "sao-non-deblock");
-    TOOLOPT(!param->bSaoNonDeblocked && param->bEnableSAO, "sao");
+    TOOLOPT(!param->bSaoNonDeblocked && param->enableSAO, "sao");
     TOOLOPT(param->rc.bStatWrite, "stats-write");
     TOOLOPT(param->rc.bStatRead,  "stats-read");
     TOOLOPT(param->bSingleSeiNal, "single-sei");
@@ -1968,7 +1968,7 @@
     BOOL(p->bEnableLoopFilter, "deblock");
     if (p->bEnableLoopFilter)
         s += sprintf(s, "=%d:%d", p->deblockingFilterTCOffset, p->deblockingFilterBetaOffset);
-    BOOL(p->bEnableSAO, "sao");
+    s += sprintf(s, " sao=%d", p->enableSAO);
     BOOL(p->bSaoNonDeblocked, "sao-non-deblock");
     s += sprintf(s, " rd=%d", p->rdLevel);
     BOOL(p->bEnableEarlySkip, "early-skip");
@@ -2261,7 +2261,7 @@
     dst->bEnableLoopFilter = src->bEnableLoopFilter;
     dst->deblockingFilterBetaOffset = src->deblockingFilterBetaOffset;
     dst->deblockingFilterTCOffset = src->deblockingFilterTCOffset;
-    dst->bEnableSAO = src->bEnableSAO;
+    dst->enableSAO = src->enableSAO;
     dst->bSaoNonDeblocked = src->bSaoNonDeblocked;
     dst->rdLevel = src->rdLevel;
     dst->bEnableEarlySkip = src->bEnableEarlySkip;
diff -r a092e82e6acf -r f6d9a0145c4f 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 f6d9a0145c4f 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->enableSAO)
+            {
+                Slice* slice = frameEnc->m_encData->m_slice;
+                slice->m_bUseSao = curEncoder->m_frameFilter.m_useSao = 1;
+                switch (m_param->enableSAO)
+                {
+                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);
@@ -2543,7 +2565,7 @@
     sps->quadtreeTUMaxDepthInter = m_param->tuQTMaxInterDepth;
     sps->quadtreeTUMaxDepthIntra = m_param->tuQTMaxIntraDepth;
 
-    sps->bUseSAO = m_param->bEnableSAO;
+    sps->bUseSAO = m_param->enableSAO ? 1 : 0;
 
     sps->bUseAMP = m_param->bEnableAMP;
     sps->maxAMPDepth = m_param->bEnableAMP ? m_param->maxCUDepth : 0;
@@ -2891,7 +2913,6 @@
 
     }
 
-
     if (p->interlaceMode)
         x265_log(p, X265_LOG_WARNING, "Support for interlaced video is experimental\n");
 
@@ -3076,9 +3097,9 @@
     }
 
     /* some options make no sense if others are disabled */
-    p->bSaoNonDeblocked &= p->bEnableSAO;
+    p->bSaoNonDeblocked &= (p->enableSAO == 4 ? 1 : 0);
     p->bEnableTSkipFast &= p->bEnableTransformSkip;
-    p->bLimitSAO &= p->bEnableSAO;
+    p->bLimitSAO &= (p->enableSAO == 4 ? 1 : 0);
     /* initialize the conformance window */
     m_conformanceWindow.bEnabled = false;
     m_conformanceWindow.rightOffset = 0;
diff -r a092e82e6acf -r f6d9a0145c4f 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->enableSAO)
+    {
+        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 f6d9a0145c4f source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp	Thu Aug 01 22:55:21 2019 +0200
+++ b/source/encoder/frameencoder.cpp	Tue Sep 03 14:25:44 2019 +0530
@@ -110,9 +110,9 @@
     m_numRows = numRows;
     m_numCols = numCols;
     m_reconfigure = false;
-    m_filterRowDelay = ((m_param->bEnableSAO && m_param->bSaoNonDeblocked)
-                        || (!m_param->bEnableLoopFilter && m_param->bEnableSAO)) ?
-                        2 : (m_param->bEnableSAO || m_param->bEnableLoopFilter ? 1 : 0);
+    m_filterRowDelay = ((m_param->enableSAO && m_param->bSaoNonDeblocked)
+                        || (!m_param->bEnableLoopFilter && m_param->enableSAO)) ?
+                        2 : (m_param->enableSAO || m_param->bEnableLoopFilter ? 1 : 0);
     m_filterRowDelayCus = m_filterRowDelay * numCols;
     m_rows = new CTURow[m_numRows];
     bool ok = !!m_numRows;
@@ -634,7 +634,7 @@
         if (!m_param->bEnableWavefront)
             m_backupStreams = new Bitstream[numSubstreams];
         m_substreamSizes = X265_MALLOC(uint32_t, numSubstreams);
-        if (!m_param->bEnableSAO)
+        if (!m_param->enableSAO)
             for (uint32_t i = 0; i < numSubstreams; i++)
                 m_rows[i].rowGoOnCoder.setBitstream(&m_outStreams[i]);
     }
@@ -981,7 +981,7 @@
     m_entropyCoder.setBitstream(&m_bs);
 
     // finish encode of each CTU row, only required when SAO is enabled
-    if (m_param->bEnableSAO)
+    if (m_param->enableSAO)
         encodeSlice(0);
 
     m_entropyCoder.setBitstream(&m_bs);
@@ -1515,11 +1515,11 @@
             curRow.bufferedEntropy.loadContexts(rowCoder);
 
         /* SAO parameter estimation using non-deblocked pixels for CTU bottom and right boundary areas */
-        if (m_param->bEnableSAO && m_param->bSaoNonDeblocked)
+        if (m_param->enableSAO && m_param->bSaoNonDeblocked)
             m_frameFilter.m_parallelFilter[row].m_sao.calcSaoStatsCu_BeforeDblk(m_frame, col, row);
 
         /* Deblock with idle threading */
-        if (m_param->bEnableLoopFilter | m_param->bEnableSAO)
+        if (m_param->bEnableLoopFilter | m_param->enableSAO)
         {
             // NOTE: in VBV mode, we may reencode anytime, so we can't do Deblock stage-Horizon and SAO
             if (!bIsVbv)
@@ -1833,12 +1833,12 @@
 
     /* flush row bitstream (if WPP and no SAO) or flush frame if no WPP and no SAO */
     /* end_of_sub_stream_one_bit / end_of_slice_segment_flag */
-    if (!m_param->bEnableSAO && (m_param->bEnableWavefront || bLastRowInSlice))
+    if (!m_param->enableSAO && (m_param->bEnableWavefront || bLastRowInSlice))
         rowCoder.finishSlice();
 
 
     /* Processing left Deblock block with current threading */
-    if ((m_param->bEnableLoopFilter | m_param->bEnableSAO) & (rowInSlice >= 2))
+    if ((m_param->bEnableLoopFilter | m_param->enableSAO) & (rowInSlice >= 2))
     {
         /* Check conditional to start previous row process with current threading */
         if (m_frameFilter.m_parallelFilter[row - 2].m_lastDeblocked.get() == (int)numCols)
diff -r a092e82e6acf -r f6d9a0145c4f 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 f6d9a0145c4f 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;
+    bool          m_useSao;
     FrameEncoder* m_frameEncoder;
     int           m_hChromaShift;
     int           m_vChromaShift;
diff -r a092e82e6acf -r f6d9a0145c4f 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
@@ -17,7 +17,7 @@
 BasketballDrive_1920x1080_50.y4m,--preset veryfast --tune zerolatency --no-temporal-mvp
 BasketballDrive_1920x1080_50.y4m,--preset faster --aq-strength 2 --merange 190 --slices 3
 BasketballDrive_1920x1080_50.y4m,--preset medium --ctu 16 --max-tu-size 8 --subme 7 --qg-size 16 --cu-lossless --tu-inter-depth 3 --limit-tu 1
-BasketballDrive_1920x1080_50.y4m,--preset medium --keyint -1 --nr-inter 100 -F4 --no-sao
+BasketballDrive_1920x1080_50.y4m,--preset medium --keyint -1 --nr-inter 100 -F4 --sao 0
 BasketballDrive_1920x1080_50.y4m,--preset medium --no-cutree --analysis-save x265_analysis.dat --analysis-reuse-level 2 --bitrate 7000 --limit-modes::--preset medium --no-cutree --analysis-load x265_analysis.dat --analysis-reuse-level 2 --bitrate 7000 --limit-modes
 BasketballDrive_1920x1080_50.y4m,--preset slow --nr-intra 100 -F4 --aq-strength 3 --qg-size 16 --limit-refs 1
 BasketballDrive_1920x1080_50.y4m,--preset slower --lossless --chromaloc 3 --subme 0 --limit-tu 4
@@ -32,7 +32,7 @@
 Coastguard-4k.y4m,--preset medium --rdoq-level 1 --tune ssim --no-signhide --me umh --slices 2
 Coastguard-4k.y4m,--preset slow --tune psnr --cbqpoffs -1 --crqpoffs 1 --limit-refs 1
 CrowdRun_1920x1080_50_10bit_422.yuv,--preset ultrafast --weightp --tune zerolatency --qg-size 16
-CrowdRun_1920x1080_50_10bit_422.yuv,--preset superfast --weightp --no-wpp --sao
+CrowdRun_1920x1080_50_10bit_422.yuv,--preset superfast --weightp --no-wpp --sao 4
 CrowdRun_1920x1080_50_10bit_422.yuv,--preset veryfast --temporal-layers --tune grain
 CrowdRun_1920x1080_50_10bit_422.yuv,--preset faster --max-tu-size 4 --min-cu-size 32
 CrowdRun_1920x1080_50_10bit_422.yuv,--preset fast --aq-mode 0 --sar 2 --range full
@@ -74,7 +74,7 @@
 News-4k.y4m,--preset ultrafast --no-cutree --analysis-save x265_analysis.dat --analysis-reuse-level 2 --bitrate 15000::--preset ultrafast --no-cutree --analysis-load x265_analysis.dat --analysis-reuse-level 2 --bitrate 15000
 News-4k.y4m,--preset superfast --lookahead-slices 6 --aq-mode 0
 News-4k.y4m,--preset superfast --slices 4 --aq-mode 0 
-News-4k.y4m,--preset medium --tune ssim --no-sao --qg-size 16
+News-4k.y4m,--preset medium --tune ssim --sao 0 --qg-size 16
 News-4k.y4m,--preset veryslow --no-rskip
 News-4k.y4m,--preset veryslow --pme --crf 40
 OldTownCross_1920x1080_50_10bit_422.yuv,--preset superfast --weightp
@@ -134,7 +134,7 @@
 parkrun_ter_720p50.y4m,--preset slower --fast-intra --no-rect --tune grain
 silent_cif_420.y4m,--preset superfast --weightp --rect
 silent_cif_420.y4m,--preset medium --me full --rect --amp
-silent_cif_420.y4m,--preset placebo --ctu 32 --no-sao --qg-size 16
+silent_cif_420.y4m,--preset placebo --ctu 32 --sao 0 --qg-size 16
 washdc_422_ntsc.y4m,--preset ultrafast --weightp --tu-intra-depth 4
 vtc1nw_422_ntsc.y4m,--preset superfast --weightp --nr-intra 100 -F4
 washdc_422_ntsc.y4m,--preset superfast --psy-rd 1 --tune zerolatency
diff -r a092e82e6acf -r f6d9a0145c4f source/test/smoke-tests.txt
--- a/source/test/smoke-tests.txt	Thu Aug 01 22:55:21 2019 +0200
+++ b/source/test/smoke-tests.txt	Tue Sep 03 14:25:44 2019 +0530
@@ -19,7 +19,7 @@
 DucksAndLegs_1920x1080_60_10bit_422.yuv,--preset=veryfast --min-cu 16
 DucksAndLegs_1920x1080_60_10bit_422.yuv,--preset=fast --weightb --interlace bff
 DucksAndLegs_1920x1080_60_10bit_422.yuv,--preset=veryslow --limit-ref 1 --limit-mode --tskip --limit-tu 1
-CrowdRun_1920x1080_50_10bit_444.yuv,--preset=superfast --bitrate 7000 --sao --limit-sao
+CrowdRun_1920x1080_50_10bit_444.yuv,--preset=superfast --bitrate 7000 --sao 4 --limit-sao
 # Main12 intraCost overflow bug test
 720p50_parkrun_ter.y4m,--preset medium
 720p50_parkrun_ter.y4m,--preset=fast --hevc-aq --no-cutree
diff -r a092e82e6acf -r f6d9a0145c4f 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
@@ -1208,12 +1208,16 @@
      * This is the coded div2 value, actual offset is doubled at use */
     int       deblockingFilterBetaOffset;
 
-    /* Enable the Sample Adaptive Offset loop filter, which reduces distortion
+    /* Tune the Sample Adaptive Offset loop filter, which reduces distortion
      * effects by adjusting reconstructed sample values based on histogram
      * analysis to better approximate the original samples. When enabled it adds
      * a CU row of reference lag, reducing frame parallelism effectiveness.
-     * Default is enabled */
-    int       bEnableSAO;
+     * Default is 4 - enabled for all slices 
+     * The 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       enableSAO;
 
     /* Note: when deblocking and SAO are both enabled, the loop filter CU lag is
      * only one row, as they operate in series on the same row. */
diff -r a092e82e6acf -r f6d9a0145c4f 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
@@ -199,8 +199,7 @@
     { "lft",                  no_argument, NULL, 0 }, /* DEPRECATED */
     { "no-deblock",           no_argument, NULL, 0 },
     { "deblock",        required_argument, NULL, 0 },
-    { "no-sao",               no_argument, NULL, 0 },
-    { "sao",                  no_argument, NULL, 0 },
+    { "sao",            required_argument, NULL, 0 },
     { "no-sao-non-deblock",   no_argument, NULL, 0 },
     { "sao-non-deblock",      no_argument, NULL, 0 },
     { "no-ssim",              no_argument, NULL, 0 },
@@ -586,7 +585,7 @@
     H0("                                 It represents the percentage of maximum AU size used. Default %.1f\n", param->maxAUSizeFactor);
     H0("\nLoop filters (deblock and SAO):\n");
     H0("   --[no-]deblock                Enable Deblocking Loop Filter, optionally specify tC:Beta offsets Default %s\n", OPT(param->bEnableLoopFilter));
-    H0("   --[no-]sao                    Enable Sample Adaptive Offset. Default %s\n", OPT(param->bEnableSAO));
+    H0("   --sao <0..4>                  Enable Slice-based Sample Adaptive Offset. Default %d\n", param->enableSAO);
     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("\nVUI options:\n");
-------------- next part --------------
A non-text attachment was scrubbed...
Name: x265-1.patch
Type: text/x-patch
Size: 23305 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20190910/0b67c775/attachment-0001.bin>


More information about the x265-devel mailing list