Remove EncodedFrame::MissingFrame and start removing Decode() param

Remove EncodedFrame::MissingFrame, as it was always false in actual
in-use code anyway, and remove usages of the Decode missing_frames param
within WebRTC. Uses/overrides in other projects will be cleaned up
shortly, allowing that variant to be removed from the interface.

Bug: webrtc:15444
Change-Id: Id299d82e441a351deff81c0f2812707a985d23d8
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/317802
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Auto-Submit: Tony Herre <herre@google.com>
Commit-Queue: Tony Herre <herre@google.com>
Cr-Commit-Position: refs/heads/main@{#40662}
diff --git a/api/test/mock_video_decoder.h b/api/test/mock_video_decoder.h
index 34f732c..dc499d4 100644
--- a/api/test/mock_video_decoder.h
+++ b/api/test/mock_video_decoder.h
@@ -18,6 +18,9 @@
 
 namespace webrtc {
 
+using testing::_;
+using testing::Invoke;
+
 class MockDecodedImageCallback : public DecodedImageCallback {
  public:
   MOCK_METHOD(int32_t,
@@ -43,6 +46,14 @@
     // Make `Configure` succeed by default, so that individual tests that
     // verify other methods wouldn't need to stub `Configure`.
     ON_CALL(*this, Configure).WillByDefault(testing::Return(true));
+
+    // TODO(bugs.webrtc.org/15444): Remove once all tests have been migrated to
+    // expecting calls Decode without a missing_frames param.
+    ON_CALL(*this, Decode(_, _))
+        .WillByDefault(Invoke([this](const EncodedImage& input_image,
+                                     int64_t render_time_ms) {
+          return Decode(input_image, /*missing_frames=*/false, render_time_ms);
+        }));
   }
 
   ~MockVideoDecoder() override { Destruct(); }
@@ -51,10 +62,14 @@
   MOCK_METHOD(int32_t,
               Decode,
               (const EncodedImage& input_image,
-               bool missing_frames,
                int64_t render_time_ms),
               (override));
   MOCK_METHOD(int32_t,
+              Decode,
+              (const EncodedImage& input_image,
+               bool missing_frames,
+               int64_t render_time_ms));
+  MOCK_METHOD(int32_t,
               RegisterDecodeCompleteCallback,
               (DecodedImageCallback * callback),
               (override));
diff --git a/api/video/encoded_frame.h b/api/video/encoded_frame.h
index 72473ba..1e626f0 100644
--- a/api/video/encoded_frame.h
+++ b/api/video/encoded_frame.h
@@ -62,8 +62,6 @@
 
   uint8_t PayloadType() const { return _payloadType; }
 
-  bool MissingFrame() const { return _missingFrame; }
-
   void SetRenderTime(const int64_t renderTimeMs) {
     _renderTimeMs = renderTimeMs;
   }
@@ -94,7 +92,6 @@
   // getters/setters as needed.
   int64_t _renderTimeMs = -1;
   uint8_t _payloadType = 0;
-  bool _missingFrame = false;
   CodecSpecificInfo _codecSpecificInfo;
   VideoCodecType _codec = kVideoCodecGeneric;
 
diff --git a/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc b/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc
index 73dedc8..97be625 100644
--- a/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc
+++ b/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc
@@ -45,7 +45,6 @@
     }
 
     int32_t Decode(const EncodedImage& input_image,
-                   bool missing_frames,
                    int64_t render_time_ms) override {
       ++decode_count_;
       return decode_return_code_;
@@ -84,7 +83,7 @@
 
   EncodedImage encoded_image;
   encoded_image._frameType = VideoFrameType::kVideoFrameKey;
-  fallback_wrapper_->Decode(encoded_image, false, -1);
+  fallback_wrapper_->Decode(encoded_image, -1);
   EXPECT_EQ(1, fake_decoder_->configure_count_)
       << "Initialized decoder should not be reinitialized.";
   EXPECT_EQ(1, fake_decoder_->decode_count_);
@@ -98,7 +97,7 @@
 
   EncodedImage encoded_image;
   encoded_image._frameType = VideoFrameType::kVideoFrameKey;
-  fallback_wrapper_->Decode(encoded_image, false, -1);
+  fallback_wrapper_->Decode(encoded_image, -1);
   EXPECT_EQ(1, fake_decoder_->configure_count_)
       << "Should not have attempted reinitializing the fallback decoder on "
          "keyframe.";
@@ -113,12 +112,12 @@
 
   fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
   EncodedImage encoded_image;
-  fallback_wrapper_->Decode(encoded_image, false, -1);
+  fallback_wrapper_->Decode(encoded_image, -1);
   EXPECT_EQ(1, fake_decoder_->decode_count_);
 
   // Software fallback should be sticky, fake_decoder_ shouldn't be used.
   encoded_image._frameType = VideoFrameType::kVideoFrameKey;
-  fallback_wrapper_->Decode(encoded_image, false, -1);
+  fallback_wrapper_->Decode(encoded_image, -1);
   EXPECT_EQ(1, fake_decoder_->decode_count_)
       << "Decoder shouldn't be used after failure.";
 
@@ -131,10 +130,10 @@
   fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR;
   EncodedImage encoded_image;
   EXPECT_EQ(fake_decoder_->decode_return_code_,
-            fallback_wrapper_->Decode(encoded_image, false, -1));
+            fallback_wrapper_->Decode(encoded_image, -1));
   EXPECT_EQ(1, fake_decoder_->decode_count_);
 
-  fallback_wrapper_->Decode(encoded_image, false, -1);
+  fallback_wrapper_->Decode(encoded_image, -1);
   EXPECT_EQ(2, fake_decoder_->decode_count_)
       << "Decoder should be active even though previous decode failed.";
 }
@@ -144,14 +143,14 @@
 
   fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
   EncodedImage encoded_image;
-  fallback_wrapper_->Decode(encoded_image, false, -1);
+  fallback_wrapper_->Decode(encoded_image, -1);
   EXPECT_EQ(1, fake_decoder_->decode_count_);
 
   fallback_wrapper_->Release();
   fallback_wrapper_->Configure({});
 
   fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
-  fallback_wrapper_->Decode(encoded_image, false, -1);
+  fallback_wrapper_->Decode(encoded_image, -1);
   EXPECT_EQ(2, fake_decoder_->decode_count_)
       << "Should not be using fallback after reinit.";
 }
@@ -164,7 +163,7 @@
   fallback_wrapper_->Configure({});
   fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
   EncodedImage encoded_image;
-  fallback_wrapper_->Decode(encoded_image, false, -1);
+  fallback_wrapper_->Decode(encoded_image, -1);
   EXPECT_EQ(2, fake_decoder_->release_count_)
       << "Decoder should be released during fallback.";
   fallback_wrapper_->Release();
@@ -200,7 +199,7 @@
 
   fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
   EncodedImage encoded_image;
-  fallback_wrapper_->Decode(encoded_image, false, -1);
+  fallback_wrapper_->Decode(encoded_image, -1);
   // Hard coded expected value since libvpx is the software implementation name
   // for VP8. Change accordingly if the underlying implementation does.
   EXPECT_STREQ("libvpx (fallback from: fake-decoder)",
@@ -215,13 +214,13 @@
   EncodedImage encoded_image;
   encoded_image._frameType = VideoFrameType::kVideoFrameKey;
   // Doesn't fallback from a single error.
-  fallback_wrapper_->Decode(encoded_image, false, -1);
+  fallback_wrapper_->Decode(encoded_image, -1);
   EXPECT_STREQ("fake-decoder", fallback_wrapper_->ImplementationName());
 
   // However, many frames with the same error, fallback should happen.
   const int kNumFramesToEncode = 10;
   for (int i = 0; i < kNumFramesToEncode; ++i) {
-    fallback_wrapper_->Decode(encoded_image, false, -1);
+    fallback_wrapper_->Decode(encoded_image, -1);
   }
   // Hard coded expected value since libvpx is the software implementation name
   // for VP8. Change accordingly if the underlying implementation does.
@@ -241,7 +240,7 @@
   // Many decoded frames with the same error
   const int kNumFramesToEncode = 10;
   for (int i = 0; i < kNumFramesToEncode; ++i) {
-    fallback_wrapper_->Decode(encoded_image, false, -1);
+    fallback_wrapper_->Decode(encoded_image, -1);
   }
   EXPECT_STREQ("fake-decoder", fallback_wrapper_->ImplementationName());
 
@@ -259,9 +258,9 @@
   for (int i = 0; i < kNumFramesToEncode; ++i) {
     // Interleaved errors and successful decodes.
     fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR;
-    fallback_wrapper_->Decode(encoded_image, false, -1);
+    fallback_wrapper_->Decode(encoded_image, -1);
     fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
-    fallback_wrapper_->Decode(encoded_image, false, -1);
+    fallback_wrapper_->Decode(encoded_image, -1);
   }
   EXPECT_STREQ("fake-decoder", fallback_wrapper_->ImplementationName());
   fallback_wrapper_->Release();
@@ -289,7 +288,7 @@
 
   EncodedImage encoded_image;
   encoded_image._frameType = VideoFrameType::kVideoFrameKey;
-  fallback_wrapper_->Decode(encoded_image, false, -1);
+  fallback_wrapper_->Decode(encoded_image, -1);
   EXPECT_EQ(1, sw_fallback_decoder_->configure_count_);
   EXPECT_EQ(1, sw_fallback_decoder_->decode_count_);
 
diff --git a/api/video_codecs/video_decoder.h b/api/video_codecs/video_decoder.h
index aa7ee24..40614ce 100644
--- a/api/video_codecs/video_decoder.h
+++ b/api/video_codecs/video_decoder.h
@@ -98,9 +98,20 @@
   // times, in such case only latest `settings` are in effect.
   virtual bool Configure(const Settings& settings) = 0;
 
+  // TODO(bugs.webrtc.org/15444): Make pure virtual once all subclasses have
+  // migrated to implementing this class.
+  virtual int32_t Decode(const EncodedImage& input_image,
+                         int64_t render_time_ms) {
+    return Decode(input_image, /*missing_frame=*/false, render_time_ms);
+  }
+
+  // TODO(bugs.webrtc.org/15444): Migrate all subclasses to Decode() without
+  // missing_frame and delete this.
   virtual int32_t Decode(const EncodedImage& input_image,
                          bool missing_frames,
-                         int64_t render_time_ms) = 0;
+                         int64_t render_time_ms) {
+    return Decode(input_image, render_time_ms);
+  }
 
   virtual int32_t RegisterDecodeCompleteCallback(
       DecodedImageCallback* callback) = 0;
diff --git a/api/video_codecs/video_decoder_software_fallback_wrapper.cc b/api/video_codecs/video_decoder_software_fallback_wrapper.cc
index cf6f823..c52ddbe 100644
--- a/api/video_codecs/video_decoder_software_fallback_wrapper.cc
+++ b/api/video_codecs/video_decoder_software_fallback_wrapper.cc
@@ -41,7 +41,6 @@
   bool Configure(const Settings& settings) override;
 
   int32_t Decode(const EncodedImage& input_image,
-                 bool missing_frames,
                  int64_t render_time_ms) override;
 
   int32_t RegisterDecodeCompleteCallback(
@@ -176,7 +175,6 @@
 
 int32_t VideoDecoderSoftwareFallbackWrapper::Decode(
     const EncodedImage& input_image,
-    bool missing_frames,
     int64_t render_time_ms) {
   TRACE_EVENT0("webrtc", "VideoDecoderSoftwareFallbackWrapper::Decode");
   switch (decoder_type_) {
@@ -184,7 +182,7 @@
       return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
     case DecoderType::kHardware: {
       int32_t ret = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
-      ret = hw_decoder_->Decode(input_image, missing_frames, render_time_ms);
+      ret = hw_decoder_->Decode(input_image, render_time_ms);
       if (ret != WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE) {
         if (ret != WEBRTC_VIDEO_CODEC_ERROR) {
           ++hw_decoded_frames_since_last_fallback_;
@@ -212,8 +210,7 @@
       [[fallthrough]];
     }
     case DecoderType::kFallback:
-      return fallback_decoder_->Decode(input_image, missing_frames,
-                                       render_time_ms);
+      return fallback_decoder_->Decode(input_image, render_time_ms);
     default:
       RTC_DCHECK_NOTREACHED();
       return WEBRTC_VIDEO_CODEC_ERROR;
diff --git a/media/engine/fake_webrtc_video_engine.cc b/media/engine/fake_webrtc_video_engine.cc
index 77d92d7..adbaf6c 100644
--- a/media/engine/fake_webrtc_video_engine.cc
+++ b/media/engine/fake_webrtc_video_engine.cc
@@ -60,7 +60,6 @@
 }
 
 int32_t FakeWebRtcVideoDecoder::Decode(const webrtc::EncodedImage&,
-                                       bool,
                                        int64_t) {
   num_frames_received_++;
   return WEBRTC_VIDEO_CODEC_OK;
diff --git a/media/engine/fake_webrtc_video_engine.h b/media/engine/fake_webrtc_video_engine.h
index 0bbddd2..87d107a 100644
--- a/media/engine/fake_webrtc_video_engine.h
+++ b/media/engine/fake_webrtc_video_engine.h
@@ -45,7 +45,7 @@
   ~FakeWebRtcVideoDecoder();
 
   bool Configure(const Settings& settings) override;
-  int32_t Decode(const webrtc::EncodedImage&, bool, int64_t) override;
+  int32_t Decode(const webrtc::EncodedImage&, int64_t) override;
   int32_t RegisterDecodeCompleteCallback(
       webrtc::DecodedImageCallback*) override;
   int32_t Release() override;
diff --git a/modules/video_coding/codecs/av1/dav1d_decoder.cc b/modules/video_coding/codecs/av1/dav1d_decoder.cc
index a2cd6d8..3100c0d 100644
--- a/modules/video_coding/codecs/av1/dav1d_decoder.cc
+++ b/modules/video_coding/codecs/av1/dav1d_decoder.cc
@@ -35,7 +35,6 @@
 
   bool Configure(const Settings& settings) override;
   int32_t Decode(const EncodedImage& encoded_image,
-                 bool missing_frames,
                  int64_t render_time_ms) override;
   int32_t RegisterDecodeCompleteCallback(
       DecodedImageCallback* callback) override;
@@ -119,7 +118,6 @@
 }
 
 int32_t Dav1dDecoder::Decode(const EncodedImage& encoded_image,
-                             bool /*missing_frames*/,
                              int64_t /*render_time_ms*/) {
   if (!context_ || decode_complete_callback_ == nullptr) {
     return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
diff --git a/modules/video_coding/codecs/av1/libaom_av1_unittest.cc b/modules/video_coding/codecs/av1/libaom_av1_unittest.cc
index 29aa539..766b766 100644
--- a/modules/video_coding/codecs/av1/libaom_av1_unittest.cc
+++ b/modules/video_coding/codecs/av1/libaom_av1_unittest.cc
@@ -89,8 +89,8 @@
 
   void Decode(int64_t frame_id, const EncodedImage& image) {
     ASSERT_THAT(decoder_, NotNull());
-    int32_t error = decoder_->Decode(image, /*missing_frames=*/false,
-                                     /*render_time_ms=*/image.capture_time_ms_);
+    int32_t error =
+        decoder_->Decode(image, /*render_time_ms=*/image.capture_time_ms_);
     if (error != WEBRTC_VIDEO_CODEC_OK) {
       ADD_FAILURE() << "Failed to decode frame id " << frame_id
                     << " with error code " << error << " by decoder#"
diff --git a/modules/video_coding/codecs/h264/test/h264_impl_unittest.cc b/modules/video_coding/codecs/h264/test/h264_impl_unittest.cc
index b8dc859..b8a9add 100644
--- a/modules/video_coding/codecs/h264/test/h264_impl_unittest.cc
+++ b/modules/video_coding/codecs/h264/test/h264_impl_unittest.cc
@@ -62,7 +62,7 @@
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info));
   // First frame should be a key frame.
   encoded_frame._frameType = VideoFrameType::kVideoFrameKey;
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, 0));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, 0));
   std::unique_ptr<VideoFrame> decoded_frame;
   absl::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
@@ -87,7 +87,7 @@
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info));
   // First frame should be a key frame.
   encoded_frame._frameType = VideoFrameType::kVideoFrameKey;
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, 0));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, 0));
   std::unique_ptr<VideoFrame> decoded_frame;
   absl::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
diff --git a/modules/video_coding/codecs/multiplex/include/multiplex_decoder_adapter.h b/modules/video_coding/codecs/multiplex/include/multiplex_decoder_adapter.h
index e73f7d0..d58981e 100644
--- a/modules/video_coding/codecs/multiplex/include/multiplex_decoder_adapter.h
+++ b/modules/video_coding/codecs/multiplex/include/multiplex_decoder_adapter.h
@@ -33,7 +33,6 @@
   // Implements VideoDecoder
   bool Configure(const Settings& settings) override;
   int32_t Decode(const EncodedImage& input_image,
-                 bool missing_frames,
                  int64_t render_time_ms) override;
   int32_t RegisterDecodeCompleteCallback(
       DecodedImageCallback* callback) override;
diff --git a/modules/video_coding/codecs/multiplex/multiplex_decoder_adapter.cc b/modules/video_coding/codecs/multiplex/multiplex_decoder_adapter.cc
index 0ad3d38..9641df3 100644
--- a/modules/video_coding/codecs/multiplex/multiplex_decoder_adapter.cc
+++ b/modules/video_coding/codecs/multiplex/multiplex_decoder_adapter.cc
@@ -125,7 +125,6 @@
 }
 
 int32_t MultiplexDecoderAdapter::Decode(const EncodedImage& input_image,
-                                        bool missing_frames,
                                         int64_t render_time_ms) {
   MultiplexImage image = MultiplexEncodedImagePacker::Unpack(input_image);
 
@@ -149,8 +148,7 @@
   int32_t rv = 0;
   for (size_t i = 0; i < image.image_components.size(); i++) {
     rv = decoders_[image.image_components[i].component_index]->Decode(
-        image.image_components[i].encoded_image, missing_frames,
-        render_time_ms);
+        image.image_components[i].encoded_image, render_time_ms);
     if (rv != WEBRTC_VIDEO_CODEC_OK)
       return rv;
   }
diff --git a/modules/video_coding/codecs/multiplex/test/multiplex_adapter_unittest.cc b/modules/video_coding/codecs/multiplex/test/multiplex_adapter_unittest.cc
index be0f5de..a2f36a3 100644
--- a/modules/video_coding/codecs/multiplex/test/multiplex_adapter_unittest.cc
+++ b/modules/video_coding/codecs/multiplex/test/multiplex_adapter_unittest.cc
@@ -218,7 +218,7 @@
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info));
   EXPECT_EQ(kVideoCodecMultiplex, codec_specific_info.codecType);
 
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, -1));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, -1));
   std::unique_ptr<VideoFrame> decoded_frame;
   absl::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
@@ -235,7 +235,7 @@
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info));
   EXPECT_EQ(kVideoCodecMultiplex, codec_specific_info.codecType);
 
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, 0));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, 0));
   std::unique_ptr<VideoFrame> decoded_frame;
   absl::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
diff --git a/modules/video_coding/codecs/test/video_codec_test.cc b/modules/video_coding/codecs/test/video_codec_test.cc
index 82620248..587af46 100644
--- a/modules/video_coding/codecs/test/video_codec_test.cc
+++ b/modules/video_coding/codecs/test/video_codec_test.cc
@@ -355,8 +355,7 @@
       callbacks_[frame.Timestamp()] = std::move(callback);
     }
 
-    decoder_->Decode(frame, /*missing_frames=*/false,
-                     /*render_time_ms=*/0);
+    decoder_->Decode(frame, /*render_time_ms=*/0);
   }
 
   void Flush() override {
diff --git a/modules/video_coding/codecs/test/videoprocessor.cc b/modules/video_coding/codecs/test/videoprocessor.cc
index cb934c4..3d7f6ff 100644
--- a/modules/video_coding/codecs/test/videoprocessor.cc
+++ b/modules/video_coding/codecs/test/videoprocessor.cc
@@ -638,7 +638,7 @@
 
   frame_stat->decode_start_ns = rtc::TimeNanos();
   frame_stat->decode_return_code =
-      decoders_->at(spatial_idx)->Decode(encoded_image, false, 0);
+      decoders_->at(spatial_idx)->Decode(encoded_image, 0);
 }
 
 const webrtc::EncodedImage* VideoProcessor::BuildAndStoreSuperframe(
diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc b/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc
index 1ac7189..01cedb5 100644
--- a/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc
+++ b/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc
@@ -37,7 +37,6 @@
 
 namespace webrtc {
 namespace {
-constexpr int kVp8ErrorPropagationTh = 30;
 // vpx_decoder.h documentation indicates decode deadline is time in us, with
 // "Set to zero for unlimited.", but actual implementation requires this to be
 // a mode with 0 meaning allow delay and 1 not allowing it.
@@ -122,7 +121,6 @@
       decode_complete_callback_(NULL),
       inited_(false),
       decoder_(NULL),
-      propagation_cnt_(-1),
       last_frame_width_(0),
       last_frame_height_(0),
       key_frame_required_(true),
@@ -156,7 +154,6 @@
     return false;
   }
 
-  propagation_cnt_ = -1;
   inited_ = true;
 
   // Always start with a complete key frame.
@@ -170,7 +167,12 @@
 }
 
 int LibvpxVp8Decoder::Decode(const EncodedImage& input_image,
-                             bool missing_frames,
+                             int64_t render_time_ms) {
+  return Decode(input_image, /*missing_frames=*/false, render_time_ms);
+}
+
+int LibvpxVp8Decoder::Decode(const EncodedImage& input_image,
+                             bool /*missing_frames*/,
                              int64_t /*render_time_ms*/) {
   if (!inited_) {
     return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
@@ -179,9 +181,6 @@
     return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
   }
   if (input_image.data() == NULL && input_image.size() > 0) {
-    // Reset to avoid requesting key frames too often.
-    if (propagation_cnt_ > 0)
-      propagation_cnt_ = 0;
     return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
   }
 
@@ -234,34 +233,6 @@
       return WEBRTC_VIDEO_CODEC_ERROR;
     key_frame_required_ = false;
   }
-  // Restrict error propagation using key frame requests.
-  // Reset on a key frame refresh.
-  if (input_image._frameType == VideoFrameType::kVideoFrameKey) {
-    propagation_cnt_ = -1;
-    // Start count on first loss.
-  } else if (missing_frames && propagation_cnt_ == -1) {
-    propagation_cnt_ = 0;
-  }
-  if (propagation_cnt_ >= 0) {
-    propagation_cnt_++;
-  }
-
-  vpx_codec_iter_t iter = NULL;
-  vpx_image_t* img;
-  int ret;
-
-  // Check for missing frames.
-  if (missing_frames) {
-    // Call decoder with zero data length to signal missing frames.
-    if (vpx_codec_decode(decoder_, NULL, 0, 0, kDecodeDeadlineRealtime)) {
-      // Reset to avoid requesting key frames too often.
-      if (propagation_cnt_ > 0)
-        propagation_cnt_ = 0;
-      return WEBRTC_VIDEO_CODEC_ERROR;
-    }
-    img = vpx_codec_get_frame(decoder_, &iter);
-    iter = NULL;
-  }
 
   const uint8_t* buffer = input_image.data();
   if (input_image.size() == 0) {
@@ -269,31 +240,20 @@
   }
   if (vpx_codec_decode(decoder_, buffer, input_image.size(), 0,
                        kDecodeDeadlineRealtime)) {
-    // Reset to avoid requesting key frames too often.
-    if (propagation_cnt_ > 0) {
-      propagation_cnt_ = 0;
-    }
     return WEBRTC_VIDEO_CODEC_ERROR;
   }
 
-  img = vpx_codec_get_frame(decoder_, &iter);
+  vpx_codec_iter_t iter = NULL;
+  vpx_image_t* img = vpx_codec_get_frame(decoder_, &iter);
   int qp;
   vpx_codec_err_t vpx_ret =
       vpx_codec_control(decoder_, VPXD_GET_LAST_QUANTIZER, &qp);
   RTC_DCHECK_EQ(vpx_ret, VPX_CODEC_OK);
-  ret = ReturnFrame(img, input_image.Timestamp(), qp, input_image.ColorSpace());
+  int ret =
+      ReturnFrame(img, input_image.Timestamp(), qp, input_image.ColorSpace());
   if (ret != 0) {
-    // Reset to avoid requesting key frames too often.
-    if (ret < 0 && propagation_cnt_ > 0)
-      propagation_cnt_ = 0;
     return ret;
   }
-  // Check Vs. threshold
-  if (propagation_cnt_ > kVp8ErrorPropagationTh) {
-    // Reset to avoid requesting key frames too often.
-    propagation_cnt_ = 0;
-    return WEBRTC_VIDEO_CODEC_ERROR;
-  }
   return WEBRTC_VIDEO_CODEC_OK;
 }
 
diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h b/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h
index f9acd70..74f4dc7 100644
--- a/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h
+++ b/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h
@@ -31,6 +31,11 @@
 
   bool Configure(const Settings& settings) override;
   int Decode(const EncodedImage& input_image,
+             int64_t /*render_time_ms*/) override;
+
+  // TODO(bugs.webrtc.org/15444): Remove once all subclasses have been migrated
+  // to expecting calls Decode without a missing_frames param.
+  int Decode(const EncodedImage& input_image,
              bool missing_frames,
              int64_t /*render_time_ms*/) override;
 
@@ -61,7 +66,6 @@
   DecodedImageCallback* decode_complete_callback_;
   bool inited_;
   vpx_codec_ctx_t* decoder_;
-  int propagation_cnt_;
   int last_frame_width_;
   int last_frame_height_;
   bool key_frame_required_;
diff --git a/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc b/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc
index 839d696..14ac8aa 100644
--- a/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc
+++ b/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc
@@ -286,7 +286,7 @@
 
   // First frame should be a key frame.
   encoded_frame._frameType = VideoFrameType::kVideoFrameKey;
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, -1));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, -1));
   std::unique_ptr<VideoFrame> decoded_frame;
   absl::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
@@ -501,7 +501,7 @@
   // First frame should be a key frame.
   encoded_frame._frameType = VideoFrameType::kVideoFrameKey;
   encoded_frame.ntp_time_ms_ = kTestNtpTimeMs;
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, -1));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, -1));
 
   std::unique_ptr<VideoFrame> decoded_frame;
   absl::optional<uint8_t> decoded_qp;
diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_decoder.cc b/modules/video_coding/codecs/vp9/libvpx_vp9_decoder.cc
index a981f25..2dec061 100644
--- a/modules/video_coding/codecs/vp9/libvpx_vp9_decoder.cc
+++ b/modules/video_coding/codecs/vp9/libvpx_vp9_decoder.cc
@@ -188,7 +188,6 @@
 }
 
 int LibvpxVp9Decoder::Decode(const EncodedImage& input_image,
-                             bool missing_frames,
                              int64_t /*render_time_ms*/) {
   if (!inited_) {
     return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_decoder.h b/modules/video_coding/codecs/vp9/libvpx_vp9_decoder.h
index 65fc553..4275836 100644
--- a/modules/video_coding/codecs/vp9/libvpx_vp9_decoder.h
+++ b/modules/video_coding/codecs/vp9/libvpx_vp9_decoder.h
@@ -29,7 +29,6 @@
   bool Configure(const Settings& settings) override;
 
   int Decode(const EncodedImage& input_image,
-             bool missing_frames,
              int64_t /*render_time_ms*/) override;
 
   int RegisterDecodeCompleteCallback(DecodedImageCallback* callback) override;
diff --git a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
index 3bf165f..993fd24 100644
--- a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
+++ b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
@@ -143,7 +143,7 @@
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info));
   // First frame should be a key frame.
   encoded_frame._frameType = VideoFrameType::kVideoFrameKey;
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, 0));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, 0));
   std::unique_ptr<VideoFrame> decoded_frame;
   absl::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
@@ -193,7 +193,7 @@
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info));
 
   // Encoded frame without explicit color space information.
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, 0));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, 0));
   std::unique_ptr<VideoFrame> decoded_frame;
   absl::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
@@ -211,7 +211,7 @@
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info));
   // First frame should be a key frame.
   encoded_frame._frameType = VideoFrameType::kVideoFrameKey;
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, 0));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, 0));
   std::unique_ptr<VideoFrame> decoded_frame;
   absl::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
@@ -2063,7 +2063,7 @@
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info));
   // First frame should be a key frame.
   encoded_frame._frameType = VideoFrameType::kVideoFrameKey;
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, 0));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, 0));
   std::unique_ptr<VideoFrame> decoded_frame;
   absl::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
diff --git a/modules/video_coding/generic_decoder.cc b/modules/video_coding/generic_decoder.cc
index 7ebc387..a13fe8e 100644
--- a/modules/video_coding/generic_decoder.cc
+++ b/modules/video_coding/generic_decoder.cc
@@ -282,17 +282,16 @@
 }
 
 int32_t VCMGenericDecoder::Decode(const EncodedFrame& frame, Timestamp now) {
-  return Decode(frame, now, frame.RenderTimeMs(), frame.MissingFrame());
+  return Decode(frame, now, frame.RenderTimeMs());
 }
 
 int32_t VCMGenericDecoder::Decode(const VCMEncodedFrame& frame, Timestamp now) {
-  return Decode(frame, now, frame.RenderTimeMs(), frame.MissingFrame());
+  return Decode(frame, now, frame.RenderTimeMs());
 }
 
 int32_t VCMGenericDecoder::Decode(const EncodedImage& frame,
                                   Timestamp now,
-                                  int64_t render_time_ms,
-                                  int64_t missing_frame) {
+                                  int64_t render_time_ms) {
   TRACE_EVENT1("webrtc", "VCMGenericDecoder::Decode", "timestamp",
                frame.Timestamp());
   FrameInfo frame_info;
@@ -319,7 +318,7 @@
   frame_info.frame_type = frame.FrameType();
   _callback->Map(std::move(frame_info));
 
-  int32_t ret = decoder_->Decode(frame, missing_frame, render_time_ms);
+  int32_t ret = decoder_->Decode(frame, render_time_ms);
   VideoDecoder::DecoderInfo decoder_info = decoder_->GetDecoderInfo();
   if (decoder_info != decoder_info_) {
     RTC_LOG(LS_INFO) << "Changed decoder implementation to: "
diff --git a/modules/video_coding/generic_decoder.h b/modules/video_coding/generic_decoder.h
index be08fc6..b1fb1f3 100644
--- a/modules/video_coding/generic_decoder.h
+++ b/modules/video_coding/generic_decoder.h
@@ -120,8 +120,7 @@
  private:
   int32_t Decode(const EncodedImage& frame,
                  Timestamp now,
-                 int64_t render_time_ms,
-                 int64_t missing_frame);
+                 int64_t render_time_ms);
   VCMDecodedFrameCallback* _callback = nullptr;
   VideoDecoder* const decoder_;
   VideoContentType _last_keyframe_content_type;
diff --git a/modules/video_coding/utility/simulcast_test_fixture_impl.cc b/modules/video_coding/utility/simulcast_test_fixture_impl.cc
index 5a111c0..338835e 100644
--- a/modules/video_coding/utility/simulcast_test_fixture_impl.cc
+++ b/modules/video_coding/utility/simulcast_test_fixture_impl.cc
@@ -894,9 +894,9 @@
   EncodedImage encoded_frame;
   // Only encoding one frame - so will be a key frame.
   encoder_callback.GetLastEncodedKeyFrame(&encoded_frame);
-  EXPECT_EQ(0, decoder_->Decode(encoded_frame, false, 0));
+  EXPECT_EQ(0, decoder_->Decode(encoded_frame, 0));
   encoder_callback.GetLastEncodedFrame(&encoded_frame);
-  decoder_->Decode(encoded_frame, false, 0);
+  decoder_->Decode(encoded_frame, 0);
   EXPECT_EQ(2, decoder_callback.DecodedFrames());
 }
 
@@ -932,7 +932,7 @@
         EXPECT_EQ(decodedImage.width(), kDefaultWidth / 4);
         EXPECT_EQ(decodedImage.height(), kDefaultHeight / 4);
       }));
-  EXPECT_EQ(0, decoder_->Decode(encoded_frame[0], false, 0));
+  EXPECT_EQ(0, decoder_->Decode(encoded_frame[0], 0));
 
   EXPECT_CALL(decoder_callback, Decoded(_, _, _))
       .WillOnce(::testing::Invoke([](VideoFrame& decodedImage,
@@ -941,7 +941,7 @@
         EXPECT_EQ(decodedImage.width(), kDefaultWidth / 2);
         EXPECT_EQ(decodedImage.height(), kDefaultHeight / 2);
       }));
-  EXPECT_EQ(0, decoder_->Decode(encoded_frame[1], false, 0));
+  EXPECT_EQ(0, decoder_->Decode(encoded_frame[1], 0));
 
   EXPECT_CALL(decoder_callback, Decoded(_, _, _))
       .WillOnce(::testing::Invoke([](VideoFrame& decodedImage,
@@ -950,7 +950,7 @@
         EXPECT_EQ(decodedImage.width(), kDefaultWidth);
         EXPECT_EQ(decodedImage.height(), kDefaultHeight);
       }));
-  EXPECT_EQ(0, decoder_->Decode(encoded_frame[2], false, 0));
+  EXPECT_EQ(0, decoder_->Decode(encoded_frame[2], 0));
 }
 
 void SimulcastTestFixtureImpl::
diff --git a/modules/video_coding/video_receiver2_unittest.cc b/modules/video_coding/video_receiver2_unittest.cc
index b524316..88a19df 100644
--- a/modules/video_coding/video_receiver2_unittest.cc
+++ b/modules/video_coding/video_receiver2_unittest.cc
@@ -123,7 +123,7 @@
   auto decoder = std::make_unique<NiceMock<MockVideoDecoder>>();
   EXPECT_CALL(*decoder, RegisterDecodeCompleteCallback)
       .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
-  EXPECT_CALL(*decoder, Decode).WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
+  EXPECT_CALL(*decoder, Decode(_, _)).WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
   EXPECT_CALL(*decoder, Release).WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
 
   // Register the decoder. Note that this moves ownership of the mock object
diff --git a/modules/video_coding/video_receiver_unittest.cc b/modules/video_coding/video_receiver_unittest.cc
index 8a70664..2063653 100644
--- a/modules/video_coding/video_receiver_unittest.cc
+++ b/modules/video_coding/video_receiver_unittest.cc
@@ -109,7 +109,7 @@
       ++header->sequenceNumber;
     }
     receiver_.Process();
-    EXPECT_CALL(decoder_, Decode(_, _, _)).Times(0);
+    EXPECT_CALL(decoder_, Decode(_, _)).Times(0);
     EXPECT_EQ(VCM_FRAME_NOT_READY, receiver_.Decode(kMaxWaitTimeMs));
   }
 
@@ -123,7 +123,7 @@
     EXPECT_CALL(packet_request_callback_, ResendPackets(_, _)).Times(0);
 
     receiver_.Process();
-    EXPECT_CALL(decoder_, Decode(_, _, _)).Times(1);
+    EXPECT_CALL(decoder_, Decode(_, _)).Times(1);
     EXPECT_EQ(0, receiver_.Decode(kMaxWaitTimeMs));
   }
 
diff --git a/rtc_tools/video_replay.cc b/rtc_tools/video_replay.cc
index 2600598..242ce1b 100644
--- a/rtc_tools/video_replay.cc
+++ b/rtc_tools/video_replay.cc
@@ -240,7 +240,6 @@
   ~DecoderBitstreamFileWriter() override { fclose(file_); }
 
   int32_t Decode(const EncodedImage& encoded_frame,
-                 bool /* missing_frames */,
                  int64_t /* render_time_ms */) override {
     if (fwrite(encoded_frame.data(), 1, encoded_frame.size(), file_) <
         encoded_frame.size()) {
@@ -276,7 +275,6 @@
   ~DecoderIvfFileWriter() override { file_writer_->Close(); }
 
   int32_t Decode(const EncodedImage& encoded_frame,
-                 bool /* missing_frames */,
                  int64_t render_time_ms) override {
     if (!file_writer_->WriteFrame(encoded_frame, video_codec_type_)) {
       return WEBRTC_VIDEO_CODEC_ERROR;
diff --git a/sdk/objc/api/video_codec/RTCWrappedNativeVideoDecoder.mm b/sdk/objc/api/video_codec/RTCWrappedNativeVideoDecoder.mm
index 261874d..29d2265 100644
--- a/sdk/objc/api/video_codec/RTCWrappedNativeVideoDecoder.mm
+++ b/sdk/objc/api/video_codec/RTCWrappedNativeVideoDecoder.mm
@@ -46,6 +46,7 @@
   return 0;
 }
 
+// TODO(bugs.webrtc.org/15444): Remove obsolete missingFrames param.
 - (NSInteger)decode:(RTC_OBJC_TYPE(RTCEncodedImage) *)encodedImage
         missingFrames:(BOOL)missingFrames
     codecSpecificInfo:(nullable id<RTC_OBJC_TYPE(RTCCodecSpecificInfo)>)info
diff --git a/sdk/objc/base/RTCVideoDecoder.h b/sdk/objc/base/RTCVideoDecoder.h
index ccddd42..2565afa 100644
--- a/sdk/objc/base/RTCVideoDecoder.h
+++ b/sdk/objc/base/RTCVideoDecoder.h
@@ -29,6 +29,7 @@
     - (void)setCallback : (RTCVideoDecoderCallback)callback;
 - (NSInteger)startDecodeWithNumberOfCores:(int)numberOfCores;
 - (NSInteger)releaseDecoder;
+// TODO(bugs.webrtc.org/15444): Remove obsolete missingFrames param.
 - (NSInteger)decode:(RTC_OBJC_TYPE(RTCEncodedImage) *)encodedImage
         missingFrames:(BOOL)missingFrames
     codecSpecificInfo:(nullable id<RTC_OBJC_TYPE(RTCCodecSpecificInfo)>)info
diff --git a/sdk/objc/components/video_codec/RTCVideoDecoderH264.mm b/sdk/objc/components/video_codec/RTCVideoDecoderH264.mm
index 3f30bb1..6708b26 100644
--- a/sdk/objc/components/video_codec/RTCVideoDecoderH264.mm
+++ b/sdk/objc/components/video_codec/RTCVideoDecoderH264.mm
@@ -98,6 +98,7 @@
   return WEBRTC_VIDEO_CODEC_OK;
 }
 
+// TODO(bugs.webrtc.org/15444): Remove obsolete missingFrames param.
 - (NSInteger)decode:(RTC_OBJC_TYPE(RTCEncodedImage) *)inputImage
         missingFrames:(BOOL)missingFrames
     codecSpecificInfo:(nullable id<RTC_OBJC_TYPE(RTCCodecSpecificInfo)>)info
diff --git a/sdk/objc/native/src/objc_video_decoder_factory.mm b/sdk/objc/native/src/objc_video_decoder_factory.mm
index da3b302..bf5e898 100644
--- a/sdk/objc/native/src/objc_video_decoder_factory.mm
+++ b/sdk/objc/native/src/objc_video_decoder_factory.mm
@@ -43,13 +43,12 @@
   }
 
   int32_t Decode(const EncodedImage &input_image,
-                 bool missing_frames,
                  int64_t render_time_ms = -1) override {
     RTC_OBJC_TYPE(RTCEncodedImage) *encodedImage =
         [[RTC_OBJC_TYPE(RTCEncodedImage) alloc] initWithNativeEncodedImage:input_image];
 
     return [decoder_ decode:encodedImage
-              missingFrames:missing_frames
+              missingFrames:false
           codecSpecificInfo:nil
                renderTimeMs:render_time_ms];
   }
diff --git a/test/fake_decoder.cc b/test/fake_decoder.cc
index 53fce37..b5fd15b 100644
--- a/test/fake_decoder.cc
+++ b/test/fake_decoder.cc
@@ -41,7 +41,6 @@
 }
 
 int32_t FakeDecoder::Decode(const EncodedImage& input,
-                            bool missing_frames,
                             int64_t render_time_ms) {
   if (input._encodedWidth > 0 && input._encodedHeight > 0) {
     width_ = input._encodedWidth;
@@ -103,7 +102,6 @@
 }
 
 int32_t FakeH264Decoder::Decode(const EncodedImage& input,
-                                bool missing_frames,
                                 int64_t render_time_ms) {
   uint8_t value = 0;
   for (size_t i = 0; i < input.size(); ++i) {
@@ -119,7 +117,7 @@
     }
     ++value;
   }
-  return FakeDecoder::Decode(input, missing_frames, render_time_ms);
+  return FakeDecoder::Decode(input, render_time_ms);
 }
 
 }  // namespace test
diff --git a/test/fake_decoder.h b/test/fake_decoder.h
index cea92b4..e14eae0 100644
--- a/test/fake_decoder.h
+++ b/test/fake_decoder.h
@@ -35,7 +35,6 @@
   bool Configure(const Settings& settings) override;
 
   int32_t Decode(const EncodedImage& input,
-                 bool missing_frames,
                  int64_t render_time_ms) override;
 
   int32_t RegisterDecodeCompleteCallback(
@@ -64,7 +63,6 @@
   virtual ~FakeH264Decoder() {}
 
   int32_t Decode(const EncodedImage& input,
-                 bool missing_frames,
                  int64_t render_time_ms) override;
 };
 
diff --git a/test/fake_vp8_decoder.cc b/test/fake_vp8_decoder.cc
index 137614a..db18b9b 100644
--- a/test/fake_vp8_decoder.cc
+++ b/test/fake_vp8_decoder.cc
@@ -44,7 +44,6 @@
 }
 
 int32_t FakeVp8Decoder::Decode(const EncodedImage& input,
-                               bool missing_frames,
                                int64_t render_time_ms) {
   constexpr size_t kMinPayLoadHeaderLength = 10;
   if (input.size() < kMinPayLoadHeaderLength) {
diff --git a/test/fake_vp8_decoder.h b/test/fake_vp8_decoder.h
index a73922e..95cc4b6 100644
--- a/test/fake_vp8_decoder.h
+++ b/test/fake_vp8_decoder.h
@@ -28,7 +28,6 @@
   bool Configure(const Settings& settings) override;
 
   int32_t Decode(const EncodedImage& input,
-                 bool missing_frames,
                  int64_t render_time_ms) override;
 
   int32_t RegisterDecodeCompleteCallback(
diff --git a/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc b/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc
index b958f4d..4d19c91 100644
--- a/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc
+++ b/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc
@@ -51,7 +51,6 @@
 }
 
 int32_t QualityAnalyzingVideoDecoder::Decode(const EncodedImage& input_image,
-                                             bool missing_frames,
                                              int64_t render_time_ms) {
   // Image  extractor extracts id from provided EncodedImage and also returns
   // the image with the original buffer. Buffer can be modified in place, so
@@ -96,8 +95,7 @@
   // thread.
   analyzer_->OnFramePreDecode(
       peer_name_, out.id.value_or(VideoFrame::kNotSetId), *origin_image);
-  int32_t result =
-      delegate_->Decode(*origin_image, missing_frames, render_time_ms);
+  int32_t result = delegate_->Decode(*origin_image, render_time_ms);
   if (result != WEBRTC_VIDEO_CODEC_OK) {
     // If delegate decoder failed, then cleanup data for this image.
     VideoQualityAnalyzerInterface::DecoderStats stats;
diff --git a/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h b/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h
index a86f419..2f0c2b9 100644
--- a/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h
+++ b/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h
@@ -59,7 +59,6 @@
   // Methods of VideoDecoder interface.
   bool Configure(const Settings& settings) override;
   int32_t Decode(const EncodedImage& input_image,
-                 bool missing_frames,
                  int64_t render_time_ms) override;
   int32_t RegisterDecodeCompleteCallback(
       DecodedImageCallback* callback) override;
diff --git a/test/testsupport/ivf_video_frame_generator.cc b/test/testsupport/ivf_video_frame_generator.cc
index 0c7504b..ec3c948 100644
--- a/test/testsupport/ivf_video_frame_generator.cc
+++ b/test/testsupport/ivf_video_frame_generator.cc
@@ -79,8 +79,7 @@
   RTC_CHECK(image);
   // Last parameter is undocumented and there is no usage of it found.
   RTC_CHECK_EQ(WEBRTC_VIDEO_CODEC_OK,
-               video_decoder_->Decode(*image, /*missing_frames=*/false,
-                                      /*render_time_ms=*/0));
+               video_decoder_->Decode(*image, /*render_time_ms=*/0));
   bool decoded = next_frame_decoded_.Wait(kMaxNextFrameWaitTimeout);
   RTC_CHECK(decoded) << "Failed to decode next frame in "
                      << kMaxNextFrameWaitTimeout << ". Can't continue";
diff --git a/test/video_decoder_proxy_factory.h b/test/video_decoder_proxy_factory.h
index 6fd3805..f2b318e 100644
--- a/test/video_decoder_proxy_factory.h
+++ b/test/video_decoder_proxy_factory.h
@@ -48,9 +48,8 @@
 
    private:
     int32_t Decode(const EncodedImage& input_image,
-                   bool missing_frames,
                    int64_t render_time_ms) override {
-      return decoder_->Decode(input_image, missing_frames, render_time_ms);
+      return decoder_->Decode(input_image, render_time_ms);
     }
     bool Configure(const Settings& settings) override {
       return decoder_->Configure(settings);
diff --git a/video/frame_dumping_decoder.cc b/video/frame_dumping_decoder.cc
index 9592565..cfb2098 100644
--- a/video/frame_dumping_decoder.cc
+++ b/video/frame_dumping_decoder.cc
@@ -26,7 +26,6 @@
 
   bool Configure(const Settings& settings) override;
   int32_t Decode(const EncodedImage& input_image,
-                 bool missing_frames,
                  int64_t render_time_ms) override;
   int32_t RegisterDecodeCompleteCallback(
       DecodedImageCallback* callback) override;
@@ -54,9 +53,8 @@
 }
 
 int32_t FrameDumpingDecoder::Decode(const EncodedImage& input_image,
-                                    bool missing_frames,
                                     int64_t render_time_ms) {
-  int32_t ret = decoder_->Decode(input_image, missing_frames, render_time_ms);
+  int32_t ret = decoder_->Decode(input_image, render_time_ms);
   writer_->WriteFrame(input_image, codec_type_);
 
   return ret;
diff --git a/video/video_receive_stream2.cc b/video/video_receive_stream2.cc
index 36343ec..6c1df7d 100644
--- a/video/video_receive_stream2.cc
+++ b/video/video_receive_stream2.cc
@@ -134,7 +134,6 @@
   }
 
   int32_t Decode(const webrtc::EncodedImage& input_image,
-                 bool missing_frames,
                  int64_t render_time_ms) override {
     RTC_LOG(LS_ERROR) << "The NullVideoDecoder doesn't support decoding.";
     return WEBRTC_VIDEO_CODEC_OK;
diff --git a/video/video_receive_stream2_unittest.cc b/video/video_receive_stream2_unittest.cc
index 7ae446f..084b128 100644
--- a/video/video_receive_stream2_unittest.cc
+++ b/video/video_receive_stream2_unittest.cc
@@ -210,7 +210,7 @@
     // By default, mock decode will wrap the fake decoder.
     ON_CALL(mock_decoder_, Configure)
         .WillByDefault(Invoke(&fake_decoder_, &test::FakeDecoder::Configure));
-    ON_CALL(mock_decoder_, Decode).WillByDefault(DefaultDecodeAction());
+    ON_CALL(mock_decoder_, Decode(_, _)).WillByDefault(DefaultDecodeAction());
     ON_CALL(mock_decoder_, RegisterDecodeCompleteCallback)
         .WillByDefault(
             Invoke(&fake_decoder_,
@@ -304,7 +304,7 @@
   rtppacket.SetTimestamp(0);
   EXPECT_CALL(mock_decoder_, RegisterDecodeCompleteCallback(_));
   video_receive_stream_->Start();
-  EXPECT_CALL(mock_decoder_, Decode(_, false, _));
+  EXPECT_CALL(mock_decoder_, Decode(_, _));
   RtpPacketReceived parsed_packet;
   ASSERT_TRUE(parsed_packet.Parse(rtppacket.data(), rtppacket.size()));
   rtp_stream_receiver_controller_.OnRtpPacket(parsed_packet);
@@ -469,7 +469,7 @@
       CreateVideoDecoder(Field(&SdpVideoFormat::name, testing::Eq("H264"))));
   EXPECT_CALL(mock_decoder_, Configure);
   EXPECT_CALL(mock_decoder_, RegisterDecodeCompleteCallback);
-  EXPECT_CALL(mock_decoder_, Decode);
+  EXPECT_CALL(mock_decoder_, Decode(_, _));
   RtpPacketReceived parsed_packet;
   ASSERT_TRUE(parsed_packet.Parse(rtppacket.data(), rtppacket.size()));
   rtp_stream_receiver_controller_.OnRtpPacket(parsed_packet);
@@ -764,11 +764,10 @@
 
   // Expect frames are decoded in order.
   InSequence seq;
-  EXPECT_CALL(mock_decoder_,
-              Decode(test::RtpTimestamp(kFirstRtpTimestamp), _, _));
+  EXPECT_CALL(mock_decoder_, Decode(test::RtpTimestamp(kFirstRtpTimestamp), _));
   EXPECT_CALL(mock_decoder_, Decode(test::RtpTimestamp(kFirstRtpTimestamp +
                                                        k30FpsRtpTimestampDelta),
-                                    _, _))
+                                    _))
       .Times(1);
   video_receive_stream_->OnCompleteFrame(std::move(key_frame));
   EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame());
@@ -806,14 +805,13 @@
 
   // Expect frames are decoded in order despite delta_frame1 arriving first.
   InSequence seq;
-  EXPECT_CALL(mock_decoder_,
-              Decode(test::RtpTimestamp(kFirstRtpTimestamp), _, _))
+  EXPECT_CALL(mock_decoder_, Decode(test::RtpTimestamp(kFirstRtpTimestamp), _))
       .Times(1);
   EXPECT_CALL(mock_decoder_,
-              Decode(test::RtpTimestamp(RtpTimestampForFrame(1)), _, _))
+              Decode(test::RtpTimestamp(RtpTimestampForFrame(1)), _))
       .Times(1);
   EXPECT_CALL(mock_decoder_,
-              Decode(test::RtpTimestamp(RtpTimestampForFrame(2)), _, _))
+              Decode(test::RtpTimestamp(RtpTimestampForFrame(2)), _))
       .Times(1);
   key_frame->SetReceivedTime(clock_->CurrentTime().ms());
   video_receive_stream_->OnCompleteFrame(std::move(key_frame));
@@ -855,7 +853,7 @@
                  .Build();
 
   // No decodes should be called until `sl2` is received.
-  EXPECT_CALL(mock_decoder_, Decode).Times(0);
+  EXPECT_CALL(mock_decoder_, Decode(_, _)).Times(0);
   sl0->SetReceivedTime(clock_->CurrentTime().ms());
   video_receive_stream_->OnCompleteFrame(std::move(sl0));
   EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()),
@@ -864,8 +862,7 @@
   EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()),
               DidNotReceiveFrame());
   // When `sl2` arrives decode should happen.
-  EXPECT_CALL(mock_decoder_,
-              Decode(test::RtpTimestamp(kFirstRtpTimestamp), _, _))
+  EXPECT_CALL(mock_decoder_, Decode(test::RtpTimestamp(kFirstRtpTimestamp), _))
       .Times(1);
   video_receive_stream_->OnCompleteFrame(std::move(sl2));
   EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame());
@@ -903,15 +900,14 @@
                             .AsLast()
                             .Build();
   InSequence seq;
-  EXPECT_CALL(mock_decoder_,
-              Decode(test::RtpTimestamp(kFirstRtpTimestamp), _, _))
+  EXPECT_CALL(mock_decoder_, Decode(test::RtpTimestamp(kFirstRtpTimestamp), _))
       .WillOnce(testing::DoAll(Invoke([&] {
                                  // System halt will be simulated in the decode.
                                  time_controller_.AdvanceTime(k30FpsDelay * 2);
                                }),
                                DefaultDecodeAction()));
   EXPECT_CALL(mock_decoder_,
-              Decode(test::RtpTimestamp(RtpTimestampForFrame(2)), _, _));
+              Decode(test::RtpTimestamp(RtpTimestampForFrame(2)), _));
   video_receive_stream_->OnCompleteFrame(std::move(key_frame));
   video_receive_stream_->OnCompleteFrame(std::move(ffwd_frame));
   video_receive_stream_->OnCompleteFrame(std::move(rendered_frame));
@@ -959,10 +955,10 @@
 
   InSequence seq;
   EXPECT_CALL(mock_decoder_,
-              Decode(test::RtpTimestamp(RtpTimestampForFrame(1)), _, _))
+              Decode(test::RtpTimestamp(RtpTimestampForFrame(1)), _))
       .Times(1);
   EXPECT_CALL(mock_decoder_,
-              Decode(test::RtpTimestamp(RtpTimestampForFrame(2)), _, _))
+              Decode(test::RtpTimestamp(RtpTimestampForFrame(2)), _))
       .Times(1);
   // Simulate f1 arriving after f2 but before f2 is decoded.
   video_receive_stream_->OnCompleteFrame(std::move(f2));
@@ -1021,7 +1017,7 @@
           .ReceivedTime(clock_->CurrentTime())
           .AsLast()
           .Build());
-  EXPECT_CALL(mock_decoder_, Decode(test::RtpTimestamp(kWrapAroundRtp), _, _))
+  EXPECT_CALL(mock_decoder_, Decode(test::RtpTimestamp(kWrapAroundRtp), _))
       .Times(1);
   EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame());