Revert "Delete CodecSpecificInfo argument from VideoDecoder::Decode"

This reverts commit 39d3a7de02d63894d12e7332322e1d80cd7c0d40.

Reason for revert: This change broke an internal project

Original change's description:
> Delete CodecSpecificInfo argument from VideoDecoder::Decode
> 
> Bug: webrtc:10379
> Change-Id: I079b419604bf4e9c1994fe203d7db131a0ccddb6
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/125920
> Commit-Queue: Niels Moller <nisse@webrtc.org>
> Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
> Reviewed-by: Kári Helgason <kthelgason@webrtc.org>
> Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> Reviewed-by: Erik Språng <sprang@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#27022}

TBR=brandtr@webrtc.org,kwiberg@webrtc.org,nisse@webrtc.org,kthelgason@webrtc.org,sprang@webrtc.org

Change-Id: I2c730cc1834a3b23203fae3d7881f0890802c37b
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:10379
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/126320
Reviewed-by: Jeroen de Borst <jeroendb@webrtc.org>
Commit-Queue: Jeroen de Borst <jeroendb@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27026}
diff --git a/api/test/mock_video_decoder.h b/api/test/mock_video_decoder.h
index 6dee760..56ff546 100644
--- a/api/test/mock_video_decoder.h
+++ b/api/test/mock_video_decoder.h
@@ -41,9 +41,10 @@
 
   MOCK_METHOD2(InitDecode,
                int32_t(const VideoCodec* codecSettings, int32_t numberOfCores));
-  MOCK_METHOD3(Decode,
+  MOCK_METHOD4(Decode,
                int32_t(const EncodedImage& inputImage,
                        bool missingFrames,
+                       const CodecSpecificInfo* codecSpecificInfo,
                        int64_t renderTimeMs));
   MOCK_METHOD1(RegisterDecodeCompleteCallback,
                int32_t(DecodedImageCallback* callback));
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 0e97173..06b893c 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
@@ -49,6 +49,7 @@
 
     int32_t Decode(const EncodedImage& input_image,
                    bool missing_frames,
+                   const CodecSpecificInfo* codec_specific_info,
                    int64_t render_time_ms) override {
       ++decode_count_;
       return decode_return_code_;
@@ -88,7 +89,7 @@
 
   EncodedImage encoded_image;
   encoded_image._frameType = kVideoFrameKey;
-  fallback_wrapper_->Decode(encoded_image, false, -1);
+  fallback_wrapper_->Decode(encoded_image, false, nullptr, -1);
   EXPECT_EQ(1, fake_decoder_->init_decode_count_)
       << "Initialized decoder should not be reinitialized.";
   EXPECT_EQ(1, fake_decoder_->decode_count_);
@@ -103,7 +104,7 @@
 
   EncodedImage encoded_image;
   encoded_image._frameType = kVideoFrameKey;
-  fallback_wrapper_->Decode(encoded_image, false, -1);
+  fallback_wrapper_->Decode(encoded_image, false, nullptr, -1);
   EXPECT_EQ(1, fake_decoder_->init_decode_count_)
       << "Should not have attempted reinitializing the fallback decoder on "
          "keyframe.";
@@ -119,12 +120,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, false, nullptr, -1);
   EXPECT_EQ(1, fake_decoder_->decode_count_);
 
   // Software fallback should be sticky, fake_decoder_ shouldn't be used.
   encoded_image._frameType = kVideoFrameKey;
-  fallback_wrapper_->Decode(encoded_image, false, -1);
+  fallback_wrapper_->Decode(encoded_image, false, nullptr, -1);
   EXPECT_EQ(1, fake_decoder_->decode_count_)
       << "Decoder shouldn't be used after failure.";
 
@@ -138,10 +139,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, false, nullptr, -1));
   EXPECT_EQ(1, fake_decoder_->decode_count_);
 
-  fallback_wrapper_->Decode(encoded_image, false, -1);
+  fallback_wrapper_->Decode(encoded_image, false, nullptr, -1);
   EXPECT_EQ(2, fake_decoder_->decode_count_)
       << "Decoder should be active even though previous decode failed.";
 }
@@ -152,14 +153,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, false, nullptr, -1);
   EXPECT_EQ(1, fake_decoder_->decode_count_);
 
   fallback_wrapper_->Release();
   fallback_wrapper_->InitDecode(&codec, 2);
 
   fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
-  fallback_wrapper_->Decode(encoded_image, false, -1);
+  fallback_wrapper_->Decode(encoded_image, false, nullptr, -1);
   EXPECT_EQ(2, fake_decoder_->decode_count_)
       << "Should not be using fallback after reinit.";
 }
@@ -173,7 +174,7 @@
   fallback_wrapper_->InitDecode(&codec, 2);
   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, false, nullptr, -1);
   EXPECT_EQ(2, fake_decoder_->release_count_)
       << "Decoder should be released during fallback.";
   fallback_wrapper_->Release();
@@ -211,7 +212,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, false, nullptr, -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)",
@@ -242,7 +243,7 @@
 
   EncodedImage encoded_image;
   encoded_image._frameType = kVideoFrameKey;
-  fallback_wrapper_->Decode(encoded_image, false, -1);
+  fallback_wrapper_->Decode(encoded_image, false, nullptr, -1);
   EXPECT_EQ(1, sw_fallback_decoder_->init_decode_count_);
   EXPECT_EQ(1, sw_fallback_decoder_->decode_count_);
 
diff --git a/api/video_codecs/video_decoder.cc b/api/video_codecs/video_decoder.cc
index 32725b9..b5fff32 100644
--- a/api/video_codecs/video_decoder.cc
+++ b/api/video_codecs/video_decoder.cc
@@ -33,19 +33,6 @@
   return -1;
 }
 
-int32_t VideoDecoder::Decode(const EncodedImage& input_image,
-                             bool missing_frames,
-                             int64_t render_time_ms) {
-  return Decode(input_image, missing_frames, nullptr, render_time_ms);
-}
-
-int32_t VideoDecoder::Decode(const EncodedImage& input_image,
-                             bool missing_frames,
-                             const CodecSpecificInfo* codec_specific_info,
-                             int64_t render_time_ms) {
-  return Decode(input_image, missing_frames, render_time_ms);
-}
-
 bool VideoDecoder::PrefersLateDecoding() const {
   return true;
 }
diff --git a/api/video_codecs/video_decoder.h b/api/video_codecs/video_decoder.h
index 3403987..36cf80f 100644
--- a/api/video_codecs/video_decoder.h
+++ b/api/video_codecs/video_decoder.h
@@ -57,14 +57,8 @@
 
   virtual int32_t Decode(const EncodedImage& input_image,
                          bool missing_frames,
-                         int64_t render_time_ms);
-
-  // TODO(bugs.webrtc.org/10379): Deprecated. Delete, and make above method pure
-  // virtual, as soon as downstream applications are updated.
-  virtual int32_t Decode(const EncodedImage& input_image,
-                         bool missing_frames,
                          const CodecSpecificInfo* codec_specific_info,
-                         int64_t render_time_ms);
+                         int64_t render_time_ms) = 0;
 
   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 9bf1dfd..0bbce3e 100644
--- a/api/video_codecs/video_decoder_software_fallback_wrapper.cc
+++ b/api/video_codecs/video_decoder_software_fallback_wrapper.cc
@@ -40,6 +40,7 @@
 
   int32_t Decode(const EncodedImage& input_image,
                  bool missing_frames,
+                 const CodecSpecificInfo* codec_specific_info,
                  int64_t render_time_ms) override;
 
   int32_t RegisterDecodeCompleteCallback(
@@ -146,6 +147,7 @@
 int32_t VideoDecoderSoftwareFallbackWrapper::Decode(
     const EncodedImage& input_image,
     bool missing_frames,
+    const CodecSpecificInfo* codec_specific_info,
     int64_t render_time_ms) {
   TRACE_EVENT0("webrtc", "VideoDecoderSoftwareFallbackWrapper::Decode");
   switch (decoder_type_) {
@@ -153,7 +155,8 @@
       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, missing_frames,
+                                codec_specific_info, render_time_ms);
       if (ret != WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE) {
         return ret;
       }
@@ -169,7 +172,7 @@
     }
     case DecoderType::kFallback:
       return fallback_decoder_->Decode(input_image, missing_frames,
-                                       render_time_ms);
+                                       codec_specific_info, render_time_ms);
     default:
       RTC_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 c8be0b0..d4de300 100644
--- a/media/engine/fake_webrtc_video_engine.cc
+++ b/media/engine/fake_webrtc_video_engine.cc
@@ -57,6 +57,7 @@
 
 int32_t FakeWebRtcVideoDecoder::Decode(const webrtc::EncodedImage&,
                                        bool,
+                                       const webrtc::CodecSpecificInfo*,
                                        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 dcd723a..3ab924a 100644
--- a/media/engine/fake_webrtc_video_engine.h
+++ b/media/engine/fake_webrtc_video_engine.h
@@ -46,6 +46,7 @@
   int32_t InitDecode(const webrtc::VideoCodec*, int32_t) override;
   int32_t Decode(const webrtc::EncodedImage&,
                  bool,
+                 const webrtc::CodecSpecificInfo*,
                  int64_t) override;
   int32_t RegisterDecodeCompleteCallback(
       webrtc::DecodedImageCallback*) override;
diff --git a/modules/video_coding/codecs/h264/h264_decoder_impl.cc b/modules/video_coding/codecs/h264/h264_decoder_impl.cc
index d72ef06..e5d31ed 100644
--- a/modules/video_coding/codecs/h264/h264_decoder_impl.cc
+++ b/modules/video_coding/codecs/h264/h264_decoder_impl.cc
@@ -228,6 +228,7 @@
 
 int32_t H264DecoderImpl::Decode(const EncodedImage& input_image,
                                 bool /*missing_frames*/,
+                                const CodecSpecificInfo* codec_specific_info,
                                 int64_t /*render_time_ms*/) {
   if (!IsInitialized()) {
     ReportError();
@@ -244,6 +245,11 @@
     ReportError();
     return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
   }
+  if (codec_specific_info &&
+      codec_specific_info->codecType != kVideoCodecH264) {
+    ReportError();
+    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
+  }
 
   // FFmpeg requires padding due to some optimized bitstream readers reading 32
   // or 64 bits at once and could read over the end. See avcodec_decode_video2.
diff --git a/modules/video_coding/codecs/h264/h264_decoder_impl.h b/modules/video_coding/codecs/h264/h264_decoder_impl.h
index f932568..a709177 100644
--- a/modules/video_coding/codecs/h264/h264_decoder_impl.h
+++ b/modules/video_coding/codecs/h264/h264_decoder_impl.h
@@ -49,6 +49,7 @@
   // |missing_frames|, |fragmentation| and |render_time_ms| are ignored.
   int32_t Decode(const EncodedImage& input_image,
                  bool /*missing_frames*/,
+                 const CodecSpecificInfo* codec_specific_info = nullptr,
                  int64_t render_time_ms = -1) override;
 
   const char* ImplementationName() const override;
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 12357f5..57c3a9f 100644
--- a/modules/video_coding/codecs/h264/test/h264_impl_unittest.cc
+++ b/modules/video_coding/codecs/h264/test/h264_impl_unittest.cc
@@ -71,7 +71,8 @@
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info));
   // First frame should be a key frame.
   encoded_frame._frameType = kVideoFrameKey;
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, 0));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+            decoder_->Decode(encoded_frame, false, nullptr, 0));
   std::unique_ptr<VideoFrame> decoded_frame;
   absl::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
@@ -97,7 +98,8 @@
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info));
   // First frame should be a key frame.
   encoded_frame._frameType = kVideoFrameKey;
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, 0));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+            decoder_->Decode(encoded_frame, false, nullptr, 0));
   std::unique_ptr<VideoFrame> decoded_frame;
   absl::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
@@ -138,7 +140,8 @@
   // Add color space to encoded frame.
   ColorSpace color_space = CreateTestColorSpace(/*with_hdr_metadata=*/false);
   encoded_frame.SetColorSpace(color_space);
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, 0));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+            decoder_->Decode(encoded_frame, false, nullptr, 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 8976250..73b67c9 100644
--- a/modules/video_coding/codecs/multiplex/include/multiplex_decoder_adapter.h
+++ b/modules/video_coding/codecs/multiplex/include/multiplex_decoder_adapter.h
@@ -35,6 +35,7 @@
                      int32_t number_of_cores) override;
   int32_t Decode(const EncodedImage& input_image,
                  bool missing_frames,
+                 const CodecSpecificInfo* codec_specific_info,
                  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 d1c8220..0facbe4 100644
--- a/modules/video_coding/codecs/multiplex/multiplex_decoder_adapter.cc
+++ b/modules/video_coding/codecs/multiplex/multiplex_decoder_adapter.cc
@@ -130,6 +130,7 @@
 int32_t MultiplexDecoderAdapter::Decode(
     const EncodedImage& input_image,
     bool missing_frames,
+    const CodecSpecificInfo* codec_specific_info,
     int64_t render_time_ms) {
   MultiplexImage image = MultiplexEncodedImagePacker::Unpack(input_image);
 
@@ -153,7 +154,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,
+        image.image_components[i].encoded_image, missing_frames, nullptr,
         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 8b4b837..3aa7c28 100644
--- a/modules/video_coding/codecs/multiplex/test/multiplex_adapter_unittest.cc
+++ b/modules/video_coding/codecs/multiplex/test/multiplex_adapter_unittest.cc
@@ -225,7 +225,8 @@
   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, false, &codec_specific_info, -1));
   std::unique_ptr<VideoFrame> decoded_frame;
   absl::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
@@ -242,7 +243,8 @@
   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, false, nullptr, 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/videoprocessor.cc b/modules/video_coding/codecs/test/videoprocessor.cc
index a9dacbe..7458006 100644
--- a/modules/video_coding/codecs/test/videoprocessor.cc
+++ b/modules/video_coding/codecs/test/videoprocessor.cc
@@ -529,7 +529,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, false, nullptr, 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 0b26e8b..d7258c9 100644
--- a/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc
+++ b/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc
@@ -153,6 +153,7 @@
 
 int LibvpxVp8Decoder::Decode(const EncodedImage& input_image,
                              bool missing_frames,
+                             const CodecSpecificInfo* codec_specific_info,
                              int64_t /*render_time_ms*/) {
   if (!inited_) {
     return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h b/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h
index 2fa9a8f..a6ddfef 100644
--- a/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h
+++ b/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h
@@ -34,6 +34,7 @@
 
   int Decode(const EncodedImage& input_image,
              bool missing_frames,
+             const CodecSpecificInfo* codec_specific_info,
              int64_t /*render_time_ms*/) override;
 
   int RegisterDecodeCompleteCallback(DecodedImageCallback* callback) override;
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 f2e826b..05e2f05 100644
--- a/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc
+++ b/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc
@@ -210,7 +210,8 @@
 
   // First frame should be a key frame.
   encoded_frame._frameType = kVideoFrameKey;
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, -1));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+            decoder_->Decode(encoded_frame, false, nullptr, -1));
   std::unique_ptr<VideoFrame> decoded_frame;
   absl::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
@@ -229,7 +230,8 @@
   // Encoded frame with explicit color space information.
   ColorSpace color_space = CreateTestColorSpace(/*with_hdr_metadata=*/false);
   encoded_frame.SetColorSpace(color_space);
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, -1));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+            decoder_->Decode(encoded_frame, false, nullptr, -1));
   std::unique_ptr<VideoFrame> decoded_frame;
   absl::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
@@ -323,7 +325,8 @@
   // First frame should be a key frame.
   encoded_frame._frameType = 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, false, nullptr, -1));
 
   std::unique_ptr<VideoFrame> decoded_frame;
   absl::optional<uint8_t> decoded_qp;
@@ -349,15 +352,16 @@
   // Setting complete to false -> should return an error.
   encoded_frame._completeFrame = false;
   EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR,
-            decoder_->Decode(encoded_frame, false, -1));
+            decoder_->Decode(encoded_frame, false, nullptr, -1));
   // Setting complete back to true. Forcing a delta frame.
   encoded_frame._frameType = kVideoFrameDelta;
   encoded_frame._completeFrame = true;
   EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR,
-            decoder_->Decode(encoded_frame, false, -1));
+            decoder_->Decode(encoded_frame, false, nullptr, -1));
   // Now setting a key frame.
   encoded_frame._frameType = kVideoFrameKey;
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, -1));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+            decoder_->Decode(encoded_frame, false, nullptr, -1));
   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/vp9/test/vp9_impl_unittest.cc b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
index c7ae176..cd29915 100644
--- a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
+++ b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
@@ -128,7 +128,8 @@
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info));
   // First frame should be a key frame.
   encoded_frame._frameType = kVideoFrameKey;
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, 0));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+            decoder_->Decode(encoded_frame, false, nullptr, 0));
   std::unique_ptr<VideoFrame> decoded_frame;
   absl::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
@@ -197,7 +198,8 @@
   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, false, nullptr, 0));
   std::unique_ptr<VideoFrame> decoded_frame;
   absl::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
@@ -210,7 +212,8 @@
   // Encoded frame with explicit color space information.
   ColorSpace color_space = CreateTestColorSpace(/*with_hdr_metadata=*/true);
   encoded_frame.SetColorSpace(color_space);
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, 0));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+            decoder_->Decode(encoded_frame, false, nullptr, 0));
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
   ASSERT_TRUE(decoded_frame);
   ASSERT_TRUE(decoded_frame->color_space());
@@ -225,7 +228,8 @@
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info));
   // First frame should be a key frame.
   encoded_frame._frameType = kVideoFrameKey;
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, 0));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+            decoder_->Decode(encoded_frame, false, nullptr, 0));
   std::unique_ptr<VideoFrame> decoded_frame;
   absl::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
@@ -1427,7 +1431,8 @@
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info));
   // First frame should be a key frame.
   encoded_frame._frameType = kVideoFrameKey;
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, 0));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+            decoder_->Decode(encoded_frame, false, nullptr, 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/vp9/vp9_impl.cc b/modules/video_coding/codecs/vp9/vp9_impl.cc
index 4b0461a..e39e9bb 100644
--- a/modules/video_coding/codecs/vp9/vp9_impl.cc
+++ b/modules/video_coding/codecs/vp9/vp9_impl.cc
@@ -1507,6 +1507,7 @@
 
 int VP9DecoderImpl::Decode(const EncodedImage& input_image,
                            bool missing_frames,
+                           const CodecSpecificInfo* codec_specific_info,
                            int64_t /*render_time_ms*/) {
   if (!inited_) {
     return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
diff --git a/modules/video_coding/codecs/vp9/vp9_impl.h b/modules/video_coding/codecs/vp9/vp9_impl.h
index 7ca4b55..3fc5398 100644
--- a/modules/video_coding/codecs/vp9/vp9_impl.h
+++ b/modules/video_coding/codecs/vp9/vp9_impl.h
@@ -184,6 +184,7 @@
 
   int Decode(const EncodedImage& input_image,
              bool missing_frames,
+             const CodecSpecificInfo* codec_specific_info,
              int64_t /*render_time_ms*/) override;
 
   int RegisterDecodeCompleteCallback(DecodedImageCallback* callback) override;
diff --git a/modules/video_coding/generic_decoder.cc b/modules/video_coding/generic_decoder.cc
index f6f23da..6ef4c36 100644
--- a/modules/video_coding/generic_decoder.cc
+++ b/modules/video_coding/generic_decoder.cc
@@ -230,7 +230,7 @@
 
   _nextFrameInfoIdx = (_nextFrameInfoIdx + 1) % kDecoderFrameMemoryLength;
   int32_t ret = decoder_->Decode(frame.EncodedImage(), frame.MissingFrame(),
-                                 frame.RenderTimeMs());
+                                 frame.CodecSpecific(), frame.RenderTimeMs());
 
   _callback->OnDecoderImplementationName(decoder_->ImplementationName());
   if (ret < WEBRTC_VIDEO_CODEC_OK) {
diff --git a/modules/video_coding/utility/simulcast_test_fixture_impl.cc b/modules/video_coding/utility/simulcast_test_fixture_impl.cc
index 12220bc..edef45d 100644
--- a/modules/video_coding/utility/simulcast_test_fixture_impl.cc
+++ b/modules/video_coding/utility/simulcast_test_fixture_impl.cc
@@ -832,9 +832,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, false, NULL, 0));
   encoder_callback.GetLastEncodedFrame(&encoded_frame);
-  decoder_->Decode(encoded_frame, false, 0);
+  decoder_->Decode(encoded_frame, false, NULL, 0);
   EXPECT_EQ(2, decoder_callback.DecodedFrames());
 }
 
@@ -875,7 +875,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], false, NULL, 0));
 
   EXPECT_CALL(decoder_callback, Decoded(_, _, _))
       .WillOnce(testing::Invoke([](VideoFrame& decodedImage,
@@ -884,7 +884,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], false, NULL, 0));
 
   EXPECT_CALL(decoder_callback, Decoded(_, _, _))
       .WillOnce(testing::Invoke([](VideoFrame& decodedImage,
@@ -893,7 +893,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], false, NULL, 0));
 }
 
 }  // namespace test
diff --git a/modules/video_coding/video_receiver_unittest.cc b/modules/video_coding/video_receiver_unittest.cc
index 2cf6c36..0d26fc5 100644
--- a/modules/video_coding/video_receiver_unittest.cc
+++ b/modules/video_coding/video_receiver_unittest.cc
@@ -75,7 +75,7 @@
       ++header->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));
   }
 
@@ -87,7 +87,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/sdk/objc/unittests/objc_video_decoder_factory_tests.mm b/sdk/objc/unittests/objc_video_decoder_factory_tests.mm
index 312e78e..9d2d484 100644
--- a/sdk/objc/unittests/objc_video_decoder_factory_tests.mm
+++ b/sdk/objc/unittests/objc_video_decoder_factory_tests.mm
@@ -71,16 +71,20 @@
   std::unique_ptr<webrtc::VideoDecoder> decoder = GetObjCDecoder(CreateOKDecoderFactory());
 
   webrtc::EncodedImage encoded_image;
+  webrtc::CodecSpecificInfo info;
+  info.codecType = webrtc::kVideoCodecH264;
 
-  EXPECT_EQ(decoder->Decode(encoded_image, false, 0), WEBRTC_VIDEO_CODEC_OK);
+  EXPECT_EQ(decoder->Decode(encoded_image, false, &info, 0), WEBRTC_VIDEO_CODEC_OK);
 }
 
 TEST(ObjCVideoDecoderFactoryTest, DecodeReturnsErrorOnFail) {
   std::unique_ptr<webrtc::VideoDecoder> decoder = GetObjCDecoder(CreateErrorDecoderFactory());
 
   webrtc::EncodedImage encoded_image;
+  webrtc::CodecSpecificInfo info;
+  info.codecType = webrtc::kVideoCodecH264;
 
-  EXPECT_EQ(decoder->Decode(encoded_image, false, 0), WEBRTC_VIDEO_CODEC_ERROR);
+  EXPECT_EQ(decoder->Decode(encoded_image, false, &info, 0), WEBRTC_VIDEO_CODEC_ERROR);
 }
 
 TEST(ObjCVideoDecoderFactoryTest, ReleaseDecodeReturnsOKOnSuccess) {
diff --git a/test/fake_decoder.cc b/test/fake_decoder.cc
index 10ac851..70fe085 100644
--- a/test/fake_decoder.cc
+++ b/test/fake_decoder.cc
@@ -39,6 +39,7 @@
 
 int32_t FakeDecoder::Decode(const EncodedImage& input,
                             bool missing_frames,
+                            const CodecSpecificInfo* codec_specific_info,
                             int64_t render_time_ms) {
   if (input._encodedWidth > 0 && input._encodedHeight > 0) {
     width_ = input._encodedWidth;
@@ -76,6 +77,7 @@
 
 int32_t FakeH264Decoder::Decode(const EncodedImage& input,
                                 bool missing_frames,
+                                const CodecSpecificInfo* codec_specific_info,
                                 int64_t render_time_ms) {
   uint8_t value = 0;
   for (size_t i = 0; i < input.size(); ++i) {
@@ -91,7 +93,8 @@
     }
     ++value;
   }
-  return FakeDecoder::Decode(input, missing_frames, render_time_ms);
+  return FakeDecoder::Decode(input, missing_frames, codec_specific_info,
+                             render_time_ms);
 }
 
 }  // namespace test
diff --git a/test/fake_decoder.h b/test/fake_decoder.h
index 8fe7427..1176feb 100644
--- a/test/fake_decoder.h
+++ b/test/fake_decoder.h
@@ -31,6 +31,7 @@
 
   int32_t Decode(const EncodedImage& input,
                  bool missing_frames,
+                 const CodecSpecificInfo* codec_specific_info,
                  int64_t render_time_ms) override;
 
   int32_t RegisterDecodeCompleteCallback(
@@ -54,6 +55,7 @@
 
   int32_t Decode(const EncodedImage& input,
                  bool missing_frames,
+                 const CodecSpecificInfo* codec_specific_info,
                  int64_t render_time_ms) override;
 };
 
diff --git a/test/fake_vp8_decoder.cc b/test/fake_vp8_decoder.cc
index faaa554..7a244ca 100644
--- a/test/fake_vp8_decoder.cc
+++ b/test/fake_vp8_decoder.cc
@@ -46,6 +46,7 @@
 
 int32_t FakeVp8Decoder::Decode(const EncodedImage& input,
                                bool missing_frames,
+                               const CodecSpecificInfo* codec_specific_info,
                                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 4f0fa3d..36ff3b3 100644
--- a/test/fake_vp8_decoder.h
+++ b/test/fake_vp8_decoder.h
@@ -31,6 +31,7 @@
 
   int32_t Decode(const EncodedImage& input,
                  bool missing_frames,
+                 const CodecSpecificInfo* codec_specific_info,
                  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 8294189..e916143 100644
--- a/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc
+++ b/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc
@@ -53,6 +53,7 @@
 int32_t QualityAnalyzingVideoDecoder::Decode(
     const EncodedImage& input_image,
     bool missing_frames,
+    const CodecSpecificInfo* codec_specific_info,
     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
@@ -94,8 +95,8 @@
   // the map only after |delegate_| Decode method will be invoked. Image will be
   // removed inside DecodedImageCallback, which can be done on separate thread.
   analyzer_->OnFrameReceived(out.id, *origin_image);
-  int32_t result =
-      delegate_->Decode(*origin_image, missing_frames, render_time_ms);
+  int32_t result = delegate_->Decode(*origin_image, missing_frames,
+                                     codec_specific_info, render_time_ms);
   if (result != WEBRTC_VIDEO_CODEC_OK) {
     // If delegate decoder failed, then cleanup data for this image.
     {
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 c1ebcaa..a323937 100644
--- a/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h
+++ b/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h
@@ -63,6 +63,7 @@
                      int32_t number_of_cores) override;
   int32_t Decode(const EncodedImage& input_image,
                  bool missing_frames,
+                 const CodecSpecificInfo* codec_specific_info,
                  int64_t render_time_ms) override;
   int32_t RegisterDecodeCompleteCallback(
       DecodedImageCallback* callback) override;
diff --git a/test/video_decoder_proxy_factory.h b/test/video_decoder_proxy_factory.h
index b58c399..250750c 100644
--- a/test/video_decoder_proxy_factory.h
+++ b/test/video_decoder_proxy_factory.h
@@ -50,8 +50,10 @@
    private:
     int32_t Decode(const EncodedImage& input_image,
                    bool missing_frames,
+                   const CodecSpecificInfo* codec_specific_info,
                    int64_t render_time_ms) override {
-      return decoder_->Decode(input_image, missing_frames, render_time_ms);
+      return decoder_->Decode(input_image, missing_frames, codec_specific_info,
+                              render_time_ms);
     }
     int32_t InitDecode(const VideoCodec* config,
                        int32_t number_of_cores) override {
diff --git a/video/frame_dumping_decoder.cc b/video/frame_dumping_decoder.cc
index 09cf3e9..f42edce 100644
--- a/video/frame_dumping_decoder.cc
+++ b/video/frame_dumping_decoder.cc
@@ -26,16 +26,17 @@
 
 int32_t FrameDumpingDecoder::InitDecode(const VideoCodec* codec_settings,
                                         int32_t number_of_cores) {
-  codec_type_ = codec_settings->codecType;
   return decoder_->InitDecode(codec_settings, number_of_cores);
 }
 
 int32_t FrameDumpingDecoder::Decode(
     const EncodedImage& input_image,
     bool missing_frames,
+    const CodecSpecificInfo* codec_specific_info,
     int64_t render_time_ms) {
-  int32_t ret = decoder_->Decode(input_image, missing_frames, render_time_ms);
-  writer_->WriteFrame(input_image, codec_type_);
+  int32_t ret = decoder_->Decode(input_image, missing_frames,
+                                 codec_specific_info, render_time_ms);
+  writer_->WriteFrame(input_image, codec_specific_info->codecType);
 
   return ret;
 }
diff --git a/video/frame_dumping_decoder.h b/video/frame_dumping_decoder.h
index 5bb2271..9f3ed89 100644
--- a/video/frame_dumping_decoder.h
+++ b/video/frame_dumping_decoder.h
@@ -32,6 +32,7 @@
                      int32_t number_of_cores) override;
   int32_t Decode(const EncodedImage& input_image,
                  bool missing_frames,
+                 const CodecSpecificInfo* codec_specific_info,
                  int64_t render_time_ms) override;
   int32_t RegisterDecodeCompleteCallback(
       DecodedImageCallback* callback) override;
@@ -41,7 +42,6 @@
 
  private:
   std::unique_ptr<VideoDecoder> decoder_;
-  VideoCodecType codec_type_ = VideoCodecType::kVideoCodecGeneric;
   std::unique_ptr<IvfFileWriter> writer_;
 };
 
diff --git a/video/video_receive_stream.cc b/video/video_receive_stream.cc
index 6c158dd..904e0a5 100644
--- a/video/video_receive_stream.cc
+++ b/video/video_receive_stream.cc
@@ -102,6 +102,7 @@
 
   int32_t Decode(const webrtc::EncodedImage& input_image,
                  bool missing_frames,
+                 const webrtc::CodecSpecificInfo* codec_specific_info,
                  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_stream_unittest.cc b/video/video_receive_stream_unittest.cc
index 84b0302..642143a 100644
--- a/video/video_receive_stream_unittest.cc
+++ b/video/video_receive_stream_unittest.cc
@@ -50,9 +50,10 @@
  public:
   MOCK_METHOD2(InitDecode,
                int32_t(const VideoCodec* config, int32_t number_of_cores));
-  MOCK_METHOD3(Decode,
+  MOCK_METHOD4(Decode,
                int32_t(const EncodedImage& input,
                        bool missing_frames,
+                       const CodecSpecificInfo* codec_specific_info,
                        int64_t render_time_ms));
   MOCK_METHOD1(RegisterDecodeCompleteCallback,
                int32_t(DecodedImageCallback* callback));
@@ -140,7 +141,7 @@
       }));
   EXPECT_CALL(mock_h264_video_decoder_, RegisterDecodeCompleteCallback(_));
   video_receive_stream_->Start();
-  EXPECT_CALL(mock_h264_video_decoder_, Decode(_, false, _));
+  EXPECT_CALL(mock_h264_video_decoder_, Decode(_, false, _, _));
   RtpPacketReceived parsed_packet;
   ASSERT_TRUE(parsed_packet.Parse(rtppacket.data(), rtppacket.size()));
   rtp_stream_receiver_controller_.OnRtpPacket(parsed_packet);