diff --git a/source/Lib/EncoderLib/EncTemporalFilter.cpp b/source/Lib/EncoderLib/EncTemporalFilter.cpp
index 31e605e45d4e58719fb09faf58ed043f839ef9df..a882f64d16ed9f1ffc198aa97e54553bc648613b 100644
--- a/source/Lib/EncoderLib/EncTemporalFilter.cpp
+++ b/source/Lib/EncoderLib/EncTemporalFilter.cpp
@@ -388,21 +388,15 @@ void EncTemporalFilter::subsampleLuma(const PelStorage &input, PelStorage &outpu
   output.extendBorderPel(m_padding, m_padding);
 }
 
-int EncTemporalFilter::motionErrorLuma(const PelStorage &orig,
-  const PelStorage &buffer,
-  const int x,
-  const int y,
-  int dx,
-  int dy,
-  const int bs,
-  const int besterror = 8 * 8 * 1024 * 1024) const
+int64_t EncTemporalFilter::motionErrorLuma(const PelStorage& orig, const PelStorage& buffer, const int x, const int y,
+                                           int dx, int dy, const int bs, const int64_t besterror) const
 {
   const Pel* origOrigin = orig.Y().buf;
   const ptrdiff_t origStride = orig.Y().stride;
   const Pel* buffOrigin = buffer.Y().buf;
   const ptrdiff_t buffStride = buffer.Y().stride;
 
-  int error = 0;
+  int64_t error = 0;   // int64_t to avoid overflow at higher bit depths
   if (((dx | dy) & 0xF) == 0)
   {
     dx /= m_motionVectorFactor;
@@ -489,6 +483,10 @@ void EncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const P
   const int origWidth  = orig.Y().width;
   const int origHeight = orig.Y().height;
 
+  const int    bitShift = m_internalBitDepth[ChannelType::LUMA];
+  const double offset   = 5.0 / (1 << (2 * BASELINE_BIT_DEPTH - 16)) * (1 << (2 * bitShift - 16));
+  const double scale    = 50.0 / (1 << (2 * BASELINE_BIT_DEPTH - 16)) * (1 << (2 * bitShift - 16));
+
   for (int blockY = 0; blockY + blockSize <= origHeight; blockY += stepSize)
   {
     for (int blockX = 0; blockX + blockSize <= origWidth; blockX += stepSize)
@@ -510,7 +508,8 @@ void EncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const P
             if ((testx >= 0) && (testx < origWidth / (2 * blockSize)) && (testy >= 0) && (testy < origHeight / (2 * blockSize)))
             {
               MotionVector old = previous->get(testx, testy);
-              int error = motionErrorLuma(orig, buffer, blockX, blockY, old.x * factor, old.y * factor, blockSize, best.error);
+              const int64_t error =
+                motionErrorLuma(orig, buffer, blockX, blockY, old.x * factor, old.y * factor, blockSize, best.error);
               if (error < best.error)
               {
                 best.set(old.x * factor, old.y * factor, error);
@@ -518,7 +517,7 @@ void EncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const P
             }
           }
         }
-        int error = motionErrorLuma(orig, buffer, blockX, blockY, 0, 0, blockSize, best.error);
+        const int64_t error = motionErrorLuma(orig, buffer, blockX, blockY, 0, 0, blockSize, best.error);
         if (error < best.error)
         {
           best.set(0, 0, error);
@@ -529,7 +528,8 @@ void EncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const P
       {
         for (int x2 = prevBest.x / m_motionVectorFactor - range; x2 <= prevBest.x / m_motionVectorFactor + range; x2++)
         {
-          int error = motionErrorLuma(orig, buffer, blockX, blockY, x2 * m_motionVectorFactor, y2 * m_motionVectorFactor, blockSize, best.error);
+          const int64_t error = motionErrorLuma(orig, buffer, blockX, blockY, x2 * m_motionVectorFactor,
+                                                y2 * m_motionVectorFactor, blockSize, best.error);
           if (error < best.error)
           {
             best.set(x2 * m_motionVectorFactor, y2 * m_motionVectorFactor, error);
@@ -544,7 +544,7 @@ void EncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const P
         {
           for (int x2 = prevBest.x - doubleRange; x2 <= prevBest.x + doubleRange; x2 += 4)
           {
-            int error = motionErrorLuma(orig, buffer, blockX, blockY, x2, y2, blockSize, best.error);
+            const int64_t error = motionErrorLuma(orig, buffer, blockX, blockY, x2, y2, blockSize, best.error);
             if (error < best.error)
             {
               best.set(x2, y2, error);
@@ -558,7 +558,7 @@ void EncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const P
         {
           for (int x2 = prevBest.x - doubleRange; x2 <= prevBest.x + doubleRange; x2++)
           {
-            int error = motionErrorLuma(orig, buffer, blockX, blockY, x2, y2, blockSize, best.error);
+            const int64_t error = motionErrorLuma(orig, buffer, blockX, blockY, x2, y2, blockSize, best.error);
             if (error < best.error)
             {
               best.set(x2, y2, error);
@@ -570,7 +570,8 @@ void EncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const P
       if (blockY > 0)
       {
         MotionVector aboveMV = mvs.get(blockX / stepSize, (blockY - stepSize) / stepSize);
-        int error = motionErrorLuma(orig, buffer, blockX, blockY, aboveMV.x, aboveMV.y, blockSize, best.error);
+        const int64_t error =
+          motionErrorLuma(orig, buffer, blockX, blockY, aboveMV.x, aboveMV.y, blockSize, best.error);
         if (error < best.error)
         {
           best.set(aboveMV.x, aboveMV.y, error);
@@ -579,7 +580,7 @@ void EncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const P
       if (blockX > 0)
       {
         MotionVector leftMV = mvs.get((blockX - stepSize) / stepSize, blockY / stepSize);
-        int error = motionErrorLuma(orig, buffer, blockX, blockY, leftMV.x, leftMV.y, blockSize, best.error);
+        const int64_t error  = motionErrorLuma(orig, buffer, blockX, blockY, leftMV.x, leftMV.y, blockSize, best.error);
         if (error < best.error)
         {
           best.set(leftMV.x, leftMV.y, error);
@@ -607,7 +608,8 @@ void EncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const P
           variance = variance + (pix - avg) * (pix - avg);
         }
       }
-      best.error = (int)(20 * ((best.error + 5.0) / (variance + 5.0)) + (best.error / (blockSize * blockSize)) / 50);
+      best.error = (int64_t) (20 * ((best.error + offset) / (variance + offset)))
+                   + (int64_t) (best.error / (blockSize * blockSize) / scale);
       mvs.get(blockX / stepSize, blockY / stepSize) = best;
     }
   }
@@ -749,7 +751,10 @@ void EncTemporalFilter::bilateralFilter(const PelStorage &orgPic,
     const double sigmaSq = isChroma(compID) ? chromaSigmaSq : lumaSigmaSq;
     const double weightScaling = overallStrength * (isChroma(compID) ? m_chromaFactor : 0.4);
     const Pel         maxSampleValue        = (1 << m_internalBitDepth[toChannelType(compID)]) - 1;
-    const double bitDepthDiffWeighting = 1024.0 / (maxSampleValue + 1);
+    const double      bitDepthDiffWeighting = 1.0 * (1 << BASELINE_BIT_DEPTH) / (maxSampleValue + 1);
+
+    const int    bitShift = m_internalBitDepth[ChannelType::LUMA];
+    const double offset   = 5.0 / (1 << (2 * BASELINE_BIT_DEPTH - 16)) * (1 << (2 * bitShift - 16));
 
     const int lumaBlockSize = 8;
     const int csx           = getComponentScaleX(compID, m_chromaFormatIdc);
@@ -800,7 +805,7 @@ void EncTemporalFilter::bilateralFilter(const PelStorage &orgPic,
             const int cntV = blockSizeX * blockSizeY;
             const int cntD = 2 * cntV - blockSizeX - blockSizeY;
             srcFrameInfo[i].mvs.get(x / blockSizeX, y / blockSizeY).noise =
-              (int) round((15.0 * cntD / cntV * variance + 5.0) / (diffsum + 5.0));
+              (int) round((15.0 * cntD / cntV * variance + offset) / (diffsum + offset));
           }
         }
         double minError = 9999999;
@@ -810,8 +815,9 @@ void EncTemporalFilter::bilateralFilter(const PelStorage &orgPic,
         }
         for (int i = 0; i < numRefs; i++)
         {
-          const int error = srcFrameInfo[i].mvs.get(x / blockSizeX, y / blockSizeY).error;
-          const int noise = srcFrameInfo[i].mvs.get(x / blockSizeX, y / blockSizeY).noise;
+          const int64_t error = srcFrameInfo[i].mvs.get(x / blockSizeX, y / blockSizeY).error;
+          const int     noise = srcFrameInfo[i].mvs.get(x / blockSizeX, y / blockSizeY).noise;
+
           const Pel *pCorrectedPelPtr = correctedPics[i].bufs[c].buf + (y * correctedPics[i].bufs[c].stride + x);
           const int refVal = (int) *pCorrectedPelPtr;
           double diff = (double)(refVal - orgVal);
diff --git a/source/Lib/EncoderLib/EncTemporalFilter.h b/source/Lib/EncoderLib/EncTemporalFilter.h
index 241580d7b7b8155e3986772c2439f1f3f5e96168..f06db166309bdb6155b213e6387f8ce0faf52766 100644
--- a/source/Lib/EncoderLib/EncTemporalFilter.h
+++ b/source/Lib/EncoderLib/EncTemporalFilter.h
@@ -49,11 +49,18 @@
 
 struct MotionVector
 {
-  int x, y;
-  int error;
-  int noise;
-  MotionVector() : x(0), y(0), error(INT_LEAST32_MAX), noise(0) {}
-  void set(int vectorX, int vectorY, int errorValue) { x = vectorX; y = vectorY; error = errorValue; }
+  int     x     = 0;
+  int     y     = 0;
+  int64_t error = std::numeric_limits<int64_t>::max();
+  int     noise = 0;
+
+  MotionVector() = default;
+  void set(int vectorX, int vectorY, int64_t errorValue)
+  {
+    x     = vectorX;
+    y     = vectorY;
+    error = errorValue;
+  }
 };
 
 template <class T>
@@ -120,6 +127,8 @@ public:
   bool filter(PelStorage *orgPic, int frame);
 
 private:
+  static constexpr int BASELINE_BIT_DEPTH = 10;
+
   // Private static member variables
   static const double m_chromaFactor;
   static const double m_sigmaMultiplier;
@@ -165,7 +174,8 @@ private:
 
   // Private functions
   void subsampleLuma(const PelStorage &input, PelStorage &output, const int factor = 2) const;
-  int motionErrorLuma(const PelStorage &orig, const PelStorage &buffer, const int x, const int y, int dx, int dy, const int bs, const int besterror) const;
+  int64_t motionErrorLuma(const PelStorage& orig, const PelStorage& buffer, const int x, const int y, int dx, int dy,
+                          const int bs, const int64_t besterror) const;
   void motionEstimationLuma(Array2D<MotionVector> &mvs, const PelStorage &orig, const PelStorage &buffer, const int bs,
     const Array2D<MotionVector> *previous=0, const int factor = 1, const bool doubleRes = false) const;
   void motionEstimation(Array2D<MotionVector> &mvs, const PelStorage &orgPic, const PelStorage &buffer, const PelStorage &origSubsampled2, const PelStorage &origSubsampled4) const;