<div dir="ltr">From 4bf3e68331547af4565c0a96cb537b8cd5d22b89 Mon Sep 17 00:00:00 2001<br>From: AnusuyaKumarasamy <<a href="mailto:anusuya.kumarasamy@multicorewareinc.com" target="_blank">anusuya.kumarasamy@multicorewareinc.com</a>><br>Date: Fri, 26 Jul 2024 21:16:22 +0530<br>Subject: [PATCH 8/9] Add compile-time flag for scc<br><br>---<br> doc/reST/cli.rst                    | 16 ++++++++++<br> source/CMakeLists.txt               |  5 ++++<br> source/common/cudata.cpp            | 27 ++++++++++++-----<br> source/common/cudata.h              |  6 ++++<br> source/common/frame.cpp             |  9 +++---<br> source/common/frame.h               |  2 +-<br> source/common/framedata.h           |  2 +-<br> source/common/param.cpp             |  9 ++++++<br> source/common/predict.cpp           | 16 +++++++---<br> source/common/slice.cpp             | 14 +++++++++<br> source/common/slice.h               | 12 ++++++--<br> source/encoder/analysis.cpp         | 32 +++++++++++++++++++-<br> source/encoder/analysis.h           |  6 +++-<br> source/encoder/dpb.cpp              |  4 ++-<br> source/encoder/encoder.cpp          |  4 +++<br> source/encoder/entropy.cpp          | 22 ++++++++++++++<br> source/encoder/frameencoder.cpp     |  4 +++<br> source/encoder/level.cpp            | 25 +++++++++++-----<br> source/encoder/search.cpp           | 45 +++++++++++++++++++++++++++--<br> source/encoder/search.h             |  5 ++++<br> source/encoder/weightPrediction.cpp |  2 ++<br> source/x265.h                       |  7 +++++<br> source/x265cli.cpp                  |  2 ++<br> source/x265cli.h                    |  2 ++<br> 24 files changed, 243 insertions(+), 35 deletions(-)<br><br>diff --git a/doc/reST/cli.rst b/doc/reST/cli.rst<br>index 298ee334a..f1aca5320 100755<br>--- a/doc/reST/cli.rst<br>+++ b/doc/reST/cli.rst<br>@@ -2923,4 +2923,20 @@ Multiview Encode Options<br> <br> **CLI_ONLY**<br> <br>+<br>+Screen Content Coding Options<br>+===================<br>+.. option:: --scc <integer><br>+<br>+    Enable screen content coding support in x265. Default disabled.<br>+    This option can be enabled only when ENABLE_SCC_EXT is set during the make of x265.<br>+    SCC enables intrablockcopy in CTU analysis which can be enabled in two modes [1-2].<br>+    Mode 1- Does limited search,faster than mode 2<br>+    Mode 2- Does full and exhaustive search<br>+<br>+    Note : Enabling SCC will disable weight prediction.<br>+           Enabling SCC expects rd-level of 6.<br>+<br>+    **CLI_ONLY**<br>+<br> .. vim: noet<br>diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt<br>index 9abf607d4..140625181 100755<br>--- a/source/CMakeLists.txt<br>+++ b/source/CMakeLists.txt<br>@@ -605,6 +605,11 @@ if(ENABLE_MULTIVIEW)<br>     add_definitions(-DENABLE_MULTIVIEW)<br> endif()<br> <br>+option(ENABLE_SCC_EXT "Enable screen content coding extension in HEVC" OFF)<br>+if(ENABLE_SCC_EXT)<br>+    add_definitions(-DENABLE_SCC_EXT)<br>+endif()<br>+<br> add_subdirectory(encoder)<br> add_subdirectory(common)<br> <br>diff --git a/source/common/cudata.cpp b/source/common/cudata.cpp<br>index e95f4830d..23ceeaeaf 100644<br>--- a/source/common/cudata.cpp<br>+++ b/source/common/cudata.cpp<br>@@ -290,8 +290,10 @@ void CUData::initCTU(const Frame& frame, uint32_t cuAddr, int qp, uint32_t first<br>     m_bFirstRowInSlice = (uint8_t)firstRowInSlice;<br>     m_bLastRowInSlice  = (uint8_t)lastRowInSlice;<br>     m_bLastCuInSlice   = (uint8_t)lastCuInSlice;<br>+#if ENABLE_SCC_EXT<br>     m_lastIntraBCMv[0].set(0, 0);<br>     m_lastIntraBCMv[1].set(0, 0);<br>+#endif<br> <br>     /* sequential memsets */<br>     m_partSet((uint8_t*)m_qp, (uint8_t)qp);<br>@@ -363,11 +365,13 @@ void CUData::initSubCU(const CUData& ctu, const CUGeom& cuGeom, int qp, MV lastI<br>     memset(m_predMode, 0, (ctu.m_chromaFormat == X265_CSP_I400 ? BytesPerPartition - 13 : BytesPerPartition - 9) * m_numPartitions);<br>     memset(m_distortion, 0, m_numPartitions * sizeof(sse_t));<br> <br>+#if ENABLE_SCC_EXT<br>     if (lastIntraBCMv)<br>     {<br>         for (int i = 0; i < 2; i++)<br>             m_lastIntraBCMv[i] = lastIntraBCMv[i];<br>     }<br>+#endif<br> }<br> <br> /* Copy the results of a sub-part (split) CU to the parent CU */<br>@@ -423,8 +427,10 @@ void CUData::copyPartFrom(const CUData& subCU, const CUGeom& childGeom, uint32_t<br>         memcpy(m_trCoeff[1] + tmpC2, subCU.m_trCoeff[1], sizeof(coeff_t) * tmpC);<br>         memcpy(m_trCoeff[2] + tmpC2, subCU.m_trCoeff[2], sizeof(coeff_t) * tmpC);<br>     }<br>+#if ENABLE_SCC_EXT<br>     for (int i = 0; i < 2; i++)<br>         m_lastIntraBCMv[i] = subCU.m_lastIntraBCMv[i];<br>+#endif<br> }<br> <br> /* If a sub-CU part is not present (off the edge of the picture) its depth and<br>@@ -1601,7 +1607,11 @@ uint32_t CUData::getInterMergeCandidates(uint32_t absPartIdx, uint32_t puIdx, MV<br>                 return maxNumMergeCand;<br>         }<br>     }<br>+#if ENABLE_SCC_EXT<br>     if (m_slice->m_bTemporalMvp)<br>+#else<br>+    if (m_slice->m_sps->bTemporalMVPEnabled)<br>+#endif<br>     {<br>         uint32_t partIdxRB = deriveRightBottomIdx(puIdx);<br>         MV colmv;<br>@@ -1692,8 +1702,10 @@ uint32_t CUData::getInterMergeCandidates(uint32_t absPartIdx, uint32_t puIdx, MV<br>         }<br>     }<br>     int numRefIdx0 = m_slice->m_numRefIdx[0];<br>+#if ENABLE_SCC_EXT<br>     if (m_slice->m_param->bEnableSCC)<br>         numRefIdx0--;<br>+#endif<br>     int numRefIdx = (isInterB) ? X265_MIN(numRefIdx0, m_slice->m_numRefIdx[1]) : numRefIdx0;<br>     int r = 0;<br>     int refcnt = 0;<br>@@ -1732,7 +1744,7 @@ int CUData::getPMV(InterNeighbourMV* neighbours, uint32_t picList, uint32_t refI<br>     bool validDirect[MD_ABOVE_LEFT + 1];<br>     bool validIndirect[MD_ABOVE_LEFT + 1];<br> <br>-#if ENABLE_MULTIVIEW<br>+#if (ENABLE_MULTIVIEW || ENABLE_SCC_EXT)<br>     if (m_slice->m_param->numViews > 1 || m_slice->m_param->bEnableSCC)<br>     {<br>         // Left candidate.<br>@@ -1827,8 +1839,8 @@ int CUData::getPMV(InterNeighbourMV* neighbours, uint32_t picList, uint32_t refI<br> <br>     // Get the collocated candidate. At this step, either the first candidate<br>     // was found or its value is 0.<br>-#if ENABLE_MULTIVIEW<br>-    if (m_slice->m_param->numViews > 1 || !!m_slice->m_param->bEnableSCC)<br>+#if ENABLE_MULTIVIEW || ENABLE_SCC_EXT<br>+    if (m_slice->m_param->numViews > 1 || m_slice->m_param->bEnableSCC)<br>     {<br>         if (m_slice->m_bTemporalMvp && num < 2)<br>         {<br>@@ -1921,7 +1933,7 @@ void CUData::getNeighbourMV(uint32_t puIdx, uint32_t absPartIdx, InterNeighbourM<br>     getInterNeighbourMV(neighbours + MD_ABOVE,      partIdxRT, MD_ABOVE);<br>     getInterNeighbourMV(neighbours + MD_ABOVE_LEFT, partIdxLT, MD_ABOVE_LEFT);<br> <br>-    if (m_slice->m_bTemporalMvp && !(!!m_slice->m_param->bEnableSCC || m_slice->m_param->numViews > 1))<br>+    if (m_slice->m_bTemporalMvp && !(m_slice->m_param->bEnableSCC || m_slice->m_param->numViews > 1))<br>     {<br>         uint32_t absPartAddr = m_absIdxInCTU + absPartIdx;<br>         uint32_t partIdxRB = deriveRightBottomIdx(puIdx);<br>@@ -2059,7 +2071,7 @@ bool CUData::getIndirectPMV(MV& outMV, InterNeighbourMV *neighbours, uint32_t pi<br>             int neibRefPOC = m_slice->m_refPOCList[picList][partRefIdx];<br>             MV mvp = neighbours->mv[picList];<br> <br>-#if ENABLE_MULTIVIEW<br>+#if ENABLE_MULTIVIEW || ENABLE_SCC_EXT<br>             if ((curRefPOC == curPOC) == (neibRefPOC == curPOC))<br>             {<br>                 if (curRefPOC == curPOC)<br>@@ -2107,7 +2119,7 @@ bool CUData::getColMVP(MV& outMV, int& outRefIdx, int picList, int cuAddr, int p<br>     int curRefPOC = m_slice->m_refPOCList[picList][outRefIdx];<br>     int curPOC = m_slice->m_poc;<br> <br>-#if ENABLE_MULTIVIEW<br>+#if ENABLE_MULTIVIEW || ENABLE_SCC_EXT<br>     if ((colPOC == colRefPOC) != (curPOC == curRefPOC))<br>         return false;<br>     else if (curRefPOC == curPOC)<br>@@ -2268,7 +2280,7 @@ void CUData::calcCTUGeoms(uint32_t ctuWidth, uint32_t ctuHeight, uint32_t maxCUS<br>     }<br> }<br> <br>-<br>+#if ENABLE_SCC_EXT<br> bool CUData::getDerivedBV(uint32_t absPartIdx, const MV& currentMv, MV& derivedMv, uint32_t width, uint32_t height)<br> {<br>     const int   ctuWidth = m_slice->m_param->maxCUSize;<br>@@ -2564,3 +2576,4 @@ bool CUData::is8x8BipredRestriction(MV mvL0, MV mvL1, int iRefIdxL0, int iRefIdx<br>     }<br>     return b8x8BiPredRestricted;<br> }<br>+#endif<br>diff --git a/source/common/cudata.h b/source/common/cudata.h<br>index 69cfb4947..2b669a802 100644<br>--- a/source/common/cudata.h<br>+++ b/source/common/cudata.h<br>@@ -37,7 +37,9 @@ class FrameData;<br> class Slice;<br> struct TUEntropyCodingParameters;<br> struct CUDataMemPool;<br>+#if ENABLE_SCC_EXT<br> struct IBC;<br>+#endif<br> <br> enum PartSize<br> {<br>@@ -241,7 +243,9 @@ public:<br>     uint32_t*       m_collectCUVariance;<br>     uint32_t*       m_collectCUCount;<br> <br>+#if ENABLE_SCC_EXT<br>     MV              m_lastIntraBCMv[2];<br>+#endif<br> <br>     CUData();<br> <br>@@ -322,12 +326,14 @@ public:<br>     const CUData* getPUAboveRightAdi(uint32_t& arPartUnitIdx, uint32_t curPartUnitIdx, uint32_t partUnitOffset) const;<br>     const CUData* getPUBelowLeftAdi(uint32_t& blPartUnitIdx, uint32_t curPartUnitIdx, uint32_t partUnitOffset) const;<br> <br>+#if ENABLE_SCC_EXT<br>     void getIntraBCMVPsEncOnly(uint32_t absPartIdx, MV* MvPred, int& nbPred, int puIdx);<br>     bool getDerivedBV(uint32_t absPartIdx, const MV& currentMv, MV& derivedMv, uint32_t width, uint32_t height);<br>     bool isIntraBC(const CUData* cu, uint32_t absPartIdx) const;<br>     bool getColMVPIBC(int ctuRsAddr, int partUnitIdx, MV& rcMv);<br>     void roundMergeCandidates(MVField(*candMvField)[2], int iCount) const;<br>     bool is8x8BipredRestriction(MV mvL0, MV mvL1, int iRefIdxL0, int iRefIdxL1) const;<br>+#endif<br> <br> protected:<br> <br>diff --git a/source/common/frame.cpp b/source/common/frame.cpp<br>index b561a67b1..4c800e94e 100644<br>--- a/source/common/frame.cpp<br>+++ b/source/common/frame.cpp<br>@@ -37,7 +37,7 @@ Frame::Frame()<br>     m_reconColCount = NULL;<br>     m_countRefEncoders = 0;<br>     m_encData = NULL;<br>-    for (int i = 0; i < 2; i++)<br>+    for (int i = 0; i < NUM_RECON_VERSION; i++)<br>         m_reconPic[i] = NULL;<br>     m_quantOffsets = NULL;<br>     m_next = NULL;<br>@@ -211,7 +211,7 @@ bool Frame::allocEncodeData(x265_param *param, const SPS& sps)<br>         m_reconPic[i] = new PicYuv;<br>         m_encData->m_reconPic[i] = m_reconPic[i];<br>     }<br>-    bool ok = m_encData->create(*param, sps, m_fencPic->m_picCsp) && m_reconPic[0]->create(param) && (!!param->bEnableSCC ? (!!param->bEnableSCC && m_reconPic[1]->create(param)) : 1);<br>+    bool ok = m_encData->create(*param, sps, m_fencPic->m_picCsp) && m_reconPic[0]->create(param) && (param->bEnableSCC ? (param->bEnableSCC && m_reconPic[1]->create(param)) : 1);<br>     if (ok)<br>     {<br>         /* initialize right border of m_reconPicYuv as SAO may read beyond the<br>@@ -243,9 +243,8 @@ bool Frame::allocEncodeData(x265_param *param, const SPS& sps)<br> void Frame::reinit(const SPS& sps)<br> {<br>     m_bChromaExtended = false;<br>-    m_reconPic[0] = m_encData->m_reconPic[0];<br>-    if (!!m_param->bEnableSCC)<br>-        m_reconPic[1] = m_encData->m_reconPic[1];<br>+    for (int i = 0; i < !!m_param->bEnableSCC + 1; i++)<br>+        m_reconPic[i] = m_encData->m_reconPic[i];<br>     m_encData->reinit(sps);<br> }<br> <br>diff --git a/source/common/frame.h b/source/common/frame.h<br>index 4e6a4beed..4fa90ef54 100644<br>--- a/source/common/frame.h<br>+++ b/source/common/frame.h<br>@@ -81,7 +81,7 @@ public:<br>     /* These two items will be NULL until the Frame begins to be encoded, at which point<br>      * it will be assigned a FrameData instance, which comes with a reconstructed image PicYuv */<br>     FrameData*             m_encData;<br>-    PicYuv*                m_reconPic[2];<br>+    PicYuv*                m_reconPic[NUM_RECON_VERSION];<br> <br>     /* Data associated with x265_picture */<br>     PicYuv*                m_fencPic;<br>diff --git a/source/common/framedata.h b/source/common/framedata.h<br>index 66a00696c..6b9bde09a 100644<br>--- a/source/common/framedata.h<br>+++ b/source/common/framedata.h<br>@@ -115,7 +115,7 @@ public:<br>     const x265_param* m_param;<br> <br>     FrameData*     m_freeListNext;<br>-    PicYuv*        m_reconPic[2];<br>+    PicYuv*        m_reconPic[NUM_RECON_VERSION];<br>     bool           m_bHasReferences;   /* used during DPB/RPS updates */<br>     int            m_frameEncoderID;   /* the ID of the FrameEncoder encoding this frame */<br>     JobProvider*   m_jobProvider;<br>diff --git a/source/common/param.cpp b/source/common/param.cpp<br>index bbf33dae9..5288bf453 100755<br>--- a/source/common/param.cpp<br>+++ b/source/common/param.cpp<br>@@ -1476,12 +1476,14 @@ int x265_param_parse(x265_param* p, const char* name, const char* value)<br>             p->numViews = atoi(value);<br>         }<br> #endif<br>+#if ENABLE_SCC_EXT<br>         OPT("scc")<br>         {<br>             p->bEnableSCC = atoi(value);<br>             if (p->bEnableSCC)<br>                 p->bEnableWeightedPred = false;<br>         }<br>+#endif<br>         else<br>             return X265_PARAM_BAD_NAME;<br>     }<br>@@ -1964,6 +1966,9 @@ int x265_check_params(x265_param* param)<br>     CHECK((param->numViews > 2), "Multi-View Encoding currently support only 2 views");<br>     CHECK((param->numViews > 1) && (param->internalBitDepth != 8), "BitDepthConstraint must be 8 for Multiview main profile");<br>     CHECK((param->numViews > 1 && param->rc.rateControlMode != X265_RC_CQP), "Multiview encode supported only with CQP mode");<br>+#endif<br>+#if ENABLE_SCC_EXT<br>+    CHECK(!!param->bEnableSCC&& param->rdLevel != 6, "Enabling scc extension in x265 requires rdlevel of 6 ");<br> #endif<br>     return check_failed;<br> }<br>@@ -2406,7 +2411,9 @@ char *x265_param2string(x265_param* p, int padx, int pady)<br>     s += sprintf(s, " num-views=%d", p->numViews);<br>     s += sprintf(s, " format=%d", p->format);<br> #endif<br>+#if ENABLE_SCC_EXT<br>     s += sprintf(s, "scc=%d", p->bEnableSCC);<br>+#endif<br>     BOOL(p->bEnableSBRC, "sbrc");<br> #undef BOOL<br>     return buf;<br>@@ -2937,7 +2944,9 @@ void x265_copy_params(x265_param* dst, x265_param* src)<br>     dst->format = src->format;<br> #endif<br>     dst->numLayers = src->numLayers;<br>+#if ENABLE_SCC_EXT<br>     dst->bEnableSCC = src->bEnableSCC;<br>+#endif<br> <br>     if (src->videoSignalTypePreset) dst->videoSignalTypePreset = strdup(src->videoSignalTypePreset);<br>     else dst->videoSignalTypePreset = NULL;<br>diff --git a/source/common/predict.cpp b/source/common/predict.cpp<br>index e6fc478e3..8e9c32d23 100644<br>--- a/source/common/predict.cpp<br>+++ b/source/common/predict.cpp<br>@@ -112,7 +112,8 @@ void Predict::motionCompensation(const CUData& cu, const PredictionUnit& pu, Yuv<br>         }<br>         else<br>         {<br>-            if (!!cu.m_slice->m_param->bEnableSCC && refIdx0 == (cu.m_slice->m_numRefIdx[0] - 1))<br>+#if ENABLE_SCC_EXT<br>+            if (cu.m_slice->m_param->bEnableSCC && refIdx0 == (cu.m_slice->m_numRefIdx[0] - 1))<br>             {<br>                 if (bLuma)<br>                     predInterLumaPixel(pu, predYuv, *cu.m_slice->m_refFrameList[0][refIdx0]->m_reconPic[1], mv0);<br>@@ -120,6 +121,7 @@ void Predict::motionCompensation(const CUData& cu, const PredictionUnit& pu, Yuv<br>                     predInterChromaPixel(pu, predYuv, *cu.m_slice->m_refFrameList[0][refIdx0]->m_reconPic[1], mv0);<br>             }<br>             else<br>+#endif<br>             {<br>                 if (bLuma)<br>                     predInterLumaPixel(pu, predYuv, *cu.m_slice->m_refReconPicList[0][refIdx0], mv0);<br>@@ -184,17 +186,21 @@ void Predict::motionCompensation(const CUData& cu, const PredictionUnit& pu, Yuv<br> <br>             if (bLuma)<br>             {<br>-                if (!!cu.m_slice->m_param->bEnableSCC && refIdx0 == (cu.m_slice->m_numRefIdx[0] - 1))<br>+#if ENABLE_SCC_EXT<br>+                if (cu.m_slice->m_param->bEnableSCC && refIdx0 == (cu.m_slice->m_numRefIdx[0] - 1))<br>                     predInterLumaShort(pu, m_predShortYuv[0], *cu.m_slice->m_refFrameList[0][refIdx0]->m_reconPic[1], mv0);<br>                 else<br>+#endif<br>                     predInterLumaShort(pu, m_predShortYuv[0], *cu.m_slice->m_refReconPicList[0][refIdx0], mv0);<br>                 predInterLumaShort(pu, m_predShortYuv[1], *cu.m_slice->m_refReconPicList[1][refIdx1], mv1);<br>             }<br>             if (bChroma)<br>             {<br>-                if (!!cu.m_slice->m_param->bEnableSCC && refIdx0 == (cu.m_slice->m_numRefIdx[0] - 1))<br>+#if ENABLE_SCC_EXT<br>+                if (cu.m_slice->m_param->bEnableSCC && refIdx0 == (cu.m_slice->m_numRefIdx[0] - 1))<br>                     predInterChromaShort(pu, m_predShortYuv[0], *cu.m_slice->m_refFrameList[0][refIdx0]->m_reconPic[1], mv0);<br>                 else<br>+#endif<br>                     predInterChromaShort(pu, m_predShortYuv[0], *cu.m_slice->m_refReconPicList[0][refIdx0], mv0);<br>                 predInterChromaShort(pu, m_predShortYuv[1], *cu.m_slice->m_refReconPicList[1][refIdx1], mv1);<br>             }<br>@@ -222,7 +228,8 @@ void Predict::motionCompensation(const CUData& cu, const PredictionUnit& pu, Yuv<br>             }<br>             else<br>             {<br>-                if (!!cu.m_slice->m_param->bEnableSCC && refIdx0 == (cu.m_slice->m_numRefIdx[0] - 1))<br>+#if ENABLE_SCC_EXT<br>+                if (cu.m_slice->m_param->bEnableSCC && refIdx0 == (cu.m_slice->m_numRefIdx[0] - 1))<br>                 {<br>                     if (bLuma)<br>                         predInterLumaPixel(pu, predYuv, *cu.m_slice->m_refFrameList[0][refIdx0]->m_reconPic[1], mv0);<br>@@ -230,6 +237,7 @@ void Predict::motionCompensation(const CUData& cu, const PredictionUnit& pu, Yuv<br>                         predInterChromaPixel(pu, predYuv, *cu.m_slice->m_refFrameList[0][refIdx0]->m_reconPic[1], mv0);<br>                 }<br>                 else<br>+#endif<br>                 {<br>                     if (bLuma)<br>                         predInterLumaPixel(pu, predYuv, *cu.m_slice->m_refReconPicList[0][refIdx0], mv0);<br>diff --git a/source/common/slice.cpp b/source/common/slice.cpp<br>index d67aaae0b..24ccff933 100644<br>--- a/source/common/slice.cpp<br>+++ b/source/common/slice.cpp<br>@@ -63,6 +63,7 @@ void Slice::setRefPicList(PicList& picList, PicList& refPicSetInterLayer0, PicLi<br>         memset(m_refPOCList, 0, sizeof(m_refPOCList));<br>         m_numRefIdx[1] = m_numRefIdx[0] = 0;<br> <br>+#if ENABLE_SCC_EXT<br>         if (!checkNumPocTotalCurr)<br>         {<br>             if (m_rps.numberOfPictures == 0)<br>@@ -76,10 +77,12 @@ void Slice::setRefPicList(PicList& picList, PicList& refPicSetInterLayer0, PicLi<br>             }<br>             return;<br>         }<br>+#endif<br> <br>         return;<br>     }<br> <br>+#if ENABLE_SCC_EXT<br>     /*Reset the number of references for I-slice marked as P-slice*/<br>     if (m_param->bEnableSCC && m_sliceType != m_origSliceType)<br>     {<br>@@ -99,6 +102,7 @@ void Slice::setRefPicList(PicList& picList, PicList& refPicSetInterLayer0, PicLi<br>         }<br>         m_lastEncPic = prevPic;<br>     }<br>+#endif<br> <br>     Frame* refPic = NULL;<br>     Frame* refPicSetStCurr0[MAX_NUM_REF];<br>@@ -141,8 +145,10 @@ void Slice::setRefPicList(PicList& picList, PicList& refPicSetInterLayer0, PicLi<br>     int numPocTotalCurr = numPocStCurr0 + numPocStCurr1 + numPocLtCurr;<br> #endif<br> <br>+#if ENABLE_SCC_EXT<br>     if (m_param->bEnableSCC)<br>         numPocTotalCurr++;<br>+#endif<br> <br>     int cIdx = 0;<br>     for (i = 0; i < numPocStCurr0; i++, cIdx++)<br>@@ -166,8 +172,10 @@ void Slice::setRefPicList(PicList& picList, PicList& refPicSetInterLayer0, PicLi<br>             rpsCurrList0[cIdx] = refPicSetInterLayer1.getPOC(m_poc, 0);<br> #endif<br> <br>+#if ENABLE_SCC_EXT<br>     if (m_param->bEnableSCC)<br>         rpsCurrList0[cIdx++] = picList.getPOC(m_poc);<br>+#endif<br> <br>     X265_CHECK(cIdx == numPocTotalCurr, "RPS index check fail\n");<br> <br>@@ -195,8 +203,10 @@ void Slice::setRefPicList(PicList& picList, PicList& refPicSetInterLayer0, PicLi<br>                 rpsCurrList1[cIdx] = refPicSetInterLayer0.getPOC(m_poc, 0);<br> #endif<br> <br>+#if  ENABLE_SCC_EXT<br>         if (m_param->bEnableSCC)<br>             rpsCurrList1[cIdx++] = picList.getPOC(m_poc);<br>+#endif<br> <br>         X265_CHECK(cIdx == numPocTotalCurr, "RPS index check fail\n");<br>     }<br>@@ -211,10 +221,12 @@ void Slice::setRefPicList(PicList& picList, PicList& refPicSetInterLayer0, PicLi<br> #endif<br>     }<br> <br>+#if  ENABLE_SCC_EXT<br>     if (m_param->bEnableSCC && numPocTotalCurr > m_numRefIdx[0])<br>     {<br>         m_refFrameList[0][m_numRefIdx[0] - 1] = picList.getPOC(m_poc);<br>     }<br>+#endif<br> <br>     if (m_sliceType != B_SLICE)<br>     {<br>@@ -253,6 +265,7 @@ void Slice::disableWeights()<br>             }<br> }<br> <br>+#if  ENABLE_SCC_EXT<br> bool Slice::isOnlyCurrentPictureAsReference() const<br> {<br>     if (m_sliceType == I_SLICE)<br>@@ -278,6 +291,7 @@ bool Slice::isOnlyCurrentPictureAsReference() const<br> <br>     return true;<br> }<br>+#endif<br> <br> /* Sorts the deltaPOC and Used by current values in the RPS based on the<br>  * deltaPOC values.  deltaPOC values are sorted with -ve values before the +ve<br>diff --git a/source/common/slice.h b/source/common/slice.h<br>index b5be561fd..d23479778 100644<br>--- a/source/common/slice.h<br>+++ b/source/common/slice.h<br>@@ -403,10 +403,12 @@ public:<br>     int         m_fieldNum;<br>     Frame*      m_mcstfRefFrameList[2][MAX_MCSTF_TEMPORAL_WINDOW_LENGTH];<br> <br>-    Frame* m_lastEncPic;<br>+#if  ENABLE_SCC_EXT<br>+    Frame*      m_lastEncPic;<br>     bool        m_bLMvdL1Zero;<br>-    bool        m_bTemporalMvp;<br>     bool        m_useIntegerMv;<br>+#endif<br>+    bool        m_bTemporalMvp;<br> <br>     Slice()<br>     {<br>@@ -423,9 +425,11 @@ public:<br>         m_rpsIdx = -1;<br>         m_chromaQpOffset[0] = m_chromaQpOffset[1] = 0;<br>         m_fieldNum = 0;<br>-        m_bTemporalMvp = false;<br>+#if  ENABLE_SCC_EXT<br>         m_lastEncPic = NULL;<br>         m_useIntegerMv = false;<br>+#endif<br>+        m_bTemporalMvp = false;<br>     }<br> <br>     void disableWeights();<br>@@ -435,7 +439,9 @@ public:<br>     void createInterLayerReferencePictureSet(PicList& picList, PicList& refPicSetInterLayer0, PicList& refPicSetInterLayer1);<br> #endif<br> <br>+#if  ENABLE_SCC_EXT<br>     bool isOnlyCurrentPictureAsReference() const;<br>+#endif<br> <br>     bool getRapPicFlag() const<br>     {<br>diff --git a/source/encoder/analysis.cpp b/source/encoder/analysis.cpp<br>index 7a910cbb9..4ff6a69f6 100644<br>--- a/source/encoder/analysis.cpp<br>+++ b/source/encoder/analysis.cpp<br>@@ -223,9 +223,11 @@ Mode& Analysis::compressCTU(CUData& ctu, Frame& frame, const CUGeom& cuGeom, con<br>     }<br>     ProfileCUScope(ctu, totalCTUTime, totalCTUs);<br> <br>+#if  ENABLE_SCC_EXT<br>     memset(m_ibc.m_BVs, 0, sizeof(m_ibc.m_BVs));<br>     memset(m_ibc.m_lastIntraBCMv, 0, sizeof(m_ibc.m_lastIntraBCMv));<br>     m_ibc.m_numBV16s = 0; m_ibc.m_numBVs = 0;<br>+#endif<br>     if (m_slice->m_sliceType == I_SLICE || (m_param->bEnableSCC && (m_slice->m_numRefIdx[0] == 1) && m_slice->m_refPOCList[0][0] == m_slice->m_poc))<br>     {<br>         x265_analysis_intra_data* intraDataCTU = m_frame->m_analysisData.intraData;<br>@@ -573,6 +575,7 @@ uint64_t Analysis::compressIntraCU(const CUData& parentCTU, const CUGeom& cuGeom<br>             checkBestMode(md.pred[PRED_INTRA_NxN], depth);<br>         }<br> <br>+#if ENABLE_SCC_EXT<br>         bool intraBlockCopyFastSearch = (m_param->bEnableSCC == 1) ? true : false, bUse1DSearchFor8x8 = false;<br>         if (m_param->bEnableSCC)<br>         {<br>@@ -607,6 +610,7 @@ uint64_t Analysis::compressIntraCU(const CUData& parentCTU, const CUGeom& cuGeom<br>                 checkBestMode(md.pred[PRED_IBC_Nx2N], depth);<br>             }<br>         }<br>+#endif<br> <br>         if (m_bTryLossless)<br>             tryLossless(cuGeom);<br>@@ -615,6 +619,7 @@ uint64_t Analysis::compressIntraCU(const CUData& parentCTU, const CUGeom& cuGeom<br>             addSplitFlagCost(*md.bestMode, cuGeom.depth);<br>     }<br> <br>+#if ENABLE_SCC_EXT<br>     // If Intra BC keep last coded Mv<br>     if (md.bestMode && md.bestMode->cu.isInter(0))<br>     {<br>@@ -697,6 +702,7 @@ uint64_t Analysis::compressIntraCU(const CUData& parentCTU, const CUGeom& cuGeom<br>             }<br>         }<br>     } // is inter<br>+#endif<br> <br>     // stop recursion if we reach the depth of previous analysis decision<br>     mightSplit &= !(bAlreadyDecided && bDecidedDepth) || split;<br>@@ -739,6 +745,7 @@ uint64_t Analysis::compressIntraCU(const CUData& parentCTU, const CUGeom& cuGeom<br>                 else<br>                     compressIntraCU(parentCTU, childGeom, nextQP, ibc);<br> <br>+#if ENABLE_SCC_EXT<br>                 if (nd.bestMode->cu.m_lastIntraBCMv[0].x != 0 || nd.bestMode->cu.m_lastIntraBCMv[0].y != 0)<br>                 {<br>                     for (int i = 0; i < 2; i++)<br>@@ -746,6 +753,7 @@ uint64_t Analysis::compressIntraCU(const CUData& parentCTU, const CUGeom& cuGeom<br>                         ibc.m_lastIntraBCMv[i] = nd.bestMode->cu.m_lastIntraBCMv[i];<br>                     }<br>                 }<br>+#endif<br> <br>                 // Save best CU and pred data for this sub CU<br>                 splitCU->copyPartFrom(nd.bestMode->cu, childGeom, subPartIdx);<br>@@ -2163,12 +2171,14 @@ SplitData Analysis::compressInterCU_rd5_6(const CUData& parentCTU, const CUGeom&<br>             checkInter_rd5_6(md.pred[PRED_2Nx2N], cuGeom, SIZE_2Nx2N, refMasks);<br>             checkBestMode(md.pred[PRED_2Nx2N], cuGeom.depth);<br> <br>+#if ENABLE_SCC_EXT<br>             interBest = md.bestMode;<br>             if (m_param->bEnableSCC)<br>             {<br>                 md.pred[PRED_MERGE_IBC].cu.initSubCU(parentCTU, cuGeom, qp, ibc.m_lastIntraBCMv);<br>                 checkRDCostIntraBCMerge2Nx2N(md.pred[PRED_MERGE_IBC], cuGeom);<br>             }<br>+#endif<br> <br>             if (m_param->recursionSkipMode == RDCOST_BASED_RSKIP && depth && m_modeDepth[depth - 1].bestMode)<br>                 skipRecursion = md.bestMode && !md.bestMode->cu.getQtRootCbf(0);<br>@@ -2208,11 +2218,13 @@ SplitData Analysis::compressInterCU_rd5_6(const CUData& parentCTU, const CUGeom&<br> <br>                     splitData[subPartIdx] = compressInterCU_rd5_6(parentCTU, childGeom, nextQP, ibc);<br> <br>+#if ENABLE_SCC_EXT<br>                     if (nd.bestMode->cu.m_lastIntraBCMv[0].x != 0 || nd.bestMode->cu.m_lastIntraBCMv[0].y != 0)<br>                     {<br>                         for (int i = 0; i < 2; i++)<br>                             ibc.m_lastIntraBCMv[i] = nd.bestMode->cu.m_lastIntraBCMv[i];<br>                     }<br>+#endif<br> <br>                     // Save best CU and pred data for this sub CU<br>                     splitIntra |= nd.bestMode->cu.isIntra(0);<br>@@ -2447,6 +2459,7 @@ SplitData Analysis::compressInterCU_rd5_6(const CUData& parentCTU, const CUGeom&<br>                     }<br>                 }<br> <br>+#if ENABLE_SCC_EXT<br>                 if (m_param->bEnableSCC)<br>                 {<br>                     bool intraBlockCopyFastSearch = (m_param->bEnableSCC == 1) ? true : false, bUse1DSearchFor8x8 = false, bValid;<br>@@ -2494,6 +2507,7 @@ SplitData Analysis::compressInterCU_rd5_6(const CUData& parentCTU, const CUGeom&<br>                         checkBestMode(md.pred[PRED_IBC_Nx2N], depth);<br>                     }<br>                 }<br>+#endif<br> <br>                 if ((m_slice->m_sliceType != B_SLICE || m_param->bIntraInBFrames) && (cuGeom.log2CUSize != MAX_LOG2_CU_SIZE) && !((m_param->bCTUInfo & 4) && bCtuInfoCheck))<br>                 {<br>@@ -2518,6 +2532,7 @@ SplitData Analysis::compressInterCU_rd5_6(const CUData& parentCTU, const CUGeom&<br>                 }<br>             }<br> <br>+#if ENABLE_SCC_EXT<br>             // If Intra BC keep last coded Mv<br>             if (md.bestMode->cu.isInter(0))<br>             {<br>@@ -2600,6 +2615,7 @@ SplitData Analysis::compressInterCU_rd5_6(const CUData& parentCTU, const CUGeom&<br>                     }<br>                 }<br>             } // is inter<br>+#endif<br> <br>             if ((md.bestMode->cu.isInter(0) && !(md.bestMode->cu.m_mergeFlag[0] && md.bestMode->cu.m_partSize[0] == SIZE_2Nx2N)) && (m_frame->m_fencPic->m_picCsp == X265_CSP_I400 && m_csp != X265_CSP_I400))<br>             {<br>@@ -2650,7 +2666,7 @@ SplitData Analysis::compressInterCU_rd5_6(const CUData& parentCTU, const CUGeom&<br>             else<br>             {<br>                 /* use best merge/inter mode, in case of intra use 2Nx2N inter references */<br>-                CUData& cu = md.bestMode->cu.isIntra(0) ? md.pred[PRED_2Nx2N].cu : interBest->cu;<br>+                CUData& cu = md.bestMode->cu.isIntra(0) ? md.pred[PRED_2Nx2N].cu : (m_param->bEnableSCC ? interBest->cu : md.bestMode->cu);<br>                 uint32_t numPU = cu.getNumPartInter(0);<br>                 for (uint32_t puIdx = 0, subPartIdx = 0; puIdx < numPU; puIdx++, subPartIdx += cu.getPUOffset(puIdx, 0))<br>                     splitCUData.splitRefs |= cu.getBestRefIdx(subPartIdx);<br>@@ -3196,7 +3212,9 @@ void Analysis::checkMerge2Nx2N_rd5_6(Mode& skip, Mode& merge, const CUGeom& cuGe<br>     MVField candMvField[MRG_MAX_NUM_CANDS][2]; // double length for mv of both lists<br>     uint8_t candDir[MRG_MAX_NUM_CANDS];<br>     uint32_t numMergeCand = merge.cu.getInterMergeCandidates(0, 0, candMvField, candDir);<br>+#if ENABLE_SCC_EXT<br>     restrictBipredMergeCand(&<a href="http://merge.cu" target="_blank">merge.cu</a>, 0, candMvField, candDir, numMergeCand);<br>+#endif<br> <br>     PredictionUnit pu(<a href="http://merge.cu" target="_blank">merge.cu</a>, cuGeom, 0);<br> <br>@@ -3252,10 +3270,12 @@ void Analysis::checkMerge2Nx2N_rd5_6(Mode& skip, Mode& merge, const CUGeom& cuGe<br>             candMvField[i][0].mv.x > maxSafeMv)<br>             // skip merge candidates which reference beyond safe reference area<br>             continue;<br>+#if ENABLE_SCC_EXT<br>         if ((candDir[i] == 1 || candDir[i] == 3) && (m_slice->m_refPOCList[0][candMvField[i][0].refIdx] == m_slice->m_poc))<br>         {<br>             continue;<br>         }<br>+#endif<br>         tempPred->cu.m_mvpIdx[0][0] = (uint8_t)i;    /* merge candidate ID is stored in L0 MVP idx */<br>         tempPred->cu.m_interDir[0] = candDir[i];<br>         tempPred->cu.m_mv[0][0] = candMvField[i][0].mv;<br>@@ -3320,6 +3340,7 @@ void Analysis::checkMerge2Nx2N_rd5_6(Mode& skip, Mode& merge, const CUGeom& cuGe<br>     }<br> }<br> <br>+#if ENABLE_SCC_EXT<br> void Analysis::checkRDCostIntraBCMerge2Nx2N(Mode& mergeIBC, const CUGeom& cuGeom)<br> {<br>     mergeIBC.initCosts();<br>@@ -3386,6 +3407,7 @@ void Analysis::checkRDCostIntraBCMerge2Nx2N(Mode& mergeIBC, const CUGeom& cuGeom<br>     checkBestMode(mergeIBC, depth);<br>     checkDQP(mergeIBC, cuGeom);<br> }<br>+#endif<br> <br> void Analysis::checkInter_rd0_4(Mode& interMode, const CUGeom& cuGeom, PartSize partSize, uint32_t refMask[2])<br> {<br>@@ -3509,6 +3531,7 @@ void Analysis::checkInter_rd5_6(Mode& interMode, const CUGeom& cuGeom, PartSize<br>     }<br> }<br> <br>+#if ENABLE_SCC_EXT<br> void Analysis::checkIntraBC_rd5_6(Mode& intraBCMode, const CUGeom& cuGeom, PartSize ePartSize, bool testOnlyPred, bool bUse1DSearchFor8x8, IBC& ibc, MV* iMVCandList)<br> {<br>     intraBCMode.initCosts();<br>@@ -3534,12 +3557,17 @@ void Analysis::checkIntraBC_rd5_6(Mode& intraBCMode, const CUGeom& cuGeom, PartS<br>         iMVCandList[1] = intraBCMode.cu.m_mv[0][partAddr];<br>     }<br> }<br>+#endif<br> <br> void Analysis::checkBidir2Nx2N(Mode& inter2Nx2N, Mode& bidir2Nx2N, const CUGeom& cuGeom)<br> {<br>     CUData& cu = bidir2Nx2N.cu;<br> <br>+#if ENABLE_SCC_EXT<br>     if ((cu.is8x8BipredRestriction(inter2Nx2N.bestME[0][0].mv, inter2Nx2N.bestME[0][1].mv, inter2Nx2N.bestME[0][0].ref, inter2Nx2N.bestME[0][1].ref) ? (cu.m_cuDepth[0] == 3) : cu.isBipredRestriction()) || inter2Nx2N.bestME[0][0].cost == MAX_UINT || inter2Nx2N.bestME[0][1].cost == MAX_UINT)<br>+#else<br>+    if (cu.isBipredRestriction() || inter2Nx2N.bestME[0][0].cost == MAX_UINT || inter2Nx2N.bestME[0][1].cost == MAX_UINT)<br>+#endif<br>     {<br>         bidir2Nx2N.sa8dCost = MAX_INT64;<br>         bidir2Nx2N.rdCost = MAX_INT64;<br>@@ -4175,8 +4203,10 @@ int Analysis::findSameContentRefCount(const CUData& parentCTU, const CUGeom& cuG<br>         for (int i = 0; i < m_frame->m_encData->m_slice->m_numRefIdx[list]; i++)<br>         {<br>             int refPoc = m_frame->m_encData->m_slice->m_refFrameList[list][i]->m_poc;<br>+#if ENABLE_SCC_EXT<br>             if (refPoc == m_curPoc)<br>                 continue;<br>+#endif<br>             int refPrevChange = m_frame->m_encData->m_slice->m_refFrameList[list][i]->m_addOnPrevChange[parentCTU.m_cuAddr][cuGeom.absPartIdx];<br>             if ((refPoc < prevChange && refPoc < m_curPoc) || (refPoc > m_curPoc && prevChange < m_curPoc && refPrevChange > m_curPoc) || ((refPoc == prevChange) && (m_additionalCtuInfo[cuGeom.absPartIdx] == CTU_INFO_CHANGE)))<br>                 sameContentRef++;    /* Content changed */<br>diff --git a/source/encoder/analysis.h b/source/encoder/analysis.h<br>index 7f4f1c988..ad1ef6b63 100644<br>--- a/source/encoder/analysis.h<br>+++ b/source/encoder/analysis.h<br>@@ -75,12 +75,14 @@ public:<br>         PRED_nRx2N,<br>         PRED_INTRA_NxN, /* 4x4 intra PU blocks for 8x8 CU */<br>         PRED_LOSSLESS,  /* lossless encode of best mode */<br>+#if ENABLE_SCC_EXT<br>         PRED_IBC_2Nx2N,<br>         PRED_IBC_Nx2N,<br>         PRED_IBC_2NxN,<br>         PRED_MIXED_IBC_NX2N,<br>         PRED_MIXED_IBC_2NXN,<br>         PRED_MERGE_IBC,<br>+#endif<br>         MAX_PRED_TYPES<br>     };<br> <br>@@ -170,7 +172,7 @@ protected:<br>     void qprdRefine(const CUData& parentCTU, const CUGeom& cuGeom, int32_t qp, int32_t lqp);<br> <br>     /* full analysis for an I-slice CU */<br>-    uint64_t compressIntraCU(const CUData& parentCTU, const CUGeom& cuGeom, int32_t qp, IBC &ibc);<br>+    uint64_t compressIntraCU(const CUData& parentCTU, const CUGeom& cuGeom, int32_t qp, IBC& ibc);<br> <br>     /* full analysis for a P or B slice CU */<br>     uint32_t compressInterCU_dist(const CUData& parentCTU, const CUGeom& cuGeom, int32_t qp);<br>@@ -189,8 +191,10 @@ protected:<br> <br>     void checkBidir2Nx2N(Mode& inter2Nx2N, Mode& bidir2Nx2N, const CUGeom& cuGeom);<br> <br>+#if ENABLE_SCC_EXT<br>     void checkRDCostIntraBCMerge2Nx2N(Mode& merge, const CUGeom& cuGeom);<br>     void checkIntraBC_rd5_6(Mode& intraBCMode, const CUGeom& cuGeom, PartSize ePartSize, bool testOnlyPred, bool bUse1DSearchFor8x8, IBC& ibc, MV* iMVCandList = NULL);<br>+#endif<br> <br>     /* encode current bestMode losslessly, pick best RD cost */<br>     void tryLossless(const CUGeom& cuGeom);<br>diff --git a/source/encoder/dpb.cpp b/source/encoder/dpb.cpp<br>index 8ef1f7abe..498d62c1a 100644<br>--- a/source/encoder/dpb.cpp<br>+++ b/source/encoder/dpb.cpp<br>@@ -327,7 +327,8 @@ void DPB::prepareEncode(Frame *newFrame)<br>         slice->m_colRefIdx = 0;<br>     }<br> <br>-<br>+    slice->m_bTemporalMvp = slice->m_sps->bTemporalMVPEnabled;<br>+#if ENABLE_SCC_EXT<br>     bool bGPBcheck = false;<br>     if (slice->m_sliceType == B_SLICE)<br>     {<br>@@ -377,6 +378,7 @@ void DPB::prepareEncode(Frame *newFrame)<br>         else<br>             slice->m_bTemporalMvp = true;<br>     }<br>+#endif<br> <br>     // Disable Loopfilter in bound area, because we will do slice-parallelism in future<br>     slice->m_sLFaseFlag = (newFrame->m_param->maxSlices > 1) ? false : ((SLFASE_CONSTANT & (1 << (pocCurr % 31))) > 0);<br>diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp<br>index 4043342c1..1a16f039d 100644<br>--- a/source/encoder/encoder.cpp<br>+++ b/source/encoder/encoder.cpp<br>@@ -629,7 +629,9 @@ int Encoder::getRefFrameList(PicYuv** l0, PicYuv** l1, int sliceType, int poc, i<br>                     int l0POC = framePtr->m_encData->m_slice->m_refFrameList[0][j]->m_poc;<br>                     pocL0[j] = l0POC;<br>                     Frame* l0Fp = m_dpb->m_picList.getPOC(l0POC, 0);<br>+#if ENABLE_SCC_EXT<br>                     if (l0POC != poc)<br>+#endif<br>                     {<br>                         while (l0Fp->m_reconRowFlag[l0Fp->m_numRows - 1].get() == 0)<br>                             l0Fp->m_reconRowFlag[l0Fp->m_numRows - 1].waitForChange(0); /* If recon is not ready, current frame encoder has to wait. */<br>@@ -3716,11 +3718,13 @@ void Encoder::initPPS(PPS *pps)<br>     }<br> #endif<br> <br>+#if ENABLE_SCC_EXT<br>     if (m_param->bEnableSCC)<br>     {<br>         pps->profileIdc = Profile::MAINSCC;<br>         pps->pps_extension_flag = true;<br>     }<br>+#endif<br> }<br> <br> void Encoder::configureZone(x265_param *p, x265_param *zone)<br>diff --git a/source/encoder/entropy.cpp b/source/encoder/entropy.cpp<br>index 22408e6f3..12cfc3ef7 100644<br>--- a/source/encoder/entropy.cpp<br>+++ b/source/encoder/entropy.cpp<br>@@ -599,6 +599,7 @@ void Entropy::codeSPS(const SPS& sps, const ScalingList& scalingList, const Prof<br>     }<br> #endif<br> <br>+#if ENABLE_SCC_EXT<br>     if (ptl.profileIdc[0] == Profile::MAINSCC)<br>     {<br>         bool sps_extension_flags[NUM_EXTENSION_FLAGS] = { false };<br>@@ -610,6 +611,7 @@ void Entropy::codeSPS(const SPS& sps, const ScalingList& scalingList, const Prof<br>         WRITE_CODE(0, 2, "motion_vector_resolution_control_idc");<br>         WRITE_FLAG(0, "intra_boundary_filter_disabled_flag");<br>     }<br>+#endif<br> }<br> <br> void Entropy::codePPS( const PPS& pps, bool filerAcross, int iPPSInitQpMinus26, int layer)<br>@@ -680,6 +682,7 @@ void Entropy::codePPS( const PPS& pps, bool filerAcross, int iPPSInitQpMinus26,<br> #endif<br> <br> <br>+#if ENABLE_SCC_EXT<br>     if (pps.profileIdc == Profile::MAINSCC)<br>     {<br>         bool pps_extension_flags[NUM_EXTENSION_FLAGS] = { false };<br>@@ -690,6 +693,7 @@ void Entropy::codePPS( const PPS& pps, bool filerAcross, int iPPSInitQpMinus26,<br>         WRITE_FLAG(0, "adaptive_colour_trans_flag");<br>         WRITE_FLAG(0, "palette_predictor_initializer_flag");<br>     }<br>+#endif<br> }<br> <br> void Entropy::codeProfileTier(const ProfileTierLevel& ptl, int maxTempSubLayers, int layer)<br>@@ -997,7 +1001,11 @@ void Entropy::codeSliceHeader(const Slice& slice, FrameData& encData, uint32_t s<br>         }<br> <br>         if (slice.m_sps->bTemporalMVPEnabled)<br>+#if ENABLE_SCC_EXT<br>             WRITE_FLAG(slice.m_bTemporalMvp, "slice_temporal_mvp_enable_flag");<br>+#else<br>+            WRITE_FLAG(1, "slice_temporal_mvp_enable_flag");<br>+#endif<br>     }<br>     const SAOParam *saoParam = encData.m_saoParam;<br>     if (slice.m_bUseSao)<br>@@ -1037,9 +1045,17 @@ void Entropy::codeSliceHeader(const Slice& slice, FrameData& encData, uint32_t s<br>     }<br> <br>     if (slice.isInterB())<br>+#if ENABLE_SCC_EXT<br>         WRITE_FLAG(slice.m_bLMvdL1Zero, "mvd_l1_zero_flag");<br>+#else<br>+        WRITE_FLAG(0, "mvd_l1_zero_flag");<br>+#endif<br> <br>+#if ENABLE_SCC_EXT<br>     if (slice.m_bTemporalMvp)<br>+#else<br>+    if (slice.m_sps->bTemporalMVPEnabled)<br>+#endif<br>     {<br>         if (slice.m_sliceType == B_SLICE)<br>             WRITE_FLAG(slice.m_colFromL0Flag, "collocated_from_l0_flag");<br>@@ -1726,8 +1742,10 @@ void Entropy::codePredWeightTable(const Slice& slice)<br>         {<br>             for (int ref = 0; ref < slice.m_numRefIdx[list]; ref++)<br>             {<br>+#if ENABLE_SCC_EXT<br>                 if (slice.m_poc == slice.m_refPOCList[list][ref])<br>                     continue;<br>+#endif<br>                 wp = slice.m_weightPredTable[list][ref];<br>                 if (!bDenomCoded)<br>                 {<br>@@ -1748,8 +1766,10 @@ void Entropy::codePredWeightTable(const Slice& slice)<br>             {<br>                 for (int ref = 0; ref < slice.m_numRefIdx[list]; ref++)<br>                 {<br>+#if ENABLE_SCC_EXT<br>                     if (slice.m_poc == slice.m_refPOCList[list][ref])<br>                         continue;<br>+#endif<br>                     wp = slice.m_weightPredTable[list][ref];<br>                     WRITE_FLAG(!!wp[1].wtPresent, "chroma_weight_lX_flag");<br>                     totalSignalledWeightFlags += 2 * wp[1].wtPresent;<br>@@ -1758,8 +1778,10 @@ void Entropy::codePredWeightTable(const Slice& slice)<br> <br>             for (int ref = 0; ref < slice.m_numRefIdx[list]; ref++)<br>             {<br>+#if ENABLE_SCC_EXT<br>                 if (slice.m_poc == slice.m_refPOCList[list][ref])<br>                     continue;<br>+#endif<br>                 wp = slice.m_weightPredTable[list][ref];<br>                 if (wp[0].wtPresent)<br>                 {<br>diff --git a/source/encoder/frameencoder.cpp b/source/encoder/frameencoder.cpp<br>index 286eb520a..7d02d0d96 100644<br>--- a/source/encoder/frameencoder.cpp<br>+++ b/source/encoder/frameencoder.cpp<br>@@ -911,9 +911,11 @@ void FrameEncoder::compressFrame(int layer)<br>                     {<br>                         Frame *refpic = slice->m_refFrameList[l][ref];<br> <br>+#if ENABLE_SCC_EXT<br>                         /*Exempt the current pic as reference*/<br>                         if (m_param->bEnableSCC && refpic->m_poc == m_frame[layer]->m_poc)<br>                             continue;<br>+#endif<br> <br>                         // NOTE: we unnecessary wait row that beyond current slice boundary<br>                         const int rowIdx = X265_MIN(sliceEndRow, (row + m_refLagRows));<br>@@ -957,9 +959,11 @@ void FrameEncoder::compressFrame(int layer)<br>                     {<br>                         Frame *refpic = slice->m_refFrameList[list][ref];<br> <br>+#if ENABLE_SCC_EXT<br>                         /*Exempt the current pic as reference*/<br>                         if (m_param->bEnableSCC && refpic->m_poc == m_frame[layer]->m_poc)<br>                             continue;<br>+#endif<br> <br>                         const int rowIdx = X265_MIN(m_numRows - 1, (i + m_refLagRows));<br>                         while (refpic->m_reconRowFlag[rowIdx].get() == 0)<br>diff --git a/source/encoder/level.cpp b/source/encoder/level.cpp<br>index 84f407702..a87b49d90 100644<br>--- a/source/encoder/level.cpp<br>+++ b/source/encoder/level.cpp<br>@@ -60,6 +60,7 @@ LevelSpec levels[] =<br>     { MAX_UINT, MAX_UINT, MAX_UINT, MAX_UINT, MAX_UINT, MAX_UINT, 1, Level::LEVEL8_5, "8.5", 85 },<br> };<br> <br>+#if ENABLE_SCC_EXT<br> enum SCCProfileName<br> {<br>     NONE = 0,<br>@@ -84,6 +85,7 @@ static const SCCProfileName validSCCProfileNames[1][4/* bit depth constraint 8=0<br>         { NONE,         NONE,          NONE,      NONE                             }  // 16-bit intra for 400, 420, 422 and 444<br>     },<br> };<br>+#endif<br> <br> static inline int _confirm(x265_param* param, bool bflag, const char* message)<br> {<br>@@ -113,9 +115,7 @@ void determineLevel(const x265_param &param, VPS& vps)<br>         /* Probably an HEVC v1 profile, but must check to be sure */<br>         if (param.internalBitDepth <= 8)<br>         {<br>-            if (param.bEnableSCC)<br>-                vps.ptl.profileIdc[0] = Profile::MAINSCC;<br>-            else if (vps.ptl.onePictureOnlyConstraintFlag)<br>+            if (vps.ptl.onePictureOnlyConstraintFlag)<br>                 vps.ptl.profileIdc[0] = Profile::MAINSTILLPICTURE;<br>             else if (vps.ptl.intraConstraintFlag)<br>                 vps.ptl.profileIdc[0] = Profile::MAINREXT; /* Main Intra */<br>@@ -130,9 +130,7 @@ void determineLevel(const x265_param &param, VPS& vps)<br>         else if (param.internalBitDepth <= 10)<br>         {<br>             /* note there is no 10bit still picture profile */<br>-            if (param.bEnableSCC)<br>-                vps.ptl.profileIdc[0] = Profile::MAINSCC;<br>-            else if (vps.ptl.intraConstraintFlag)<br>+            if (vps.ptl.intraConstraintFlag)<br>                 vps.ptl.profileIdc[0] = Profile::MAINREXT; /* Main10 Intra */<br>             else<br>                 vps.ptl.profileIdc[0] = Profile::MAIN10;<br>@@ -151,12 +149,17 @@ void determineLevel(const x265_param &param, VPS& vps)<br>         vps.ptl.profileIdc[1] = Profile::MULTIVIEWMAIN;<br> #endif<br> <br>+#if ENABLE_SCC_EXT<br>+    if (param.bEnableSCC)<br>+        vps.ptl.profileIdc[0] = Profile::MAINSCC;<br>+<br>     /* determine which profiles are compatible with this stream */<br>     if (vps.ptl.profileIdc[0] == Profile::MAINSCC)<br>     {<br>         vps.ptl.onePictureOnlyConstraintFlag = false;<br>         vps.ptl.intraConstraintFlag = param.keyframeMax <= 1 || vps.ptl.onePictureOnlyConstraintFlag;<br>     }<br>+#endif<br> <br>     memset(vps.ptl.profileCompatibilityFlag, 0, sizeof(vps.ptl.profileCompatibilityFlag));<br>     vps.ptl.profileCompatibilityFlag[vps.ptl.profileIdc[0]] = true;<br>@@ -171,14 +174,16 @@ void determineLevel(const x265_param &param, VPS& vps)<br>     }<br>     else if (vps.ptl.profileIdc[0] == Profile::MAINREXT)<br>         vps.ptl.profileCompatibilityFlag[Profile::MAINREXT] = true;<br>+#if ENABLE_SCC_EXT<br>     else if (vps.ptl.profileIdc[0] == Profile::MAINSCC)<br>         vps.ptl.profileCompatibilityFlag[Profile::MAINSCC] = true;<br>+#endif<br> <br>     uint32_t lumaSamples = param.sourceWidth * param.sourceHeight;<br>     uint32_t samplesPerSec = (uint32_t)(lumaSamples * ((double)param.fpsNum / param.fpsDenom));<br>     uint32_t bitrate = param.rc.vbvMaxBitrate ? param.rc.vbvMaxBitrate : param.rc.bitrate;<br> <br>-    const uint32_t MaxDpbPicBuf = !!param.bEnableSCC ? 7 : 6;<br>+    const uint32_t MaxDpbPicBuf = param.bEnableSCC ? 7 : 6;<br>     vps.ptl.levelIdc = Level::NONE;<br>     vps.ptl.tierFlag = Level::MAIN;<br> <br>@@ -277,6 +282,7 @@ void determineLevel(const x265_param &param, VPS& vps)<br>         break;<br>     }<br> <br>+#if ENABLE_SCC_EXT<br>     x265_param m_param = param;<br> #define CHECK(expr, msg) check_failed |= _confirm(&m_param, expr, msg)<br>     int check_failed = 0; /* abort if there is a fatal configuration problem */<br>@@ -292,6 +298,7 @@ void determineLevel(const x265_param &param, VPS& vps)<br>         const bool bValidProfile = (bitDepthIdx > 2 || chromaFormatIdx > 3) ? false : (validSCCProfileNames[0][bitDepthIdx][chromaFormatIdx] != NONE);<br>         CHECK(!bValidProfile, "Invalid intra constraint flag, bit depth constraint flag and chroma format constraint flag combination for a RExt profile");<br>     }<br>+#endif<br> <br>     static const char* profiles[] = { "None", "Main", "Main 10", "Main Still Picture", "RExt", "", "", "", "", "Main Scc" };<br>     static const char *tiers[]    = { "Main", "High" };<br>@@ -354,6 +361,7 @@ void determineLevel(const x265_param &param, VPS& vps)<br>             strcat(profbuf, " Intra");<br>     }<br> <br>+#if ENABLE_SCC_EXT<br>     if (vps.ptl.profileIdc[0] == Profile::MAINSCC)<br>     {<br>         if (param.internalCsp == X265_CSP_I420)<br>@@ -371,6 +379,7 @@ void determineLevel(const x265_param &param, VPS& vps)<br>                 strcpy(profbuf, "Main 4:4:4 10 Scc");<br>         }<br>     }<br>+#endif<br> <br>     x265_log(&param, X265_LOG_INFO, "%s profile, Level-%s (%s tier)\n",<br>              profbuf, levels[i].name, tiers[vps.ptl.tierFlag]);<br>@@ -504,7 +513,7 @@ bool enforceLevel(x265_param& param, VPS& vps)<br>     }<br> <br>     /* The value of sps_max_dec_pic_buffering_minus1[ HighestTid ] + 1 shall be less than or equal to MaxDpbSize */<br>-    const uint32_t MaxDpbPicBuf = !!param.bEnableSCC ? 7 : 6;<br>+    const uint32_t MaxDpbPicBuf = param.bEnableSCC ? 7 : 6;<br>     uint32_t maxDpbSize = MaxDpbPicBuf;<br>     if (!param.uhdBluray) /* Do not change MaxDpbPicBuf for UHD-Bluray */<br>     {<br>diff --git a/source/encoder/search.cpp b/source/encoder/search.cpp<br>index 4fd3b21b1..71a52a1cd 100644<br>--- a/source/encoder/search.cpp<br>+++ b/source/encoder/search.cpp<br>@@ -76,7 +76,9 @@ bool Search::initSearch(const x265_param& param, ScalingList& scalingList)<br>     m_param = &param;<br>     m_bFrameParallel = param.frameNumThreads > 1;<br>     m_numLayers = g_log2Size[param.maxCUSize] - 2;<br>+#if ENABLE_SCC_EXT<br>     m_ibcEnabled = param.bEnableSCC;<br>+#endif<br> <br>     m_rdCost.setPsyRdScale(param.psyRd);<br>     m_rdCost.setSsimRd(param.bSsimRd);<br>@@ -172,8 +174,10 @@ bool Search::initSearch(const x265_param& param, ScalingList& scalingList)<br>     CHECKED_MALLOC(m_tsResidual, int16_t, MAX_TS_SIZE * MAX_TS_SIZE);<br>     CHECKED_MALLOC(m_tsRecon,    pixel,   MAX_TS_SIZE * MAX_TS_SIZE);<br> <br>+#if ENABLE_SCC_EXT<br>     m_numBVs = 0;<br>     m_numBV16s = 0;<br>+#endif<br> <br>     return ok;<br> <br>@@ -1289,8 +1293,10 @@ void Search::checkIntra(Mode& intraMode, const CUGeom& cuGeom, PartSize partSize<br>     updateModeCost(intraMode);<br>     checkDQP(intraMode, cuGeom);<br> <br>-    if (!!m_param->bEnableSCC)<br>+#if ENABLE_SCC_EXT<br>+    if (m_param->bEnableSCC)<br>         intraMode.reconYuv.copyToPicYuv(*m_frame->m_reconPic[1], cu.m_cuAddr, cuGeom.absPartIdx);<br>+#endif<br> }<br> <br> /* Note that this function does not save the best intra prediction, it must<br>@@ -1902,7 +1908,22 @@ uint32_t Search::mergeEstimation(CUData& cu, const CUGeom& cuGeom, const Predict<br>     MVField  candMvField[MRG_MAX_NUM_CANDS][2];<br>     uint8_t  candDir[MRG_MAX_NUM_CANDS];<br>     uint32_t numMergeCand = cu.getInterMergeCandidates(pu.puAbsPartIdx, puIdx, candMvField, candDir);<br>+#if ENABLE_SCC_EXT<br>     restrictBipredMergeCand(&cu, 0, candMvField, candDir, numMergeCand);<br>+#else<br>+    if (cu.isBipredRestriction())<br>+    {<br>+        /* do not allow bidir merge candidates if PU is smaller than 8x8, drop L1 reference */<br>+        for (uint32_t mergeCand = 0; mergeCand < numMergeCand; ++mergeCand)<br>+        {<br>+            if (candDir[mergeCand] == 3)<br>+            {<br>+                candDir[mergeCand] = 1;<br>+                candMvField[mergeCand][1].refIdx = REF_NOT_VALID;<br>+            }<br>+        }<br>+    }<br>+#endif<br> <br>     Yuv& tempYuv = m_rqt[cuGeom.depth].tmpPredYuv;<br> <br>@@ -1931,10 +1952,12 @@ uint32_t Search::mergeEstimation(CUData& cu, const CUGeom& cuGeom, const Predict<br>                 continue;<br>         }<br> <br>+#if ENABLE_SCC_EXT<br>         if ((candDir[mergeCand] == 1 || candDir[mergeCand] == 3) && (m_slice->m_refPOCList[0][candMvField[mergeCand][0].refIdx] == m_slice->m_poc))<br>         {<br>             continue;<br>         }<br>+#endif<br>         cu.m_mv[0][pu.puAbsPartIdx] = candMvField[mergeCand][0].mv;<br>         cu.m_refIdx[0][pu.puAbsPartIdx] = (int8_t)candMvField[mergeCand][0].refIdx;<br>         cu.m_mv[1][pu.puAbsPartIdx] = candMvField[mergeCand][1].mv;<br>@@ -2014,9 +2037,11 @@ int Search::selectMVP(const CUData& cu, const PredictionUnit& pu, const MV amvp[<br>                 continue;<br>         }<br>         cu.clipMv(mvCand);<br>-        if (!!m_slice->m_param->bEnableSCC && !list && ref == m_slice->m_numRefIdx[0] - 1)<br>+#if ENABLE_SCC_EXT<br>+        if (m_slice->m_param->bEnableSCC && !list && ref == m_slice->m_numRefIdx[0] - 1)<br>             predInterLumaPixel(pu, tmpPredYuv, *m_slice->m_refFrameList[list][ref]->m_reconPic[1], mvCand);<br>         else<br>+#endif<br>             predInterLumaPixel(pu, tmpPredYuv, *m_slice->m_refReconPicList[list][ref], mvCand);<br>         costs[i] = m_me.bufSAD(tmpPredYuv.getLumaAddr(pu.puAbsPartIdx), tmpPredYuv.m_size);<br>     }<br>@@ -2089,8 +2114,10 @@ void Search::singleMotionEstimation(Search& master, Mode& interMode, const Predi<br> {<br>     uint32_t bits = master.m_listSelBits[list] + MVP_IDX_BITS;<br>     int numIdx = m_slice->m_numRefIdx[list];<br>+#if ENABLE_SCC_EXT<br>     if (!list && m_ibcEnabled)<br>         numIdx--;<br>+#endif<br>     bits += getTUBits(ref, numIdx);<br> <br>     MotionData* bestME = interMode.bestME[part];<br>@@ -2252,8 +2279,10 @@ void Search::predInterSearch(Mode& interMode, const CUGeom& cuGeom, bool bChroma<br>                 }<br>                 uint32_t bits = m_listSelBits[list] + MVP_IDX_BITS;<br>                 int numIdx = m_slice->m_numRefIdx[list];<br>+#if ENABLE_SCC_EXT<br>                 if (!list && m_ibcEnabled)<br>                     numIdx--;<br>+#endif<br>                 bits += getTUBits(ref, numIdx);<br> <br>                 int numMvc = cu.getPMV(interMode.interNeighbours, list, ref, interMode.amvpCand[list][ref], mvc, puIdx, pu.puAbsPartIdx);<br>@@ -2363,8 +2392,10 @@ void Search::predInterSearch(Mode& interMode, const CUGeom& cuGeom, bool bChroma<br>             {<br>                 int idx = 0;<br>                 int numIdx = numRefIdx[list];<br>+#if ENABLE_SCC_EXT<br>                 if (!list && m_ibcEnabled)<br>                     numIdx--;<br>+#endif<br>                 for (int ref = 0; ref < numIdx; ref++)<br>                 {<br>                     if (!(refMask & (1 << ref)))<br>@@ -2405,8 +2436,10 @@ void Search::predInterSearch(Mode& interMode, const CUGeom& cuGeom, bool bChroma<br>             for (int list = 0; list < numPredDir; list++)<br>             {<br>                 int numIdx = numRefIdx[list];<br>+#if ENABLE_SCC_EXT<br>                 if (!list && m_ibcEnabled)<br>                     numIdx--;<br>+#endif<br>                 for (int ref = 0; ref < numIdx; ref++)<br>                 {<br>                     ProfileCounter(interMode.cu, totalMotionReferences[cuGeom.depth]);<br>@@ -2473,10 +2506,12 @@ void Search::predInterSearch(Mode& interMode, const CUGeom& cuGeom, bool bChroma<br>                     /* Refine MVP selection, updates: mvpIdx, bits, cost */<br>                     mvp = checkBestMVP(amvp, outmv, mvpIdx, bits, cost);<br> <br>+#if ENABLE_SCC_EXT<br>                     if (list <= 1 && ref <= 1 && (cu.m_partSize[0] == SIZE_2NxN || cu.m_partSize[0] == SIZE_Nx2N) && (1 << cu.m_log2CUSize[0]) <= 16)<br>                     {<br>                         iMVCandList[4 * list + 2 * ref + puIdx] = outmv;<br>                     }<br>+#endif<br> <br>                     if (cost < bestME[list].cost)<br>                     {<br>@@ -2670,6 +2705,7 @@ void Search::predInterSearch(Mode& interMode, const CUGeom& cuGeom, bool bChroma<br>     interMode.sa8dBits += totalmebits;<br> }<br> <br>+#if ENABLE_SCC_EXT<br> uint32_t Search::getSAD(pixel* ref, int refStride, const pixel* curr, int currStride, int width, int height)<br> {<br>     uint32_t dist = 0;<br>@@ -4397,6 +4433,7 @@ bool Search::predMixedIntraBCInterSearch(Mode& intraBCMixedMode, const CUGeom& c<br> <br>     return true;<br> }<br>+#endif<br> <br> void Search::getBlkBits(PartSize cuMode, bool bPSlice, int partIdx, uint32_t lastMode, uint32_t blockBit[3])<br> {<br>@@ -4734,8 +4771,10 @@ void Search::encodeResAndCalcRdInterCU(Mode& interMode, const CUGeom& cuGeom)<br>     updateModeCost(interMode);<br>     checkDQP(interMode, cuGeom);<br> <br>-    if (!!m_param->bEnableSCC)<br>+#if ENABLE_SCC_EXT<br>+    if (m_param->bEnableSCC)<br>         interMode.reconYuv.copyToPicYuv(*m_frame->m_reconPic[1], cu.m_cuAddr, cuGeom.absPartIdx);<br>+#endif<br> }<br> <br> void Search::residualTransformQuantInter(Mode& mode, const CUGeom& cuGeom, uint32_t absPartIdx, uint32_t tuDepth, const uint32_t depthRange[2])<br>diff --git a/source/encoder/search.h b/source/encoder/search.h<br>index 3ae3655b1..f12ac02e0 100644<br>--- a/source/encoder/search.h<br>+++ b/source/encoder/search.h<br>@@ -288,11 +288,14 @@ public:<br> <br>     bool            m_vertRestriction;<br> <br>+#if ENABLE_SCC_EXT<br>     int             m_ibcEnabled;<br>     int             m_numBVs;<br>     int             m_numBV16s;<br>     MV              m_BVs[64];<br>     uint32_t        m_lastCandCost;<br>+#endif<br>+<br> #if DETAILED_CU_STATS<br>     /* Accumulate CU statistics separately for each frame encoder */<br>     CUStats         m_stats[X265_MAX_FRAME_THREADS];<br>@@ -336,6 +339,7 @@ public:<br> <br>     MV getLowresMV(const CUData& cu, const PredictionUnit& pu, int list, int ref);<br> <br>+#if ENABLE_SCC_EXT<br>     bool      predIntraBCSearch(Mode& intraBCMode, const CUGeom& cuGeom, bool bChromaMC, PartSize ePartSize, bool testOnlyPred, bool bUse1DSearchFor8x8, IBC& ibc);<br>     void      intraBlockCopyEstimate(Mode& intraBCMode, const CUGeom& cuGeom, int puIdx, MV* pred, MV& mv, uint32_t& cost, bool testOnlyPred, bool bUse1DSearchFor8x8, IBC& ibc);<br>     void      setIntraSearchRange(Mode& intraBCMode, MV& pred, int puIdx, int roiWidth, int roiHeight, MV& searchRangeLT, MV& searchRangeRB);<br>@@ -352,6 +356,7 @@ public:<br>     uint32_t  getSAD(pixel* ref, int refStride, const pixel* curr, int currStride, int width, int height);<br>     bool      predMixedIntraBCInterSearch(Mode& intraBCMode, const CUGeom& cuGeom, bool bChromaMC, PartSize ePartSize, MV* iMVCandList);<br>     void      restrictBipredMergeCand(CUData* cu, uint32_t puIdx, MVField(*mvFieldNeighbours)[2], uint8_t* interDirNeighbours, uint32_t numValidMergeCand);<br>+#endif<br> <br>     class PME : public BondedTaskGroup<br>     {<br>diff --git a/source/encoder/weightPrediction.cpp b/source/encoder/weightPrediction.cpp<br>index 724757429..a4a34f826 100644<br>--- a/source/encoder/weightPrediction.cpp<br>+++ b/source/encoder/weightPrediction.cpp<br>@@ -492,8 +492,10 @@ void weightAnalyse(Slice& slice, Frame& frame, x265_param& param)<br>         chromaDenom = weights[1].log2WeightDenom;<br> <br>         int numIdx = slice.m_numRefIdx[list];<br>+#if ENABLE_SCC_EXT<br>         if (!list && param.bEnableSCC)<br>             numIdx--;<br>+#endif<br> <br>         /* reset weight states */<br>         for (int ref = 1; ref < numIdx; ref++)<br>diff --git a/source/x265.h b/source/x265.h<br>index 889dda934..c8651c7dd 100644<br>--- a/source/x265.h<br>+++ b/source/x265.h<br>@@ -654,6 +654,7 @@ typedef enum<br> #define MAX_LAYERS              1<br> #endif<br> <br>+#if ENABLE_SCC_EXT<br> /* SCC Extension Options */<br> #define SCC_EXT_IDX               3<br> #define NUM_EXTENSION_FLAGS       8<br>@@ -661,6 +662,10 @@ typedef enum<br> #define CHROMA_REFINEMENT_CANDIDATES  8<br> #define SCM_S0067_IBC_FULL_1D_SEARCH_FOR_PU  2 ///< Do full horizontal/vertical search for Nx2N<br> #define SCM_S0067_MAX_CAND_SIZE  32 ///< 32 or 64, 16 by default<br>+#define NUM_RECON_VERSION          2<br>+#else<br>+#define NUM_RECON_VERSION          1<br>+#endif<br> <br> #define X265_IPRATIO_STRENGTH   1.43<br> <br>@@ -2374,7 +2379,9 @@ static const char * const x265_profile_names[] = {<br> <br>     "main444-16-intra", "main444-16-stillpicture", /* Not Supported! */<br> <br>+#if ENABLE_SCC_EXT<br>     "main-scc", "main10-scc", "main444-scc", "main444-10-scc", /* Screen content coding */<br>+#endif<br>     0<br> };<br> <br>diff --git a/source/x265cli.cpp b/source/x265cli.cpp<br>index 2e02b1e44..d4fe886cc 100755<br>--- a/source/x265cli.cpp<br>+++ b/source/x265cli.cpp<br>@@ -382,7 +382,9 @@ namespace X265_NS {<br>         H0("   --format                      Format of the input video 0 : normal, 1 : side-by-side, 2 : over-under  Default %d\n", param->format);<br>         H0("   --multiview-config            Configuration file for Multiview Encoding\n");<br> #endif<br>+#if ENABLE_SCC_EXT<br>         H0("   --scc <integer>               Enable screen content coding. 0: Diabled, 1:Intrablockcopy fast search with 1x2 CTUs search range, 2: Intrablockcopy Full search. Default %d\n", param->bEnableSCC);<br>+#endif<br> #ifdef SVT_HEVC<br>         H0("   --[no]svt                     Enable SVT HEVC encoder %s\n", OPT(param->bEnableSvtHevc));<br>         H0("   --[no-]svt-hme                Enable Hierarchial motion estimation(HME) in SVT HEVC encoder \n");<br>diff --git a/source/x265cli.h b/source/x265cli.h<br>index 654356287..2ec48352d 100644<br>--- a/source/x265cli.h<br>+++ b/source/x265cli.h<br>@@ -366,7 +366,9 @@ static const struct option long_options[] =<br>     { "multiview-config", required_argument, NULL, 0 },<br>     { "format", required_argument, NULL, 0 },<br> #endif<br>+#if ENABLE_SCC_EXT<br>     { "scc",        required_argument, NULL, 0 },<br>+#endif<br> #ifdef SVT_HEVC<br>     { "svt",     no_argument, NULL, 0 },<br>     { "no-svt",  no_argument, NULL, 0 },<br>-- <br>2.36.0.windows.1<br><br></div>