Use VideoDecoder::Configure interface when setting up decoder

Bug: webrtc:13045
Change-Id: I322ff91d96bab8bb7c40f4dea1c9c2b5c7631635
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/228420
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34756}
diff --git a/modules/video_coding/decoder_database.cc b/modules/video_coding/decoder_database.cc
index d4841cd..467e99c 100644
--- a/modules/video_coding/decoder_database.cc
+++ b/modules/video_coding/decoder_database.cc
@@ -48,19 +48,17 @@
          decoders_.find(payload_type) != decoders_.end();
 }
 
-bool VCMDecoderDataBase::RegisterReceiveCodec(uint8_t payload_type,
-                                              const VideoCodec& receive_codec,
-                                              int number_of_cores) {
-  if (number_of_cores < 0) {
+bool VCMDecoderDataBase::RegisterReceiveCodec(
+    uint8_t payload_type,
+    const VideoDecoder::Settings& settings) {
+  if (settings.number_of_cores() < 0) {
     return false;
   }
   // If payload value already exists, erase old and insert new.
   if (payload_type == current_payload_type_) {
     current_payload_type_ = absl::nullopt;
   }
-  auto& entry = decoder_settings_[payload_type];
-  entry.settings = receive_codec;
-  entry.number_of_cores = number_of_cores;
+  decoder_settings_[payload_type] = settings;
   return true;
 }
 
@@ -127,16 +125,14 @@
   // the first frame being of a different resolution than the database values.
   // This is best effort, since there's no guarantee that width/height have been
   // parsed yet (and may be zero).
-  if (frame.EncodedImage()._encodedWidth > 0 &&
-      frame.EncodedImage()._encodedHeight > 0) {
-    decoder_item->second.settings.width = frame.EncodedImage()._encodedWidth;
-    decoder_item->second.settings.height = frame.EncodedImage()._encodedHeight;
+  RenderResolution frame_resolution(frame.EncodedImage()._encodedWidth,
+                                    frame.EncodedImage()._encodedHeight);
+  if (frame_resolution.Valid()) {
+    decoder_item->second.set_max_render_resolution(frame_resolution);
   }
-  int err = current_decoder_->InitDecode(&decoder_item->second.settings,
-                                         decoder_item->second.number_of_cores);
-  if (err < 0) {
+  if (!current_decoder_->Configure(decoder_item->second)) {
     current_decoder_ = absl::nullopt;
-    RTC_LOG(LS_ERROR) << "Failed to initialize decoder. Error code: " << err;
+    RTC_LOG(LS_ERROR) << "Failed to initialize decoder.";
   }
 }
 
diff --git a/modules/video_coding/decoder_database.h b/modules/video_coding/decoder_database.h
index e726669..9c573ae 100644
--- a/modules/video_coding/decoder_database.h
+++ b/modules/video_coding/decoder_database.h
@@ -35,8 +35,7 @@
   bool IsExternalDecoderRegistered(uint8_t payload_type) const;
 
   bool RegisterReceiveCodec(uint8_t payload_type,
-                            const VideoCodec& receive_codec,
-                            int number_of_cores);
+                            const VideoDecoder::Settings& settings);
   bool DeregisterReceiveCodec(uint8_t payload_type);
 
   // Returns a decoder specified by frame.PayloadType. The decoded frame
@@ -49,17 +48,12 @@
       VCMDecodedFrameCallback* decoded_frame_callback);
 
  private:
-  struct DecoderSettings {
-    VideoCodec settings;
-    int number_of_cores;
-  };
-
   void CreateAndInitDecoder(const VCMEncodedFrame& frame);
 
   absl::optional<uint8_t> current_payload_type_;
   absl::optional<VCMGenericDecoder> current_decoder_;
   // Initialization paramaters for decoders keyed by payload type.
-  std::map<uint8_t, DecoderSettings> decoder_settings_;
+  std::map<uint8_t, VideoDecoder::Settings> decoder_settings_;
   // Decoders keyed by payload type.
   std::map<uint8_t, VideoDecoder*> decoders_;
 };
diff --git a/modules/video_coding/generic_decoder.cc b/modules/video_coding/generic_decoder.cc
index efa215e..fe59d5c 100644
--- a/modules/video_coding/generic_decoder.cc
+++ b/modules/video_coding/generic_decoder.cc
@@ -245,18 +245,17 @@
   decoder_->Release();
 }
 
-int32_t VCMGenericDecoder::InitDecode(const VideoCodec* settings,
-                                      int32_t numberOfCores) {
-  TRACE_EVENT0("webrtc", "VCMGenericDecoder::InitDecode");
+bool VCMGenericDecoder::Configure(const VideoDecoder::Settings& settings) {
+  TRACE_EVENT0("webrtc", "VCMGenericDecoder::Configure");
 
-  int err = decoder_->InitDecode(settings, numberOfCores);
+  bool ok = decoder_->Configure(settings);
   decoder_info_ = decoder_->GetDecoderInfo();
   RTC_LOG(LS_INFO) << "Decoder implementation: " << decoder_info_.ToString();
   if (_callback) {
     _callback->OnDecoderImplementationName(
         decoder_info_.implementation_name.c_str());
   }
-  return err;
+  return ok;
 }
 
 int32_t VCMGenericDecoder::Decode(const VCMEncodedFrame& frame, Timestamp now) {
diff --git a/modules/video_coding/generic_decoder.h b/modules/video_coding/generic_decoder.h
index aaab5fc..31d8460 100644
--- a/modules/video_coding/generic_decoder.h
+++ b/modules/video_coding/generic_decoder.h
@@ -15,6 +15,7 @@
 
 #include "api/sequence_checker.h"
 #include "api/units/time_delta.h"
+#include "api/video_codecs/video_decoder.h"
 #include "modules/video_coding/encoded_frame.h"
 #include "modules/video_coding/include/video_codec_interface.h"
 #include "modules/video_coding/timestamp_map.h"
@@ -80,9 +81,9 @@
   ~VCMGenericDecoder();
 
   /**
-   * Initialize the decoder with the information from the VideoCodec
+   * Initialize the decoder with the information from the `settings`
    */
-  int32_t InitDecode(const VideoCodec* settings, int32_t numberOfCores);
+  bool Configure(const VideoDecoder::Settings& settings);
 
   /**
    * Decode to a raw I420 frame,
diff --git a/modules/video_coding/generic_decoder_unittest.cc b/modules/video_coding/generic_decoder_unittest.cc
index 6237c96..466459e 100644
--- a/modules/video_coding/generic_decoder_unittest.cc
+++ b/modules/video_coding/generic_decoder_unittest.cc
@@ -15,6 +15,7 @@
 
 #include "absl/types/optional.h"
 #include "api/task_queue/default_task_queue_factory.h"
+#include "api/video_codecs/video_decoder.h"
 #include "common_video/test/utilities.h"
 #include "modules/video_coding/timing.h"
 #include "rtc_base/event.h"
@@ -74,11 +75,11 @@
   void SetUp() override {
     generic_decoder_.RegisterDecodeCompleteCallback(&vcm_callback_);
     vcm_callback_.SetUserReceiveCallback(&user_callback_);
-    VideoCodec settings;
-    settings.codecType = kVideoCodecVP8;
-    settings.width = 10;
-    settings.height = 10;
-    generic_decoder_.InitDecode(&settings, /*numberOfCores=*/4);
+    VideoDecoder::Settings settings;
+    settings.set_codec_type(kVideoCodecVP8);
+    settings.set_max_render_resolution({10, 10});
+    settings.set_number_of_cores(4);
+    generic_decoder_.Configure(settings);
   }
 
   SimulatedClock clock_;
diff --git a/modules/video_coding/include/video_coding.h b/modules/video_coding/include/video_coding.h
index df4533e..b54b7e4 100644
--- a/modules/video_coding/include/video_coding.h
+++ b/modules/video_coding/include/video_coding.h
@@ -13,6 +13,7 @@
 
 #include "api/video/video_frame.h"
 #include "api/video_codecs/video_codec.h"
+#include "api/video_codecs/video_decoder.h"
 #include "modules/include/module.h"
 #include "modules/rtp_rtcp/source/rtp_video_header.h"
 #include "modules/video_coding/include/video_coding_defines.h"
@@ -43,12 +44,13 @@
   //
   // Input:
   //      - payload_type      : RTP payload type
-  //      - receiveCodec      : Settings for the codec to be registered.
-  //      - numberOfCores     : Number of CPU cores that the decoder is allowed
-  //      to use.
+  //      - settings          : Settings for the decoder to be registered.
   //
-  // Return value      : VCM_OK, on success.
-  //                     < 0,    on error.
+  // Return value      : true,  on success.
+  //                     false, on error.
+  virtual bool RegisterReceiveCodec(uint8_t payload_type,
+                                    const VideoDecoder::Settings& settings) = 0;
+  ABSL_DEPRECATED("Use RegisterReceiveCodec above")
   virtual int32_t RegisterReceiveCodec(uint8_t payload_type,
                                        const VideoCodec* receiveCodec,
                                        int32_t numberOfCores) = 0;
diff --git a/modules/video_coding/video_coding_impl.cc b/modules/video_coding/video_coding_impl.cc
index f19ea51..6f4903e 100644
--- a/modules/video_coding/video_coding_impl.cc
+++ b/modules/video_coding/video_coding_impl.cc
@@ -56,11 +56,25 @@
 
   void Process() override { receiver_.Process(); }
 
+  bool RegisterReceiveCodec(
+      uint8_t payload_type,
+      const VideoDecoder::Settings& decoder_settings) override {
+    return receiver_.RegisterReceiveCodec(payload_type, decoder_settings);
+  }
+
   int32_t RegisterReceiveCodec(uint8_t payload_type,
-                               const VideoCodec* receiveCodec,
-                               int32_t numberOfCores) override {
-    return receiver_.RegisterReceiveCodec(payload_type, receiveCodec,
-                                          numberOfCores);
+                               const VideoCodec* receive_codec,
+                               int32_t number_of_cores) override {
+    VideoDecoder::Settings decoder_settings;
+    if (receive_codec != nullptr) {
+      decoder_settings.set_codec_type(receive_codec->codecType);
+      decoder_settings.set_max_render_resolution(
+          {receive_codec->width, receive_codec->height});
+      decoder_settings.set_buffer_pool_size(receive_codec->buffer_pool_size);
+    }
+    decoder_settings.set_number_of_cores(number_of_cores);
+    return receiver_.RegisterReceiveCodec(payload_type, decoder_settings) ? 0
+                                                                          : -1;
   }
 
   void RegisterExternalDecoder(VideoDecoder* externalDecoder,
diff --git a/modules/video_coding/video_coding_impl.h b/modules/video_coding/video_coding_impl.h
index 9633fb7..5b7ae03 100644
--- a/modules/video_coding/video_coding_impl.h
+++ b/modules/video_coding/video_coding_impl.h
@@ -59,9 +59,8 @@
   VideoReceiver(Clock* clock, VCMTiming* timing);
   ~VideoReceiver() override;
 
-  int32_t RegisterReceiveCodec(uint8_t payload_type,
-                               const VideoCodec* receiveCodec,
-                               int32_t numberOfCores);
+  bool RegisterReceiveCodec(uint8_t payload_type,
+                            const VideoDecoder::Settings& settings);
 
   void RegisterExternalDecoder(VideoDecoder* externalDecoder,
                                uint8_t payloadType);
diff --git a/modules/video_coding/video_receiver.cc b/modules/video_coding/video_receiver.cc
index f06a9ab..4cc99c6 100644
--- a/modules/video_coding/video_receiver.cc
+++ b/modules/video_coding/video_receiver.cc
@@ -246,18 +246,11 @@
 }
 
 // Register possible receive codecs, can be called multiple times
-int32_t VideoReceiver::RegisterReceiveCodec(uint8_t payload_type,
-                                            const VideoCodec* receiveCodec,
-                                            int32_t numberOfCores) {
+bool VideoReceiver::RegisterReceiveCodec(
+    uint8_t payload_type,
+    const VideoDecoder::Settings& settings) {
   RTC_DCHECK_RUN_ON(&construction_thread_checker_);
-  if (receiveCodec == nullptr) {
-    return VCM_PARAMETER_ERROR;
-  }
-  if (!_codecDataBase.RegisterReceiveCodec(payload_type, *receiveCodec,
-                                           numberOfCores)) {
-    return -1;
-  }
-  return 0;
+  return _codecDataBase.RegisterReceiveCodec(payload_type, settings);
 }
 
 // Incoming packet from network parsed and ready for decode, non blocking.
diff --git a/modules/video_coding/video_receiver2.cc b/modules/video_coding/video_receiver2.cc
index d26d3f4..add6917 100644
--- a/modules/video_coding/video_receiver2.cc
+++ b/modules/video_coding/video_receiver2.cc
@@ -110,19 +110,12 @@
 }
 
 // Register possible receive codecs, can be called multiple times
-int32_t VideoReceiver2::RegisterReceiveCodec(uint8_t payload_type,
-                                             const VideoCodec* receiveCodec,
-                                             int32_t numberOfCores) {
+bool VideoReceiver2::RegisterReceiveCodec(
+    uint8_t payload_type,
+    const VideoDecoder::Settings& settings) {
   RTC_DCHECK_RUN_ON(&construction_sequence_checker_);
   RTC_DCHECK(!IsDecoderThreadRunning());
-  if (receiveCodec == nullptr) {
-    return VCM_PARAMETER_ERROR;
-  }
-  if (!codecDataBase_.RegisterReceiveCodec(payload_type, *receiveCodec,
-                                           numberOfCores)) {
-    return -1;
-  }
-  return 0;
+  return codecDataBase_.RegisterReceiveCodec(payload_type, settings);
 }
 
 bool VideoReceiver2::IsDecoderThreadRunning() {
diff --git a/modules/video_coding/video_receiver2.h b/modules/video_coding/video_receiver2.h
index 8bcf2ac..261b52a 100644
--- a/modules/video_coding/video_receiver2.h
+++ b/modules/video_coding/video_receiver2.h
@@ -12,6 +12,7 @@
 #define MODULES_VIDEO_CODING_VIDEO_RECEIVER2_H_
 
 #include "api/sequence_checker.h"
+#include "api/video_codecs/video_decoder.h"
 #include "modules/video_coding/decoder_database.h"
 #include "modules/video_coding/encoded_frame.h"
 #include "modules/video_coding/generic_decoder.h"
@@ -30,9 +31,8 @@
   VideoReceiver2(Clock* clock, VCMTiming* timing);
   ~VideoReceiver2();
 
-  int32_t RegisterReceiveCodec(uint8_t payload_type,
-                               const VideoCodec* receiveCodec,
-                               int32_t numberOfCores);
+  bool RegisterReceiveCodec(uint8_t payload_type,
+                            const VideoDecoder::Settings& decoder_settings);
 
   void RegisterExternalDecoder(VideoDecoder* externalDecoder,
                                uint8_t payloadType);
diff --git a/modules/video_coding/video_receiver_unittest.cc b/modules/video_coding/video_receiver_unittest.cc
index fcd4f44..d56ed63 100644
--- a/modules/video_coding/video_receiver_unittest.cc
+++ b/modules/video_coding/video_receiver_unittest.cc
@@ -9,12 +9,12 @@
  */
 
 #include "api/test/mock_video_decoder.h"
+#include "api/video_codecs/video_decoder.h"
 #include "modules/video_coding/include/video_coding.h"
 #include "modules/video_coding/timing.h"
 #include "modules/video_coding/video_coding_impl.h"
 #include "system_wrappers/include/clock.h"
 #include "test/gtest.h"
-#include "test/video_codec_settings.h"
 
 using ::testing::_;
 using ::testing::AnyNumber;
@@ -56,9 +56,9 @@
   virtual void SetUp() {
     // Register decoder.
     receiver_.RegisterExternalDecoder(&decoder_, kUnusedPayloadType);
-    webrtc::test::CodecSettings(kVideoCodecVP8, &settings_);
-    EXPECT_EQ(
-        0, receiver_.RegisterReceiveCodec(kUnusedPayloadType, &settings_, 1));
+    VideoDecoder::Settings settings;
+    settings.set_codec_type(kVideoCodecVP8);
+    EXPECT_TRUE(receiver_.RegisterReceiveCodec(kUnusedPayloadType, settings));
 
     // Set protection mode.
     const size_t kMaxNackListSize = 250;
@@ -119,7 +119,6 @@
   }
 
   SimulatedClock clock_;
-  VideoCodec settings_;
   NiceMock<MockVideoDecoder> decoder_;
   NiceMock<MockPacketRequestCallback> packet_request_callback_;
   VCMTiming timing_;