diff --git a/source/Lib/CommonLib/InterPrediction.cpp b/source/Lib/CommonLib/InterPrediction.cpp
index 6c53825bec82e618483d8fb95a161c3c70554d1b..802a7cdc7b5c85b804cedef18b6732c5d50fa4bc 100644
--- a/source/Lib/CommonLib/InterPrediction.cpp
+++ b/source/Lib/CommonLib/InterPrediction.cpp
@@ -512,6 +512,15 @@ void InterPrediction::xPredInterBi(PredictionUnit& pu, PelUnitBuf &pcYuvPred)
 #if JVET_N0266_SMALL_BLOCKS
   CHECK( !pu.cu->affine && pu.refIdx[0] >= 0 && pu.refIdx[1] >= 0 && ( pu.lwidth() + pu.lheight() == 12 ), "invalid 4x8/8x4 bi-predicted blocks" );
 #endif
+#if JVET_N0146_DMVR_BDOF_CONDITION
+  WPScalingParam *wp0;
+  WPScalingParam *wp1;
+  int refIdx0 = pu.refIdx[REF_PIC_LIST_0];
+  int refIdx1 = pu.refIdx[REF_PIC_LIST_1];
+  pu.cs->slice->getWpScaling(REF_PIC_LIST_0, refIdx0, wp0);
+  pu.cs->slice->getWpScaling(REF_PIC_LIST_1, refIdx1, wp1);
+#endif
+
   bool bioApplied = false;
   if (pu.cs->sps->getBDOFEnabledFlag())
   {
@@ -521,7 +530,11 @@ void InterPrediction::xPredInterBi(PredictionUnit& pu, PelUnitBuf &pcYuvPred)
     }
     else
     {
+#if JVET_N0146_DMVR_BDOF_CONDITION
+      const bool biocheck0 = !((wp0[COMPONENT_Y].bPresentFlag || wp1[COMPONENT_Y].bPresentFlag) && slice.getSliceType() == B_SLICE);
+#else
       const bool biocheck0 = !(pps.getWPBiPred() && slice.getSliceType() == B_SLICE);
+#endif
       const bool biocheck1 = !(pps.getUseWP() && slice.getSliceType() == P_SLICE);
       if (biocheck0
         && biocheck1
@@ -597,6 +610,33 @@ void InterPrediction::xPredInterBi(PredictionUnit& pu, PelUnitBuf &pcYuvPred)
       }
     }
   }
+#if JVET_N0146_DMVR_BDOF_CONDITION
+  CPelUnitBuf srcPred0 = ( pu.chromaFormat == CHROMA_400 ?
+                           CPelUnitBuf(pu.chromaFormat, PelBuf(m_acYuvPred[0][0], pcYuvPred.Y())) :
+                           CPelUnitBuf(pu.chromaFormat, PelBuf(m_acYuvPred[0][0], pcYuvPred.Y()), PelBuf(m_acYuvPred[0][1], pcYuvPred.Cb()), PelBuf(m_acYuvPred[0][2], pcYuvPred.Cr())) );
+  CPelUnitBuf srcPred1 = ( pu.chromaFormat == CHROMA_400 ?
+                           CPelUnitBuf(pu.chromaFormat, PelBuf(m_acYuvPred[1][0], pcYuvPred.Y())) :
+                           CPelUnitBuf(pu.chromaFormat, PelBuf(m_acYuvPred[1][0], pcYuvPred.Y()), PelBuf(m_acYuvPred[1][1], pcYuvPred.Cb()), PelBuf(m_acYuvPred[1][2], pcYuvPred.Cr())) );
+  if( (!dmvrApplied) && (!bioApplied) && pps.getWPBiPred() && slice.getSliceType() == B_SLICE && pu.cu->GBiIdx==GBI_DEFAULT)
+  {
+    xWeightedPredictionBi( pu, srcPred0, srcPred1, pcYuvPred, m_maxCompIDToPred );
+  }
+  else if( pps.getUseWP() && slice.getSliceType() == P_SLICE )
+  {
+    xWeightedPredictionUni( pu, srcPred0, REF_PIC_LIST_0, pcYuvPred, -1, m_maxCompIDToPred );
+  }
+  else
+  {
+    if (dmvrApplied)
+    {
+      xProcessDMVR(pu, pcYuvPred, slice.clpRngs(), bioApplied);
+    }
+    else
+    {
+      xWeightedAverage( pu, srcPred0, srcPred1, pcYuvPred, slice.getSPS()->getBitDepths(), slice.clpRngs(), bioApplied );
+    }
+  }
+#else
   if (dmvrApplied)
   {
     xProcessDMVR(pu, pcYuvPred, slice.clpRngs(), bioApplied);
@@ -624,6 +664,7 @@ void InterPrediction::xPredInterBi(PredictionUnit& pu, PelUnitBuf &pcYuvPred)
     xWeightedAverage( pu, srcPred0, srcPred1, pcYuvPred, slice.getSPS()->getBitDepths(), slice.clpRngs(), bioApplied );
     }
   }
+#endif
 }
 
 void InterPrediction::xPredInterBlk ( const ComponentID& compID, const PredictionUnit& pu, const Picture* refPic, const Mv& _mv, PelUnitBuf& dstPic, const bool& bi, const ClpRng& clpRng
@@ -1151,7 +1192,28 @@ void InterPrediction::xWeightedAverage(const PredictionUnit& pu, const CPelUnitB
         pcYuvDst.bufs[0].addAvg(CPelBuf(pSrcY0, src0Stride, pu.lumaSize()), CPelBuf(pSrcY1, src1Stride, pu.lumaSize()), clpRngs.comp[0]);
       }
     }
+#if JVET_N0146_DMVR_BDOF_CONDITION
+    if (pu.cs->pps->getWPBiPred())
+    {
+      const int iRefIdx0 = pu.refIdx[0];
+      const int iRefIdx1 = pu.refIdx[1];
+      WPScalingParam  *pwp0;
+      WPScalingParam  *pwp1;
+      getWpScaling(pu.cu->slice, iRefIdx0, iRefIdx1, pwp0, pwp1);
+      if (!bioApplied)
+      {
+        addWeightBiComponent(pcYuvSrc0, pcYuvSrc1, pu.cu->slice->clpRngs(), pwp0, pwp1, pcYuvDst, true, COMPONENT_Y);
+      }
+      addWeightBiComponent(pcYuvSrc0, pcYuvSrc1, pu.cu->slice->clpRngs(), pwp0, pwp1, pcYuvDst, true, COMPONENT_Cb);
+      addWeightBiComponent(pcYuvSrc0, pcYuvSrc1, pu.cu->slice->clpRngs(), pwp0, pwp1, pcYuvDst, true, COMPONENT_Cr);
+    }
+    else
+    {
+      pcYuvDst.addAvg(pcYuvSrc0, pcYuvSrc1, clpRngs, bioApplied);
+    }
+#else
     pcYuvDst.addAvg(pcYuvSrc0, pcYuvSrc1, clpRngs, bioApplied);
+#endif
   }
   else if( iRefIdx0 >= 0 && iRefIdx1 < 0 )
   {
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 057ef2e8fb4451fce176aeeab9c26e2f9b9be999..eae8e65c887ae847e7e85c98c9c8491700aa0a3d 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -50,6 +50,8 @@
 #include <assert.h>
 #include <cassert>
 
+#define JVET_N0146_DMVR_BDOF_CONDITION                    1 // JVET-N146/N0162/N0442/N0153/N0262/N0440/N0086 applicable condition of DMVR and BDOF
+
 #define JVET_N0470_SMVD_FIX                               1 // remove mvd_l1_zero_flag condition, align to spec text.
 
 #define JVET_N0235_SMVD_SPS                               1
diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp
index 61e48236adcfd483dc8f066a04a25dfe035b11d2..43bfb9bf62cbc991ebbaf2473eab130a07b97cf6 100644
--- a/source/Lib/CommonLib/UnitTools.cpp
+++ b/source/Lib/CommonLib/UnitTools.cpp
@@ -1917,6 +1917,14 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx,
 }
 bool PU::checkDMVRCondition(const PredictionUnit& pu)
 {
+#if JVET_N0146_DMVR_BDOF_CONDITION
+    WPScalingParam *wp0;
+    WPScalingParam *wp1;
+    int refIdx0 = pu.refIdx[REF_PIC_LIST_0];
+    int refIdx1 = pu.refIdx[REF_PIC_LIST_1];
+    pu.cs->slice->getWpScaling(REF_PIC_LIST_0, refIdx0, wp0);
+    pu.cs->slice->getWpScaling(REF_PIC_LIST_1, refIdx1, wp1);
+#endif
   if (pu.cs->sps->getUseDMVR())
   {
     return pu.mergeFlag
@@ -1931,6 +1939,10 @@ bool PU::checkDMVRCondition(const PredictionUnit& pu)
       && ((pu.lheight() * pu.lwidth()) >= 128)
 #else
       && ((pu.lheight() * pu.lwidth()) >= 64)
+#endif
+#if JVET_N0146_DMVR_BDOF_CONDITION
+      && (pu.cu->GBiIdx == GBI_DEFAULT)
+      && ((!wp0[COMPONENT_Y].bPresentFlag) && (!wp1[COMPONENT_Y].bPresentFlag))
 #endif
       ;
   }
diff --git a/source/Lib/CommonLib/WeightPrediction.cpp b/source/Lib/CommonLib/WeightPrediction.cpp
index 8495736e89b85b9ef48ec2111027fd8a74986bcb..6a645952d4a6ce6aa898327960ab83f63e6b31a4 100644
--- a/source/Lib/CommonLib/WeightPrediction.cpp
+++ b/source/Lib/CommonLib/WeightPrediction.cpp
@@ -215,6 +215,64 @@ void WeightPrediction::addWeightBi(const CPelUnitBuf          &pcYuvSrc0,
   } // compID loop
 }
 
+#if JVET_N0146_DMVR_BDOF_CONDITION
+void WeightPrediction::addWeightBiComponent(const CPelUnitBuf          &pcYuvSrc0,
+                                            const CPelUnitBuf          &pcYuvSrc1,
+                                            const ClpRngs              &clpRngs,
+                                            const WPScalingParam *const wp0,
+                                            const WPScalingParam *const wp1,
+                                                  PelUnitBuf           &rpcYuvDst,
+                                            const bool                  bRoundLuma /*= true*/,
+                                            const ComponentID           Comp)
+{
+  const bool enableRounding[MAX_NUM_COMPONENT] = { bRoundLuma, true, true };
+
+  const ComponentID compID = ComponentID(Comp);
+
+  const Pel* src0 = pcYuvSrc0.bufs[compID].buf;
+  const Pel* src1 = pcYuvSrc1.bufs[compID].buf;
+        Pel* dst  = rpcYuvDst.bufs[compID].buf;
+
+  // Luma : --------------------------------------------
+  const ClpRng& clpRng = clpRngs.comp[compID];
+  const int  w0       = wp0[compID].w;
+  const int  offset   = wp0[compID].offset;
+  const int  clipBD   = clpRng.bd;
+  const int  shiftNum = std::max<int>(2, (IF_INTERNAL_PREC - clipBD));
+  const int  shift    = wp0[compID].shift + shiftNum;
+  const int  round    = (enableRounding[compID] && (shift > 0)) ? (1 << (shift - 1)) : 0;
+  const int  w1       = wp1[compID].w;
+  const int  height  = rpcYuvDst.bufs[compID].height;
+  const int  width   = rpcYuvDst.bufs[compID].width;
+
+  const uint32_t src0Stride = pcYuvSrc0.bufs[compID].stride;
+  const uint32_t src1Stride = pcYuvSrc1.bufs[compID].stride;
+  const uint32_t dstStride =  rpcYuvDst.bufs[compID].stride;
+
+  for (int y = height - 1; y >= 0; y--)
+  {
+    // do it in batches of 4 (partial unroll)
+    int x = width - 1;
+
+    for (; x >= 3; )
+    {
+      dst[x] = weightBidir(w0, src0[x], w1, src1[x], round, shift, offset, clpRng ); x--;
+      dst[x] = weightBidir(w0, src0[x], w1, src1[x], round, shift, offset, clpRng ); x--;
+      dst[x] = weightBidir(w0, src0[x], w1, src1[x], round, shift, offset, clpRng ); x--;
+      dst[x] = weightBidir(w0, src0[x], w1, src1[x], round, shift, offset, clpRng ); x--;
+    }
+    for (; x >= 0; x--)
+    {
+      dst[x] = weightBidir(w0, src0[x], w1, src1[x], round, shift, offset, clpRng );
+    }
+
+    src0 += src0Stride;
+    src1 += src1Stride;
+    dst += dstStride;
+  } // y loop
+}
+#endif
+
 void  WeightPrediction::addWeightUni(const CPelUnitBuf          &pcYuvSrc0,
                                      const ClpRngs              &clpRngs,
                                      const WPScalingParam *const wp0,
@@ -351,6 +409,10 @@ void  WeightPrediction::xWeightedPredictionBi(const PredictionUnit       &pu,
 
   CHECK( !pu.cs->pps->getWPBiPred(), "Weighted Bi-prediction disabled" );
 
+#if JVET_N0146_DMVR_BDOF_CONDITION
+  if (iRefIdx0 < 0 && iRefIdx1 < 0) return;
+#endif
+
   getWpScaling(pu.cu->slice, iRefIdx0, iRefIdx1, pwp0, pwp1, maxNumComp);
 
   if (iRefIdx0 >= 0 && iRefIdx1 >= 0)
diff --git a/source/Lib/CommonLib/WeightPrediction.h b/source/Lib/CommonLib/WeightPrediction.h
index 2cbb82fa608e06ad25ff95a80fbc822a7aa16c37..86671665fbb0281d99f56961040e69e2b334b8aa 100644
--- a/source/Lib/CommonLib/WeightPrediction.h
+++ b/source/Lib/CommonLib/WeightPrediction.h
@@ -71,6 +71,17 @@ public:
                                 const bool                  bRoundLuma = true,
                                 const ComponentID           maxNumComp = MAX_NUM_COMPONENT );
 
+#if JVET_N0146_DMVR_BDOF_CONDITION
+  void addWeightBiComponent(    const CPelUnitBuf          &pcYuvSrc0,
+                                const CPelUnitBuf          &pcYuvSrc1,
+                                const ClpRngs              &clpRngs,
+                                const WPScalingParam *const wp0,
+                                const WPScalingParam *const wp1,
+                                      PelUnitBuf           &rpcYuvDst,
+                                const bool                  bRoundLuma = true,
+                                const ComponentID           Comp = COMPONENT_Y);
+#endif
+
   void  addWeightUni(           const CPelUnitBuf          &pcYuvSrc0,
                                 const ClpRngs              &clpRngs,
                                 const WPScalingParam *const wp0,