Revert "Remove VCMEncoderDataBase and put remaining code into VideoStreamEncoder"

This reverts commit 715c4765b1ac20017e6e3b8b925d02536c6610c3.

Reason for revert: Breaks WebRTC roll to Chromium.
https://chromium-review.googlesource.com/c/chromium/src/+/1484629

# Fatal error in: ../../third_party/webrtc/modules/rtp_rtcp/source/rtp_sender.cc, line 796
# last system error: 0
# Check failed: diff_ms >= static_cast<int64_t>(0) (-307 vs. 0)
#

Original change's description:
> Remove VCMEncoderDataBase and put remaining code into VideoStreamEncoder
>
> Since this "data base" only holds a single encoder instance it just
> serves to confuse object ownership. Removing it and giving ownership
> of generic encoder instance to VideoStreamEncoder.
>
> This CL also removes VideoSender interface from video_coding_impl.h,
> which is mostly a leftover from
> https://webrtc-review.googlesource.com/c/src/+/123540
>
> Bug: webrtc:10164
> Change-Id: I9b7fec940dbcbccf3aa1278c2555da3bd5169ae1
> Reviewed-on: https://webrtc-review.googlesource.com/c/123920
> Commit-Queue: Erik Språng <sprang@webrtc.org>
> Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> Reviewed-by: Niels Moller <nisse@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#26835}

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

Change-Id: I5432878c4c2e497cd848c4ce1b190e0307df03ca
Bug: webrtc:10164
Reviewed-on: https://webrtc-review.googlesource.com/c/124402
Commit-Queue: Sami Kalliomäki <sakal@webrtc.org>
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26841}
diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn
index f3807fa..8c56078 100644
--- a/modules/video_coding/BUILD.gn
+++ b/modules/video_coding/BUILD.gn
@@ -102,6 +102,8 @@
     "decoder_database.h",
     "decoding_state.cc",
     "decoding_state.h",
+    "encoder_database.cc",
+    "encoder_database.h",
     "fec_controller_default.cc",
     "fec_controller_default.h",
     "fec_rate_table.h",
diff --git a/modules/video_coding/encoder_database.cc b/modules/video_coding/encoder_database.cc
new file mode 100644
index 0000000..0497e3a
--- /dev/null
+++ b/modules/video_coding/encoder_database.cc
@@ -0,0 +1,186 @@
+/*
+ *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "modules/video_coding/encoder_database.h"
+
+#include <string.h>
+
+#include "common_types.h"  // NOLINT(build/include)
+#include "rtc_base/checks.h"
+#include "rtc_base/logging.h"
+
+namespace webrtc {
+
+namespace {
+const size_t kDefaultPayloadSize = 1440;
+}
+
+VCMEncoderDataBase::VCMEncoderDataBase(
+    VCMEncodedFrameCallback* encoded_frame_callback)
+    : number_of_cores_(0),
+      max_payload_size_(kDefaultPayloadSize),
+      pending_encoder_reset_(true),
+      send_codec_(),
+      external_encoder_(nullptr),
+      internal_source_(false),
+      encoded_frame_callback_(encoded_frame_callback) {}
+
+VCMEncoderDataBase::~VCMEncoderDataBase() {
+  DeleteEncoder();
+}
+
+// Assuming only one registered encoder - since only one used, no need for more.
+bool VCMEncoderDataBase::SetSendCodec(const VideoCodec* send_codec,
+                                      int number_of_cores,
+                                      size_t max_payload_size) {
+  RTC_DCHECK(send_codec);
+  if (max_payload_size == 0) {
+    max_payload_size = kDefaultPayloadSize;
+  }
+  RTC_DCHECK_GE(number_of_cores, 1);
+  // Make sure the start bit rate is sane...
+  RTC_DCHECK_LE(send_codec->startBitrate, 1000000);
+  bool reset_required = pending_encoder_reset_;
+  if (number_of_cores_ != number_of_cores) {
+    number_of_cores_ = number_of_cores;
+    reset_required = true;
+  }
+  if (max_payload_size_ != max_payload_size) {
+    max_payload_size_ = max_payload_size;
+    reset_required = true;
+  }
+
+  VideoCodec new_send_codec;
+  memcpy(&new_send_codec, send_codec, sizeof(new_send_codec));
+
+  if (new_send_codec.maxBitrate == 0) {
+    // max is one bit per pixel
+    new_send_codec.maxBitrate = (static_cast<int>(send_codec->height) *
+                                 static_cast<int>(send_codec->width) *
+                                 static_cast<int>(send_codec->maxFramerate)) /
+                                1000;
+    if (send_codec->startBitrate > new_send_codec.maxBitrate) {
+      // But if the user tries to set a higher start bit rate we will
+      // increase the max accordingly.
+      new_send_codec.maxBitrate = send_codec->startBitrate;
+    }
+  }
+
+  if (new_send_codec.startBitrate > new_send_codec.maxBitrate)
+    new_send_codec.startBitrate = new_send_codec.maxBitrate;
+
+  if (!reset_required) {
+    reset_required = RequiresEncoderReset(new_send_codec);
+  }
+
+  memcpy(&send_codec_, &new_send_codec, sizeof(send_codec_));
+
+  if (!reset_required) {
+    return true;
+  }
+
+  // If encoder exists, will destroy it and create new one.
+  DeleteEncoder();
+  ptr_encoder_.reset(new VCMGenericEncoder(
+      external_encoder_, encoded_frame_callback_, internal_source_));
+  encoded_frame_callback_->SetInternalSource(internal_source_);
+  if (ptr_encoder_->InitEncode(&send_codec_, number_of_cores_,
+                               max_payload_size_) < 0) {
+    RTC_LOG(LS_ERROR) << "Failed to initialize video encoder.";
+    DeleteEncoder();
+    return false;
+  }
+
+  pending_encoder_reset_ = false;
+
+  return true;
+}
+
+void VCMEncoderDataBase::DeregisterExternalEncoder() {
+  DeleteEncoder();
+  memset(&send_codec_, 0, sizeof(VideoCodec));
+  external_encoder_ = nullptr;
+  internal_source_ = false;
+}
+
+void VCMEncoderDataBase::RegisterExternalEncoder(VideoEncoder* external_encoder,
+                                                 bool internal_source) {
+  // Since only one encoder can be used at a given time, only one external
+  // encoder can be registered/used.
+  RTC_CHECK(external_encoder_ == nullptr);
+  external_encoder_ = external_encoder;
+  internal_source_ = internal_source;
+  pending_encoder_reset_ = true;
+}
+
+bool VCMEncoderDataBase::RequiresEncoderReset(
+    const VideoCodec& new_send_codec) {
+  if (!ptr_encoder_)
+    return true;
+
+  // Does not check startBitrate, maxFramerate or plType
+  if (new_send_codec.codecType != send_codec_.codecType ||
+      new_send_codec.width != send_codec_.width ||
+      new_send_codec.height != send_codec_.height ||
+      new_send_codec.maxBitrate != send_codec_.maxBitrate ||
+      new_send_codec.minBitrate != send_codec_.minBitrate ||
+      new_send_codec.qpMax != send_codec_.qpMax ||
+      new_send_codec.numberOfSimulcastStreams !=
+          send_codec_.numberOfSimulcastStreams ||
+      new_send_codec.mode != send_codec_.mode) {
+    return true;
+  }
+
+  switch (new_send_codec.codecType) {
+    case kVideoCodecVP8:
+      if (new_send_codec.VP8() != *send_codec_.VP8()) {
+        return true;
+      }
+      break;
+
+    case kVideoCodecVP9:
+      if (new_send_codec.VP9() != *send_codec_.VP9()) {
+        return true;
+      }
+      break;
+
+    case kVideoCodecH264:
+      if (new_send_codec.H264() != *send_codec_.H264()) {
+        return true;
+      }
+      break;
+
+    default:
+      break;
+  }
+
+  for (unsigned char i = 0; i < new_send_codec.numberOfSimulcastStreams; ++i) {
+    if (new_send_codec.simulcastStream[i] != send_codec_.simulcastStream[i])
+      return true;
+  }
+  return false;
+}
+
+VCMGenericEncoder* VCMEncoderDataBase::GetEncoder() {
+  return ptr_encoder_.get();
+}
+
+void VCMEncoderDataBase::DeleteEncoder() {
+  if (!ptr_encoder_)
+    return;
+  ptr_encoder_->Release();
+  ptr_encoder_.reset();
+}
+
+bool VCMEncoderDataBase::MatchesCurrentResolution(int width, int height) const {
+  return send_codec_.width == width && send_codec_.height == height;
+}
+
+}  // namespace webrtc
diff --git a/modules/video_coding/encoder_database.h b/modules/video_coding/encoder_database.h
new file mode 100644
index 0000000..09baff0
--- /dev/null
+++ b/modules/video_coding/encoder_database.h
@@ -0,0 +1,68 @@
+/*
+ *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef MODULES_VIDEO_CODING_ENCODER_DATABASE_H_
+#define MODULES_VIDEO_CODING_ENCODER_DATABASE_H_
+
+#include <stddef.h>
+#include <memory>
+
+#include "api/video_codecs/video_codec.h"
+#include "api/video_codecs/video_encoder.h"
+#include "modules/video_coding/generic_encoder.h"
+
+namespace webrtc {
+
+class VCMEncoderDataBase {
+ public:
+  explicit VCMEncoderDataBase(VCMEncodedFrameCallback* encoded_frame_callback);
+  ~VCMEncoderDataBase();
+
+  // Sets the sender side codec and initiates the desired codec given the
+  // VideoCodec struct.
+  // Returns true if the codec was successfully registered, false otherwise.
+  bool SetSendCodec(const VideoCodec* send_codec,
+                    int number_of_cores,
+                    size_t max_payload_size);
+
+  // Registers and initializes an external encoder object.
+  // |internal_source| should be set to true if the codec has an internal
+  // video source and doesn't need the user to provide it with frames via
+  // the Encode() method.
+  void RegisterExternalEncoder(VideoEncoder* external_encoder,
+                               bool internal_source);
+
+  // Deregisters any external encoder.
+  void DeregisterExternalEncoder();
+
+  VCMGenericEncoder* GetEncoder();
+
+  bool MatchesCurrentResolution(int width, int height) const;
+
+ private:
+  // Determines whether a new codec has to be created or not.
+  // Checks every setting apart from maxFramerate and startBitrate.
+  bool RequiresEncoderReset(const VideoCodec& send_codec);
+
+  void DeleteEncoder();
+
+  int number_of_cores_;
+  size_t max_payload_size_;
+  bool pending_encoder_reset_;
+  VideoCodec send_codec_;
+  VideoEncoder* external_encoder_;
+  bool internal_source_;
+  VCMEncodedFrameCallback* const encoded_frame_callback_;
+  std::unique_ptr<VCMGenericEncoder> ptr_encoder_;
+};
+
+}  // namespace webrtc
+
+#endif  // MODULES_VIDEO_CODING_ENCODER_DATABASE_H_
diff --git a/modules/video_coding/video_coding_impl.h b/modules/video_coding/video_coding_impl.h
index 0681eec..87fc5f6 100644
--- a/modules/video_coding/video_coding_impl.h
+++ b/modules/video_coding/video_coding_impl.h
@@ -19,6 +19,7 @@
 
 #include "absl/types/optional.h"
 #include "modules/video_coding/decoder_database.h"
+#include "modules/video_coding/encoder_database.h"
 #include "modules/video_coding/frame_buffer.h"
 #include "modules/video_coding/generic_decoder.h"
 #include "modules/video_coding/generic_encoder.h"
@@ -56,6 +57,47 @@
   int64_t _latestMs;
 };
 
+class VideoSender {
+ public:
+  typedef VideoCodingModule::SenderNackMode SenderNackMode;
+
+  VideoSender(Clock* clock, EncodedImageCallback* post_encode_callback);
+  ~VideoSender();
+
+  // Register the send codec to be used.
+  // This method must be called on the construction thread.
+  int32_t RegisterSendCodec(const VideoCodec* sendCodec,
+                            uint32_t numberOfCores,
+                            uint32_t maxPayloadSize);
+
+  void RegisterExternalEncoder(VideoEncoder* externalEncoder,
+                               bool internalSource);
+
+  // Update the the encoder with new bitrate allocation and framerate.
+  int32_t SetChannelParameters(const VideoBitrateAllocation& bitrate_allocation,
+                               uint32_t framerate_fps);
+
+  int32_t AddVideoFrame(const VideoFrame& videoFrame,
+                        const CodecSpecificInfo* codecSpecificInfo,
+                        absl::optional<VideoEncoder::EncoderInfo> encoder_info);
+
+  int32_t IntraFrameRequest(size_t stream_index);
+
+ private:
+  rtc::CriticalSection encoder_crit_;
+  VCMGenericEncoder* _encoder;
+  VCMEncodedFrameCallback _encodedFrameCallback RTC_GUARDED_BY(encoder_crit_);
+  VCMEncoderDataBase _codecDataBase RTC_GUARDED_BY(encoder_crit_);
+
+  // Must be accessed on the construction thread of VideoSender.
+  VideoCodec current_codec_;
+  rtc::SequencedTaskChecker sequenced_checker_;
+
+  rtc::CriticalSection params_crit_;
+  bool encoder_has_internal_source_ RTC_GUARDED_BY(params_crit_);
+  std::vector<FrameType> next_frame_types_ RTC_GUARDED_BY(params_crit_);
+};
+
 class VideoReceiver : public Module {
  public:
   VideoReceiver(Clock* clock,