diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index b71b815576eef06e75da4e3e049c0116a5e33b7f..a68b90ae01fe6e578c082dd809363fac7449ad6e 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -53,6 +53,8 @@
 #define JVET_Q0512_ENC_CHROMA_TS_ACT                      1 // JVET-Q0512: encoder-side improvement on enabling chroma transform-skip for ACT
 #define JVET_Q0446_MIP_CONST_SHIFT_OFFSET                 1 // JVET-Q0446: MIP with constant shift and offset
 
+#define JVET_Q0447_WP_PARAM_ESTIM                         1 // JVET-Q0447: Add search iterations for method 2,3 and 4
+
 #define JVET_Q0820_ACT                                    1 // JVET-Q0820: ACT bug fixes and reversible ACT transform 
 
 #define JVET_Q0353_ACT_SW_FIX                             1 // JVET-Q0353: Bug fix of ACT 
diff --git a/source/Lib/EncoderLib/WeightPredAnalysis.cpp b/source/Lib/EncoderLib/WeightPredAnalysis.cpp
index 5117c79d98d9a4e5cc9b05c7c79e576a55bc439f..454be151796ba9dc67a0220e4883c5b5858d1636 100644
--- a/source/Lib/EncoderLib/WeightPredAnalysis.cpp
+++ b/source/Lib/EncoderLib/WeightPredAnalysis.cpp
@@ -98,6 +98,7 @@ void xCalcHistogram(const Pel  *pPel,
   }
 }
 
+#if !JVET_Q0447_WP_PARAM_ESTIM
 static
 Distortion xCalcHistDistortion (const std::vector<int> &histogram0,
                                 const std::vector<int> &histogram1)
@@ -114,6 +115,7 @@ Distortion xCalcHistDistortion (const std::vector<int> &histogram0,
 
   return distortion;
 }
+#endif
 
 static
 void xScaleHistogram(const std::vector<int> &histogramInput,
@@ -144,6 +146,28 @@ void xScaleHistogram(const std::vector<int> &histogramInput,
   }
 }
 
+#if JVET_Q0447_WP_PARAM_ESTIM
+static
+Distortion xCalcHistCumulDistortion(const std::vector<int>& histogram0,
+  const std::vector<int>& histogram1)
+{
+  Distortion distortion = 0;
+  CHECK(histogram0.size() != histogram1.size(), "Different histogram sizes");
+  const int numElements = int(histogram0.size());
+
+  int64_t  cumul = 0;
+
+  // Scan histograms to compute histogram distortion
+  for (int i = 0; i < numElements; i++)
+  {
+    cumul += (int64_t)histogram0[i] - (int64_t)histogram1[i];
+    distortion += (Distortion)(abs(cumul));
+  }
+
+  return distortion;
+}
+#endif
+
 static
 Distortion xSearchHistogram(const std::vector<int> &histogramSource,
                             const std::vector<int> &histogramRef,
@@ -178,7 +202,11 @@ Distortion xSearchHistogram(const std::vector<int> &histogramSource,
                searchOffset++)
       {
         xScaleHistogram(histogramRef, outputHistogram, bitDepth, log2Denom, searchWeight, searchOffset, bHighPrecision);
+#if JVET_Q0447_WP_PARAM_ESTIM
+        const Distortion distortion = xCalcHistCumulDistortion(histogramSource, outputHistogram);
+#else
         const Distortion distortion = xCalcHistDistortion(histogramSource, outputHistogram);
+#endif
 
         if (distortion < minDistortion)
         {
@@ -197,7 +225,11 @@ Distortion xSearchHistogram(const std::vector<int> &histogramSource,
         const int deltaOffset   = Clip3( -4*maxOffset, 4*maxOffset-1, (searchOffset - pred) ); // signed 10bit (if !bHighPrecision)
         const int clippedOffset = Clip3( -1*maxOffset, 1*maxOffset-1, (deltaOffset  + pred) ); // signed 8bit  (if !bHighPrecision)
         xScaleHistogram(histogramRef, outputHistogram, bitDepth, log2Denom, searchWeight, clippedOffset, bHighPrecision);
+#if JVET_Q0447_WP_PARAM_ESTIM
+        const Distortion distortion = xCalcHistCumulDistortion(histogramSource, outputHistogram);
+#else
         const Distortion distortion = xCalcHistDistortion(histogramSource, outputHistogram);
+#endif
 
         if (distortion < minDistortion)
         {
@@ -510,28 +542,79 @@ bool WeightPredAnalysis::xSelectWPHistExtClip(Slice *const slice, const int log2
               int          offsetDef  = 0;
 
         // calculate SAD costs with/without wp for luma
+#if JVET_Q0447_WP_PARAM_ESTIM
+              std::vector<int> histogramOrg;
+              std::vector<int> histogramRef;
+              uint64_t SADnoWP = std::numeric_limits<uint64_t>::max();
+              if (bUseHistogram && compID == COMPONENT_Y)
+              {
+                xCalcHistogram(pOrg, histogramOrg, width, height, orgStride, 1 << bitDepth);
+                xCalcHistogram(pRef, histogramRef, width, height, refStride, 1 << bitDepth);
+
+                std::vector<int> histogramRef_noWP;
+                xScaleHistogram(histogramRef, histogramRef_noWP, bitDepth, log2Denom, defaultWeight, 0, useHighPrecision);
+                SADnoWP = (uint64_t)xCalcHistCumulDistortion(histogramOrg, histogramRef_noWP);
+              }
+              else
+              {
+                SADnoWP = (uint64_t)xCalcSADvalueWPOptionalClip(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, defaultWeight, 0, useHighPrecision, bClipInitialSADWP);
+              }
+#else
         const int64_t SADnoWP = xCalcSADvalueWPOptionalClip(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, defaultWeight, 0, useHighPrecision, bClipInitialSADWP);
+#endif
         if (SADnoWP > 0)
         {
+#if JVET_Q0447_WP_PARAM_ESTIM
+          uint64_t SADWP = std::numeric_limits<uint64_t>::max();
+          if (bUseHistogram && compID == COMPONENT_Y)
+          {
+            std::vector<int> histogramRef_WP;
+            xScaleHistogram(histogramRef, histogramRef_WP, bitDepth, log2Denom, weight, offset, useHighPrecision);
+            SADWP = (uint64_t)xCalcHistCumulDistortion(histogramOrg, histogramRef_WP);
+          }
+          else
+          {
+            SADWP = (uint64_t)xCalcSADvalueWPOptionalClip(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, weight, offset, useHighPrecision, bClipInitialSADWP);
+          }
+#else
           const int64_t SADWP   = xCalcSADvalueWPOptionalClip(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, weight,   offset, useHighPrecision, bClipInitialSADWP);
+#endif
           const double dRatioSAD = (double)SADWP / (double)SADnoWP;
           double dRatioSr0SAD = std::numeric_limits<double>::max();
           double dRatioSrSAD  = std::numeric_limits<double>::max();
 
           if (bUseHistogram)
           {
+#if !JVET_Q0447_WP_PARAM_ESTIM
             std::vector<int> histogramOrg;// = pPic->getHistogram(compID);
             std::vector<int> histogramRef;// = slice->getRefPic(eRefPicList, refIdxTemp)->getPicYuvRec()->getHistogram(compID);
+#endif
             std::vector<int> searchedHistogram;
 
+#if !JVET_Q0447_WP_PARAM_ESTIM
             // Compute histograms
             xCalcHistogram(pOrg, histogramOrg, width, height, orgStride, 1 << bitDepth);
             xCalcHistogram(pRef, histogramRef, width, height, refStride, 1 << bitDepth);
+#endif
 
             // Do a histogram search around DC WP parameters; resulting distortion and 'searchedHistogram' is discarded
             xSearchHistogram(histogramOrg, histogramRef, searchedHistogram, bitDepth, log2Denom, weight, offset, useHighPrecision, compID);
             // calculate updated WP SAD
+#if JVET_Q0447_WP_PARAM_ESTIM
+            uint64_t SADSrWP = std::numeric_limits<uint64_t>::max();
+            if (bUseHistogram && compID == COMPONENT_Y)
+            {
+              std::vector<int> histogramRef_SrWP;
+              xScaleHistogram(histogramRef, histogramRef_SrWP, bitDepth, log2Denom, weight, offset, useHighPrecision);
+              SADSrWP = (uint64_t)xCalcHistCumulDistortion(histogramOrg, histogramRef_SrWP);
+            }
+            else
+            {
+              SADSrWP = (uint64_t)xCalcSADvalueWP(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, weight, offset, useHighPrecision);
+            }
+#else
             const int64_t SADSrWP = xCalcSADvalueWP(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, weight, offset, useHighPrecision);
+#endif
             dRatioSrSAD  = (double)SADSrWP  / (double)SADnoWP;
 
             if (bDoEnhancement)
@@ -539,7 +622,21 @@ bool WeightPredAnalysis::xSelectWPHistExtClip(Slice *const slice, const int log2
               // Do the same around the default ones; resulting distortion and 'searchedHistogram' is discarded
               xSearchHistogram(histogramOrg, histogramRef, searchedHistogram, bitDepth, log2Denom, weightDef, offsetDef, useHighPrecision, compID);
               // calculate updated WP SAD
+#if JVET_Q0447_WP_PARAM_ESTIM
+              uint64_t SADSr0WP = std::numeric_limits<uint64_t>::max();
+              if (bUseHistogram && compID == COMPONENT_Y)
+              {
+                std::vector<int> histogramRef_SrWP;
+                xScaleHistogram(histogramRef, histogramRef_SrWP, bitDepth, log2Denom, weightDef, offsetDef, useHighPrecision);
+                SADSr0WP = (uint64_t)xCalcHistCumulDistortion(histogramOrg, histogramRef_SrWP);
+              }
+              else
+              {
+                SADSr0WP = (uint64_t)xCalcSADvalueWP(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, weightDef, offsetDef, useHighPrecision);
+              }
+#else
               const int64_t SADSr0WP = xCalcSADvalueWP(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, weightDef, offsetDef, useHighPrecision);
+#endif
               dRatioSr0SAD = (double)SADSr0WP / (double)SADnoWP;
             }
           }