diff --git a/cfg/encoder_intra_vtm.cfg b/cfg/encoder_intra_vtm.cfg
index ddc4dedad848dad11a83c285a8722612bbfe97b5..37c7b4e0206ad568cf9e5898d956ef08860f2d49 100644
--- a/cfg/encoder_intra_vtm.cfg
+++ b/cfg/encoder_intra_vtm.cfg
@@ -114,7 +114,7 @@ LMCSEnable                   : 1      # LMCS: 0: disable, 1:enable
 LMCSSignalType               : 0      # Input signal type: 0:SDR, 1:HDR-PQ, 2:HDR-HLG
 LMCSUpdateCtrl               : 1      # LMCS model update control: 0:RA, 1:AI, 2:LDB/LDP
 MIP                          : 1
-
+JCCR                         : 1      # JCCR: disable, 1:enable
 # Fast tools
 PBIntraFast                  : 1
 ISPFast                      : 1
diff --git a/cfg/encoder_lowdelay_P_vtm.cfg b/cfg/encoder_lowdelay_P_vtm.cfg
index 2d24145ce7acb6aabf6cc9e5b58d88f1aa0d3db0..f0959ac3d0ccec644a5bb2ab6dd53a6119cf4d3c 100644
--- a/cfg/encoder_lowdelay_P_vtm.cfg
+++ b/cfg/encoder_lowdelay_P_vtm.cfg
@@ -130,7 +130,7 @@ LMCSEnable                   : 1      # LMCS: 0: disable, 1:enable
 LMCSSignalType               : 0      # Input signal type: 0:SDR, 1:HDR-PQ, 2:HDR-HLG
 LMCSUpdateCtrl               : 2      # LMCS model update control: 0:RA, 1:AI, 2:LDB/LDP
 MIP                          : 1
-
+JCCR                         : 1      # JCCR: disable, 1:enable
 # Fast tools
 PBIntraFast                  : 1
 ISPFast                      : 1
diff --git a/cfg/encoder_lowdelay_vtm.cfg b/cfg/encoder_lowdelay_vtm.cfg
index 1c7925030439df8d5d21787f90c455d2d77d3a1c..a4d91a7f16a9ecab25fcf352066fdbad01090499 100644
--- a/cfg/encoder_lowdelay_vtm.cfg
+++ b/cfg/encoder_lowdelay_vtm.cfg
@@ -134,7 +134,7 @@ LMCSEnable                   : 1      # LMCS: 0: disable, 1:enable
 LMCSSignalType               : 0      # Input signal type: 0:SDR, 1:HDR-PQ, 2:HDR-HLG
 LMCSUpdateCtrl               : 2      # LMCS model update control: 0:RA, 1:AI, 2:LDB/LDP
 MIP                          : 1
-
+JCCR                         : 1      # JCCR: disable, 1:enable
 # Fast tools
 PBIntraFast                  : 1
 ISPFast                      : 1
diff --git a/cfg/encoder_randomaccess_vtm.cfg b/cfg/encoder_randomaccess_vtm.cfg
index 7938ee72a22e3e306fe3f352ed1508229168130f..e98c72cf7052a82117b5cecc726be5322e473d18 100644
--- a/cfg/encoder_randomaccess_vtm.cfg
+++ b/cfg/encoder_randomaccess_vtm.cfg
@@ -152,7 +152,7 @@ LMCSUpdateCtrl               : 0      # LMCS model update control: 0:RA, 1:AI, 2
 MIP                          : 1
 DMVR                         : 1
 SMVD                         : 1
-
+JCCR                         : 1      # JCCR: disable, 1:enable
 # Fast tools
 PBIntraFast                  : 1
 ISPFast                      : 1
diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp
index 1899e02191fa13a3343b0bb3d26dd4a33dc130c4..1ad0f68e327377dd9e3a365ce6c49fb4a031206d 100644
--- a/source/App/EncoderApp/EncApp.cpp
+++ b/source/App/EncoderApp/EncApp.cpp
@@ -290,6 +290,9 @@ void EncApp::xInitLibCfg()
   m_cEncLib.setMMVD                                              ( m_MMVD );
   m_cEncLib.setMmvdDisNum                                        (m_MmvdDisNum);
   m_cEncLib.setRDPCM                                              ( m_RdpcmMode );
+#if JVET_O0376_SPS_JCCR_FLAG
+  m_cEncLib.setJCCR                                               (m_JccrMode);
+#endif
   m_cEncLib.setIBCMode                                           ( m_IBCMode );
   m_cEncLib.setIBCLocalSearchRangeX                              ( m_IBCLocalSearchRangeX );
   m_cEncLib.setIBCLocalSearchRangeY                              ( m_IBCLocalSearchRangeY );
diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp
index fdce40a52b0f364cce33db557f1fbc6f4b288d85..299f07a07b130ebfbfb299a8c2dca3120fdebda3 100644
--- a/source/App/EncoderApp/EncAppCfg.cpp
+++ b/source/App/EncoderApp/EncAppCfg.cpp
@@ -901,6 +901,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ("DMVR",                                            m_DMVR,                                           false, "Decoder-side Motion Vector Refinement")
   ("MmvdDisNum",                                      m_MmvdDisNum,                                     8,     "Number of MMVD Distance Entries")
   ( "RDPCM",                                         m_RdpcmMode,                                       false, "RDPCM")
+#if JVET_O0376_SPS_JCCR_FLAG
+    ("JCCR",                                          m_JccrMode,                                       false, "JCCR")
+#endif
   ( "IBC",                                            m_IBCMode,                                           0u, "IBCMode (0x1:enabled, 0x0:disabled)  [default: disabled]")
   ( "IBCLocalSearchRangeX",                           m_IBCLocalSearchRangeX,                            128u, "Search range of IBC local search in x direction")
   ( "IBCLocalSearchRangeY",                           m_IBCLocalSearchRangeY,                            128u, "Search range of IBC local search in y direction")
@@ -2206,6 +2209,9 @@ bool EncAppCfg::xCheckParameter()
     xConfirmPara(m_DMVR, "DMVR only allowed with NEXT profile");
     xConfirmPara(m_MmvdDisNum, "Number of distance MMVD entry setting only allowed with NEXT profile");
     xConfirmPara(m_RdpcmMode, "RDPCM only allowed with NEXT profile");
+#if JVET_O0376_SPS_JCCR_FLAG
+    xConfirmPara(m_JccrMode, "JCCR only allowed with NEXT profile");
+#endif
     // ADD_NEW_TOOL : (parameter check) add a check for next tools here
   }
   else
@@ -2495,11 +2501,20 @@ bool EncAppCfg::xCheckParameter()
   xConfirmPara( m_cbQpOffsetDualTree >  12,   "Max. Chroma Cb QP Offset for dual tree is  12" );
   xConfirmPara( m_crQpOffsetDualTree < -12,   "Min. Chroma Cr QP Offset for dual tree is -12" );
   xConfirmPara( m_crQpOffsetDualTree >  12,   "Max. Chroma Cr QP Offset for dual tree is  12" );
-  xConfirmPara( m_cbCrQpOffset < -12,         "Min. Joint Cb-Cr QP Offset is -12" );
-  xConfirmPara( m_cbCrQpOffset >  12,         "Max. Joint Cb-Cr QP Offset is  12" );
-  xConfirmPara( m_cbCrQpOffsetDualTree < -12, "Min. Joint Cb-Cr QP Offset for dual tree is -12" );
-  xConfirmPara( m_cbCrQpOffsetDualTree >  12, "Max. Joint Cb-Cr QP Offset for dual tree is  12" );
-
+#if JVET_O0376_SPS_JCCR_FLAG
+  if (m_JccrMode)
+  {
+    xConfirmPara(m_cbCrQpOffset < -12, "Min. Joint Cb-Cr QP Offset is -12");
+    xConfirmPara(m_cbCrQpOffset >  12, "Max. Joint Cb-Cr QP Offset is  12");
+    xConfirmPara(m_cbCrQpOffsetDualTree < -12, "Min. Joint Cb-Cr QP Offset for dual tree is -12");
+    xConfirmPara(m_cbCrQpOffsetDualTree >  12, "Max. Joint Cb-Cr QP Offset for dual tree is  12");
+  }
+#else
+  xConfirmPara(m_cbCrQpOffset < -12, "Min. Joint Cb-Cr QP Offset is -12");
+  xConfirmPara(m_cbCrQpOffset >  12, "Max. Joint Cb-Cr QP Offset is  12");
+  xConfirmPara(m_cbCrQpOffsetDualTree < -12, "Min. Joint Cb-Cr QP Offset for dual tree is -12");
+  xConfirmPara(m_cbCrQpOffsetDualTree >  12, "Max. Joint Cb-Cr QP Offset for dual tree is  12");
+#endif
   xConfirmPara( m_iQPAdaptationRange <= 0,                                                  "QP Adaptation Range must be more than 0" );
   if (m_iDecodingRefreshType == 2)
   {
@@ -3377,6 +3392,9 @@ void EncAppCfg::xPrintParameter()
     msg(VERBOSE, "DMVR:%d ", m_DMVR);
     msg(VERBOSE, "MmvdDisNum:%d ", m_MmvdDisNum);
     msg(VERBOSE, "RDPCM:%d ", m_RdpcmMode );
+#if JVET_O0376_SPS_JCCR_FLAG
+    msg(VERBOSE, "JCCR:%d ", m_JccrMode);
+#endif
   }
     msg(VERBOSE, "IBC:%d ", m_IBCMode);
   msg( VERBOSE, "HashME:%d ", m_HashME );
diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h
index 87b431e03fadc863d7bf805e2b00bf82fdc9fe14..bf8315902b159b47941802c84b865ec897593111 100644
--- a/source/App/EncoderApp/EncAppCfg.h
+++ b/source/App/EncoderApp/EncAppCfg.h
@@ -283,6 +283,9 @@ protected:
   bool      m_MMVD;
   int       m_MmvdDisNum;
   bool      m_RdpcmMode;
+#if JVET_O0376_SPS_JCCR_FLAG
+  bool      m_JccrMode;
+#endif
   unsigned  m_IBCMode;
   unsigned  m_IBCLocalSearchRangeX;
   unsigned  m_IBCLocalSearchRangeY;
diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h
index a4f18555dbd1ee3941c359f800dac838e474f48f..4b73f4821410e663a706c1e3dafb12afc5d690a4 100644
--- a/source/Lib/CommonLib/Slice.h
+++ b/source/Lib/CommonLib/Slice.h
@@ -185,6 +185,9 @@ class ConstraintInfo
   bool              m_noPartitionConstraintsOverrideConstraintFlag;
   bool              m_noSaoConstraintFlag;
   bool              m_noAlfConstraintFlag;
+#if JVET_O0376_SPS_JCCR_FLAG
+  bool              m_noJccrConstraintFlag;
+#endif
   bool              m_noPcmConstraintFlag;
   bool              m_noRefWraparoundConstraintFlag;
   bool              m_noTemporalMvpConstraintFlag;
@@ -284,6 +287,10 @@ public:
   void          setNoSaoConstraintFlag(bool bVal) { m_noSaoConstraintFlag = bVal; }
   bool          getNoAlfConstraintFlag() const { return m_noAlfConstraintFlag; }
   void          setNoAlfConstraintFlag(bool bVal) { m_noAlfConstraintFlag = bVal; }
+#if JVET_O0376_SPS_JCCR_FLAG
+  bool          getNoJccrConstraintFlag() const { return m_noJccrConstraintFlag; }
+  void          setNoJccrConstraintFlag(bool bVal) { m_noJccrConstraintFlag = bVal; }
+#endif
   bool          getNoPcmConstraintFlag() const { return m_noPcmConstraintFlag; }
   void          setNoPcmConstraintFlag(bool bVal) { m_noPcmConstraintFlag = bVal; }
   bool          getNoRefWraparoundConstraintFlag() const { return m_noRefWraparoundConstraintFlag; }
@@ -753,7 +760,9 @@ private:
 #endif
 
   bool              m_saoEnabledFlag;
-
+#if JVET_O0376_SPS_JCCR_FLAG
+  bool              m_jccrEnabledFlag;
+#endif
   bool              m_bTemporalIdNestingFlag; // temporal_id_nesting_flag
 
   bool              m_scalingListEnabledFlag;
@@ -935,7 +944,10 @@ public:
 
   bool                    getALFEnabledFlag() const                                                       { return m_alfEnabledFlag; }
   void                    setALFEnabledFlag( bool b )                                                     { m_alfEnabledFlag = b; }
-
+#if JVET_O0376_SPS_JCCR_FLAG
+  void                    setJCCREnabledFlag(bool bVal)                                                   { m_jccrEnabledFlag = bVal; }
+  bool                    getJCCREnabledFlag() const                                                      { return m_jccrEnabledFlag; }
+#endif
   bool                    getSBTMVPEnabledFlag() const                                                    { return m_sbtmvpEnabledFlag; }
   void                    setSBTMVPEnabledFlag(bool b)                                                    { m_sbtmvpEnabledFlag = b; }
 
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 4e5bbc845034fe952a0b46316edaf5d8b996ebe1..910ac54be730b723c5cfbb1566a063c38271ad2a 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -50,6 +50,8 @@
 #include <assert.h>
 #include <cassert>
 
+#define JVET_O0376_SPS_JCCR_FLAG                          1 // JVET-O0376: add the JCCR control flag in SPS
+
 #define JVET_O1136_TS_BDPCM_SIGNALLING                    1 // JVET-O1136: Unified syntax for JVET-O0165/O0200/O0783 on TS and BDPCM signalling
 
 #define JVET_O0219_LFNST_TRANSFORM_SET_FOR_LMCMODE        1
diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp
index a7994d0b13c5da909499843e4045b56a5135d6fa..13bb29553f710859d1c1e1c8b40f313015af47f5 100644
--- a/source/Lib/DecoderLib/CABACReader.cpp
+++ b/source/Lib/DecoderLib/CABACReader.cpp
@@ -2628,6 +2628,13 @@ void CABACReader::cu_chroma_qp_offset( CodingUnit& cu )
 #if JVET_O0105_ICT
 void CABACReader::joint_cb_cr( TransformUnit& tu, const int cbfMask )
 {
+#if JVET_O0376_SPS_JCCR_FLAG
+  if (!tu.cu->slice->getSPS()->getJCCREnabledFlag())
+  {
+    return;
+  }
+#endif
+
 #if JVET_O0543_ICT_ICU_ONLY
   if( ( CU::isIntra( *tu.cu ) && cbfMask ) || ( cbfMask == 3 ) )
 #else
diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp
index 1f7817faba04d938648ef2a3b1bfcc22b16dc1b5..85220de4210939afe00dea5126f9abbedf4c63b7 100644
--- a/source/Lib/DecoderLib/VLCReader.cpp
+++ b/source/Lib/DecoderLib/VLCReader.cpp
@@ -1220,7 +1220,9 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
 #endif
   READ_FLAG( uiCode, "sps_sao_enabled_flag" );                      pcSPS->setSAOEnabledFlag ( uiCode ? true : false );
   READ_FLAG( uiCode, "sps_alf_enabled_flag" );                      pcSPS->setALFEnabledFlag ( uiCode ? true : false );
-
+#if JVET_O0376_SPS_JCCR_FLAG
+  READ_FLAG(uiCode, "sps_jccr_enabled_flag");                      pcSPS->setJCCREnabledFlag(uiCode ? true : false);
+#endif
   READ_FLAG( uiCode, "sps_pcm_enabled_flag" );                          pcSPS->setPCMEnabledFlag( uiCode ? true : false );
   if( pcSPS->getPCMEnabledFlag() )
   {
@@ -2065,10 +2067,21 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
       }
     }
 #if JVET_O0105_ICT
+#if JVET_O0376_SPS_JCCR_FLAG
+    if (bChroma && sps->getJCCREnabledFlag())
+    {
+      READ_FLAG(uiCode, "joint_cb_cr_sign_flag"); pcSlice->setJointCbCrSignFlag(uiCode != 0);
+    }
+    else
+    {
+      pcSlice->setJointCbCrSignFlag(0);
+    }
+#else
     if (bChroma)
     {
-      READ_FLAG( uiCode, "joint_cb_cr_sign_flag" ); pcSlice->setJointCbCrSignFlag( uiCode != 0 );
+      READ_FLAG(uiCode, "joint_cb_cr_sign_flag"); pcSlice->setJointCbCrSignFlag(uiCode != 0);
     }
+#endif 
 #endif
 
     READ_SVLC( iCode, "slice_qp_delta" );
@@ -2098,13 +2111,24 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
         CHECK( pcSlice->getSliceChromaQpDelta(COMPONENT_Cr) >  12, "Invalid chroma QP offset" );
         CHECK( (pps->getQpOffset(COMPONENT_Cr) + pcSlice->getSliceChromaQpDelta(COMPONENT_Cr)) < -12, "Invalid chroma QP offset" );
         CHECK( (pps->getQpOffset(COMPONENT_Cr) + pcSlice->getSliceChromaQpDelta(COMPONENT_Cr)) >  12, "Invalid chroma QP offset" );
-
-        READ_SVLC( iCode, "slice_cb_cr_qp_offset" );
-        pcSlice->setSliceChromaQpDelta(JOINT_CbCr, iCode );
-        CHECK( pcSlice->getSliceChromaQpDelta(JOINT_CbCr) < -12, "Invalid chroma QP offset" );
-        CHECK( pcSlice->getSliceChromaQpDelta(JOINT_CbCr) >  12, "Invalid chroma QP offset" );
-        CHECK( (pps->getQpOffset(JOINT_CbCr) + pcSlice->getSliceChromaQpDelta(JOINT_CbCr)) < -12, "Invalid chroma QP offset" );
-        CHECK( (pps->getQpOffset(JOINT_CbCr) + pcSlice->getSliceChromaQpDelta(JOINT_CbCr)) >  12, "Invalid chroma QP offset" );
+#if JVET_O0376_SPS_JCCR_FLAG
+        if (sps->getJCCREnabledFlag())
+        {
+          READ_SVLC(iCode, "slice_cb_cr_qp_offset");
+          pcSlice->setSliceChromaQpDelta(JOINT_CbCr, iCode);
+          CHECK(pcSlice->getSliceChromaQpDelta(JOINT_CbCr) < -12, "Invalid chroma QP offset");
+          CHECK(pcSlice->getSliceChromaQpDelta(JOINT_CbCr) >  12, "Invalid chroma QP offset");
+          CHECK((pps->getQpOffset(JOINT_CbCr) + pcSlice->getSliceChromaQpDelta(JOINT_CbCr)) < -12, "Invalid chroma QP offset");
+          CHECK((pps->getQpOffset(JOINT_CbCr) + pcSlice->getSliceChromaQpDelta(JOINT_CbCr)) >  12, "Invalid chroma QP offset");
+        }
+#else
+        READ_SVLC(iCode, "slice_cb_cr_qp_offset");
+        pcSlice->setSliceChromaQpDelta(JOINT_CbCr, iCode);
+        CHECK(pcSlice->getSliceChromaQpDelta(JOINT_CbCr) < -12, "Invalid chroma QP offset");
+        CHECK(pcSlice->getSliceChromaQpDelta(JOINT_CbCr) >  12, "Invalid chroma QP offset");
+        CHECK((pps->getQpOffset(JOINT_CbCr) + pcSlice->getSliceChromaQpDelta(JOINT_CbCr)) < -12, "Invalid chroma QP offset");
+        CHECK((pps->getQpOffset(JOINT_CbCr) + pcSlice->getSliceChromaQpDelta(JOINT_CbCr)) >  12, "Invalid chroma QP offset");
+#endif
       }
     }
 
@@ -2289,6 +2313,10 @@ void HLSyntaxReader::parseConstraintInfo(ConstraintInfo *cinfo)
   READ_FLAG(symbol, "no_partition_constraints_override_constraint_flag"); cinfo->setNoPartitionConstraintsOverrideConstraintFlag(symbol > 0 ? true : false);
   READ_FLAG(symbol,  "no_sao_constraint_flag");                    cinfo->setNoSaoConstraintFlag(symbol > 0 ? true : false);
   READ_FLAG(symbol,  "no_alf_constraint_flag");                    cinfo->setNoAlfConstraintFlag(symbol > 0 ? true : false);
+#if JVET_O0376_SPS_JCCR_FLAG
+  READ_FLAG(symbol, "no_jccr_constraint_flag");                    cinfo->setNoAlfConstraintFlag(symbol > 0 ? true : false);
+#endif
+
   READ_FLAG(symbol,  "no_pcm_constraint_flag");                    cinfo->setNoPcmConstraintFlag(symbol > 0 ? true : false);
   READ_FLAG(symbol,  "no_ref_wraparound_constraint_flag");         cinfo->setNoRefWraparoundConstraintFlag(symbol > 0 ? true : false);
   READ_FLAG(symbol,  "no_temporal_mvp_constraint_flag");           cinfo->setNoTemporalMvpConstraintFlag(symbol > 0 ? true : false);
diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp
index 7ec4f7a723360205af7b1d98a3adf8f7b3bd2ec0..d718594bddb779eb47f480bcc55be92af39a37f5 100644
--- a/source/Lib/EncoderLib/CABACWriter.cpp
+++ b/source/Lib/EncoderLib/CABACWriter.cpp
@@ -2501,6 +2501,13 @@ void CABACWriter::cu_chroma_qp_offset( const CodingUnit& cu )
 #if JVET_O0105_ICT
 void CABACWriter::joint_cb_cr( const TransformUnit& tu, const int cbfMask )
 {
+#if JVET_O0376_SPS_JCCR_FLAG
+  if (!tu.cu->slice->getSPS()->getJCCREnabledFlag())
+  {
+    return;
+  }
+#endif
+
   CHECK( tu.jointCbCr && tu.jointCbCr != cbfMask, "wrong value of jointCbCr (" << (int)tu.jointCbCr << " vs " << (int)cbfMask << ")" );
 #if JVET_O0543_ICT_ICU_ONLY
   if( ( CU::isIntra( *tu.cu ) && cbfMask ) || ( cbfMask == 3 ) )
diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h
index 1a4af6c703fe9f96b779e00f5e984c930ab6017d..16b4a18a8b066018fc7eba15865bbec1f5dfd714 100644
--- a/source/Lib/EncoderLib/EncCfg.h
+++ b/source/Lib/EncoderLib/EncCfg.h
@@ -299,6 +299,9 @@ protected:
   bool      m_MMVD;
   int       m_MmvdDisNum;
   bool      m_RdpcmMode;
+#if JVET_O0376_SPS_JCCR_FLAG
+  bool      m_JccrMode;
+#endif
   unsigned  m_IBCMode;
   unsigned  m_IBCLocalSearchRangeX;
   unsigned  m_IBCLocalSearchRangeY;
@@ -873,6 +876,10 @@ public:
   int       getMmvdDisNum                   ()         const { return m_MmvdDisNum; }
   void      setRDPCM                     ( bool b )       { m_RdpcmMode = b; }
   bool      getRDPCM                     ()         const { return m_RdpcmMode; }
+#if JVET_O0376_SPS_JCCR_FLAG
+  void      setJCCR                       (bool b)        { m_JccrMode = b; }
+  bool      getJCCR                      ()         const { return m_JccrMode; }
+#endif
   void      setIBCMode                      (unsigned n)     { m_IBCMode = n; }
   unsigned  getIBCMode                      ()         const { return m_IBCMode; }
   void      setIBCLocalSearchRangeX         (unsigned n)     { m_IBCLocalSearchRangeX = n; }
diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp
index 1a202e9d28b4a2214364a6f700daeb4ddbb6d090..00863d2a982b9982685dadb2fb6870200dbe92c0 100644
--- a/source/Lib/EncoderLib/EncGOP.cpp
+++ b/source/Lib/EncoderLib/EncGOP.cpp
@@ -2092,7 +2092,14 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
       // overwrite chroma qp offset for dual tree
       pcSlice->setSliceChromaQpDelta(COMPONENT_Cb, m_pcCfg->getChromaCbQpOffsetDualTree());
       pcSlice->setSliceChromaQpDelta(COMPONENT_Cr, m_pcCfg->getChromaCrQpOffsetDualTree());
-      pcSlice->setSliceChromaQpDelta(JOINT_CbCr,   m_pcCfg->getChromaCbCrQpOffsetDualTree());
+#if JVET_O0376_SPS_JCCR_FLAG
+      if (pcSlice->getSPS()->getJCCREnabledFlag())
+      {
+        pcSlice->setSliceChromaQpDelta(JOINT_CbCr, m_pcCfg->getChromaCbCrQpOffsetDualTree());
+      }
+#else
+      pcSlice->setSliceChromaQpDelta(JOINT_CbCr, m_pcCfg->getChromaCbCrQpOffsetDualTree());
+#endif
       m_pcSliceEncoder->setUpLambda(pcSlice, pcSlice->getLambdas()[0], pcSlice->getSliceQp());
     }
     if (pcSlice->getSPS()->getUseReshaper())
diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp
index ce97ff3119d935a3e1285c6efe55d32a056a4ef0..49847fc041a35c325fe8bd3e92ca724d32581d6c 100644
--- a/source/Lib/EncoderLib/EncLib.cpp
+++ b/source/Lib/EncoderLib/EncLib.cpp
@@ -980,7 +980,9 @@ void EncLib::xInitSPS(SPS &sps)
   }
 
   sps.setSAOEnabledFlag( m_bUseSAO );
-
+#if JVET_O0376_SPS_JCCR_FLAG
+  sps.setJCCREnabledFlag(m_JccrMode);
+#endif
   sps.setMaxTLayers( m_maxTempLayer );
   sps.setTemporalIdNestingFlag( ( m_maxTempLayer == 1 ) ? true : false );
 
diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp
index 1e75780bbd9b591b0458bf9c8f06a95d8b1aa350..d24c90172c9fd3e1d610a6ad813ed2463fa5fa27 100644
--- a/source/Lib/EncoderLib/EncSlice.cpp
+++ b/source/Lib/EncoderLib/EncSlice.cpp
@@ -1554,7 +1554,14 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons
   checkDisFracMmvd( pcPic, startCtuTsAddr, boundingCtuTsAddr );
 
 #if JVET_O0105_ICT
-  setJointCbCrModes( cs, Position(0, 0), cs.area.lumaSize() );
+#if JVET_O0376_SPS_JCCR_FLAG
+  if (pcSlice->getSPS()->getJCCREnabledFlag())
+  {
+    setJointCbCrModes(cs, Position(0, 0), cs.area.lumaSize());
+  }
+#else
+  setJointCbCrModes(cs, Position(0, 0), cs.area.lumaSize());
+#endif
 #endif
 
   // for every CTU in the slice segment (may terminate sooner if there is a byte limit on the slice-segment)
diff --git a/source/Lib/EncoderLib/InterSearch.cpp b/source/Lib/EncoderLib/InterSearch.cpp
index 9aaac4ded7edcc3ff8ef90f5afc19a24b88d726d..ef8162bd5012a5beca158eee5e4b29a95c375727 100644
--- a/source/Lib/EncoderLib/InterSearch.cpp
+++ b/source/Lib/EncoderLib/InterSearch.cpp
@@ -6929,9 +6929,11 @@ void InterSearch::xEstimateInterResidualQT(CodingStructure &cs, Partitioner &par
     {
       const CompArea& cbArea = tu.blocks[COMPONENT_Cb];
       const CompArea& crArea = tu.blocks[COMPONENT_Cr];
-
+#if JVET_O0376_SPS_JCCR_FLAG
+      bool checkJointCbCr = (tu.cu->slice->getSPS()->getJCCREnabledFlag()) &&(!tu.noResidual) && (TU::getCbf(tu, COMPONENT_Cb) || TU::getCbf(tu, COMPONENT_Cr));
+#else
       bool checkJointCbCr = !tu.noResidual && (TU::getCbf(tu, COMPONENT_Cb) || TU::getCbf(tu, COMPONENT_Cr));
-
+#endif
 #if JVET_O0105_ICT
       const int channelBitDepth = sps.getBitDepth(toChannelType(COMPONENT_Cb));
       bool      reshape         = slice.getLmcsEnabledFlag() && m_pcReshape->getCTUFlag() && slice.getLmcsChromaResidualScaleFlag()
diff --git a/source/Lib/EncoderLib/IntraSearch.cpp b/source/Lib/EncoderLib/IntraSearch.cpp
index cc7c2a3bbb86529efdff2d49909b0a4f2070520d..398aadf4874ce970e23844fb961863438faa3d3a 100644
--- a/source/Lib/EncoderLib/IntraSearch.cpp
+++ b/source/Lib/EncoderLib/IntraSearch.cpp
@@ -2966,11 +2966,20 @@ ChromaCbfs IntraSearch::xRecurIntraChromaCodingQT( CodingStructure &cs, Partitio
 #if JVET_O0105_ICT
       bool       lastIsBest     = false;
       std::vector<int>  jointCbfMasksToTest;
-      if( TU::getCbf(tmpTU, COMPONENT_Cb) || TU::getCbf(tmpTU, COMPONENT_Cr) )
+#if JVET_O0376_SPS_JCCR_FLAG
+      if (cs.sps->getJCCREnabledFlag())
       {
-        jointCbfMasksToTest = m_pcTrQuant->selectICTCandidates( currTU, orgResiCb, orgResiCr );
+        if (TU::getCbf(tmpTU, COMPONENT_Cb) || TU::getCbf(tmpTU, COMPONENT_Cr))
+        {
+          jointCbfMasksToTest = m_pcTrQuant->selectICTCandidates(currTU, orgResiCb, orgResiCr);
+        }
       }
-
+#else
+      if (TU::getCbf(tmpTU, COMPONENT_Cb) || TU::getCbf(tmpTU, COMPONENT_Cr))
+      {
+        jointCbfMasksToTest = m_pcTrQuant->selectICTCandidates(currTU, orgResiCb, orgResiCr);
+      }
+#endif
       for( int cbfMask : jointCbfMasksToTest )
 #else
       bool       checkJointCbCr = TU::getCbf(tmpTU, COMPONENT_Cb) || TU::getCbf(tmpTU, COMPONENT_Cr);
diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp
index 90f7a64f4bd26655c48861991b1521d5560b0877..5bd5cb37ac21ce79636660fe5f2d7fe3d0b6a1ef 100644
--- a/source/Lib/EncoderLib/VLCWriter.cpp
+++ b/source/Lib/EncoderLib/VLCWriter.cpp
@@ -813,7 +813,9 @@ void HLSWriter::codeSPS( const SPS* pcSPS )
 #endif
   WRITE_FLAG( pcSPS->getSAOEnabledFlag(),                                            "sps_sao_enabled_flag");
   WRITE_FLAG( pcSPS->getALFEnabledFlag(),                                            "sps_alf_enabled_flag" );
-
+#if JVET_O0376_SPS_JCCR_FLAG
+  WRITE_FLAG(pcSPS->getJCCREnabledFlag(),                                            "sps_jccr_enabled_flag");
+#endif
   WRITE_FLAG( pcSPS->getPCMEnabledFlag() ? 1 : 0,                                    "sps_pcm_enabled_flag");
   if( pcSPS->getPCMEnabledFlag() )
   {
@@ -1430,10 +1432,17 @@ void HLSWriter::codeSliceHeader         ( Slice* pcSlice )
       }
     }
 #if JVET_O0105_ICT
+#if JVET_O0376_SPS_JCCR_FLAG
+    if (chromaEnabled && pcSlice->getSPS()->getJCCREnabledFlag())
+    {
+      WRITE_FLAG(pcSlice->getJointCbCrSignFlag() ? 1 : 0, "joint_cb_cr_sign_flag");
+    }
+#else
     if (chromaEnabled)
     {
-      WRITE_FLAG( pcSlice->getJointCbCrSignFlag() ? 1 : 0, "joint_cb_cr_sign_flag" );
+      WRITE_FLAG(pcSlice->getJointCbCrSignFlag() ? 1 : 0, "joint_cb_cr_sign_flag");
     }
+#endif 
 #endif
 
     int iCode = pcSlice->getSliceQp() - ( pcSlice->getPPS()->getPicInitQPMinus26() + 26 );
@@ -1447,7 +1456,14 @@ void HLSWriter::codeSliceHeader         ( Slice* pcSlice )
       if (numberValidComponents > COMPONENT_Cr)
       {
         WRITE_SVLC( pcSlice->getSliceChromaQpDelta(COMPONENT_Cr), "slice_cr_qp_offset" );
-        WRITE_SVLC( pcSlice->getSliceChromaQpDelta(JOINT_CbCr),   "slice_cb_cr_qp_offset" );
+#if JVET_O0376_SPS_JCCR_FLAG
+        if (pcSlice->getSPS()->getJCCREnabledFlag())
+        {
+          WRITE_SVLC(pcSlice->getSliceChromaQpDelta(JOINT_CbCr), "slice_cb_cr_qp_offset");
+        }
+#else
+        WRITE_SVLC(pcSlice->getSliceChromaQpDelta(JOINT_CbCr), "slice_cb_cr_qp_offset");
+#endif
       }
       CHECK(numberValidComponents < COMPONENT_Cr+1, "Too many valid components");
     }
@@ -1517,6 +1533,9 @@ void  HLSWriter::codeConstraintInfo  ( const ConstraintInfo* cinfo )
   WRITE_FLAG(cinfo->getNoPartitionConstraintsOverrideConstraintFlag() ? 1 : 0, "no_partition_constraints_override_constraint_flag");
   WRITE_FLAG(cinfo->getNoSaoConstraintFlag() ? 1 : 0, "no_sao_constraint_flag");
   WRITE_FLAG(cinfo->getNoAlfConstraintFlag() ? 1 : 0, "no_alf_constraint_flag");
+#if JVET_O0376_SPS_JCCR_FLAG
+  WRITE_FLAG(cinfo->getNoJccrConstraintFlag() ? 1 : 0, "no_jccr_constraint_flag");
+#endif
   WRITE_FLAG(cinfo->getNoPcmConstraintFlag() ? 1 : 0, "no_pcm_constraint_flag");
   WRITE_FLAG(cinfo->getNoRefWraparoundConstraintFlag() ? 1 : 0, "no_ref_wraparound_constraint_flag");
   WRITE_FLAG(cinfo->getNoTemporalMvpConstraintFlag() ? 1 : 0, "no_temporal_mvp_constraint_flag");