diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp
index ea263a36c68697e97d8fd830d83910f40f74e03b..1e24e4cdb824a6ce6bc2b49fc0f6993ee8ca6001 100644
--- a/source/App/EncoderApp/EncApp.cpp
+++ b/source/App/EncoderApp/EncApp.cpp
@@ -932,6 +932,9 @@ void EncApp::xInitLibCfg()
 #if JVET_AD0085_MPM_SORTING
   m_cEncLib.setUseMpmSorting                                     ( m_mpmSorting );
 #endif
+#if JVET_AH0136_CHROMA_REORDERING
+  m_cEncLib.setUseChromaReordering                               (m_chromaReordering);
+#endif
 #if JVET_AC0147_CCCM_NO_SUBSAMPLING
   m_cEncLib.setUseCccm                                           ( m_cccm );
 #endif
diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp
index d55f74efba6d61908ffa848fbc627bfa5e774807..d8032107fd686efe39aca62eefc471f6a3772748 100644
--- a/source/App/EncoderApp/EncAppCfg.cpp
+++ b/source/App/EncoderApp/EncAppCfg.cpp
@@ -1154,6 +1154,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
 #if JVET_AD0085_MPM_SORTING
   ( "MPMSorting",                                     m_mpmSorting,                                      true,  "Enable template-based intra MPM list construction\n" )
 #endif
+#if JVET_AH0136_CHROMA_REORDERING
+  ("ChromaReordering",                                m_chromaReordering,                                true, "Enable template-based intra chroma list reordering\n")
+#endif
 #if JVET_AC0147_CCCM_NO_SUBSAMPLING
   ( "CCCM",                                           m_cccm,                                               2,  "CCCM mode (0:off, 1:on, 2:on subsampling and no subsampling)  [default: 2]")
 #endif
@@ -4096,6 +4099,13 @@ bool EncAppCfg::xCheckParameter()
       m_mpmSorting = false;
     }
 #endif
+#if JVET_AH0136_CHROMA_REORDERING
+    if (m_chromaReordering)
+    {
+      msg(WARNING, "ChromaReordering is forcefully disabled since the enable flag of non-inter-TM tools is set off. \n");
+      m_chromaReordering = false;
+    }
+#endif
 #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
     if (m_tmibc)
     {
@@ -5790,6 +5800,9 @@ void EncAppCfg::xPrintParameter()
 #if JVET_AD0085_MPM_SORTING && !JVET_AE0174_NONINTER_TM_TOOLS_CONTROL
   msg(VERBOSE, "MPMSorting:%d ", m_mpmSorting);
 #endif
+#if JVET_AH0136_CHROMA_REORDERING && !JVET_AE0174_NONINTER_TM_TOOLS_CONTROL
+  msg(VERBOSE, "ChromaReordering:%d ", m_chromaReordering);
+#endif
 #if JVET_AC0147_CCCM_NO_SUBSAMPLING
   msg(VERBOSE, "CCCM:%d ", m_cccm);
 #endif
@@ -5843,6 +5856,9 @@ void EncAppCfg::xPrintParameter()
 #if JVET_AD0085_MPM_SORTING
   msg(VERBOSE, "MPMsorting:%d ", m_mpmSorting);
 #endif
+#if JVET_AH0136_CHROMA_REORDERING
+  msg(VERBOSE, "ChromaReordering:%d ", m_chromaReordering);
+#endif
 #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
   msg(VERBOSE, "TM-IBC:%d ", m_tmibc);
 #endif
diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h
index 5b2b551ed988340459efa8f0e43d963d729b2cde..dc8a06a036134f157de7739e160dc8c15c53d0e1 100644
--- a/source/App/EncoderApp/EncAppCfg.h
+++ b/source/App/EncoderApp/EncAppCfg.h
@@ -502,6 +502,9 @@ protected:
 #if JVET_AD0085_MPM_SORTING
   bool      m_mpmSorting;
 #endif
+#if JVET_AH0136_CHROMA_REORDERING
+  bool      m_chromaReordering;
+#endif
 #if JVET_AC0147_CCCM_NO_SUBSAMPLING
   int       m_cccm;
 #endif
diff --git a/source/Lib/CommonLib/CommonDef.h b/source/Lib/CommonLib/CommonDef.h
index 03f4a55ab0b4cf650bc2ef122b3a127d76fb7119..f3d49686ca1cd2932392cd7bb777a78f3b169c9a 100644
--- a/source/Lib/CommonLib/CommonDef.h
+++ b/source/Lib/CommonLib/CommonDef.h
@@ -663,8 +663,24 @@ static const int MDLM_T_IDX =                          LM_CHROMA_IDX + 2; ///< M
 #if JVET_Z0050_DIMD_CHROMA_FUSION && ENABLE_DIMD
 static const int DIMD_CHROMA_IDX =                     NUM_INTRA_MODE; ///< chroma mode index for derived by DIMD method
 #if JVET_AC0071_DBV
+#if JVET_AH0136_CHROMA_REORDERING
+static const int DBV_CHROMA_IDX = NUM_INTRA_MODE + 1;
+static const int DBV_CHROMA_IDX1 = NUM_INTRA_MODE + 2;
+static const int DBV_CHROMA_IDX2 = NUM_INTRA_MODE + 3;
+static const int DBV_CHROMA_IDX3 = NUM_INTRA_MODE + 4;
+static const int DBV_CHROMA_IDX4 = NUM_INTRA_MODE + 5;
+static const int DBV_CHROMA_IDX5 = NUM_INTRA_MODE + 6;
+static const int DBV_CHROMA_IDX6 = NUM_INTRA_MODE + 7;
+static const int DBV_CHROMA_IDX7 = NUM_INTRA_MODE + 8;
+static const int DBV_CHROMA_IDX8 = NUM_INTRA_MODE + 9;
+static const int DBV_CHROMA_IDX9 = NUM_INTRA_MODE + 10;
+static const int DM_CHROMA_IDX = NUM_INTRA_MODE + 11; ///< chroma mode index for derived from luma intra mode
+static const int NUM_CHROMA_TM_LINES_IN_REORDERING = 1;
+static const int NUM_CHROMA_LIST_MODE = 7 + 4 + 5 + 10; /// 7 orginal modes + 4 collocated modes + 5 neighboring modes + 10 DBV modes
+#else
 static const int DBV_CHROMA_IDX = NUM_INTRA_MODE + 1;
 static const int DM_CHROMA_IDX = NUM_INTRA_MODE + 2; ///< chroma mode index for derived from luma intra mode
+#endif
 #else
 static const int DM_CHROMA_IDX =                       NUM_INTRA_MODE + 1; ///< chroma mode index for derived from luma intra mode
 #endif
diff --git a/source/Lib/CommonLib/ContextModelling.h b/source/Lib/CommonLib/ContextModelling.h
index 2b58835eee88b72000b82a5d53b2150c8191e915..dab3c18766aad92d2783479b8cac4027da80cfae 100644
--- a/source/Lib/CommonLib/ContextModelling.h
+++ b/source/Lib/CommonLib/ContextModelling.h
@@ -72,13 +72,22 @@ public:
   static inline bool getSwitchCondition(const CodingUnit &cu,ChannelType channelType) {
     bool            condition     =
       cu.predMode == MODE_INTRA && cu.slice->getSliceType() != I_SLICE &&
-      ((!cu.tmpFlag && channelType == CHANNEL_TYPE_LUMA)||(channelType == CHANNEL_TYPE_CHROMA && cu.firstPU->intraDir[1] != DBV_CHROMA_IDX));
+      ((!cu.tmpFlag && channelType == CHANNEL_TYPE_LUMA)||(channelType == CHANNEL_TYPE_CHROMA 
+#if JVET_AH0136_CHROMA_REORDERING
+        && !(cu.firstPU->intraDir[1] >= DBV_CHROMA_IDX && cu.firstPU->intraDir[1] <= DBV_CHROMA_IDX9)
+#else
+        && cu.firstPU->intraDir[1] != DBV_CHROMA_IDX
+#endif
+        ));
     assert(cu.slice->getSliceType() != I_SLICE || channelType == cu.chType);
     int tmpMaxSize = cu.cs->sps->getIntraTMPMaxSize();
     condition = condition || (cu.predMode == MODE_IBC && channelType == CHANNEL_TYPE_LUMA && cu.slice->getSliceType() == I_SLICE)
                 || (cu.predMode == MODE_INTRA && ((channelType == CHANNEL_TYPE_LUMA && cu.tmpFlag && !cu.bdpcmMode && !cu.dimd
-                                                && cu.lwidth() <= tmpMaxSize && cu.lheight() <= tmpMaxSize) ||
-                                               (channelType == CHANNEL_TYPE_CHROMA && cu.firstPU->intraDir[1] == DBV_CHROMA_IDX)) && cu.slice->getSliceType() == I_SLICE);
+                                                && cu.lwidth() <= tmpMaxSize && cu.lheight() <= tmpMaxSize)
+#if !JVET_AH0136_CHROMA_REORDERING
+                  || (channelType == CHANNEL_TYPE_CHROMA && cu.firstPU->intraDir[1] == DBV_CHROMA_IDX)
+#endif
+                  ) && cu.slice->getSliceType() == I_SLICE);
     return condition;
   }
 #endif
diff --git a/source/Lib/CommonLib/IntraPrediction.cpp b/source/Lib/CommonLib/IntraPrediction.cpp
index d29044c58b0a54209b9ce73ba88874c607d86c91..6aa0217fd4fbf39feb0461079957a661fcbab647 100644
--- a/source/Lib/CommonLib/IntraPrediction.cpp
+++ b/source/Lib/CommonLib/IntraPrediction.cpp
@@ -4371,7 +4371,11 @@ void IntraPrediction::generateDimdBlending(PelBuf &piPred, const PredictionUnit
 
 #if JVET_Z0050_DIMD_CHROMA_FUSION
 #if JVET_AD0188_CCP_MERGE
-void IntraPrediction::geneChromaFusionPred( const ComponentID compId, PelBuf &piPred, PredictionUnit &pu )
+void IntraPrediction::geneChromaFusionPred( const ComponentID compId, PelBuf &piPred, PredictionUnit &pu 
+#if JVET_AH0136_CHROMA_REORDERING
+  , InterPrediction *pcInterPred
+#endif
+)
 #else
 void IntraPrediction::geneChromaFusionPred(const ComponentID compId, PelBuf &piPred, const PredictionUnit &pu)
 #endif
@@ -4406,9 +4410,19 @@ void IntraPrediction::geneChromaFusionPred(const ComponentID compId, PelBuf &piP
     pu2.intraDir[1] = LM_CHROMA_IDX + pu.isChromaFusion - 2;
     if (!pu.cs->pcv->isEncoder || !pu2.cs->slice->isIntra() || !CS::isDualITree(*pu.cs))
     {
+#if JVET_AH0136_CHROMA_REORDERING
+      xCflmCreateChromaPred(pu, compId, piPred, pcInterPred);
+#else
       xCflmCreateChromaPred(pu, compId, piPred);
+#endif
     }
     predIntraChromaLM(compId, piPred, pu2, area, pu2.intraDir[1]);
+#if JVET_AH0136_CHROMA_REORDERING && JVET_AC0071_DBV
+    if (PU::isDbvMode(pu.intraDir[1]) && pu.cu->rribcFlipType != 0)
+    {
+      piPred.flipSignal(pu.cu->rribcFlipType == 1);
+    }
+#endif
     return;
   }
 #endif
@@ -4516,7 +4530,11 @@ void IntraPrediction::geneChromaFusionPred(const ComponentID compId, PelBuf &piP
 #endif
 
 #if JVET_AC0071_DBV && JVET_AA0070_RRIBC
+#if JVET_AH0136_CHROMA_REORDERING
+  if (PU::isDbvMode(pu.intraDir[1]) && pu.cu->rribcFlipType != 0)
+#else
   if (pu.intraDir[1] == DBV_CHROMA_IDX && pu.cu->rribcFlipType != 0)
+#endif
   {
     predLmBuffer.flipSignal(pu.cu->rribcFlipType == 1);
   }
@@ -5712,6 +5730,282 @@ void IntraPrediction::xFillReferenceSamples( const CPelBuf &recoBuf, Pel* refBuf
   }
 }
 
+#if JVET_AH0136_CHROMA_REORDERING
+void IntraPrediction::xFillReferenceSamplesForCoLuma(const CPelBuf &recoBuf, Pel* refBufUnfiltered, const CompArea &area, const CodingUnit &cu)
+{
+  const ChannelType      chType = toChannelType(area.compID);
+  const CodingStructure &cs = *cu.cs;
+  const SPS             &sps = *cs.sps;
+  const PreCalcValues   &pcv = *cs.pcv;
+
+  const int multiRefIdx = 0;
+
+  const int  tuWidth = area.width;
+  const int  tuHeight = area.height;
+  const int  predSize = m_topRefLength;
+  const int  predHSize = m_leftRefLength;
+  const int predStride = predSize + 1 + multiRefIdx;
+  m_refBufferStride[area.compID] = predStride;
+
+  const bool noShift = pcv.noChroma2x2 && area.width == 4; // don't shift on the lowest level (chroma not-split)
+  const int  unitWidth = tuWidth <= 2 && cu.ispMode && isLuma(area.compID) ? tuWidth : pcv.minCUWidth >> (noShift ? 0 : getComponentScaleX(area.compID, sps.getChromaFormatIdc()));
+  const int  unitHeight = tuHeight <= 2 && cu.ispMode && isLuma(area.compID) ? tuHeight : pcv.minCUHeight >> (noShift ? 0 : getComponentScaleY(area.compID, sps.getChromaFormatIdc()));
+
+  const int  totalAboveUnits = (predSize + (unitWidth - 1)) / unitWidth;
+  const int  totalLeftUnits = (predHSize + (unitHeight - 1)) / unitHeight;
+  const int  totalUnits = totalAboveUnits + totalLeftUnits + 1; //+1 for top-left
+
+  const int  numAboveUnits = std::max<int>(tuWidth / unitWidth, 1);
+  const int  numLeftUnits = std::max<int>(tuHeight / unitHeight, 1);
+  const int  numAboveRightUnits = totalAboveUnits - numAboveUnits;
+  const int  numLeftBelowUnits = totalLeftUnits - numLeftUnits;
+
+  CHECK(numAboveUnits <= 0 || numLeftUnits <= 0 || numAboveRightUnits <= 0 || numLeftBelowUnits <= 0, "Size not supported");
+
+  // ----- Step 1: analyze neighborhood -----
+  bool  neighborFlags[4 * MAX_NUM_PART_IDXS_IN_CTU_WIDTH + 1];
+  int   numIntraNeighbor = 0;
+
+  memset(neighborFlags, 0, totalUnits);
+
+  neighborFlags[totalLeftUnits] = area.x > 0 && area.y > 0;
+  numIntraNeighbor += neighborFlags[totalLeftUnits] ? 1 : 0;
+  numIntraNeighbor += area.y > 0 ? numAboveUnits : 0;
+  for (int i = totalLeftUnits + 1; i < totalLeftUnits + 1 + numAboveUnits; i++)
+  {
+    neighborFlags[i] = area.y > 0 ? true : false;
+  }
+  int picWidth = sps.getMaxPicWidthInLumaSamples();
+  int ctuWidth = sps.getCTUSize();
+  int ctuWidthInNum = area.x / ctuWidth;
+  int wUnit = std::min((picWidth - area.x - tuWidth) / unitWidth, ((ctuWidthInNum + 1) * ctuWidth - area.x - tuWidth) / unitWidth);
+  numIntraNeighbor += area.y > 0 ? std::min(numAboveRightUnits, wUnit) : 0;
+  for (int i = totalLeftUnits + 1 + numAboveUnits; i < totalLeftUnits + 1 + numAboveUnits + numAboveRightUnits; i++)
+  {
+    neighborFlags[i] = area.y > 0 ? ( i - (totalLeftUnits + 1 + numAboveUnits) < wUnit ? true : false) : false;
+  }
+  numIntraNeighbor += area.x > 0 ? numLeftUnits : 0;
+  for (int i = totalLeftUnits - 1; i > totalLeftUnits - 1 - numLeftUnits; i--)
+  {
+    neighborFlags[i] = area.x > 0 ? true : false;
+  }
+  int picHeight = sps.getMaxPicHeightInLumaSamples();
+  int ctuHeight = sps.getCTUSize();
+  int ctuHeightInNum = area.y / ctuHeight;
+  int hUnit = std::min((picHeight - area.y - tuHeight) / unitHeight, ((ctuHeightInNum + 1) * ctuHeight - area.y - tuHeight) / unitHeight);
+  numIntraNeighbor += area.x > 0 ? std::min(numLeftBelowUnits, hUnit) : 0;
+  int y = 0;
+  for (int i = totalLeftUnits - 1 - numLeftUnits; i > totalLeftUnits - 1 - numLeftUnits - numLeftBelowUnits; i--)
+  {
+    neighborFlags[i] = area.x > 0 ? (y < hUnit ? true : false) : false;
+    y++;
+  }
+
+  // ----- Step 2: fill reference samples (depending on neighborhood) -----
+
+  const Pel*  srcBuf = recoBuf.buf;
+  const int   srcStride = recoBuf.stride;
+  Pel*  ptrDst = refBufUnfiltered;
+  const Pel*  ptrSrc;
+  const Pel   valueDC = 1 << (sps.getBitDepth(chType) - 1);
+
+  if (numIntraNeighbor == 0)
+  {
+    // Fill border with DC value
+    for (int j = 0; j <= predSize + multiRefIdx; j++)
+    {
+      ptrDst[j] = valueDC;
+    }
+    for (int i = 0; i <= predHSize + multiRefIdx; i++)
+    {
+      ptrDst[i + predStride] = valueDC;
+    }
+  }
+  else if (numIntraNeighbor == totalUnits)
+  {
+    // Fill top-left border and top and top right with rec. samples
+    ptrSrc = srcBuf - (1 + multiRefIdx) * srcStride - (1 + multiRefIdx);
+
+    std::memcpy(ptrDst, ptrSrc, sizeof(*ptrDst) * (predSize + multiRefIdx + 1));
+
+    for (int i = 0; i <= predHSize + multiRefIdx; i++)
+    {
+      ptrDst[i + predStride] = ptrSrc[i * srcStride];
+    }
+  }
+  else // reference samples are partially available
+  {
+    // Fill top-left sample(s) if available
+    ptrSrc = srcBuf - (1 + multiRefIdx) * srcStride - (1 + multiRefIdx);
+    ptrDst = refBufUnfiltered;
+    if (neighborFlags[totalLeftUnits])
+    {
+      ptrDst[0] = ptrSrc[0];
+      ptrDst[predStride] = ptrSrc[0];
+      for (int i = 1; i <= multiRefIdx; i++)
+      {
+        ptrDst[i] = ptrSrc[i];
+        ptrDst[i + predStride] = ptrSrc[i * srcStride];
+      }
+    }
+
+    // Fill left & below-left samples if available (downwards)
+    ptrSrc += (1 + multiRefIdx) * srcStride;
+    ptrDst += (1 + multiRefIdx) + predStride;
+    for (int unitIdx = totalLeftUnits - 1; unitIdx > 0; unitIdx--)
+    {
+      if (neighborFlags[unitIdx])
+      {
+        for (int i = 0; i < unitHeight; i++)
+        {
+          ptrDst[i] = ptrSrc[i * srcStride];
+        }
+      }
+      ptrSrc += unitHeight * srcStride;
+      ptrDst += unitHeight;
+    }
+    // Fill last below-left sample(s)
+    if (neighborFlags[0])
+    {
+      int lastSample = (predHSize % unitHeight == 0) ? unitHeight : predHSize % unitHeight;
+      for (int i = 0; i < lastSample; i++)
+      {
+        ptrDst[i] = ptrSrc[i * srcStride];
+      }
+    }
+
+    // Fill above & above-right samples if available (left-to-right)
+    ptrSrc = srcBuf - srcStride * (1 + multiRefIdx);
+    ptrDst = refBufUnfiltered + 1 + multiRefIdx;
+    for (int unitIdx = totalLeftUnits + 1; unitIdx < totalUnits - 1; unitIdx++)
+    {
+      if (neighborFlags[unitIdx])
+      {
+        for (int j = 0; j < unitWidth; j++)
+        {
+          ptrDst[j] = ptrSrc[j];
+        }
+      }
+      ptrSrc += unitWidth;
+      ptrDst += unitWidth;
+    }
+    // Fill last above-right sample(s)
+    if (neighborFlags[totalUnits - 1])
+    {
+      int lastSample = (predSize % unitWidth == 0) ? unitWidth : predSize % unitWidth;
+      for (int j = 0; j < lastSample; j++)
+      {
+        ptrDst[j] = ptrSrc[j];
+      }
+    }
+
+    // pad from first available down to the last below-left
+    ptrDst = refBufUnfiltered;
+    int lastAvailUnit = 0;
+    if (!neighborFlags[0])
+    {
+      int firstAvailUnit = 1;
+      while (firstAvailUnit < totalUnits && !neighborFlags[firstAvailUnit])
+      {
+        firstAvailUnit++;
+      }
+
+      // first available sample
+      int firstAvailRow = -1;
+      int firstAvailCol = 0;
+
+      if (firstAvailUnit < totalLeftUnits)
+      {
+        firstAvailRow = (totalLeftUnits - firstAvailUnit) * unitHeight + multiRefIdx;
+      }
+      else if (firstAvailUnit == totalLeftUnits)
+      {
+        firstAvailRow = multiRefIdx;
+      }
+      else
+      {
+        firstAvailCol = (firstAvailUnit - totalLeftUnits - 1) * unitWidth + 1 + multiRefIdx;
+      }
+
+      const Pel firstAvailSample = ptrDst[firstAvailRow < 0 ? firstAvailCol : firstAvailRow + predStride];
+
+      // last sample below-left (n.a.)
+      int lastRow = predHSize + multiRefIdx;
+
+      // fill left column
+      for (int i = lastRow; i > firstAvailRow; i--)
+      {
+        ptrDst[i + predStride] = firstAvailSample;
+      }
+      // fill top row
+      if (firstAvailCol > 0)
+      {
+        for (int j = 0; j < firstAvailCol; j++)
+        {
+          ptrDst[j] = firstAvailSample;
+        }
+      }
+      lastAvailUnit = firstAvailUnit;
+    }
+
+    // pad all other reference samples.
+    int currUnit = lastAvailUnit + 1;
+    while (currUnit < totalUnits)
+    {
+      if (!neighborFlags[currUnit]) // samples not available
+      {
+        // last available sample
+        int lastAvailRow = -1;
+        int lastAvailCol = 0;
+        if (lastAvailUnit < totalLeftUnits)
+        {
+          lastAvailRow = (totalLeftUnits - lastAvailUnit - 1) * unitHeight + multiRefIdx + 1;
+        }
+        else if (lastAvailUnit == totalLeftUnits)
+        {
+          lastAvailCol = multiRefIdx;
+        }
+        else
+        {
+          lastAvailCol = (lastAvailUnit - totalLeftUnits) * unitWidth + multiRefIdx;
+        }
+        const Pel lastAvailSample = ptrDst[lastAvailRow < 0 ? lastAvailCol : lastAvailRow + predStride];
+
+        // fill current unit with last available sample
+        if (currUnit < totalLeftUnits)
+        {
+          for (int i = lastAvailRow - 1; i >= lastAvailRow - unitHeight; i--)
+          {
+            ptrDst[i + predStride] = lastAvailSample;
+          }
+        }
+        else if (currUnit == totalLeftUnits)
+        {
+          for (int i = 0; i < multiRefIdx + 1; i++)
+          {
+            ptrDst[i + predStride] = lastAvailSample;
+          }
+          for (int j = 0; j < multiRefIdx + 1; j++)
+          {
+            ptrDst[j] = lastAvailSample;
+          }
+        }
+        else
+        {
+          int numSamplesInUnit = (currUnit == totalUnits - 1) ? ((predSize % unitWidth == 0) ? unitWidth : predSize % unitWidth) : unitWidth;
+          for (int j = lastAvailCol + 1; j <= lastAvailCol + numSamplesInUnit; j++)
+          {
+            ptrDst[j] = lastAvailSample;
+          }
+        }
+      }
+      lastAvailUnit = currUnit;
+      currUnit++;
+    }
+  }
+}
+#endif
+
 void IntraPrediction::xFilterReferenceSamples(const Pel *refBufUnfiltered, Pel *refBufFiltered, const CompArea &area,
                                               const SPS &sps, int multiRefIdx)
 {
@@ -9846,61 +10140,946 @@ void IntraPrediction::deriveDimdChromaMode(const CPelBuf &recoBufY, const CPelBu
 #if !JVET_AC0094_REF_SAMPLES_OPT
     buildHistogram(pRecoAboveY, iStrideY, 1, uiWidthAboveY, piHistogram, 2, uiWidthY, uiHeightY);
 #endif
-    buildHistogram(pRecoAboveCb, iStrideCb, 1, uiWidthAboveC, piHistogram, 2, uiWidthCb, uiHeightCb);
-    buildHistogram(pRecoAboveCr, iStrideCr, 1, uiWidthAboveC, piHistogram, 2, uiWidthCr, uiHeightCr);
-  }
-  if (numIntraLeft && numIntraAbove)
-  {
-#if !JVET_AC0094_REF_SAMPLES_OPT
-    const Pel *pRecoAboveLeftY = pRecoY - 2 - iStrideY * 2;
+    buildHistogram(pRecoAboveCb, iStrideCb, 1, uiWidthAboveC, piHistogram, 2, uiWidthCb, uiHeightCb);
+    buildHistogram(pRecoAboveCr, iStrideCr, 1, uiWidthAboveC, piHistogram, 2, uiWidthCr, uiHeightCr);
+  }
+  if (numIntraLeft && numIntraAbove)
+  {
+#if !JVET_AC0094_REF_SAMPLES_OPT
+    const Pel *pRecoAboveLeftY = pRecoY - 2 - iStrideY * 2;
+#endif
+    const Pel *pRecoAboveLeftCb = pRecoCb - 2 - iStrideCb * 2;
+    const Pel *pRecoAboveLeftCr = pRecoCr - 2 - iStrideCr * 2;
+#if !JVET_AC0094_REF_SAMPLES_OPT
+    buildHistogram(pRecoAboveLeftY, iStrideY, 2, 2, piHistogram, 3, uiWidthY, uiHeightY);
+#endif
+    buildHistogram(pRecoAboveLeftCb, iStrideCb, 2, 2, piHistogram, 3, uiWidthCb, uiHeightCb);
+    buildHistogram(pRecoAboveLeftCr, iStrideCr, 2, 2, piHistogram, 3, uiWidthCr, uiHeightCr);
+  }
+
+  int firstAmp = 0, secondAmp = 0, curAmp = 0;
+  int firstMode = 0, secondMode = 0, curMode = 0;
+
+  for (int i = 0; i < NUM_LUMA_MODE; i++)
+  {
+    curAmp = piHistogram[i];
+    curMode = i;
+    if (curAmp > firstAmp)
+    {
+      secondAmp = firstAmp;
+      secondMode = firstMode;
+      firstAmp = curAmp;
+      firstMode = curMode;
+    }
+    else
+    {
+      if (curAmp > secondAmp)
+      {
+        secondAmp = curAmp;
+        secondMode = curMode;
+      }
+    }
+  }
+
+  cu.dimdChromaMode = firstMode;
+#if JVET_AC0094_REF_SAMPLES_OPT
+  cu.dimdChromaModeSecond = secondMode;
+#else
+  int dmMode = PU::getCoLocatedIntraLumaMode(*cu.firstPU);
+  if (dmMode == firstMode)
+  {
+    cu.dimdChromaMode = secondMode;
+    if (firstMode == secondMode)
+    {
+      cu.dimdChromaMode = DC_IDX;
+    }
+  }
+#endif
+
+#if JVET_AH0136_CHROMA_REORDERING
+  if (CS::isDualITree(*cu.cs) && cu.cs->sps->getUseChromaReordering())
+  {
+    int amp[DIMD_FUSION_NUM - 1] = { 0 };
+    curAmp = 0;
+    int mode[DIMD_FUSION_NUM - 1] = { 0 };
+    curMode = 0;
+    for (int i = 0; i < NUM_LUMA_MODE; i++)
+    {
+      curAmp = piHistogram[i];
+      curMode = i;
+      for (int j = 0; j < DIMD_FUSION_NUM - 1; j++)
+      {
+        if (curAmp > amp[j])
+        {
+          for (int k = DIMD_FUSION_NUM - 2; k > j; k--)
+          {
+            amp[k] = amp[k - 1];
+            mode[k] = mode[k - 1];
+          }
+          amp[j] = curAmp;
+          mode[j] = curMode;
+          break;
+        }
+      }
+    }
+
+    for (int i = 0; i < 5; i++)
+    {
+      cu.dimdBlendModeChroma[i] = mode[i];
+    }
+  }
+#endif
+}
+#endif
+
+#if JVET_AH0136_CHROMA_REORDERING
+void IntraPrediction::deriveNonCcpChromaModes(const CPelBuf &recoBufY, const CPelBuf &recoBufCb, const CPelBuf &recoBufCr, const CompArea &areaY, const CompArea &areaCb, const CompArea &areaCr, CodingUnit &cu, PredictionUnit &pu, InterPrediction *pcInterPred)
+{
+  if (!CS::isDualITree(*pu.cs) || !pu.cs->sps->getUseChromaReordering())
+  {
+    return;
+  }
+
+  // save original info
+  int intraDir = pu.intraDir[1];
+
+  // construct collocated luma area
+  UnitArea area(CHROMA_420, areaY);
+  CodingUnit lumaCU(area);
+  PredictionUnit lumaPU(area);
+  lumaPU.cu = &lumaCU;
+  lumaCU.firstPU = &lumaPU;
+  lumaCU.cs = cu.cs;
+  lumaPU.cs = pu.cs;
+  lumaCU.slice = cu.slice;
+
+  // derive DBV info
+#if JVET_AC0071_DBV
+  PU::deriveChromaBv(pu);
+#endif
+
+  // build input list
+  static_vector<uint8_t, NUM_CHROMA_LIST_MODE> uiModeList;
+  static_vector<Distortion, NUM_CHROMA_LIST_MODE> uiCostList;
+  uint8_t chromaList[NUM_CHROMA_LIST_MODE];
+  int existNum = 0;
+  bool hasDBV = false;
+  buildChromaModeList(areaCb, cu, pu, chromaList, existNum, hasDBV);
+
+  // prepare luma pred indfo
+  int width = areaY.width;
+  int height = areaY.height;
+  const UnitArea localUnitAreaLuma(CHROMA_420, Area(0, 0, width, height));
+  PelBuf predY = m_tempBuffer[0].getBuf(localUnitAreaLuma.Y());
+  DistParam cDistParamSatd;
+  m_timdSatdCost->setDistParam(cDistParamSatd, recoBufY, predY, pu.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, true);
+  cDistParamSatd.applyWeight = false;
+  cDistParamSatd.useMR = false;
+
+  // prepare chroma pred info
+  int line = NUM_CHROMA_TM_LINES_IN_REORDERING;
+  const UnitArea localUnitAreaChroma(CHROMA_420, Area(0, 0, width + line * 2, height + line * 2));
+  PelBuf predCb = m_tempBuffer[0].getBuf(localUnitAreaChroma.Cb());
+  PelBuf predCr = m_tempBuffer[0].getBuf(localUnitAreaChroma.Cr());
+  int iRefX = 0;
+  int iRefY = 0;
+  uint32_t uiRefWidth = 0;
+  uint32_t uiRefHeight = 0;
+  TemplateType eTplType = CU::deriveTimdRefType(areaCb.x, areaCb.y, areaCb.width, areaCb.height, line, line, iRefX, iRefY, uiRefWidth, uiRefHeight);
+  const Pel* piCb = recoBufCb.buf;
+  int  iCbStride = recoBufCb.stride;
+  piCb += (iRefY - areaCb.y) * iCbStride + (iRefX - areaCb.x);
+  const Pel* piCr = recoBufCr.buf;
+  int  iCrStride = recoBufCr.stride;
+  piCr += (iRefY - areaCr.y) * iCrStride + (iRefX - areaCr.x);
+  const int channelBitDepth = pu.cu->cs->sps->getBitDepth(toChannelType(COMPONENT_Cb));
+  DistParam distParamSatd[2][2];   // above, left
+  distParamSatd[0][0].applyWeight = false;
+  distParamSatd[0][0].useMR = false;
+  distParamSatd[0][1].applyWeight = false;
+  distParamSatd[0][1].useMR = false;
+  distParamSatd[1][0].applyWeight = false;
+  distParamSatd[1][0].useMR = false;
+  distParamSatd[1][1].applyWeight = false;
+  distParamSatd[1][1].useMR = false;
+  if (eTplType == LEFT_ABOVE_NEIGHBOR)
+  {
+    m_timdSatdCost->setTimdDistParam(distParamSatd[0][0], piCb + line, predCb.buf + line, iCbStride, predCb.stride, channelBitDepth, COMPONENT_Cb, areaCb.width, line, 0, 1, false);
+    m_timdSatdCost->setTimdDistParam(distParamSatd[0][1], piCb + line * iCbStride, predCb.buf + line * predCb.stride, iCbStride, predCb.stride, channelBitDepth, COMPONENT_Cb, line, areaCb.height, 0, 1, false);
+    m_timdSatdCost->setTimdDistParam(distParamSatd[1][0], piCr + line, predCr.buf + line, iCrStride, predCr.stride, channelBitDepth, COMPONENT_Cr, areaCr.width, line, 0, 1, false);
+    m_timdSatdCost->setTimdDistParam(distParamSatd[1][1], piCr + line * iCrStride, predCr.buf + line * predCr.stride, iCrStride, predCr.stride, channelBitDepth, COMPONENT_Cr, line, areaCr.height, 0, 1, false);
+  }
+  else if (eTplType == LEFT_NEIGHBOR)
+  {
+    m_timdSatdCost->setTimdDistParam(distParamSatd[0][1], piCb, predCb.buf, iCbStride, predCb.stride, channelBitDepth, COMPONENT_Cb, line, areaCb.height, 0, 1, false);
+    m_timdSatdCost->setTimdDistParam(distParamSatd[1][1], piCr, predCr.buf, iCrStride, predCr.stride, channelBitDepth, COMPONENT_Cr, line, areaCr.height, 0, 1, false);
+  }
+  else if (eTplType == ABOVE_NEIGHBOR)
+  {
+    m_timdSatdCost->setTimdDistParam(distParamSatd[0][0], piCb, predCb.buf, iCbStride, predCb.stride, channelBitDepth, COMPONENT_Cb, areaCb.width, line, 0, 1, false);
+    m_timdSatdCost->setTimdDistParam(distParamSatd[1][0], piCr, predCr.buf, iCrStride, predCr.stride, channelBitDepth, COMPONENT_Cr, areaCr.width, line, 0, 1, false);
+  }
+
+  // early termination based on the first two costs
+  Distortion costPre[2] = { 0 };
+  int modePre[2] = { PLANAR_IDX };
+  int logW = floorLog2(areaCb.width);
+  int logH = floorLog2(areaCb.height);
+  int logN = floorLog2(NUM_CHROMA_TM_LINES_IN_REORDERING);
+
+  for (int i = 0; i < 2; i++)
+  {
+    int x = i;
+    if (hasDBV)
+    {
+      x = i == 0 ? 16 : 0;
+    }
+
+    Distortion cost = 0;
+    Distortion costL = 0;
+    Distortion costCbA = 0;
+    Distortion costCbL = 0;
+    Distortion costCrA = 0;
+    Distortion costCrL = 0;
+    bool isBad = false;
+
+    // pred co-located luma area
+    predCoLuma(areaY, recoBufY, lumaPU, chromaList[x], predY, pcInterPred, cu);
+
+    if (PU::isDbvMode(chromaList[x]))
+    {
+      int idx = chromaList[x] - DBV_CHROMA_IDX;
+      if (cu.mvs[idx] == Mv())
+      {
+        isBad = true;
+      }
+    }
+    costL += cDistParamSatd.distFunc(cDistParamSatd);
+    pu.intraDir[1] = chromaList[x];
+    if (eTplType != NO_NEIGHBOR)
+    {
+      // pred chroma TM
+      predChromaTM(areaCb, areaCr, pu, chromaList[x], predCb, predCr, eTplType, pcInterPred);
+      if (eTplType == LEFT_ABOVE_NEIGHBOR)
+      {
+        costCbA += distParamSatd[0][0].distFunc(distParamSatd[0][0]);
+        costCbL += distParamSatd[0][1].distFunc(distParamSatd[0][1]);
+        costCrA += distParamSatd[1][0].distFunc(distParamSatd[1][0]);
+        costCrL += distParamSatd[1][1].distFunc(distParamSatd[1][1]);
+        cost = 8 * costL + ((costCbA + costCrA) << (logH + 2 - logN)) + ((costCbL + costCrL) << (logW + 2 - logN));
+      }
+      else if (eTplType == LEFT_NEIGHBOR)
+      {
+        costCbL += distParamSatd[0][1].distFunc(distParamSatd[0][1]);
+        costCrL += distParamSatd[1][1].distFunc(distParamSatd[1][1]);
+        cost = 8 * costL + ((costCbL + costCrL) << (logW + 2 - logN));
+      }
+      else if (eTplType == ABOVE_NEIGHBOR)
+      {
+        costCbA += distParamSatd[0][0].distFunc(distParamSatd[0][0]);
+        costCrA += distParamSatd[1][0].distFunc(distParamSatd[1][0]);
+        cost = 8 * costL + ((costCbA + costCrA) << (logH + 2 - logN));
+      }
+      else
+      {
+        assert(0);
+      }
+    }
+    else
+    {
+      cost = costL;
+    }
+
+    pu.intraDir[1] = intraDir;
+
+    if (isBad)
+    {
+      cost = MAX_INT;
+    }
+    costPre[i] = cost;
+    modePre[i] = chromaList[x];
+  }
+  if (costPre[0] < costPre[1])
+  {
+#if JVET_AC0071_DBV
+    if (hasDBV)
+    {
+      for (uint32_t i = existNum - 1; i > 0; i--)
+      {
+        chromaList[i] = chromaList[i - 1];
+      }
+      chromaList[0] = DBV_CHROMA_IDX;
+    }
+#endif
+    for (uint32_t i = 0; i < existNum; i++)
+    {
+      cu.chromaList[i] = chromaList[i];
+    }
+    return;
+  }
+
+  for (int x = 0; x < NUM_CHROMA_LIST_MODE; x++)
+  {
+    if (chromaList[x] > DM_CHROMA_IDX)
+    {
+      continue;
+    }
+    if (chromaList[x] == modePre[0] || chromaList[x] == modePre[1])
+    {
+      updateCandList(chromaList[x], chromaList[x] == modePre[0] ? costPre[0] : costPre[1], uiModeList, uiCostList, existNum);
+      continue;
+    }
+    Distortion cost = 0;
+
+    Distortion costL = 0;
+    Distortion costCbA = 0;
+    Distortion costCbL = 0;
+    Distortion costCrA = 0;
+    Distortion costCrL = 0;
+    bool isBad = false;
+
+    // pred co-located luma area
+    predCoLuma(areaY, recoBufY, lumaPU, chromaList[x], predY, pcInterPred, cu);
+
+#if JVET_AC0071_DBV
+    if (PU::isDbvMode(chromaList[x]))
+    {
+      int idx = chromaList[x] - DBV_CHROMA_IDX;
+      if (cu.mvs[idx] == Mv())
+      {
+        isBad = true;
+      }
+    }
+#endif
+
+    costL += cDistParamSatd.distFunc(cDistParamSatd);
+
+    pu.intraDir[1] = chromaList[x];
+    if (eTplType != NO_NEIGHBOR)
+    {
+      // pred chroma TM
+      predChromaTM(areaCb, areaCr, pu, chromaList[x], predCb, predCr, eTplType, pcInterPred);
+
+      if (eTplType == LEFT_ABOVE_NEIGHBOR)
+      {
+        costCbA += distParamSatd[0][0].distFunc(distParamSatd[0][0]);
+        costCbL += distParamSatd[0][1].distFunc(distParamSatd[0][1]);
+
+        costCrA += distParamSatd[1][0].distFunc(distParamSatd[1][0]);
+        costCrL += distParamSatd[1][1].distFunc(distParamSatd[1][1]);
+        cost = 8 * costL + ((costCbA + costCrA) << (logH + 2 - logN)) + ((costCbL + costCrL) << (logW + 2 - logN));
+      }
+      else if (eTplType == LEFT_NEIGHBOR)
+      {
+        costCbL += distParamSatd[0][1].distFunc(distParamSatd[0][1]);
+        costCrL += distParamSatd[1][1].distFunc(distParamSatd[1][1]);
+        cost = 8 * costL + ((costCbL + costCrL) << (logW + 2 - logN));
+      }
+      else if (eTplType == ABOVE_NEIGHBOR)
+      {
+        costCbA += distParamSatd[0][0].distFunc(distParamSatd[0][0]);
+        costCrA += distParamSatd[1][0].distFunc(distParamSatd[1][0]);
+        cost = 8 * costL + ((costCbA + costCrA) << (logH + 2 - logN));
+      }
+      else
+      {
+        assert(0);
+      }
+    }
+    else
+    {
+      cost = costL;
+    }
+
+    pu.intraDir[1] = intraDir;
+
+    if (isBad)
+    {
+      cost = MAX_INT;
+    }
+
+    updateCandList(chromaList[x], cost, uiModeList, uiCostList, existNum);
+  }
+
+  for (uint32_t i = 0; i < existNum; i++)
+  {
+    cu.chromaList[i] = uiModeList[i];
+  }
+
+  // reste chroma mode
+  pu.intraDir[1] = intraDir;
+}
+
+void IntraPrediction::buildChromaModeList(const CompArea &area, CodingUnit &cu, PredictionUnit &pu, uint8_t chromaList[NUM_CHROMA_LIST_MODE], int &existNum, bool &hasDBV)
+{
+  // initialization
+  for (int i = 0; i < NUM_CHROMA_LIST_MODE; i++)
+  {
+    chromaList[i] = 255;
+  }
+
+  // get the orginal chroma mode list
+  int dmMode = PU::getCoLocatedIntraLumaMode(pu);
+  int startNum = 0;
+#if JVET_Z0050_DIMD_CHROMA_FUSION && ENABLE_DIMD
+  if (cu.slice->getSPS()->getUseDimd())
+  {
+    int dimdMode = cu.dimdChromaMode;
+    if (cu.dimdChromaMode == dmMode || cu.dimdChromaMode == HOR_IDX || cu.dimdChromaMode == VER_IDX)
+    {
+      int i = 1;
+      for (; i < 5; i++)
+      {
+        if (cu.dimdBlendModeChroma[i] == dmMode || cu.dimdBlendModeChroma[i] == HOR_IDX || cu.dimdBlendModeChroma[i] == VER_IDX)
+        {
+          continue;
+        }
+        break;
+      }
+      dimdMode = (i == 5) ? DC_IDX : cu.dimdBlendModeChroma[i];
+    }
+    chromaList[0] = dmMode;
+    chromaList[1] = dimdMode;
+    chromaList[2] = PLANAR_IDX;
+    chromaList[3] = DC_IDX;
+    chromaList[4] = HOR_IDX;
+    chromaList[5] = VER_IDX;
+    existNum = 6;
+    startNum = 2;
+  }
+  else
+#endif
+  {
+    chromaList[0] = dmMode;
+    chromaList[1] = PLANAR_IDX;
+    chromaList[2] = DC_IDX;
+    chromaList[3] = HOR_IDX;
+    chromaList[4] = VER_IDX;
+    existNum = 5;
+    startNum = 1;
+  }
+  bool hasMode[NUM_LUMA_MODE] = { false };
+  for (int i = startNum; i < existNum; i++)
+  {
+    if (chromaList[i] == dmMode)
+    {
+      chromaList[i] = VDIA_IDX;
+    }
+  }
+  for (int i = 0; i < existNum; i++)
+  {
+    hasMode[chromaList[i]] = true;
+  }
+
+  int addNum = 0;
+  // get co-located luma modes
+  CompArea lumaArea = CompArea(COMPONENT_Y, pu.chromaFormat, pu.Cb().lumaPos(), recalcSize(pu.chromaFormat, CHANNEL_TYPE_CHROMA, CHANNEL_TYPE_LUMA, pu.Cb().size()));
+  lumaArea = clipArea(lumaArea, pu.cs->picture->block(COMPONENT_Y));
+
+  Position posList[5] = { lumaArea.center(), lumaArea.topLeft(), lumaArea.topRight(), lumaArea.bottomLeft(), lumaArea.bottomRight() };
+  for (int n = 0; n < NUM_DBV_POSITION; n++)
+  {
+    const PredictionUnit *lumaPU = pu.cs->picture->cs->getPU(posList[n], CHANNEL_TYPE_LUMA);
+    int mode;
+    if (lumaPU->cu->timd || lumaPU->cu->tmrlFlag)
+    {
+      mode = MAP131TO67(PU::getIntraDirLuma(*lumaPU, 0));
+    }
+    else
+    {
+      mode = PU::getIntraDirLuma(*lumaPU, 0);
+    }
+    if (hasMode[mode] == false)
+    {
+      chromaList[6 + addNum] = mode;
+      hasMode[mode] = true;
+      addNum++;
+    }
+  }
+
+  // get neighboring modes
+  const Position posCand[5] =
+  {
+    pu.chromaPos().offset(-1, area.height - 1),
+    pu.chromaPos().offset(area.width - 1, -1),
+    pu.chromaPos().offset(-1, area.height),
+    pu.chromaPos().offset(area.width, -1),
+    pu.chromaPos().offset(-1, -1)
+  };
+
+  for (const Position &posLT : posCand)
+  {
+    const PredictionUnit* puRef = PU::getPUFromPos(pu, CHANNEL_TYPE_CHROMA, posLT);
+    if (puRef != nullptr && CU::isIntra(*puRef->cu) && !PU::isLMCMode(puRef->intraDir[1]) && !PU::isDbvMode(puRef->intraDir[1]))
+    {
+      int mode;
+      mode = puRef->intraDir[1];
+      if (hasMode[mode] == false)
+      {
+        chromaList[6 + addNum] = mode;
+        hasMode[mode] = true;
+        addNum++;
+      }
+    }
+  }
+
+#if JVET_AC0071_DBV
+  if (PU::hasChromaBvFlag(pu))
+  {
+    chromaList[16] = DBV_CHROMA_IDX;
+    existNum++;
+    hasDBV = true;
+    if (cu.mvsNum > 1)
+    {
+      for (int i = NUM_CHROMA_LIST_MODE - 9, j = 0; i < NUM_CHROMA_LIST_MODE && j < cu.mvsNum - 1; i++, j++)
+      {
+        chromaList[i] = DBV_CHROMA_IDX1 + j;
+      }
+    }
+  }
+#endif
+}
+
+void IntraPrediction::predCoLuma(const CompArea &area, const CPelBuf &recoBuf, PredictionUnit &pu, uint8_t predMode, PelBuf predBuf, InterPrediction *pcInterPred, CodingUnit &chromaCu)
+{
+  pu.intraDir[0] = predMode;
+
+#if JVET_AC0071_DBV
+  if (PU::isDbvMode(predMode))
+  {
+    pu.intraDir[1] = predMode;
+    int idx = predMode - DBV_CHROMA_IDX;
+    pu.mv[0] = chromaCu.mvs[idx];
+    pu.bv = chromaCu.bvs[idx];
+    pu.cu->rribcFlipType = chromaCu.rribcTypes[idx];
+    Mv mv = pu.mv[0];
+
+    bool isFracMv = pu.cs->sps->getIBCFracFlag() && mv.isFracMv<true>(pu.chromaFormat);
+    int xFrac = mv.hor & ((1 << MV_FRACTIONAL_BITS_INTERNAL) - 1);
+    int yFrac = mv.ver & ((1 << MV_FRACTIONAL_BITS_INTERNAL) - 1);
+    int xFilterTap = xFrac == 0 ? 0 : NTAPS_LUMA_IBC;
+    int yFilterTap = yFrac == 0 ? 0 : NTAPS_LUMA_IBC;
+    const uint32_t ctuSize = pu.cs->slice->getSPS()->getMaxCUWidth();
+    const int ctuSizeLog2 = floorLog2(ctuSize);
+    const int picWidth = pu.cs->slice->getPPS()->getPicWidthInLumaSamples();
+    const int picHeight = pu.cs->slice->getPPS()->getPicHeightInLumaSamples();
+    int xLumaBv = mv.hor >> MV_FRACTIONAL_BITS_INTERNAL;
+    int yLumaBv = mv.ver >> MV_FRACTIONAL_BITS_INTERNAL;
+    if (!PU::searchBv(pu, pu.blocks[COMPONENT_Y].x, pu.blocks[COMPONENT_Y].y, predBuf.width, predBuf.height, picWidth, picHeight, xLumaBv, yLumaBv, ctuSize, xFilterTap, yFilterTap, COMPONENT_Y))
+    {
+      isFracMv = false;
+    }
+    if (isFracMv)
+    {
+      PelUnitBuf pcBuf(pu.chromaFormat, predBuf, PelBuf(), PelBuf());
+      pcInterPred->getPredIBCBlk(pu, COMPONENT_Y, pu.cs->picture, mv, pcBuf);
+    }
+    else
+    {
+      const int bvShftHor = MV_FRACTIONAL_BITS_INTERNAL + ::getComponentScaleX(COMPONENT_Y, pu.chromaFormat);
+      const int bvShftVer = MV_FRACTIONAL_BITS_INTERNAL + ::getComponentScaleY(COMPONENT_Y, pu.chromaFormat);
+      int refx = pu.blocks[COMPONENT_Y].x + (mv.hor >> bvShftHor);
+      int refy = pu.blocks[COMPONENT_Y].y + (mv.ver >> bvShftVer);
+      int refStride = pu.cs->picture->getRecoBuf(COMPONENT_Y).stride;
+      Pel *ref = pu.cs->picture->getRecoBuf(COMPONENT_Y).buf;
+      Pel *refTarget = ref + refy * refStride + refx;
+      int iStride = predBuf.stride;
+      Pel *pred = predBuf.buf;
+      int iHeight = predBuf.height;
+      int iWidth = predBuf.width;
+      for (int uiY = 0; uiY < iHeight; uiY++)
+      {
+        for (int uiX = 0; uiX < iWidth; uiX++)
+        {
+          pred[uiX] = refTarget[uiX];
+        }
+        refTarget += refStride;
+        pred += iStride;
+      }
+
+      // padding
+      // left
+      if (refx < 0)
+      {
+        for (int j = 0; j < iHeight; j++)
+        {
+          for (int i = 0; i < -refx; i++)
+          {
+            pred[i + j * predBuf.stride] = pred[i - refx + j * predBuf.stride];
+          }
+        }
+        CHECK(refx != -1, "WRONG");
+      }
+      // above
+      if (refy < 0)
+      {
+        for (int j = 0; j < -refy; j++)
+        {
+          for (int i = 0; i < iWidth; i++)
+          {
+            pred[i + j * iStride] = pred[i + (j - refy) * iStride];
+          }
+        }
+        CHECK(refy != -1, "WRONG");
+      }
+      // bottom
+      bool isBottom = true;
+      if (refy + iHeight - 1 >= picHeight)
+      {
+        isBottom = false;
+      }
+      if (((refy + iHeight - 1) >> ctuSizeLog2) > (pu.blocks[COMPONENT_Y].y >> ctuSizeLog2)) // CTU
+      {
+        isBottom = false;
+      }
+      if ((((refx + iWidth - 1) >> ctuSizeLog2) > (pu.blocks[COMPONENT_Y].x >> ctuSizeLog2)) && (((refy + iHeight - 1) >> ctuSizeLog2) == (pu.blocks[COMPONENT_Y].y >> ctuSizeLog2)))
+      {
+        isBottom = false;
+      }
+      if (!isBottom)
+      {
+        for (int i = 0; i < iWidth; i++)
+        {
+          pred[i + (iHeight - 1) * predBuf.stride] = pred[i + (iHeight - 2) * predBuf.stride];
+        }
+      }
+      // right
+      bool isRight = true;
+      if (refx + iWidth - 1 >= picWidth)
+      {
+        isRight = false;
+      }
+      if ((((refx + iWidth - 1) >> ctuSizeLog2) > (pu.blocks[COMPONENT_Y].x >> ctuSizeLog2)) && (((refy + iHeight - 1) >> ctuSizeLog2) == (pu.blocks[COMPONENT_Y].y >> ctuSizeLog2)))
+      {
+        isRight = false;
+      }
+      if (!isRight)
+      {
+        for (int j = 0; j < iHeight; j++)
+        {
+          pred[iWidth - 1 + j * iStride] = pred[iWidth - 2 + j * iStride];
+        }
+      }
+
+    }
+    if (pu.cu->rribcFlipType)
+    {
+      predBuf.flipSignal(pu.cu->rribcFlipType == 1);
+    }
+
+    pu.bv.set(0, 0);
+    pu.mv[0].setZero();
+    pu.cu->rribcFlipType = 0;
+  }
+  else
+#endif
+  {
+    initPredIntraParams(pu, area, *pu.cs->sps, 0);
+    m_ipaParam.applyFusion = false;
+    m_leftRefLength = (area.height << 1);
+    m_topRefLength = (area.width << 1);
+    Pel *refBufUnfiltered = m_refBuffer[area.compID][PRED_BUF_UNFILTERED];
+    Pel *refBufFiltered = m_refBuffer[area.compID][PRED_BUF_FILTERED];
+    xFillReferenceSamplesForCoLuma(recoBuf, refBufUnfiltered, area, *pu.cu);
+    if (m_ipaParam.refFilterFlag)
+    {
+      xFilterReferenceSamples(refBufUnfiltered, refBufFiltered, area, *pu.cs->sps, 0);
+    }
+    predIntraAng(COMPONENT_Y, predBuf, pu, false);
+  }
+}
+
+void IntraPrediction::predChromaTM(const CompArea &areaCb, const CompArea &areaCr, PredictionUnit &pu, uint8_t predMode, PelBuf predCb, PelBuf predCr, TemplateType eTplType, InterPrediction *pcInterPred)
+{
+  pu.intraDir[1] = predMode;
+  int line = NUM_CHROMA_TM_LINES_IN_REORDERING;
+#if JVET_AC0071_DBV
+  if (PU::isDbvMode(predMode))
+  {
+    int idx = predMode - DBV_CHROMA_IDX;
+    Mv mv = pu.cu->mvs[idx];
+    pu.cu->rribcFlipType = pu.cu->rribcTypes[idx];
+    const CodingStructure &cs = *pu.cs;
+    Position posRT = pu.blocks[COMPONENT_Cb].topRight();
+    const PredictionUnit *puAbove = cs.getPURestricted(posRT.offset(0, -line), pu, CHANNEL_TYPE_CHROMA);
+    bool topCanUse = puAbove && pu.cu != puAbove->cu;
+    Position posLB = pu.blocks[COMPONENT_Cb].bottomLeft();
+    const PredictionUnit *puLeft = cs.getPURestricted(posLB.offset(-line, 0), pu, CHANNEL_TYPE_CHROMA);
+    bool leftCanUse = puLeft && pu.cu != puLeft->cu;
+#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
+    const int bvShiftHor = MV_FRACTIONAL_BITS_INTERNAL + ::getComponentScaleX(COMPONENT_Cb, pu.chromaFormat);
+    const int bvShiftVer = MV_FRACTIONAL_BITS_INTERNAL + ::getComponentScaleY(COMPONENT_Cb, pu.chromaFormat);
+#else
+    const int shiftSampleHor = ::getComponentScaleX(compId, pu.chromaFormat);
+    const int shiftSampleVer = ::getComponentScaleY(compId, pu.chromaFormat);
+#endif
+
+    CHECK(topCanUse == false && leftCanUse == false, "wrong type");
+
+    int filterIdx = 0;
+    CompArea area = pu.blocks[COMPONENT_Cb];
+    int uiHeight = area.height;
+    int uiWidth = area.width;
+
+    Pel tempCb[MAX_CU_SIZE * 4];
+    memset(tempCb, 0, MAX_CU_SIZE * 4 * sizeof(Pel));
+    Pel tempCr[MAX_CU_SIZE * 4];
+    memset(tempCr, 0, MAX_CU_SIZE * 4 * sizeof(Pel));
+    int stride = MAX_CU_SIZE;
+    Pel *refPixCb = tempCb;
+    Pel *refPixCr = tempCr;
+    Pel *refPixTempCb;
+    Pel *refPixTempCr;
+    const CPelBuf recBufCb = pu.cs->picture->getRecoBuf(pu.cs->picture->blocks[COMPONENT_Cb]);
+    const CPelBuf recBufCr = pu.cs->picture->getRecoBuf(pu.cs->picture->blocks[COMPONENT_Cr]);
+
+    Mv mvCurr = mv;
+    if (topCanUse)
+    {
+      Mv mvTop(0, -line);
+#if JVET_AA0070_RRIBC
+      if (pu.cu->rribcFlipType == 2)
+      {
+        mvTop.setVer(uiHeight);
+      }
+#endif
+#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
+      mvTop <<= bvShiftVer;
+#endif
+      mvTop += mvCurr;
+#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
+      if (!PU::checkIsChromaBvCandidateValidChromaTm(pu, mvTop, filterIdx, true, true))
+      {
+#if JVET_AA0070_RRIBC
+        if (pu.cu->rribcFlipType == 2)
+        {
+          mvTop.setVer(mvCurr.getVer() + ((uiHeight - line) << bvShiftVer));
+        }
+        else
+#endif
+        {
+          mvTop = mvCurr;
+        }
+      }
+#else
+#if JVET_AA0070_RRIBC
+      if (pu.cu->rribcFlipType == 2)
+      {
+        if (!PU::checkIsChromaBvCandidateValid(pu, mvTop, true, true))
+        {
+          mvTop.setVer(mvCurr.getVer() + uiHeight - line);
+        }
+      }
+      else
+#endif
+        if (!PU::checkIsChromaBvCandidateValid(pu, mvTop, true, true))
+        {
+          mvTop = mvCurr;
+        }
+#endif
+
+#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
+      bool isFracMv = pu.cs->sps->getIBCFracFlag() && mvTop.isFracMv<false>(pu.chromaFormat);
+      if (isFracMv)
+      {
+        PelUnitBuf pcBuf(pu.chromaFormat, PelBuf(), PelBuf(refPixCb, uiWidth, line), PelBuf(refPixCr, uiWidth, line));
+        pcInterPred->getPredIBCBlk(pu, COMPONENT_Cb, pu.cs->picture, mvTop, pcBuf, filterIdx == 1);
+        pcInterPred->getPredIBCBlk(pu, COMPONENT_Cr, pu.cs->picture, mvTop, pcBuf, filterIdx == 1);
+#if JVET_AA0070_RRIBC
+        pcBuf.bufs[COMPONENT_Cb].flip(pu.cu->rribcFlipType);
+        pcBuf.bufs[COMPONENT_Cr].flip(pu.cu->rribcFlipType);
+#endif
+      }
+      else
+      {
+#endif
+        refPixTempCb = refPixCb;
+        refPixTempCr = refPixCr;
+#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
+        const Pel *recCb = recBufCb.bufAt(pu.blocks[COMPONENT_Cb].pos().offset(mvTop.hor >> bvShiftHor, mvTop.ver >> bvShiftVer));
+        const Pel *recCr = recBufCr.bufAt(pu.blocks[COMPONENT_Cr].pos().offset(mvTop.hor >> bvShiftHor, mvTop.ver >> bvShiftVer));
+#else
+        const Pel *rec = recBuf.bufAt(pu.blocks[compId].pos().offset(mvTop.hor, mvTop.ver));
+#endif
+        for (int k = 0; k < uiWidth; k++)
+        {
+          for (int l = 0; l < line; l++)
+          {
+#if JVET_AA0070_RRIBC
+            int recValCb;
+            int recValCr;
+            if (pu.cu->rribcFlipType == 0)
+            {
+              recValCb = recCb[k + l * recBufCb.stride];
+              recValCr = recCr[k + l * recBufCr.stride];
+            }
+            else if (pu.cu->rribcFlipType == 1)
+            {
+              recValCb = recCb[uiWidth - 1 - k + l * recBufCb.stride];
+              recValCr = recCr[uiWidth - 1 - k + l * recBufCr.stride];
+            }
+            else
+            {
+              recValCb = recCb[k + (line - 1 - l) * recBufCb.stride];
+              recValCr = recCr[k + (line - 1 - l) * recBufCr.stride];
+            }
+#else
+            int recVal = rec[k + l * recBuf.stride];
+#endif
+            refPixTempCb[k + l * uiWidth] = recValCb;
+            refPixTempCr[k + l * uiWidth] = recValCr;
+          }
+        }
+#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
+      }
+#endif
+    }
+
+    if (leftCanUse)
+    {
+      Mv mvLeft(-line, 0);
+#if JVET_AA0070_RRIBC
+      if (pu.cu->rribcFlipType == 1)
+      {
+        mvLeft.setHor(uiWidth);
+      }
+#endif
+#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
+      mvLeft <<= bvShiftHor;
+#endif
+      mvLeft += mvCurr;
+#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
+      if (!PU::checkIsChromaBvCandidateValidChromaTm(pu, mvLeft, filterIdx, true, false))
+      {
+#if JVET_AA0070_RRIBC
+        if (pu.cu->rribcFlipType == 1)
+        {
+          mvLeft.setHor(mvCurr.getHor() + ((uiWidth - line) << bvShiftHor));
+        }
+        else
+#endif
+        {
+          mvLeft = mvCurr;
+        }
+      }
+#else
+#if JVET_AA0070_RRIBC
+      if (pu.cu->rribcFlipType == 1)
+      {
+        if (!PU::checkIsChromaBvCandidateValid(pu, mvLeft, true, false))
+        {
+          mvLeft.setHor(mvCurr.getHor() + uiWidth - DBV_TEMPLATE_SIZE);
+        }
+      }
+      else
+#endif
+        if (!PU::checkIsChromaBvCandidateValid(pu, mvLeft, true, false))
+        {
+          mvLeft = mvCurr;
+        }
+#endif
+#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
+      bool isFracMv = pu.cs->sps->getIBCFracFlag() && mvLeft.isFracMv<false>(pu.chromaFormat);
+      if (isFracMv)
+      {
+        PelUnitBuf pcBuf(pu.chromaFormat, PelBuf(), PelBuf(refPixCb + 2 * stride, line, uiHeight), PelBuf(refPixCr + 2 * stride, line, uiHeight));
+        pcInterPred->getPredIBCBlk(pu, COMPONENT_Cb, pu.cs->picture, mvLeft, pcBuf, filterIdx == 1);
+        pcInterPred->getPredIBCBlk(pu, COMPONENT_Cr, pu.cs->picture, mvLeft, pcBuf, filterIdx == 1);
+#if JVET_AA0070_RRIBC
+        pcBuf.bufs[COMPONENT_Cb].flip(pu.cu->rribcFlipType);
+        pcBuf.bufs[COMPONENT_Cr].flip(pu.cu->rribcFlipType);
+#endif
+      }
+      else
+      {
+#endif
+        refPixTempCb = refPixCb + 2 * stride;
+        refPixTempCr = refPixCr + 2 * stride;
+#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
+        const Pel *recCb = recBufCb.bufAt(pu.blocks[COMPONENT_Cb].pos().offset(mvLeft.hor >> bvShiftHor, mvLeft.ver >> bvShiftVer));
+        const Pel *recCr = recBufCr.bufAt(pu.blocks[COMPONENT_Cr].pos().offset(mvLeft.hor >> bvShiftHor, mvLeft.ver >> bvShiftVer));
+#else
+        const Pel *rec = recBuf.bufAt(pu.blocks[compId].pos().offset(mvLeft.hor, mvLeft.ver));
+#endif
+        for (int k = 0; k < uiHeight; k++)
+        {
+          for (int l = 0; l < line; l++)
+          {
+#if JVET_AA0070_RRIBC
+            int recValCb;
+            int recValCr;
+            if (pu.cu->rribcFlipType == 0)
+            {
+              recValCb = recCb[recBufCb.stride * k + l];
+              recValCr = recCr[recBufCr.stride * k + l];
+            }
+            else if (pu.cu->rribcFlipType == 1)
+            {
+              recValCb = recCb[recBufCb.stride * k + line - 1 - l];
+              recValCr = recCr[recBufCr.stride * k + line - 1 - l];
+            }
+            else
+            {
+              recValCb = recCb[recBufCb.stride * (uiHeight - 1 - k) + l];
+              recValCr = recCr[recBufCr.stride * (uiHeight - 1 - k) + l];
+            }
+#else
+            int recVal = rec[recBuf.stride * k + l];
 #endif
-    const Pel *pRecoAboveLeftCb = pRecoCb - 2 - iStrideCb * 2;
-    const Pel *pRecoAboveLeftCr = pRecoCr - 2 - iStrideCr * 2;
-#if !JVET_AC0094_REF_SAMPLES_OPT
-    buildHistogram(pRecoAboveLeftY, iStrideY, 2, 2, piHistogram, 3, uiWidthY, uiHeightY);
+            refPixTempCb[l + k * line] = recValCb;
+            refPixTempCr[l + k * line] = recValCr;
+          }
+        }
+#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
+      }
 #endif
-    buildHistogram(pRecoAboveLeftCb, iStrideCb, 2, 2, piHistogram, 3, uiWidthCb, uiHeightCb);
-    buildHistogram(pRecoAboveLeftCr, iStrideCr, 2, 2, piHistogram, 3, uiWidthCr, uiHeightCr);
-  }
-
-  int firstAmp = 0, secondAmp = 0, curAmp = 0;
-  int firstMode = 0, secondMode = 0, curMode = 0;
+    }
 
-  for (int i = 0; i < NUM_LUMA_MODE; i++)
-  {
-    curAmp = piHistogram[i];
-    curMode = i;
-    if (curAmp > firstAmp)
+    if (topCanUse && leftCanUse)
     {
-      secondAmp = firstAmp;
-      secondMode = firstMode;
-      firstAmp = curAmp;
-      firstMode = curMode;
+      for (int i = 0; i < uiWidth; i++)
+      {
+        predCb.at(line + i, 0) = tempCb[i];
+        predCr.at(line + i, 0) = tempCr[i];
+      }
+      for (int j = 0; j < uiHeight; j++)
+      {
+        predCb.at(0, line + j) = tempCb[2 * stride + j];
+        predCr.at(0, line + j) = tempCr[2 * stride + j];
+      }
     }
-    else
+
+    if (topCanUse)
     {
-      if (curAmp > secondAmp)
+      //top
+      for (int i = 0; i < uiWidth; i++)
       {
-        secondAmp = curAmp;
-        secondMode = curMode;
+        predCb.at(i, 0) = tempCb[i];
+        predCr.at(i, 0) = tempCr[i];
       }
     }
-  }
-
-  cu.dimdChromaMode = firstMode;
-#if JVET_AC0094_REF_SAMPLES_OPT
-  cu.dimdChromaModeSecond = secondMode;
-#else
-  int dmMode = PU::getCoLocatedIntraLumaMode(*cu.firstPU);
-  if (dmMode == firstMode)
-  {
-    cu.dimdChromaMode = secondMode;
-    if (firstMode == secondMode)
+    if (leftCanUse)
     {
-      cu.dimdChromaMode = DC_IDX;
+      for (int j = 0; j < uiHeight; j++)
+      {
+        predCb.at(0, j) = tempCb[2 * stride + j];
+        predCr.at(0, j) = tempCr[2 * stride + j];
+      }
     }
   }
+  else
 #endif
+  {
+    m_topRefLength = (areaCb.width + line) << 1;
+    m_leftRefLength = (areaCb.height + predMode) << 1;
+    xFillTimdReferenceSamples(pu.cs->picture->getRecoBuf(areaCb), m_refBuffer[COMPONENT_Cb][PRED_BUF_UNFILTERED], areaCb, *pu.cu, line, line);
+    initPredIntraParams(pu, areaCb, *(pu.cs->sps));
+    predTimdIntraAng(COMPONENT_Cb, pu, predMode, predCb.buf, predCb.stride, areaCb.width + line, areaCb.height + line, eTplType, line, line);
+
+    xFillTimdReferenceSamples(pu.cs->picture->getRecoBuf(areaCr), m_refBuffer[COMPONENT_Cr][PRED_BUF_UNFILTERED], areaCr, *pu.cu, line, line);
+    initPredIntraParams(pu, areaCr, *(pu.cs->sps));
+    predTimdIntraAng(COMPONENT_Cr, pu, predMode, predCr.buf, predCr.stride, areaCr.width + line, areaCr.height + line, eTplType, line, line);
+  }
 }
 #endif
 
@@ -21188,7 +22367,11 @@ void IntraPrediction::xCflmCreateLumaRef(const PredictionUnit& pu, const CompAre
   }
 }
 
-bool IntraPrediction::xCflmCreateChromaPred(const PredictionUnit& pu, const ComponentID compId, PelBuf& piPred)
+bool IntraPrediction::xCflmCreateChromaPred(const PredictionUnit& pu, const ComponentID compId, PelBuf& piPred
+#if JVET_AH0136_CHROMA_REORDERING
+  , InterPrediction *pcInterPred
+#endif
+)
 {
   uint32_t iMode = PU::getFinalIntraMode(pu, CHANNEL_TYPE_CHROMA);
 
@@ -21204,13 +22387,261 @@ bool IntraPrediction::xCflmCreateChromaPred(const PredictionUnit& pu, const Comp
     return false;
   }
 
+#if JVET_AH0136_CHROMA_REORDERING
+  Pel* piRefPred = refChroma.bufAt(0, 0);
+#endif
+
+#if JVET_AH0136_CHROMA_REORDERING && JVET_AC0071_DBV
+  if (PU::isDbvMode(iMode))
+  {
+    Mv mv = refineChromaBv(compId, pu, pcInterPred);
+
+    int tmpSize = 2;
+    const CodingStructure &cs = *pu.cs;
+    Position posRT = pu.blocks[compId].topRight();
+    const PredictionUnit *puAbove = cs.getPURestricted(posRT.offset(0, -2), pu, pu.chType);
+    bool topCanUse = puAbove && pu.cu != puAbove->cu;
+    Position posLB = pu.blocks[compId].bottomLeft();
+    const PredictionUnit *puLeft = cs.getPURestricted(posLB.offset(-2, 0), pu, pu.chType);
+    bool leftCanUse = puLeft && pu.cu != puLeft->cu;
+#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
+    const int bvShiftHor = MV_FRACTIONAL_BITS_INTERNAL + ::getComponentScaleX(compId, pu.chromaFormat);
+    const int bvShiftVer = MV_FRACTIONAL_BITS_INTERNAL + ::getComponentScaleY(compId, pu.chromaFormat);
+#else
+    const int shiftSampleHor = ::getComponentScaleX(compId, pu.chromaFormat);
+    const int shiftSampleVer = ::getComponentScaleY(compId, pu.chromaFormat);
+#endif
+    CHECK(topCanUse == false && leftCanUse == false, "wrong type");
+
+    int filterIdx = 0;
+    CompArea area = pu.blocks[compId];
+    int uiHeight = area.height;
+    int uiWidth = area.width;
+
+    Pel temp[MAX_CU_SIZE * 4];
+    memset(temp, 0, MAX_CU_SIZE * 4 * sizeof(Pel));
+    int stride = MAX_CU_SIZE;
+    Pel *refPix = temp;
+    Pel *refPixTemp;
+    const CPelBuf recBuf = pu.cs->picture->getRecoBuf(pu.cs->picture->blocks[compId]);
+
+    Mv mvCurr = mv;
+    if (topCanUse)
+    {
+      Mv mvTop(0, -tmpSize);
+#if JVET_AA0070_RRIBC
+      if (pu.cu->rribcFlipType == 2)
+      {
+        mvTop.setVer(uiHeight);
+      }
+#endif
+#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
+      mvTop <<= bvShiftVer;
+#endif
+      mvTop += mvCurr;
+#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
+      if (!PU::checkIsChromaBvCandidateValidChromaTm(pu, mvTop, filterIdx, true, true))
+      {
+#if JVET_AA0070_RRIBC
+        if (pu.cu->rribcFlipType == 2)
+        {
+          mvTop.setVer(mvCurr.getVer() + ((uiHeight - tmpSize) << bvShiftVer));
+        }
+        else
+#endif
+        {
+          mvTop = mvCurr;
+        }
+      }
+#else
+#if JVET_AA0070_RRIBC
+      if (pu.cu->rribcFlipType == 2)
+      {
+        if (!PU::checkIsChromaBvCandidateValid(pu, mvTop, true, true))
+        {
+          mvTop.setVer(mvCurr.getVer() + uiHeight - tmpSize);
+        }
+      }
+      else
+#endif
+        if (!PU::checkIsChromaBvCandidateValid(pu, mvTop, true, true))
+        {
+          mvTop = mvCurr;
+        }
+#endif
+
+#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
+      bool isFracMv = pu.cs->sps->getIBCFracFlag() && mvTop.isFracMv<false>(pu.chromaFormat);
+      if (isFracMv)
+      {
+        PelUnitBuf pcBuf(pu.chromaFormat, PelBuf(), PelBuf(refPix, uiWidth, tmpSize), PelBuf(refPix, uiWidth, tmpSize));
+        pcInterPred->getPredIBCBlk(pu, compId, pu.cs->picture, mvTop, pcBuf, filterIdx == 1);
+#if JVET_AA0070_RRIBC
+        pcBuf.bufs[compId].flip(pu.cu->rribcFlipType);
+#endif
+      }
+      else
+      {
+#endif
+        refPixTemp = refPix;
+#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
+        const Pel *rec = recBuf.bufAt(pu.blocks[compId].pos().offset(mvTop.hor >> bvShiftHor, mvTop.ver >> bvShiftVer));
+#else
+        const Pel *rec = recBuf.bufAt(pu.blocks[compId].pos().offset(mvTop.hor, mvTop.ver));
+#endif
+        for (int k = 0; k < uiWidth; k++)
+        {
+          for (int l = 0; l < tmpSize; l++)
+          {
+#if JVET_AA0070_RRIBC
+            int recVal;
+            if (pu.cu->rribcFlipType == 0)
+            {
+              recVal = rec[k + l * recBuf.stride];
+            }
+            else if (pu.cu->rribcFlipType == 1)
+            {
+              recVal = rec[uiWidth - 1 - k + l * recBuf.stride];
+            }
+            else
+            {
+              recVal = rec[k + (tmpSize - 1 - l) * recBuf.stride];
+            }
+#else
+            int recVal = rec[k + l * recBuf.stride];
+#endif
+            refPixTemp[k + l * uiWidth] = recVal;
+          }
+        }
+#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
+      }
+#endif
+    }
+
+    if (leftCanUse)
+    {
+      Mv mvLeft(-tmpSize, 0);
+#if JVET_AA0070_RRIBC
+      if (pu.cu->rribcFlipType == 1)
+      {
+        mvLeft.setHor(uiWidth);
+      }
+#endif
+#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
+      mvLeft <<= bvShiftHor;
+#endif
+      mvLeft += mvCurr;
+#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
+      if (!PU::checkIsChromaBvCandidateValidChromaTm(pu, mvLeft, filterIdx, true, false))
+      {
+#if JVET_AA0070_RRIBC
+        if (pu.cu->rribcFlipType == 1)
+        {
+          mvLeft.setHor(mvCurr.getHor() + ((uiWidth - tmpSize) << bvShiftHor));
+        }
+        else
+#endif
+        {
+          mvLeft = mvCurr;
+        }
+      }
+#else
+#if JVET_AA0070_RRIBC
+      if (pu.cu->rribcFlipType == 1)
+      {
+        if (!PU::checkIsChromaBvCandidateValid(pu, mvLeft, true, false))
+        {
+          mvLeft.setHor(mvCurr.getHor() + uiWidth - DBV_TEMPLATE_SIZE);
+        }
+      }
+      else
+#endif
+        if (!PU::checkIsChromaBvCandidateValid(pu, mvLeft, true, false))
+        {
+          mvLeft = mvCurr;
+        }
+#endif
+#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
+      bool isFracMv = pu.cs->sps->getIBCFracFlag() && mvLeft.isFracMv<false>(pu.chromaFormat);
+      if (isFracMv)
+      {
+        PelUnitBuf pcBuf(pu.chromaFormat, PelBuf(), PelBuf(refPix + 2 * stride, tmpSize, uiHeight), PelBuf(refPix + 2 * stride, tmpSize, uiHeight));
+        pcInterPred->getPredIBCBlk(pu, compId, pu.cs->picture, mvLeft, pcBuf, filterIdx == 1);
+#if JVET_AA0070_RRIBC
+        pcBuf.bufs[compId].flip(pu.cu->rribcFlipType);
+#endif
+      }
+      else
+      {
+#endif
+        refPixTemp = refPix + 2 * stride;
+#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
+        const Pel *rec = recBuf.bufAt(pu.blocks[compId].pos().offset(mvLeft.hor >> bvShiftHor, mvLeft.ver >> bvShiftVer));
+#else
+        const Pel *rec = recBuf.bufAt(pu.blocks[compId].pos().offset(mvLeft.hor, mvLeft.ver));
+#endif
+        for (int k = 0; k < uiHeight; k++)
+        {
+          for (int l = 0; l < tmpSize; l++)
+          {
+#if JVET_AA0070_RRIBC
+            int recVal;
+            if (pu.cu->rribcFlipType == 0)
+            {
+              recVal = rec[recBuf.stride * k + l];
+            }
+            else if (pu.cu->rribcFlipType == 1)
+            {
+              recVal = rec[recBuf.stride * k + tmpSize - 1 - l];
+            }
+            else
+            {
+              recVal = rec[recBuf.stride * (uiHeight - 1 - k) + l];
+            }
+#else
+            int recVal = rec[recBuf.stride * k + l];
+#endif
+            refPixTemp[l + k * tmpSize] = recVal;
+          }
+        }
+#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
+      }
+#endif
+    }
+
+    if (topCanUse)
+    {
+      //top
+      for (int i = 0; i < uiWidth; i++)
+      {
+        refChroma.at(refSizeX + i, 0) = temp[i];
+        refChroma.at(refSizeX + i, 1) = temp[uiWidth + i];
+      }
+    }
+    if (leftCanUse)
+    {
+      //left
+      for (int j = 0; j < uiHeight; j++)
+      {
+        refChroma.at(0, refSizeY + j) = temp[2 * stride + j * 2];
+        refChroma.at(1, refSizeY + j) = temp[2 * stride + j * 2 + 1];
+      }
+    }
+  }
+  else
+  {
+#endif
   m_topRefLength = areaWidth << 1;
   m_leftRefLength = areaHeight << 1;
   xFillTimdReferenceSamples(pu.cs->picture->getRecoBuf(area), m_refBuffer[compId][PRED_BUF_UNFILTERED], area, *pu.cu, refSizeX, refSizeY);
-
+#if !JVET_AH0136_CHROMA_REORDERING
   Pel* piRefPred = refChroma.bufAt(0, 0);
+#endif
   initPredIntraParams(pu, area, *(pu.cs->sps));
   predTimdIntraAng(compId, pu, iMode, piRefPred, refChroma.stride, areaWidth, areaHeight, eTplType, refSizeX, refSizeY);
+#if JVET_AH0136_CHROMA_REORDERING
+  }
+#endif
 
   // the PU reference areas
   PelBuf predChroma = xCflmGetPuBuf(pu, compId, area);
@@ -21224,6 +22655,12 @@ bool IntraPrediction::xCflmCreateChromaPred(const PredictionUnit& pu, const Comp
 
     piPredBuf += piPred.stride;
   }
+#if JVET_AH0136_CHROMA_REORDERING && JVET_AC0071_DBV
+  if (pu.cu->rribcFlipType != 0 && PU::isDbvMode(iMode))
+  {
+    predChroma.flipSignal(pu.cu->rribcFlipType == 1);
+  }
+#endif
 
 #if JVET_AB0174_CCCM_DIV_FREE
   int chromaOffset = 1 << (pu.cu->slice->getSPS()->getBitDepth(CHANNEL_TYPE_CHROMA) - 1);
diff --git a/source/Lib/CommonLib/IntraPrediction.h b/source/Lib/CommonLib/IntraPrediction.h
index d5549712cda3c7439c2b0adb958e91f6a8c7ab2b..2555acdfb1059bd102e131bd3fc09b5ec817e168 100644
--- a/source/Lib/CommonLib/IntraPrediction.h
+++ b/source/Lib/CommonLib/IntraPrediction.h
@@ -500,6 +500,9 @@ protected:
 #endif
 
   void xFillReferenceSamples      ( const CPelBuf &recoBuf,      Pel* refBufUnfiltered, const CompArea &area, const CodingUnit &cu );
+#if JVET_AH0136_CHROMA_REORDERING
+  void xFillReferenceSamplesForCoLuma(const CPelBuf &recoBuf, Pel* refBufUnfiltered, const CompArea &area, const CodingUnit &cu);
+#endif
   void xFilterReferenceSamples(const Pel *refBufUnfiltered, Pel *refBufFiltered, const CompArea &area, const SPS &sps,
                                int multiRefIdx
   );
@@ -664,7 +667,11 @@ public:
   void   xCflmCalcModels(const PredictionUnit& pu, const ComponentID compId, const CompArea& chromaArea, CccmModel& cflmModel, int modelId, int modelThr);
   void   xCflmApplyModel(const PredictionUnit& pu, const ComponentID compId, const CompArea& chromaArea, CccmModel& cflmModel, int modelId, int modelThr, PelBuf& piPred);
   void   xCflmCreateLumaRef       (const PredictionUnit& pu, const CompArea& chromaArea);
-  bool   xCflmCreateChromaPred    (const PredictionUnit& pu, const ComponentID compId, PelBuf& piPred);
+  bool   xCflmCreateChromaPred    (const PredictionUnit& pu, const ComponentID compId, PelBuf& piPred
+#if JVET_AH0136_CHROMA_REORDERING
+    , InterPrediction *pcInterPred
+#endif
+  );
   PelBuf xCflmGetRefBuf           (const PredictionUnit& pu, const ComponentID compId, const CompArea& chromaArea, int& areaWidth, int& areaHeight, int& refSizeX, int& refSizeY, int& refPosPicX, int& refPosPicY) const;
   PelBuf xCflmGetPuBuf            (const PredictionUnit& pu, const ComponentID compId, const CompArea& chromaArea) const;
   int    xCflmCalcRefAver         (const PredictionUnit& pu, const CompArea& chromaArea);
@@ -744,6 +751,12 @@ public:
   static void deriveDimdMode      (const CPelBuf &recoBuf, const CompArea &area, CodingUnit &cu);
 #if JVET_Z0050_DIMD_CHROMA_FUSION && ENABLE_DIMD
   static void deriveDimdChromaMode(const CPelBuf &recoBufY, const CPelBuf &recoBufCb, const CPelBuf &recoBufCr, const CompArea &areaY, const CompArea &areaCb, const CompArea &areaCr, CodingUnit &cu);
+#if JVET_AH0136_CHROMA_REORDERING
+   void deriveNonCcpChromaModes(const CPelBuf &recoBufY, const CPelBuf &recoBufCb, const CPelBuf &recoBufCr, const CompArea &areaY, const CompArea &areaCb, const CompArea &areaCr, CodingUnit &cu, PredictionUnit &pu, InterPrediction *pcInterPred);
+   void buildChromaModeList(const CompArea &area, CodingUnit &cu, PredictionUnit &pu, uint8_t chromaList[NUM_CHROMA_LIST_MODE], int &existNum, bool &hasDBV);
+   void predCoLuma(const CompArea &area, const CPelBuf &recoBuf, PredictionUnit &pu, uint8_t predMode, PelBuf predBuf, InterPrediction *pcInterPred, CodingUnit &chromaCu);
+   void predChromaTM(const CompArea &areaCb, const CompArea &areaCr, PredictionUnit &pu, uint8_t predMode, PelBuf predCb, PelBuf predCr, TemplateType eTplType, InterPrediction *pcInterPred);
+#endif
 #endif
 #if JVET_AB0067_MIP_DIMD_LFNST && ENABLE_DIMD
   static int deriveDimdMipMode(PelBuf& reducedPred, int width, int height, CodingUnit& cu);
@@ -980,7 +993,11 @@ public:
   void geneIntrainterPred         (const CodingUnit &cu, PelStorage& pred);
 #if JVET_Z0050_DIMD_CHROMA_FUSION
 #if JVET_AD0188_CCP_MERGE
-  void geneChromaFusionPred       (const ComponentID compId, PelBuf &piPred, PredictionUnit &pu);
+  void geneChromaFusionPred       (const ComponentID compId, PelBuf &piPred, PredictionUnit &pu
+#if JVET_AH0136_CHROMA_REORDERING
+    , InterPrediction *pcInterPred = NULL
+#endif
+  );
 #else
   void geneChromaFusionPred       (const ComponentID compId, PelBuf &piPred, const PredictionUnit &pu);
 #endif
diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp
index eb9c43a78b70fba84a9155a7f78a82e56ebe3ede..9b02bafe3dc73e111149c58e17994d7861f29a2e 100644
--- a/source/Lib/CommonLib/Slice.cpp
+++ b/source/Lib/CommonLib/Slice.cpp
@@ -3927,6 +3927,9 @@ SPS::SPS()
 #if JVET_AD0085_MPM_SORTING
 , m_mpmSorting                      ( false )
 #endif
+#if JVET_AH0136_CHROMA_REORDERING
+, m_chromaReordering                ( false )
+#endif
 #if JVET_AC0147_CCCM_NO_SUBSAMPLING
 , m_cccm                      ( false )
 #endif
diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h
index 5fcc7203fc153bb88ca8cc4bb071afddd0aae0df..b36f05e40bce68b13088e924546a26bff8dfb92a 100644
--- a/source/Lib/CommonLib/Slice.h
+++ b/source/Lib/CommonLib/Slice.h
@@ -1807,6 +1807,9 @@ private:
 #if JVET_AD0085_MPM_SORTING
   bool              m_mpmSorting;
 #endif
+#if JVET_AH0136_CHROMA_REORDERING
+  bool              m_chromaReordering;
+#endif
 #if JVET_AC0147_CCCM_NO_SUBSAMPLING
   int               m_cccm;
 #endif
@@ -2523,6 +2526,10 @@ void                    setCCALFEnabledFlag( bool b )
   void      setUseMpmSorting   (bool b)                                          { m_mpmSorting = b; }
   bool      getUseMpmSorting   ()                                      const     { return m_mpmSorting; }
 #endif
+#if JVET_AH0136_CHROMA_REORDERING
+  void      setUseChromaReordering(bool b)                                       { m_chromaReordering = b; }
+  bool      getUseChromaReordering()                                   const     { return m_chromaReordering; }
+#endif
 #if JVET_AC0147_CCCM_NO_SUBSAMPLING
   void      setUseCccm( int i )                                                  { m_cccm = i; }
   int       getUseCccm()                                               const     { return m_cccm; }
diff --git a/source/Lib/CommonLib/TrQuant.cpp b/source/Lib/CommonLib/TrQuant.cpp
index 13900446a6880807d540afd2ac26ed81a3a8c116..4c0b9d24ab785eb8122608a378560cb99e8288ce 100644
--- a/source/Lib/CommonLib/TrQuant.cpp
+++ b/source/Lib/CommonLib/TrQuant.cpp
@@ -544,7 +544,11 @@ void TrQuant::xInvLfnst( const TransformUnit &tu, const ComponentID compID )
     }
 #endif
 #if JVET_AC0071_DBV
+#if JVET_AH0136_CHROMA_REORDERING
+    if (compID != COMPONENT_Y && PU::isDbvMode(intraMode))
+#else
     if (compID != COMPONENT_Y && intraMode == DBV_CHROMA_IDX)
+#endif
     {
       intraMode = PLANAR_IDX;
     }
@@ -833,7 +837,11 @@ void TrQuant::xFwdLfnst( const TransformUnit &tu, const ComponentID compID, cons
     }
 #endif
 #if JVET_AC0071_DBV
+#if JVET_AH0136_CHROMA_REORDERING
+    if (compID != COMPONENT_Y && PU::isDbvMode(intraMode))
+#else
     if (compID != COMPONENT_Y && intraMode == DBV_CHROMA_IDX)
+#endif
     {
       intraMode = PLANAR_IDX;
     }
@@ -2735,7 +2743,11 @@ int TrQuant::getLfnstIdx(const TransformUnit &tu, ComponentID compID)
   }
 #endif
 #if JVET_AC0071_DBV
+#if JVET_AH0136_CHROMA_REORDERING
+  if (compID != COMPONENT_Y && PU::isDbvMode(intraMode))
+#else
   if (compID != COMPONENT_Y && intraMode == DBV_CHROMA_IDX)
+#endif
   {
     intraMode = PLANAR_IDX;
   }
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index de802deee3193771e44595d59284a59788a3b90a..b821550a2a64b619a3bc46c6dc741fbbf49ec9a9 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -206,6 +206,7 @@
 #define JVET_AG0059_CCP_MERGE_ENHANCEMENT                 1 // JVET-AG0059: Enhancements on CCP merge for chroma intra coding
 #define JVET_AH0065_RELAX_LINE_BUFFER                     1 // JVET-AH0065: Relaxing line buffer restriction
 #define JVET_AH0086_EIP_BIAS_AND_CLIP                     1 // JVET-AH0086: EIP with bias and clipping
+#define JVET_AH0136_CHROMA_REORDERING                     1 // JVET-AH0136: Non-CCP intra chroma mode reordering
 
 //IBC
 #define JVET_Y0058_IBC_LIST_MODIFY                        1 // JVET-Y0058: Modifications of IBC merge/AMVP list construction, ARMC-TM-IBC part is included under JVET_W0090_ARMC_TM
diff --git a/source/Lib/CommonLib/Unit.cpp b/source/Lib/CommonLib/Unit.cpp
index a051d7c6593269d51b36610c5f7065c178c51376..d8f975f3430ab23582ea3caa79e0687475e93d6e 100644
--- a/source/Lib/CommonLib/Unit.cpp
+++ b/source/Lib/CommonLib/Unit.cpp
@@ -345,6 +345,23 @@ CodingUnit& CodingUnit::operator=( const CodingUnit& other )
   }
 #endif
 #endif
+#if JVET_AH0136_CHROMA_REORDERING
+  for (uint32_t i = 0; i < 7; i++)
+  {
+    chromaList[i] = other.chromaList[i];
+  }
+  for (int i = 0; i < 5; i++)
+  {
+    dimdBlendModeChroma[i] = other.dimdBlendModeChroma[i];
+  }
+  for (int i = 0; i < 10; i++)
+  {
+    mvs[i] = other.mvs[i];
+    bvs[i] = other.bvs[i];
+    rribcTypes[i] = other.rribcTypes[i];
+  }
+  mvsNum = other.mvsNum;
+#endif
 #if TMP_FAST_ENC
 #if JVET_AD0086_ENHANCED_INTRA_TMP
 #if (JVET_AG0146_DIMD_ITMP_IBC || JVET_AG0152_SGPM_ITMP_IBC || JVET_AG0151_INTRA_TMP_MERGE_MODE)
@@ -602,6 +619,23 @@ void CodingUnit::initData()
   }
 #endif
 #endif
+#if JVET_AH0136_CHROMA_REORDERING
+  for (uint32_t i = 0; i < 7; i++)
+  {
+    chromaList[i] = -1;
+  }
+  for (int i = 0; i < 5; i++)
+  {
+    dimdBlendModeChroma[i] = -1;
+  }
+  for (int i = 0; i < 10; i++)
+  {
+    mvs[i].setZero();
+    bvs[i].setZero();
+    rribcTypes[i] = 0;
+  }
+  mvsNum = 0;
+#endif
 #if TMP_FAST_ENC
 #if JVET_AD0086_ENHANCED_INTRA_TMP
 #if (JVET_AG0146_DIMD_ITMP_IBC || JVET_AG0152_SGPM_ITMP_IBC || JVET_AG0151_INTRA_TMP_MERGE_MODE)
diff --git a/source/Lib/CommonLib/Unit.h b/source/Lib/CommonLib/Unit.h
index 769b3c2b2a78b4bb9bc6b1415f8a144b1d5b6123..fe9893ecbc3443d99650afd7c2df867d5781aa04 100644
--- a/source/Lib/CommonLib/Unit.h
+++ b/source/Lib/CommonLib/Unit.h
@@ -362,6 +362,14 @@ struct CodingUnit : public UnitArea
   int8_t         dimdRelWeight[3]; // max number of predictions to blend
 #endif
 #endif
+#if JVET_AH0136_CHROMA_REORDERING
+  int8_t         dimdBlendModeChroma[DIMD_FUSION_NUM - 1];
+  uint8_t        chromaList[7];
+  Mv             mvs[10];
+  Mv             bvs[10];
+  int            rribcTypes[10];
+  int            mvsNum;
+#endif
 #if TMP_FAST_ENC
 #if JVET_AD0086_ENHANCED_INTRA_TMP
 #if (JVET_AG0146_DIMD_ITMP_IBC || JVET_AG0152_SGPM_ITMP_IBC || JVET_AG0151_INTRA_TMP_MERGE_MODE)
@@ -546,7 +554,7 @@ struct CodingUnit : public UnitArea
 
 struct IntraPredictionData
 {
-#if ENABLE_DIMD || JVET_W0123_TIMD_FUSION
+#if ENABLE_DIMD || JVET_W0123_TIMD_FUSION || JVET_AH0136_CHROMA_REORDERING
   bool      parseLumaMode = false;
   int8_t    candId = -1;
   bool      parseChromaMode = false;
diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp
index 147f66589eaacacdee75b4bbcbfa33a46cda6fa6..7fbb092d8c3fcf92179d8ab86e0763b446644afc 100644
--- a/source/Lib/CommonLib/UnitTools.cpp
+++ b/source/Lib/CommonLib/UnitTools.cpp
@@ -3066,7 +3066,14 @@ bool PU::hasChromaFusionFlag(const PredictionUnit &pu, int intraMode)
   bool hasChromaFusionFlag = pu.cs->slice->getSliceType() == I_SLICE;
 #endif
 #if JVET_AC0071_DBV && JVET_AC0119_LM_CHROMA_FUSION
-  hasChromaFusionFlag &= intraMode != DBV_CHROMA_IDX;
+#if JVET_AH0136_CHROMA_REORDERING
+  if (!pu.cs->sps->getUseChromaReordering())
+  {
+#endif
+    hasChromaFusionFlag &= intraMode != DBV_CHROMA_IDX;
+#if JVET_AH0136_CHROMA_REORDERING
+  }
+#endif
 #endif
 #if JVET_AC0119_LM_CHROMA_FUSION
   hasChromaFusionFlag &= PU::isLMCModeEnabled(pu, LM_CHROMA_IDX);
@@ -4913,6 +4920,35 @@ uint32_t PU::getIntraDirLuma( const PredictionUnit &pu )
 
 void PU::getIntraChromaCandModes(const PredictionUnit &pu, unsigned modeList[NUM_CHROMA_MODE])
 {
+#if JVET_AH0136_CHROMA_REORDERING
+  if (CS::isDualITree(*pu.cs) && pu.cs->sps->getUseChromaReordering())
+  {
+    modeList[0] = LM_CHROMA_IDX;
+    modeList[1] = MDLM_L_IDX;
+    modeList[2] = MDLM_T_IDX;
+#if MMLM
+    modeList[3] = MMLM_CHROMA_IDX;
+    modeList[4] = MMLM_L_IDX;
+    modeList[5] = MMLM_T_IDX;
+    modeList[6] = pu.cu->chromaList[0];
+    modeList[7] = pu.cu->chromaList[1];
+    modeList[8] = pu.cu->chromaList[2];
+    modeList[9] = pu.cu->chromaList[3];
+    modeList[10] = pu.cu->chromaList[4];
+    modeList[11] = pu.cu->chromaList[5];
+    modeList[12] = pu.cu->chromaList[6];
+#else
+    modeList[3] = pu.cu->chromaList[0];
+    modeList[4] = pu.cu->chromaList[1];
+    modeList[5] = pu.cu->chromaList[2];
+    modeList[6] = pu.cu->chromaList[3];
+    modeList[7] = pu.cu->chromaList[4];
+    modeList[8] = pu.cu->chromaList[5];
+    modeList[9] = pu.cu->chromaList[6];
+#endif
+    return;
+}
+#endif
   modeList[0] = PLANAR_IDX;
   modeList[1] = VER_IDX;
   modeList[2] = HOR_IDX;
@@ -5100,7 +5136,11 @@ uint32_t PU::getFinalIntraMode( const PredictionUnit &pu, const ChannelType &chT
   }
 #endif
 #if JVET_AC0071_DBV
+#if JVET_AH0136_CHROMA_REORDERING
+  if ((pu.cs->sps->getUseChromaReordering() && CS::isDualITree(*pu.cs) && (PU::isDbvMode(pu.intraDir[1]) && !isLuma(chType) && pu.cu->mvs[pu.intraDir[1] - DBV_CHROMA_IDX] == Mv())) || ((!CS::isDualITree(*pu.cs) || !pu.cs->sps->getUseChromaReordering()) && uiIntraMode == DBV_CHROMA_IDX && !isLuma(chType) && pu.bv == Mv()))
+#else
   if (uiIntraMode == DBV_CHROMA_IDX && !isLuma(chType) && pu.bv == Mv())
+#endif
   {
     uiIntraMode = PLANAR_IDX;
   }
@@ -5166,6 +5206,16 @@ uint32_t PU::getCoLocatedIntraLumaMode(const PredictionUnit &pu)
 #endif
 
 #if JVET_AC0071_DBV
+#if JVET_AH0136_CHROMA_REORDERING
+bool PU::isDbvMode(int mode)
+{
+  if (mode >= DBV_CHROMA_IDX && mode <= DBV_CHROMA_IDX9)
+  {
+    return true;
+  }
+  return false;
+}
+#endif
 bool PU::dbvModeAvail(const PredictionUnit &pu)
 {
 #if JVET_AF0066_ENABLE_DBV_4_SINGLE_TREE
@@ -5200,6 +5250,12 @@ void PU::deriveChromaBv(PredictionUnit &pu)
   {
     return;
   }
+#endif
+#if JVET_AH0136_CHROMA_REORDERING
+  if (!pu.cs->sps->getUseIntraDBV())
+  {
+    return;
+  }
 #endif
   pu.bv.set(0, 0);
 #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
@@ -5219,6 +5275,9 @@ void PU::deriveChromaBv(PredictionUnit &pu)
   lumaArea = clipArea(lumaArea, pu.cs->picture->block(COMPONENT_Y));
 
   Position posList[5] = { lumaArea.center(), lumaArea.topLeft(), lumaArea.topRight(), lumaArea.bottomLeft(), lumaArea.bottomRight() };
+#if JVET_AH0136_CHROMA_REORDERING
+  int cnt = 0;
+#endif
   for (int n = 0; n < NUM_DBV_POSITION; n++)
   {
     const PredictionUnit *lumaPU = pu.cs->picture->cs->getPU(posList[n], CHANNEL_TYPE_LUMA);
@@ -5243,18 +5302,43 @@ void PU::deriveChromaBv(PredictionUnit &pu)
       if (PU::checkIsChromaBvCandidateValid(pu, chromaBv))
 #endif
       {
-        pu.bv = lumaBv;
+#if JVET_AH0136_CHROMA_REORDERING
+        if (pu.cs->sps->getUseChromaReordering())
+        {
+          pu.cu->bvs[cnt] = lumaBv;
+          pu.cu->bvs[cnt].changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_INT);
+          pu.cu->mvs[cnt] = lumaBv;
+          pu.cu->rribcTypes[cnt] = lumaPU->cu->rribcFlipType;
+          cnt++;
+          if (cnt - 1 > 0)
+          {
+            for (int i = 0; i < cnt - 1; i++)
+            {
+              if (pu.cu->mvs[i] == lumaBv)
+              {
+                cnt--;
+              }
+            }
+          }
+        }
+        else
+        {
+#endif
+          pu.bv = lumaBv;
 #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
-        pu.bv.changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_INT);
-        pu.mv[0] = lumaBv;
+          pu.bv.changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_INT);
+          pu.mv[0] = lumaBv;
 #endif
 #if JVET_AA0070_RRIBC
-        pu.cu->rribcFlipType = lumaPU->cu->rribcFlipType;
+          pu.cu->rribcFlipType = lumaPU->cu->rribcFlipType;
 #endif
 #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
-        pu.intraDir[1] = bkIntraDir;
+          pu.intraDir[1] = bkIntraDir;
+#endif
+          return;
+#if JVET_AH0136_CHROMA_REORDERING
+        }
 #endif
-        return;
       }
 #if JVET_AE0169_BIPREDICTIVE_IBC
       if (CU::isIBC(*lumaPU->cu) && lumaPU->interDir == 3)
@@ -5273,13 +5357,38 @@ void PU::deriveChromaBv(PredictionUnit &pu)
         if (PU::checkIsChromaBvCandidateValid(pu, chromaBv))
 #endif
         {
+#if JVET_AH0136_CHROMA_REORDERING
+          if (pu.cs->sps->getUseChromaReordering())
+          {
+            pu.cu->bvs[cnt] = lumaBv;
+            pu.cu->bvs[cnt].changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_INT);
+            pu.cu->mvs[cnt] = lumaBv;
+            pu.cu->rribcTypes[cnt] = lumaPU->cu->rribcFlipType;
+            cnt++;
+            if (cnt - 1 > 0)
+            {
+              for (int i = 0; i < cnt - 1; i++)
+              {
+                if (pu.cu->mvs[i] == lumaBv)
+                {
+                  cnt--;
+                }
+              }
+            }
+          }
+          else
+          {
+#endif
 #if JVET_AA0070_RRIBC
-          pu.cu->rribcFlipType = lumaPU->cu->rribcFlipType;
+            pu.cu->rribcFlipType = lumaPU->cu->rribcFlipType;
 #endif
 #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
-          pu.intraDir[1] = bkIntraDir;
+            pu.intraDir[1] = bkIntraDir;
+#endif
+            return;
+#if JVET_AH0136_CHROMA_REORDERING
+          }
 #endif
-          return;
         }
       }
 #endif
@@ -5288,6 +5397,9 @@ void PU::deriveChromaBv(PredictionUnit &pu)
 #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
   pu.intraDir[1] = bkIntraDir;
 #endif
+#if JVET_AH0136_CHROMA_REORDERING
+  pu.cu->mvsNum = cnt;
+#endif
 }
 
 #if JVET_AA0070_RRIBC
@@ -5399,6 +5511,44 @@ bool PU::checkIsChromaBvCandidateValid(const PredictionUnit &pu
 }
 #endif
 
+#if JVET_AH0136_CHROMA_REORDERING
+bool PU::checkIsChromaBvCandidateValidChromaTm(const PredictionUnit &pu, const Mv mv, int filterIdx, bool isRefTemplate, bool isRefAbove)
+{
+#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
+  int roiWidth = (isRefTemplate && !isRefAbove) ? 2 : pu.Cb().width;
+  int roiHeight = (isRefTemplate && isRefAbove) ? 2 : pu.Cb().height;
+  uint32_t validType = checkValidBv(pu, COMPONENT_Cb, roiWidth, roiHeight, mv, true, filterIdx);
+  return validType != IBC_BV_INVALID;
+#else
+  const int cuPelX = pu.Cb().x;
+  const int cuPelY = pu.Cb().y;
+  int roiWidth = (isRefTemplate && !isRefAbove) ? DBV_TEMPLATE_SIZE : pu.Cb().width;
+  int roiHeight = (isRefTemplate && isRefAbove) ? DBV_TEMPLATE_SIZE : pu.Cb().height;
+  int xPred = chromaBv.getHor();
+  int yPred = chromaBv.getVer();
+  if ((xPred + roiWidth) > 0 && (yPred + roiHeight) > 0)
+  {
+    return false;
+  }
+  int refRightX = cuPelX + xPred + roiWidth - 1;
+  int refLeftX = cuPelX + xPred;
+  int refBottomY = cuPelY + yPred + roiHeight - 1;
+  int refTopY = cuPelY + yPred;
+  const Position refPosLT(refLeftX, refTopY);
+  const Position refPosBR(refRightX, refBottomY);
+  if (!pu.cs->isDecomp(refPosBR, pu.chType))
+  {
+    return false;
+  }
+  if (!pu.cs->isDecomp(refPosLT, pu.chType))
+  {
+    return false;
+  }
+  return true;
+#endif
+}
+#endif
+
 int PU::getWideAngle( const TransformUnit &tu, const uint32_t dirMode, const ComponentID compID )
 {
   //This function returns a wide angle index taking into account that the values 0 and 1 are reserved
@@ -8070,8 +8220,20 @@ bool PU::searchBv(const PredictionUnit& pu, int xPos, int yPos, int width, int h
 
 #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
 #if JVET_AC0071_DBV
-  const bool isDBV     = (pu.cs->slice->getSliceType() == I_SLICE && CS::isDualITree(*pu.cs) && pu.cu->slice->getSPS()->getUseIntraDBV())
-                      && compID != COMPONENT_Y && pu.intraDir[1] == DBV_CHROMA_IDX;
+  const bool isDBV = (pu.cs->slice->getSliceType() == I_SLICE && CS::isDualITree(*pu.cs) && pu.cu->slice->getSPS()->getUseIntraDBV())
+    && compID != COMPONENT_Y &&
+#if JVET_AH0136_CHROMA_REORDERING
+    PU::isDbvMode(pu.intraDir[1]);
+#else
+    pu.intraDir[1] == DBV_CHROMA_IDX;
+#endif
+#endif
+#if JVET_AH0136_CHROMA_REORDERING && JVET_AC0071_DBV
+  bool isLumaDbv = false;
+  if (pu.cs->sps->getUseChromaReordering() && compID == COMPONENT_Y && PU::isDbvMode(pu.intraDir[1]) && CS::isDualITree(*pu.cs))
+  {
+    isLumaDbv = true;
+  }
 #endif
   const int szShiftHor = ::getComponentScaleX(compID, pu.chromaFormat);
   const int szShiftVer = ::getComponentScaleY(compID, pu.chromaFormat);
@@ -8134,6 +8296,20 @@ bool PU::searchBv(const PredictionUnit& pu, int xPos, int yPos, int width, int h
   {
     return false;
   }
+#if JVET_AH0136_CHROMA_REORDERING && JVET_AC0071_DBV
+  if (isLumaDbv)
+  {
+    if (refBottomY >> ctuSizeLog2 > yPos >> ctuSizeLog2)
+    {
+      return false;
+    }
+    if ((refRightX >> ctuSizeLog2 > xPos >> ctuSizeLog2) && (refBottomY >> ctuSizeLog2 == yPos >> ctuSizeLog2))
+    {
+      return false;
+    }
+    return true;
+  }
+#endif
 #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
   if (refRightX >= xPos && refBottomY >= yPos)
 #else
@@ -29349,7 +29525,13 @@ uint32_t PU::getFinalIntraModeForTransform( const TransformUnit &tu, const Compo
   }
 #endif
 #if JVET_AC0071_DBV
-  if (compID != COMPONENT_Y && intraMode == DBV_CHROMA_IDX)
+  if (compID != COMPONENT_Y 
+#if JVET_AH0136_CHROMA_REORDERING
+    && PU::isDbvMode(intraMode)
+#else
+    && intraMode == DBV_CHROMA_IDX
+#endif
+    )
   {
     intraMode = PLANAR_IDX;
   }
diff --git a/source/Lib/CommonLib/UnitTools.h b/source/Lib/CommonLib/UnitTools.h
index 7e0a4430109af9c8de4d2c1d310300bf9baa4aac..35cdbbcee34dcfe8f35cab6837ad0c2fd4a28a48 100644
--- a/source/Lib/CommonLib/UnitTools.h
+++ b/source/Lib/CommonLib/UnitTools.h
@@ -274,6 +274,9 @@ namespace PU
   uint32_t getCoLocatedIntraLumaMode      (const PredictionUnit &pu);
 #endif
 #if JVET_AC0071_DBV
+#if JVET_AH0136_CHROMA_REORDERING
+  bool isDbvMode(int mode);
+#endif
   bool dbvModeAvail(const PredictionUnit &pu);
   void deriveChromaBv(PredictionUnit &pu);
 #if JVET_AA0070_RRIBC
@@ -292,6 +295,9 @@ namespace PU
                                    , const Mv chromaBv
 #endif
                                    , bool isRefTemplate = false, bool isRefAbove = false);
+#endif
+#if JVET_AH0136_CHROMA_REORDERING
+  bool checkIsChromaBvCandidateValidChromaTm(const PredictionUnit &pu, const Mv mv, int filterIdx = 0, bool isRefTemplate = false, bool isRefAbove = false);
 #endif
   int      getWideAngle                   ( const TransformUnit &tu, const uint32_t dirMode, const ComponentID compID );
 #if MULTI_PASS_DMVR || JVET_W0097_GPM_MMVD_TM
diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp
index 330d73b106c825e8dc08dbec5c50053e96bc6920..50eb0a7b98275837ebe8182d0cdb75ade821af36 100644
--- a/source/Lib/DecoderLib/CABACReader.cpp
+++ b/source/Lib/DecoderLib/CABACReader.cpp
@@ -2923,10 +2923,14 @@ void CABACReader::intra_chroma_pred_mode(PredictionUnit& pu)
       pu.intraDir[1] = DBV_CHROMA_IDX;
       if (PU::hasChromaFusionFlag(pu, pu.intraDir[1]))
       {
+#if JVET_AH0136_CHROMA_REORDERING
+        intraChromaFusionMode(pu);
+#else
         if (m_BinDecoder.decodeBin(Ctx::ChromaFusionMode()) == 1)
         {
           pu.isChromaFusion = true;
         }
+#endif
       }
       DTRACE(g_trace_ctx, D_SYNTAX, "intra_chroma_pred_modes() pos=(%d,%d) dir=%d\n",
         pu.blocks[CHANNEL_TYPE_CHROMA].x, pu.blocks[CHANNEL_TYPE_CHROMA].y, pu.intraDir[CHANNEL_TYPE_CHROMA]);
@@ -2998,7 +3002,10 @@ void CABACReader::intra_chroma_pred_mode(PredictionUnit& pu)
 #endif
   }
 #endif
-
+#if JVET_AH0136_CHROMA_REORDERING
+  pu.intraDir[1] = PLANAR_IDX;
+  pu.candId = candId;
+#else
   unsigned chromaCandModes[NUM_CHROMA_MODE];
   PU::getIntraChromaCandModes(pu, chromaCandModes);
 
@@ -3013,6 +3020,7 @@ void CABACReader::intra_chroma_pred_mode(PredictionUnit& pu)
 #if ENABLE_DIMD || JVET_W0123_TIMD_FUSION
   pu.candId = candId;
 #endif
+#endif
 }
 
 void CABACReader::cu_residual( CodingUnit& cu, Partitioner &partitioner, CUCtx& cuCtx )
diff --git a/source/Lib/DecoderLib/DecCu.cpp b/source/Lib/DecoderLib/DecCu.cpp
index 13a54cf83a5252bc6c8371d97fed1165182a428b..0b081de080dcf24b1c63dc0081eb4366974daa87 100644
--- a/source/Lib/DecoderLib/DecCu.cpp
+++ b/source/Lib/DecoderLib/DecCu.cpp
@@ -469,7 +469,11 @@ void DecCu::decompressCtu( CodingStructure& cs, const UnitArea& ctuArea )
 #endif
           }
         }
+#if JVET_AH0136_CHROMA_REORDERING
+        if (currCU.firstPU->parseChromaMode && (!CS::isDualITree(cs) || !currCU.cs->sps->getUseChromaReordering()))
+#else
         if (currCU.firstPU->parseChromaMode)
+#endif
         {
           unsigned chromaCandModes[NUM_CHROMA_MODE];
           PU::getIntraChromaCandModes(*currCU.firstPU, chromaCandModes);
@@ -627,7 +631,11 @@ void DecCu::xIntraRecBlk( TransformUnit& tu, const ComponentID compID )
 #endif
 #if JVET_Z0050_DIMD_CHROMA_FUSION && ENABLE_DIMD
 #if JVET_AG0059_CCP_MERGE_ENHANCEMENT
+#if JVET_AH0136_CHROMA_REORDERING
+  if (((!PU::isLMCMode(pu.intraDir[1]) && compID == COMPONENT_Cb && !pu.cu->bdpcmModeChroma) && CS::isDualITree(cs) && pu.cs->sps->getUseChromaReordering()) || ((pu.intraDir[1] == DIMD_CHROMA_IDX || pu.ccpMergeFusionType == 1) && compID == COMPONENT_Cb))
+#else
   if ((pu.intraDir[1] == DIMD_CHROMA_IDX || pu.ccpMergeFusionType == 1) && compID == COMPONENT_Cb)
+#endif
 #else
   if (pu.intraDir[1] == DIMD_CHROMA_IDX && compID == COMPONENT_Cb)
 #endif
@@ -651,6 +659,57 @@ void DecCu::xIntraRecBlk( TransformUnit& tu, const ComponentID compID )
 #endif
   }
 #endif
+#if JVET_AH0136_CHROMA_REORDERING
+  if ((!PU::isLMCMode(pu.intraDir[1]) && compID == COMPONENT_Cb && !pu.cu->bdpcmModeChroma) && CS::isDualITree(cs) && pu.cs->sps->getUseChromaReordering())
+  {
+    CompArea areaCb = pu.Cb();
+    CompArea areaCr = pu.Cr();
+    CompArea lumaArea = CompArea(COMPONENT_Y, pu.chromaFormat, areaCb.lumaPos(), recalcSize(pu.chromaFormat, CHANNEL_TYPE_CHROMA, CHANNEL_TYPE_LUMA, areaCb.size()));
+    m_pcIntraPred->deriveNonCcpChromaModes(cs.picture->getRecoBuf(lumaArea), cs.picture->getRecoBuf(areaCb), cs.picture->getRecoBuf(areaCr), lumaArea, areaCb, areaCr, *pu.cu, pu, m_pcInterPred);
+    int chromaIdx = -1;
+#if JVET_AC0071_DBV
+#if JVET_Z0050_DIMD_CHROMA_FUSION && ENABLE_DIMD
+    if (cs.slice->getSPS()->getUseDimd())
+    {
+      chromaIdx = pu.intraDir[1] == DBV_CHROMA_IDX ? 0 : (pu.intraDir[1] == DM_CHROMA_IDX ? 1 : (pu.intraDir[1] == DIMD_CHROMA_IDX ? 2 : pu.candId + 3));
+    }
+    else
+    {
+      chromaIdx = pu.intraDir[1] == DBV_CHROMA_IDX ? 0 : (pu.intraDir[1] == DM_CHROMA_IDX ? 1 : pu.candId + 2);
+    }
+#else
+    chromaIdx = pu.intraDir[1] == DBV_CHROMA_IDX ? 0 : (pu.intraDir[1] == DM_CHROMA_IDX ? 1 : pu.candId + 2);
+#endif
+    if (!PU::hasChromaBvFlag(pu))
+    {
+      chromaIdx--;
+    }
+#else
+#if JVET_Z0050_DIMD_CHROMA_FUSION && ENABLE_DIMD
+    if (cs.slice->getSPS()->getUseDimd())
+    {
+      chromaIdx = pu.intraDir[1] == DM_CHROMA_IDX ? 0 : (pu.intraDir[1] == DIMD_CHROMA_IDX ? 1 : pu.candId + 2);
+    }
+    else
+    {
+      chromaIdx = pu.intraDir[1] == DM_CHROMA_IDX ? 0 : pu.candId + 1;
+    }
+#else
+    chromaIdx = pu.intraDir[1] == DM_CHROMA_IDX ? 0 : pu.candId + 1;
+#endif
+#endif
+    pu.intraDir[1] = pu.cu->chromaList[chromaIdx];
+#if JVET_AC0071_DBV
+    if (PU::isDbvMode(pu.intraDir[1]) && CS::isDualITree(cs))
+    {
+      pu.bv = pu.cu->bvs[pu.intraDir[1] - DBV_CHROMA_IDX];
+      pu.mv[0] = pu.cu->mvs[pu.intraDir[1] - DBV_CHROMA_IDX];
+      pu.cu->rribcFlipType = pu.cu->rribcTypes[pu.intraDir[1] - DBV_CHROMA_IDX];
+    }
+#endif
+    CHECK(pu.intraDir[1] < 0, "wrong intraDir");
+  }
+#endif
 #if JVET_AE0100_BVGCCCM
   if (pu.bvgCccmFlag && compID == COMPONENT_Cb)
   {
@@ -660,7 +719,11 @@ void DecCu::xIntraRecBlk( TransformUnit& tu, const ComponentID compID )
   }
 #endif
 #if JVET_AC0071_DBV
-  if (pu.intraDir[1] == DBV_CHROMA_IDX && compID == COMPONENT_Cb)
+  if (pu.intraDir[1] == DBV_CHROMA_IDX && compID == COMPONENT_Cb
+#if JVET_AH0136_CHROMA_REORDERING
+    && !pu.cs->sps->getUseChromaReordering()
+#endif
+    )
   {
     PU::deriveChromaBv(pu);
   }
@@ -1120,7 +1183,11 @@ void DecCu::xIntraRecBlk( TransformUnit& tu, const ComponentID compID )
       }
       else
 #if JVET_AC0071_DBV
+#if JVET_AH0136_CHROMA_REORDERING
+        if (compID != COMPONENT_Y && PU::isDbvMode(uiChFinalMode))
+#else
       if (compID != COMPONENT_Y && uiChFinalMode == DBV_CHROMA_IDX)
+#endif
       {
         m_pcIntraPred->predIntraDbv(compID, piPred, pu
 #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
@@ -1134,7 +1201,11 @@ void DecCu::xIntraRecBlk( TransformUnit& tu, const ComponentID compID )
 #if JVET_Z0050_DIMD_CHROMA_FUSION
       if (compID != COMPONENT_Y && pu.isChromaFusion)
       {
-        m_pcIntraPred->geneChromaFusionPred(compID, piPred, pu);
+        m_pcIntraPred->geneChromaFusionPred(compID, piPred, pu
+#if JVET_AH0136_CHROMA_REORDERING
+          , m_pcInterPred
+#endif
+        );
       }
 #endif
     }
@@ -1183,7 +1254,11 @@ void DecCu::xIntraRecBlk( TransformUnit& tu, const ComponentID compID )
       else
       {
 #if JVET_AC0071_DBV
+#if JVET_AH0136_CHROMA_REORDERING
+        if (PU::isDbvMode(uiChFinalMode))
+#else
         if (uiChFinalMode == DBV_CHROMA_IDX)
+#endif
         {
           m_pcIntraPred->predIntraDbv(COMPONENT_Cr, piPredCr, pu
 #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
@@ -1197,7 +1272,11 @@ void DecCu::xIntraRecBlk( TransformUnit& tu, const ComponentID compID )
 #if JVET_Z0050_DIMD_CHROMA_FUSION
         if (pu.isChromaFusion)
         {
-          m_pcIntraPred->geneChromaFusionPred(COMPONENT_Cr, piPredCr, pu);
+          m_pcIntraPred->geneChromaFusionPred(COMPONENT_Cr, piPredCr, pu
+#if JVET_AH0136_CHROMA_REORDERING
+            , m_pcInterPred
+#endif
+          );
         }
 #endif
       }
@@ -1272,7 +1351,11 @@ void DecCu::xIntraRecBlk( TransformUnit& tu, const ComponentID compID )
   if( !tu.cu->ispMode || !isLuma( compID ) )
   {
 #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS && JVET_AC0071_DBV
+#if JVET_AH0136_CHROMA_REORDERING
+    if (!(PU::isDbvMode(uiChFinalMode) && compID == COMPONENT_Cb))
+#else
     if (!(uiChFinalMode == DBV_CHROMA_IDX && compID == COMPONENT_Cb))
+#endif
 #endif
     cs.setDecomp( area );
   }
@@ -1320,7 +1403,11 @@ void DecCu::xIntraRecBlk( TransformUnit& tu, const ComponentID compID )
   pReco.copyFrom( piPred );
 #endif
 #if JVET_AC0071_DBV && JVET_AA0070_RRIBC
+#if JVET_AH0136_CHROMA_REORDERING
+  if (compID != COMPONENT_Y && PU::isDbvMode(uiChFinalMode) && tu.cu->rribcFlipType)
+#else
   if (compID != COMPONENT_Y && uiChFinalMode == DBV_CHROMA_IDX && tu.cu->rribcFlipType)
+#endif
   {
     pReco.flipSignal(tu.cu->rribcFlipType == 1);
   }
diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp
index db2922cde01247c85f2add41f654c107327867a5..882575d6aae92ac71ad3b1a7269d9d8bbaee71aa 100644
--- a/source/Lib/DecoderLib/VLCReader.cpp
+++ b/source/Lib/DecoderLib/VLCReader.cpp
@@ -2709,6 +2709,9 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
 #if JVET_AD0085_MPM_SORTING
   READ_FLAG(uiCode, "sps_mpm_sorting_enabled_flag");                pcSPS->setUseMpmSorting(uiCode != 0);
 #endif
+#if JVET_AH0136_CHROMA_REORDERING
+  READ_FLAG(uiCode, "sps_chroma_reordering_enabled_flag");          pcSPS->setUseChromaReordering(uiCode != 0);
+#endif
 #if JVET_AC0147_CCCM_NO_SUBSAMPLING
   READ_UVLC(uiCode, "sps_cccm_cand");                               pcSPS->setUseCccm(uiCode);
 #endif
diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp
index edace200777cae4060b9cee266492d0073cdbe79..78a457150e1b43906c946973b0d7884e5b2945a9 100644
--- a/source/Lib/EncoderLib/CABACWriter.cpp
+++ b/source/Lib/EncoderLib/CABACWriter.cpp
@@ -2573,16 +2573,33 @@ void CABACWriter::intra_chroma_pred_mode(const PredictionUnit& pu)
   }
 
 #if JVET_AC0071_DBV
+#if JVET_AH0136_CHROMA_REORDERING
+  bool hasDBV = false;
+#endif
   if (PU::hasChromaBvFlag(pu))
   {
+#if JVET_AH0136_CHROMA_REORDERING
+    hasDBV = true;
+    bool isDbvChromaMode = intraDir == DBV_CHROMA_IDX;
+    if (CS::isDualITree(*pu.cs) && pu.cs->sps->getUseChromaReordering())
+    {
+      int mode = PU::isDbvMode(pu.intraDir[1]) ? pu.intraDir[1] : PU::getFinalIntraMode(pu, CHANNEL_TYPE_CHROMA);
+      isDbvChromaMode = mode == pu.cu->chromaList[0];
+    }
+#else
     const bool isDbvChromaMode = intraDir == DBV_CHROMA_IDX;
+#endif
     m_BinEncoder.encodeBin(isDbvChromaMode ? 0 : 1, Ctx::DbvChromaMode());
     if (isDbvChromaMode)
     {
       if (PU::hasChromaFusionFlag(pu, pu.intraDir[1]))
       {
+#if JVET_AH0136_CHROMA_REORDERING
+        intraChromaFusionMode(pu);
+#else
         const bool isFusion = pu.isChromaFusion;
         m_BinEncoder.encodeBin(isFusion ? 1 : 0, Ctx::ChromaFusionMode());
+#endif
       }
       DTRACE(g_trace_ctx, D_SYNTAX, "intra_chroma_pred_modes() pos=(%d,%d) dir=%d\n",
         pu.blocks[CHANNEL_TYPE_CHROMA].x, pu.blocks[CHANNEL_TYPE_CHROMA].y, pu.intraDir[CHANNEL_TYPE_CHROMA]);
@@ -2591,6 +2608,108 @@ void CABACWriter::intra_chroma_pred_mode(const PredictionUnit& pu)
   }
 #endif
 
+#if JVET_AH0136_CHROMA_REORDERING
+  if (CS::isDualITree(*pu.cs) && pu.cs->sps->getUseChromaReordering())
+  {
+    int chromaIdx = 0;
+    bool hasMode = false;
+    int mode = PU::isDbvMode(pu.intraDir[1]) ? pu.intraDir[1] : PU::getFinalIntraMode(pu, CHANNEL_TYPE_CHROMA);
+    int start = 0;
+    int end = 6;
+#if JVET_AC0071_DBV
+    if (hasDBV)
+    {
+      start++;
+      end++;
+    }
+#endif
+#if ENABLE_DIMD && JVET_Z0050_DIMD_CHROMA_FUSION
+    if (!pu.cu->slice->getSPS()->getUseDimd())
+    {
+      end--;
+    }
+#endif
+    for (int i = start; i < end; i++)
+    {
+      if (mode == pu.cu->chromaList[i])
+      {
+        chromaIdx = i;
+        hasMode = true;
+        break;
+      }
+    }
+
+    if (hasDBV)
+    {
+      chromaIdx--;
+    }
+    CHECK(!hasMode, "wrong mode");
+    const bool     isDerivedMode = chromaIdx == 0;
+    m_BinEncoder.encodeBin(isDerivedMode ? 0 : 1, Ctx::IntraChromaPredMode(0));
+    if (isDerivedMode)
+    {
+#if JVET_Z0050_DIMD_CHROMA_FUSION
+      if (PU::hasChromaFusionFlag(pu, pu.intraDir[1]))
+      {
+#if JVET_AC0119_LM_CHROMA_FUSION
+        intraChromaFusionMode(pu);
+#else
+        const bool     isFusion = pu.isChromaFusion;
+        m_BinEncoder.encodeBin(isFusion ? 1 : 0, Ctx::ChromaFusionMode());
+#endif
+      }
+#endif
+      DTRACE(g_trace_ctx, D_SYNTAX, "intra_chroma_pred_modes() pos=(%d,%d) dir=%d\n",
+        pu.blocks[CHANNEL_TYPE_CHROMA].x, pu.blocks[CHANNEL_TYPE_CHROMA].y, pu.intraDir[CHANNEL_TYPE_CHROMA]);
+      return;
+    }
+
+#if JVET_Z0050_DIMD_CHROMA_FUSION && ENABLE_DIMD
+    if (pu.cu->slice->getSPS()->getUseDimd())
+    {
+      const bool     isDimdChromaMode = chromaIdx == 1;
+      m_BinEncoder.encodeBin(isDimdChromaMode ? 0 : 1, Ctx::DimdChromaMode());
+      if (isDimdChromaMode)
+      {
+        if (PU::hasChromaFusionFlag(pu, pu.intraDir[1]))
+        {
+#if JVET_AC0119_LM_CHROMA_FUSION
+          intraChromaFusionMode(pu);
+#else
+          const bool     isFusion = pu.isChromaFusion;
+          m_BinEncoder.encodeBin(isFusion ? 1 : 0, Ctx::ChromaFusionMode());
+#endif
+        }
+        DTRACE(g_trace_ctx, D_SYNTAX, "intra_chroma_pred_modes() pos=(%d,%d) dir=%d\n",
+          pu.blocks[CHANNEL_TYPE_CHROMA].x, pu.blocks[CHANNEL_TYPE_CHROMA].y, pu.intraDir[CHANNEL_TYPE_CHROMA]);
+        return;
+      }
+    }
+    else
+    {
+      chromaIdx++;
+    }
+#endif
+
+    // chroma candidate index
+    {
+      m_BinEncoder.encodeBinsEP(chromaIdx - 2, 2);
+      DTRACE(g_trace_ctx, D_SYNTAX, "intra_chroma_pred_modes() pos=(%d,%d) cand_idx=%d\n", pu.blocks[CHANNEL_TYPE_CHROMA].x, pu.blocks[CHANNEL_TYPE_CHROMA].y, chromaIdx - 2);
+#if JVET_Z0050_DIMD_CHROMA_FUSION
+      if (PU::hasChromaFusionFlag(pu, pu.intraDir[1]))
+      {
+#if JVET_AC0119_LM_CHROMA_FUSION
+        intraChromaFusionMode(pu);
+#else
+        const bool     isFusion = pu.isChromaFusion;
+        m_BinEncoder.encodeBin(isFusion ? 1 : 0, Ctx::ChromaFusionMode());
+#endif
+      }
+#endif
+    }
+    return;
+  }
+#endif
   const bool     isDerivedMode = intraDir == DM_CHROMA_IDX;
   m_BinEncoder.encodeBin(isDerivedMode ? 0 : 1, Ctx::IntraChromaPredMode(0));
   if (isDerivedMode)
diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h
index 17eafd18adb86fc9d773709221b8bcbdecd6bbf1..cb7aed7c7604e767f013ccdf5b027c16d354f573 100644
--- a/source/Lib/EncoderLib/EncCfg.h
+++ b/source/Lib/EncoderLib/EncCfg.h
@@ -509,6 +509,9 @@ protected:
 #if JVET_AD0085_MPM_SORTING
   bool      m_mpmSorting;
 #endif
+#if JVET_AH0136_CHROMA_REORDERING
+  bool      m_chromaReordering;
+#endif
 #if JVET_AC0147_CCCM_NO_SUBSAMPLING
   int       m_cccm;
 #endif
@@ -1750,6 +1753,10 @@ public:
   void      setUseMpmSorting             (bool b)         { m_mpmSorting = b; }
   bool      getUseMpmSorting             () const         { return m_mpmSorting; }
 #endif
+#if JVET_AH0136_CHROMA_REORDERING
+  void      setUseChromaReordering       (bool b)         { m_chromaReordering = b; }
+  bool      getUseChromaReordering       () const         { return m_chromaReordering; }
+#endif
 #if JVET_AC0147_CCCM_NO_SUBSAMPLING
   void      setUseCccm                   (int i)          { m_cccm = i; }
   int       getUseCccm                   () const         { return m_cccm; }
diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp
index f9b563790a1832aa35c8a553e1a5a4a21fd4f60d..c4424a5b2245e8e62a58ddce458802cebfbd3e34 100644
--- a/source/Lib/EncoderLib/EncCu.cpp
+++ b/source/Lib/EncoderLib/EncCu.cpp
@@ -2594,6 +2594,10 @@ bool EncCu::xCheckRDCostIntra(CodingStructure *&tempCS, CodingStructure *&bestCS
   int8_t dimdChromaMode = -1;
   int8_t dimdChromaModeSecond = -1;
 #endif
+#if JVET_AH0136_CHROMA_REORDERING
+  int8_t dimdBlendModeChroma[DIMD_FUSION_NUM - 1] = { 0 };
+  int chromaList[7] = { -1 };
+#endif
 #if JVET_AH0076_OBIC
   bool obicIsBlended = false;
   int obicMode[OBIC_FUSION_NUM] = { -1 };
@@ -2678,8 +2682,12 @@ bool EncCu::xCheckRDCostIntra(CodingStructure *&tempCS, CodingStructure *&bestCS
 #endif
 #endif
   }
-#if JVET_Z0050_DIMD_CHROMA_FUSION && (JVET_AC0094_REF_SAMPLES_OPT)
+#if (JVET_Z0050_DIMD_CHROMA_FUSION && (JVET_AC0094_REF_SAMPLES_OPT)) || JVET_AH0136_CHROMA_REORDERING
+#if JVET_AH0136_CHROMA_REORDERING
+  if (CS::isDualITree(*tempCS) ? isChroma(partitioner.chType) : false)
+#else
   if (tempCS->slice->getSPS()->getUseDimd() && (CS::isDualITree(*tempCS) ? isChroma(partitioner.chType) : false))
+#endif
   {
     CodingUnit cu(tempCS->area);
     cu.cs = tempCS;
@@ -2688,9 +2696,33 @@ bool EncCu::xCheckRDCostIntra(CodingStructure *&tempCS, CodingStructure *&bestCS
     const CompArea areaCb = tempCS->area.Cb();
     const CompArea areaCr = tempCS->area.Cr();
     const CompArea lumaArea = CompArea(COMPONENT_Y, (tempCS->area).chromaFormat, areaCb.lumaPos(), recalcSize((tempCS->area).chromaFormat, CHANNEL_TYPE_CHROMA, CHANNEL_TYPE_LUMA, areaCb.size()));
-    IntraPrediction::deriveDimdChromaMode(bestCS->picture->getRecoBuf(lumaArea), bestCS->picture->getRecoBuf(areaCb), bestCS->picture->getRecoBuf(areaCr), lumaArea, areaCb, areaCr, cu);
-    dimdChromaMode = cu.dimdChromaMode;
-    dimdChromaModeSecond = cu.dimdChromaModeSecond;
+#if JVET_AH0136_CHROMA_REORDERING
+    if (tempCS->slice->getSPS()->getUseDimd())
+    {
+#endif
+      IntraPrediction::deriveDimdChromaMode(bestCS->picture->getRecoBuf(lumaArea), bestCS->picture->getRecoBuf(areaCb), bestCS->picture->getRecoBuf(areaCr), lumaArea, areaCb, areaCr, cu);
+      dimdChromaMode = cu.dimdChromaMode;
+      dimdChromaModeSecond = cu.dimdChromaModeSecond;
+#if JVET_AH0136_CHROMA_REORDERING
+      for (int i = 0; i < 5; i++)
+      {
+        dimdBlendModeChroma[i] = cu.dimdBlendModeChroma[i];
+      }
+    }
+    if (tempCS->slice->getSPS()->getUseChromaReordering())
+    {
+      PredictionUnit pu(tempCS->area);
+      pu.cu = &cu;
+      cu.firstPU = &pu;
+      pu.cs = bestCS;
+      cu.cs = bestCS;
+      m_pcIntraSearch->deriveNonCcpChromaModes(bestCS->picture->getRecoBuf(lumaArea), bestCS->picture->getRecoBuf(areaCb), bestCS->picture->getRecoBuf(areaCr), lumaArea, areaCb, areaCr, cu, pu, m_pcInterSearch);
+      for (int i = 0; i < 7; i++)
+      {
+        chromaList[i] = cu.chromaList[i];
+      }
+    }
+#endif
   }
 #endif
 #elif SECONDARY_MPM
@@ -2836,8 +2868,23 @@ bool EncCu::xCheckRDCostIntra(CodingStructure *&tempCS, CodingStructure *&bestCS
           {
             cu.dimdChromaMode = dimdChromaMode;
             cu.dimdChromaModeSecond = dimdChromaModeSecond;
+#if JVET_AH0136_CHROMA_REORDERING
+            for (int i = 0; i < 5; i++)
+            {
+              cu.dimdBlendModeChroma[i] = dimdBlendModeChroma[i];
+            }
+#endif
           }
 #endif
+#endif
+#if JVET_AH0136_CHROMA_REORDERING
+          if (tempCS->slice->getSPS()->getUseChromaReordering() && (CS::isDualITree(*tempCS) ? isChroma(partitioner.chType) : false))
+          {
+            for (int i = 0; i < 7; i++)
+            {
+              cu.chromaList[i] = chromaList[i];
+            }
+          }
 #endif
           cu.lfnstIdx         = lfnstIdx;
           cu.mtsFlag          = mtsFlag;
diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp
index fe0594c14f5ac281cc451c13462f4e4d79a1f1b8..5fecb2ed3530710aa484aa0575ac917885761acb 100644
--- a/source/Lib/EncoderLib/EncLib.cpp
+++ b/source/Lib/EncoderLib/EncLib.cpp
@@ -1978,6 +1978,9 @@ void EncLib::xInitSPS( SPS& sps )
 #if JVET_AD0085_MPM_SORTING
   sps.setUseMpmSorting      ( m_mpmSorting );
 #endif
+#if JVET_AH0136_CHROMA_REORDERING
+  sps.setUseChromaReordering (m_chromaReordering);
+#endif
 #if JVET_AC0147_CCCM_NO_SUBSAMPLING
   sps.setUseCccm            ( m_cccm );
 #endif
diff --git a/source/Lib/EncoderLib/IntraSearch.cpp b/source/Lib/EncoderLib/IntraSearch.cpp
index b4f9886a09dbd19b708a3988fb6de87a0f5ff9e0..bb138346e2ebcd79a0a802f0fcae34e3b3e731c5 100644
--- a/source/Lib/EncoderLib/IntraSearch.cpp
+++ b/source/Lib/EncoderLib/IntraSearch.cpp
@@ -3688,6 +3688,12 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner
       IntraPrediction::deriveDimdChromaMode(cs.picture->getRecoBuf(lumaArea), cs.picture->getRecoBuf(areaCb), cs.picture->getRecoBuf(areaCr), lumaArea, areaCb, areaCr, *pu.cu);
 #endif
 #endif
+#if JVET_AH0136_CHROMA_REORDERING && ENABLE_DIMD && JVET_Z0050_DIMD_CHROMA_FUSION
+      if (!cu.slice->getSPS()->getUseDimd() && cu.cs->sps->getUseChromaReordering())
+      {
+        uiMaxMode--;
+      }
+#endif
 #if JVET_AC0071_DBV
       if (PU::hasChromaBvFlag(pu))
       {
@@ -3773,11 +3779,19 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner
       }
 #if JVET_Z0050_DIMD_CHROMA_FUSION && ENABLE_DIMD
 #if JVET_AC0071_DBV
+#if JVET_AH0136_CHROMA_REORDERING
+      bool modeIsEnable[NUM_INTRA_MODE + 3 + 9]; // use intra mode idx to check whether enable
+      for (int i = 0; i < NUM_INTRA_MODE + 3 + 9; i++)
+      {
+        modeIsEnable[i] = 1;
+      }
+#else
       bool modeIsEnable[NUM_INTRA_MODE + 3]; // use intra mode idx to check whether enable
       for (int i = 0; i < NUM_INTRA_MODE + 3; i++)
       {
         modeIsEnable[i] = 1;
       }
+#endif
 #else
       bool modeIsEnable[NUM_INTRA_MODE + 2]; // use intra mode idx to check whether enable
       for (int i = 0; i < NUM_INTRA_MODE + 2; i++)
@@ -3946,17 +3960,51 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner
         {
           continue;
         }
-        if ((mode == LM_CHROMA_IDX) || (mode == PLANAR_IDX) || (mode == DM_CHROMA_IDX)
-#if JVET_Z0050_DIMD_CHROMA_FUSION && ENABLE_DIMD
-          || (mode == DIMD_CHROMA_IDX)
+#if JVET_AH0136_CHROMA_REORDERING
+        if (CS::isDualITree(*pu.cs) && cu.cs->sps->getUseChromaReordering())
+        {
+          if ((mode == LM_CHROMA_IDX) || mode == pu.cu->chromaList[0] || mode == pu.cu->chromaList[1]) 
+          {
+            continue;
+          }
+#if ENABLE_DIMD && JVET_Z0050_DIMD_CHROMA_FUSION
+#if JVET_AC0071_DBV
+          if ((cu.slice->getSPS()->getUseDimd() && (mode == pu.cu->chromaList[2] || (PU::hasChromaBvFlag(pu) && mode == pu.cu->chromaList[3]))) || (!cu.slice->getSPS()->getUseDimd() && (PU::hasChromaBvFlag(pu) && mode == pu.cu->chromaList[2])))
+          {
+            continue;
+          }
+#else
+          if ((cu.slice->getSPS()->getUseDimd() && mode == pu.cu->chromaList[2]))
+          {
+            continue;
+          }
 #endif
+#else
 #if JVET_AC0071_DBV
-          || (mode == DBV_CHROMA_IDX)
+          if (PU::hasChromaBvFlag(pu) && mode == pu.cu->chromaList[2])
+          {
+            continue;
+          }
+#endif
 #endif
-          ) // only pre-check regular modes and MDLM modes, not including DM, DIMD, Planar, and LM
+        }
+        else
         {
-          continue;
+#endif
+          if ((mode == LM_CHROMA_IDX) || (mode == PLANAR_IDX) || (mode == DM_CHROMA_IDX)
+#if JVET_Z0050_DIMD_CHROMA_FUSION && ENABLE_DIMD
+            || (mode == DIMD_CHROMA_IDX)
+#endif
+#if JVET_AC0071_DBV
+            || (mode == DBV_CHROMA_IDX)
+#endif
+            ) // only pre-check regular modes and MDLM modes, not including DM, DIMD, Planar, and LM
+          {
+            continue;
+          }
+#if JVET_AH0136_CHROMA_REORDERING
         }
+#endif
         pu.intraDir[1] = mode; // temporary assigned, for SATD checking.
 
         int64_t sad = 0;
@@ -3982,8 +4030,29 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner
         }
         else
         {
-          initPredIntraParams(pu, pu.Cb(), *pu.cs->sps);
-          predIntraAng(COMPONENT_Cb, predCb, pu);
+#if JVET_AH0136_CHROMA_REORDERING && JVET_AC0071_DBV
+          if (cu.cs->sps->getUseChromaReordering() && CS::isDualITree(cs) && PU::isDbvMode(mode))
+          {
+            pu.bv = cu.bvs[mode - DBV_CHROMA_IDX];
+            pu.mv[0] = cu.mvs[mode - DBV_CHROMA_IDX];
+            pu.cu->rribcFlipType = cu.rribcTypes[mode - DBV_CHROMA_IDX];
+            predIntraDbv(COMPONENT_Cb, predCb, pu, pcInterPred);
+            if (pu.cu->rribcFlipType)
+            {
+              predCb.flipSignal(pu.cu->rribcFlipType == 1);
+            }
+            pu.bv.setZero();
+            pu.mv[0].setZero();
+            pu.cu->rribcFlipType = 0;
+          }
+          else
+          {
+#endif
+            initPredIntraParams(pu, pu.Cb(), *pu.cs->sps);
+            predIntraAng(COMPONENT_Cb, predCb, pu);
+#if JVET_AH0136_CHROMA_REORDERING
+          }
+#endif
         }
         sadCb = distParamSad.distFunc(distParamSad) * 2;
         satdCb = distParamSatd.distFunc(distParamSatd);
@@ -4001,12 +4070,39 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner
         }
         else
         {
-          initPredIntraParams(pu, pu.Cr(), *pu.cs->sps);
-          predIntraAng(COMPONENT_Cr, predCr, pu);
+#if JVET_AH0136_CHROMA_REORDERING && JVET_AC0071_DBV
+          if (cu.cs->sps->getUseChromaReordering() && CS::isDualITree(cs) && PU::isDbvMode(mode))
+          {
+            pu.bv = cu.bvs[mode - DBV_CHROMA_IDX];
+            pu.mv[0] = cu.mvs[mode - DBV_CHROMA_IDX];
+            pu.cu->rribcFlipType = cu.rribcTypes[mode - DBV_CHROMA_IDX];
+            predIntraDbv(COMPONENT_Cr, predCr, pu, pcInterPred);
+            if (pu.cu->rribcFlipType)
+            {
+              predCr.flipSignal(pu.cu->rribcFlipType == 1);
+            }
+            pu.bv.setZero();
+            pu.mv[0].setZero();
+            pu.cu->rribcFlipType = 0;
+          }
+          else
+          {
+#endif
+            initPredIntraParams(pu, pu.Cr(), *pu.cs->sps);
+            predIntraAng(COMPONENT_Cr, predCr, pu);
+#if JVET_AH0136_CHROMA_REORDERING
+          }
+#endif
         }
         sadCr = distParamSad.distFunc(distParamSad) * 2;
         satdCr = distParamSatd.distFunc(distParamSatd);
         sad += std::min(sadCr, satdCr);
+#if JVET_AH0136_CHROMA_REORDERING && JVET_AC0071_DBV
+        if (cu.cs->sps->getUseChromaReordering() && CS::isDualITree(*pu.cs) && PU::isDbvMode(mode) && cu.mvs[mode - DBV_CHROMA_IDX] == Mv())
+        {
+          sad = INT64_MAX;
+        }
+#endif
         satdSortedCost[idx] = sad;
 #if JVET_AD0120_LBCCP && MMLM
         if(mode == MMLM_CHROMA_IDX)
@@ -4873,7 +4969,11 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner
         if (uiMode < 0)
         {
             cu.bdpcmModeChroma = -uiMode;
+#if JVET_AH0136_CHROMA_REORDERING
+            chromaIntraMode = cu.bdpcmModeChroma == 2 ? VER_IDX : HOR_IDX;
+#else
             chromaIntraMode = cu.bdpcmModeChroma == 2 ? chromaCandModes[1] : chromaCandModes[2];
+#endif
         }
         else
         {
@@ -4895,7 +4995,11 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner
           }
 #endif
 #if JVET_AC0071_DBV
+#if JVET_AH0136_CHROMA_REORDERING
+          if (PU::isDbvMode(chromaIntraMode) && !PU::hasChromaBvFlag(pu))
+#else
           if (chromaIntraMode == DBV_CHROMA_IDX && !PU::hasChromaBvFlag(pu))
+#endif
           {
             continue;
           }
@@ -5119,6 +5223,9 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner
 #endif
 
 #if JVET_Z0050_DIMD_CHROMA_FUSION
+#if JVET_AH0136_CHROMA_REORDERING
+      cs.setDecomp(pu.Cb(), false);
+#endif
 #if JVET_AC0119_LM_CHROMA_FUSION
       uint32_t uiFusionModeNum = 2;
 #if MMLM
@@ -5167,8 +5274,25 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner
         if (PU::hasChromaFusionFlag(pu, chromaIntraMode))
         {
           pu.intraDir[1] = chromaIntraMode;
-          if (!xCflmCreateChromaPred(pu, COMPONENT_Cb, predStorage[uiMode].Cb()) ||
-            !xCflmCreateChromaPred(pu, COMPONENT_Cr, predStorage[uiMode].Cr()))
+#if JVET_AH0136_CHROMA_REORDERING && JVET_AC0071_DBV
+          if (cu.cs->sps->getUseChromaReordering() && PU::isDbvMode(pu.intraDir[1]) && CS::isDualITree(cs))
+          {
+            pu.bv = cu.bvs[pu.intraDir[1] - DBV_CHROMA_IDX];
+            pu.mv[0] = cu.mvs[pu.intraDir[1] - DBV_CHROMA_IDX];
+            pu.cu->rribcFlipType = cu.rribcTypes[pu.intraDir[1] - DBV_CHROMA_IDX];
+          }
+#endif
+          if (!xCflmCreateChromaPred(pu, COMPONENT_Cb, predStorage[uiMode].Cb()
+#if JVET_AH0136_CHROMA_REORDERING
+            , pcInterPred
+#endif
+          ) ||
+            !xCflmCreateChromaPred(pu, COMPONENT_Cr, predStorage[uiMode].Cr()
+#if JVET_AH0136_CHROMA_REORDERING
+              , pcInterPred
+#endif
+            ))
+
           {
             break;
           }
@@ -5184,8 +5308,17 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner
 
             fusionStorage[idx].Cb().copyFrom( predStorage[uiMode].Cb() );
             fusionStorage[idx].Cr().copyFrom( predStorage[uiMode].Cr() );
-            geneChromaFusionPred(COMPONENT_Cb, fusionStorage[idx].Cb(), pu);
-            geneChromaFusionPred(COMPONENT_Cr, fusionStorage[idx].Cr(), pu);
+
+            geneChromaFusionPred(COMPONENT_Cb, fusionStorage[idx].Cb(), pu
+#if JVET_AH0136_CHROMA_REORDERING
+              , pcInterPred
+#endif
+            );
+            geneChromaFusionPred(COMPONENT_Cr, fusionStorage[idx].Cr(), pu
+#if JVET_AH0136_CHROMA_REORDERING
+              , pcInterPred
+#endif
+            );
 
             distParamSadCb.cur = fusionStorage[idx].Cb();
             distParamSatdCb.cur = fusionStorage[idx].Cb();
@@ -5337,6 +5470,9 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner
       pu.curCand = {};
 #endif
 #endif
+#if JVET_AH0136_CHROMA_REORDERING
+      cs.setDecomp(pu.Cb(), false);
+#endif
 
 #if JVET_Z0050_CCLM_SLOPE
 #if MMLM
@@ -5436,6 +5572,10 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner
 #endif
 #if JVET_AD0188_CCP_MERGE
               ccpModelBest    = pu.curCand;
+#endif
+              isChromaFusion = pu.isChromaFusion;
+#if JVET_AA0126_GLM
+              bestGlmIdc = pu.glmIdc;
 #endif
             }
           }
@@ -8226,6 +8366,9 @@ void IntraSearch::xEncIntraHeader( CodingStructure &cs, Partitioner &partitioner
     if( isFirst )
     {
       m_CABACEstimator->bdpcm_mode( cu, ComponentID(CHANNEL_TYPE_CHROMA) );
+#if JVET_AH0136_CHROMA_REORDERING
+      if (!cu.bdpcmModeChroma)
+#endif
       m_CABACEstimator->intra_chroma_pred_mode( pu );
     }
   }
@@ -9318,7 +9461,11 @@ void IntraSearch::xIntraCodingTUBlock(TransformUnit &tu, const ComponentID &comp
     }
   }
 #if JVET_AC0071_DBV && JVET_AA0070_RRIBC
+#if JVET_AH0136_CHROMA_REORDERING
+  if (compID != COMPONENT_Y && PU::isDbvMode(uiChFinalMode) && pu.cu->rribcFlipType)
+#else
   if (compID != COMPONENT_Y && uiChFinalMode == DBV_CHROMA_IDX && pu.cu->rribcFlipType)
+#endif
   {
     cs.getRecoBuf(area).flipSignal(pu.cu->rribcFlipType == 1);
     if (jointCbCr)
@@ -11533,12 +11680,23 @@ ChromaCbfs IntraSearch::xRecurIntraChromaCodingQT( CodingStructure &cs, Partitio
     // Do predictions here to avoid repeating the "default0Save1Load2" stuff
     int  predMode   = pu.cu->bdpcmModeChroma ? BDPCM_IDX : PU::getFinalIntraMode(pu, CHANNEL_TYPE_CHROMA);
 #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS && JVET_AC0071_DBV
+#if JVET_AH0136_CHROMA_REORDERING
+    if (!PU::isDbvMode(predMode) || pu.isChromaFusion > 0)
+#else
     if (predMode != DBV_CHROMA_IDX)
+#endif
     {
       cs.setDecomp(currArea.Cb(), true); // set in advance (required for Cb2/Cr2 in 4:2:2 video)
     }
 #endif
-
+#if JVET_AH0136_CHROMA_REORDERING && JVET_AC0071_DBV
+    if (pu.cs->sps->getUseChromaReordering() && PU::isDbvMode(predMode) && CS::isDualITree(cs))
+    {
+      pu.bv = pu.cu->bvs[predMode - DBV_CHROMA_IDX];
+      pu.mv[0] = pu.cu->mvs[predMode - DBV_CHROMA_IDX];
+      pu.cu->rribcFlipType = pu.cu->rribcTypes[predMode - DBV_CHROMA_IDX];
+    }
+#endif
     PelBuf piPredCb = cs.getPredBuf(cbArea);
     PelBuf piPredCr = cs.getPredBuf(crArea);
 
@@ -11669,7 +11827,11 @@ ChromaCbfs IntraSearch::xRecurIntraChromaCodingQT( CodingStructure &cs, Partitio
       {
 #endif
 #if JVET_AC0071_DBV
+#if JVET_AH0136_CHROMA_REORDERING
+      if (PU::isDbvMode(predMode))
+#else
       if (predMode == DBV_CHROMA_IDX)
+#endif
       {
         predIntraDbv(COMPONENT_Cb, piPredCb, pu
 #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
@@ -11682,6 +11844,9 @@ ChromaCbfs IntraSearch::xRecurIntraChromaCodingQT( CodingStructure &cs, Partitio
 #endif
         );
 #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS && JVET_AC0071_DBV
+#if JVET_AH0136_CHROMA_REORDERING
+        if (pu.isChromaFusion == 0)
+#endif
         cs.setDecomp(currArea.Cb(), true); // set in advance (required for Cb2/Cr2 in 4:2:2 video)
 #endif
       }
@@ -11696,8 +11861,16 @@ ChromaCbfs IntraSearch::xRecurIntraChromaCodingQT( CodingStructure &cs, Partitio
 #if JVET_Z0050_DIMD_CHROMA_FUSION
       if (pu.isChromaFusion)
       {
-        geneChromaFusionPred(COMPONENT_Cb, piPredCb, pu);
-        geneChromaFusionPred(COMPONENT_Cr, piPredCr, pu);
+        geneChromaFusionPred(COMPONENT_Cb, piPredCb, pu
+#if JVET_AH0136_CHROMA_REORDERING
+          , pcInterPred
+#endif
+        );
+        geneChromaFusionPred(COMPONENT_Cr, piPredCr, pu
+#if JVET_AH0136_CHROMA_REORDERING
+          , pcInterPred
+#endif
+        );
       }
 #endif
 #if JVET_AC0119_LM_CHROMA_FUSION
@@ -11710,7 +11883,11 @@ ChromaCbfs IntraSearch::xRecurIntraChromaCodingQT( CodingStructure &cs, Partitio
     PelBuf resiCb  = cs.getResiBuf(cbArea);
     PelBuf resiCr  = cs.getResiBuf(crArea);
 #if JVET_AC0071_DBV && JVET_AA0070_RRIBC
+#if JVET_AH0136_CHROMA_REORDERING
+    if (PU::isDbvMode(predMode) && currTU.cu->rribcFlipType)
+#else
     if (predMode == DBV_CHROMA_IDX && currTU.cu->rribcFlipType)
+#endif
     {
       resiCb.copyFrom(cs.getOrgBuf(cbArea));
       resiCr.copyFrom(cs.getOrgBuf(crArea));
diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp
index 16f386e9256b350281f51a5b3f3cf25cdaa94da6..56dcc142ef9dd781ceb6fc98f38f84acea4b8cf7 100644
--- a/source/Lib/EncoderLib/VLCWriter.cpp
+++ b/source/Lib/EncoderLib/VLCWriter.cpp
@@ -1741,6 +1741,9 @@ void HLSWriter::codeSPS( const SPS* pcSPS )
 #if JVET_AD0085_MPM_SORTING
   WRITE_FLAG(pcSPS->getUseMpmSorting() ? 1 : 0, "sps_mpm_sorting_enabled_flag");
 #endif
+#if JVET_AH0136_CHROMA_REORDERING
+  WRITE_FLAG(pcSPS->getUseChromaReordering() ? 1 : 0, "sps_chroma_reordering_enabled_flag");
+#endif
 #if JVET_AC0147_CCCM_NO_SUBSAMPLING
   WRITE_UVLC(pcSPS->getUseCccm() , "sps_cccm_cand");
 #endif