[x265] [PATCH 1 of 2] Add option to enable slice-based SAO filter
pooja at multicorewareinc.com
pooja at multicorewareinc.com
Wed Sep 11 19:18:04 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 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");
-------------- next part --------------
A non-text attachment was scrubbed...
Name: x265-1.patch
Type: text/x-patch
Size: 16410 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20190911/fc1d67f2/attachment-0001.bin>
More information about the x265-devel
mailing list