Split VCMCodecDataBase into VCMEncoderDataBase and VCMDecoderDataBase.
Intended to ease further refactoring, cleanup and deletion in this code.
Bug: webrtc:8830
Change-Id: Ib862b073e93b67b4f8eedbbf40ad3a8354a566a2
Reviewed-on: https://webrtc-review.googlesource.com/55562
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Commit-Queue: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22120}
diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn
index 329427e..1b7b511 100644
--- a/modules/video_coding/BUILD.gn
+++ b/modules/video_coding/BUILD.gn
@@ -13,14 +13,16 @@
deps = []
sources = [
- "codec_database.cc",
- "codec_database.h",
"codec_timer.cc",
"codec_timer.h",
+ "decoder_database.cc",
+ "decoder_database.h",
"decoding_state.cc",
"decoding_state.h",
"encoded_frame.cc",
"encoded_frame.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/codec_database.cc b/modules/video_coding/codec_database.cc
deleted file mode 100644
index 975c360..0000000
--- a/modules/video_coding/codec_database.cc
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
- * Copyright (c) 2012 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/codec_database.h"
-
-#if defined(USE_BUILTIN_SW_CODECS)
-#include "modules/video_coding/codecs/h264/include/h264.h"
-#include "modules/video_coding/codecs/i420/include/i420.h" // nogncheck
-#include "modules/video_coding/codecs/vp8/include/vp8.h" // nogncheck
-#include "modules/video_coding/codecs/vp9/include/vp9.h" // nogncheck
-#endif
-
-#include "modules/video_coding/internal_defines.h"
-#include "rtc_base/checks.h"
-#include "rtc_base/logging.h"
-
-namespace {
-const size_t kDefaultPayloadSize = 1440;
-}
-
-namespace webrtc {
-
-#if defined(USE_BUILTIN_SW_CODECS)
-// Create an internal Decoder given a codec type
-static std::unique_ptr<VCMGenericDecoder> CreateDecoder(VideoCodecType type) {
- switch (type) {
- case kVideoCodecVP8:
- return std::unique_ptr<VCMGenericDecoder>(
- new VCMGenericDecoder(VP8Decoder::Create()));
- case kVideoCodecVP9:
- return std::unique_ptr<VCMGenericDecoder>(
- new VCMGenericDecoder(VP9Decoder::Create()));
- case kVideoCodecI420:
- return std::unique_ptr<VCMGenericDecoder>(
- new VCMGenericDecoder(new I420Decoder()));
- case kVideoCodecH264:
- if (H264Decoder::IsSupported()) {
- return std::unique_ptr<VCMGenericDecoder>(
- new VCMGenericDecoder(H264Decoder::Create()));
- }
- break;
- default:
- break;
- }
- RTC_LOG(LS_WARNING) << "No internal decoder of this type exists.";
- return std::unique_ptr<VCMGenericDecoder>();
-}
-#endif
-
-VCMDecoderMapItem::VCMDecoderMapItem(VideoCodec* settings,
- int number_of_cores,
- bool require_key_frame)
- : settings(settings),
- number_of_cores(number_of_cores),
- require_key_frame(require_key_frame) {
- RTC_DCHECK_GE(number_of_cores, 0);
-}
-
-VCMExtDecoderMapItem::VCMExtDecoderMapItem(
- VideoDecoder* external_decoder_instance,
- uint8_t payload_type)
- : payload_type(payload_type),
- external_decoder_instance(external_decoder_instance) {}
-
-VCMCodecDataBase::VCMCodecDataBase(
- VCMEncodedFrameCallback* encoded_frame_callback)
- : number_of_cores_(0),
- max_payload_size_(kDefaultPayloadSize),
- periodic_key_frames_(false),
- pending_encoder_reset_(true),
- send_codec_(),
- receive_codec_(),
- encoder_payload_type_(0),
- external_encoder_(nullptr),
- internal_source_(false),
- encoded_frame_callback_(encoded_frame_callback),
- dec_map_(),
- dec_external_map_() {}
-
-VCMCodecDataBase::~VCMCodecDataBase() {
- DeleteEncoder();
- ptr_decoder_.reset();
- for (auto& kv : dec_map_)
- delete kv.second;
- for (auto& kv : dec_external_map_)
- delete kv.second;
-}
-
-// Assuming only one registered encoder - since only one used, no need for more.
-bool VCMCodecDataBase::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);
- RTC_DCHECK_GE(send_codec->plType, 1);
- // Make sure the start bit rate is sane...
- RTC_DCHECK_LE(send_codec->startBitrate, 1000000);
- RTC_DCHECK(send_codec->codecType != kVideoCodecUnknown);
- 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();
- RTC_DCHECK_EQ(encoder_payload_type_, send_codec_.plType)
- << "Encoder not registered for payload type " << send_codec_.plType;
- 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;
- }
-
- // Intentionally don't check return value since the encoder registration
- // shouldn't fail because the codec doesn't support changing the periodic key
- // frame setting.
- ptr_encoder_->SetPeriodicKeyFrames(periodic_key_frames_);
-
- pending_encoder_reset_ = false;
-
- return true;
-}
-
-bool VCMCodecDataBase::DeregisterExternalEncoder(uint8_t payload_type,
- bool* was_send_codec) {
- RTC_DCHECK(was_send_codec);
- *was_send_codec = false;
- if (encoder_payload_type_ != payload_type) {
- return false;
- }
- if (send_codec_.plType == payload_type) {
- // De-register as send codec if needed.
- DeleteEncoder();
- memset(&send_codec_, 0, sizeof(VideoCodec));
- *was_send_codec = true;
- }
- encoder_payload_type_ = 0;
- external_encoder_ = nullptr;
- internal_source_ = false;
- return true;
-}
-
-void VCMCodecDataBase::RegisterExternalEncoder(VideoEncoder* external_encoder,
- uint8_t payload_type,
- bool internal_source) {
- // Since only one encoder can be used at a given time, only one external
- // encoder can be registered/used.
- external_encoder_ = external_encoder;
- encoder_payload_type_ = payload_type;
- internal_source_ = internal_source;
- pending_encoder_reset_ = true;
-}
-
-bool VCMCodecDataBase::RequiresEncoderReset(const VideoCodec& new_send_codec) {
- if (!ptr_encoder_)
- return true;
-
- // Does not check startBitrate or maxFramerate
- if (new_send_codec.codecType != send_codec_.codecType ||
- strcmp(new_send_codec.plName, send_codec_.plName) != 0 ||
- new_send_codec.plType != send_codec_.plType ||
- 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 (memcmp(&new_send_codec.VP8(), send_codec_.VP8(),
- sizeof(new_send_codec.VP8())) != 0) {
- return true;
- }
- break;
- case kVideoCodecVP9:
- if (memcmp(&new_send_codec.VP9(), send_codec_.VP9(),
- sizeof(new_send_codec.VP9())) != 0) {
- return true;
- }
- break;
- case kVideoCodecH264:
- if (memcmp(&new_send_codec.H264(), send_codec_.H264(),
- sizeof(new_send_codec.H264())) != 0) {
- return true;
- }
- break;
- case kVideoCodecGeneric:
- break;
- // Known codecs without payload-specifics
- case kVideoCodecI420:
- case kVideoCodecRED:
- case kVideoCodecULPFEC:
- case kVideoCodecFlexfec:
- case kVideoCodecMultiplex:
- break;
- // Unknown codec type, reset just to be sure.
- case kVideoCodecUnknown:
- return true;
- }
-
- if (new_send_codec.numberOfSimulcastStreams > 0) {
- for (unsigned char i = 0; i < new_send_codec.numberOfSimulcastStreams;
- ++i) {
- if (memcmp(&new_send_codec.simulcastStream[i],
- &send_codec_.simulcastStream[i],
- sizeof(new_send_codec.simulcastStream[i])) != 0) {
- return true;
- }
- }
- }
- return false;
-}
-
-VCMGenericEncoder* VCMCodecDataBase::GetEncoder() {
- return ptr_encoder_.get();
-}
-
-bool VCMCodecDataBase::SetPeriodicKeyFrames(bool enable) {
- periodic_key_frames_ = enable;
- if (ptr_encoder_) {
- return (ptr_encoder_->SetPeriodicKeyFrames(periodic_key_frames_) == 0);
- }
- return true;
-}
-
-bool VCMCodecDataBase::DeregisterExternalDecoder(uint8_t payload_type) {
- ExternalDecoderMap::iterator it = dec_external_map_.find(payload_type);
- if (it == dec_external_map_.end()) {
- // Not found
- return false;
- }
- // We can't use payload_type to check if the decoder is currently in use,
- // because payload type may be out of date (e.g. before we decode the first
- // frame after RegisterReceiveCodec)
- if (ptr_decoder_ &&
- ptr_decoder_->IsSameDecoder((*it).second->external_decoder_instance)) {
- // Release it if it was registered and in use.
- ptr_decoder_.reset();
- }
- DeregisterReceiveCodec(payload_type);
- delete it->second;
- dec_external_map_.erase(it);
- return true;
-}
-
-// Add the external encoder object to the list of external decoders.
-// Won't be registered as a receive codec until RegisterReceiveCodec is called.
-void VCMCodecDataBase::RegisterExternalDecoder(VideoDecoder* external_decoder,
- uint8_t payload_type) {
- // Check if payload value already exists, if so - erase old and insert new.
- VCMExtDecoderMapItem* ext_decoder =
- new VCMExtDecoderMapItem(external_decoder, payload_type);
- DeregisterExternalDecoder(payload_type);
- dec_external_map_[payload_type] = ext_decoder;
-}
-
-bool VCMCodecDataBase::DecoderRegistered() const {
- return !dec_map_.empty();
-}
-
-bool VCMCodecDataBase::RegisterReceiveCodec(const VideoCodec* receive_codec,
- int number_of_cores,
- bool require_key_frame) {
- if (number_of_cores < 0) {
- return false;
- }
- // Check if payload value already exists, if so - erase old and insert new.
- DeregisterReceiveCodec(receive_codec->plType);
- if (receive_codec->codecType == kVideoCodecUnknown) {
- return false;
- }
- VideoCodec* new_receive_codec = new VideoCodec(*receive_codec);
- dec_map_[receive_codec->plType] = new VCMDecoderMapItem(
- new_receive_codec, number_of_cores, require_key_frame);
- return true;
-}
-
-bool VCMCodecDataBase::DeregisterReceiveCodec(uint8_t payload_type) {
- DecoderMap::iterator it = dec_map_.find(payload_type);
- if (it == dec_map_.end()) {
- return false;
- }
- delete it->second;
- dec_map_.erase(it);
- if (receive_codec_.plType == payload_type) {
- // This codec is currently in use.
- memset(&receive_codec_, 0, sizeof(VideoCodec));
- }
- return true;
-}
-
-VCMGenericDecoder* VCMCodecDataBase::GetDecoder(
- const VCMEncodedFrame& frame,
- VCMDecodedFrameCallback* decoded_frame_callback) {
- RTC_DCHECK(decoded_frame_callback->UserReceiveCallback());
- uint8_t payload_type = frame.PayloadType();
- if (payload_type == receive_codec_.plType || payload_type == 0) {
- return ptr_decoder_.get();
- }
- // Check for exisitng decoder, if exists - delete.
- if (ptr_decoder_) {
- ptr_decoder_.reset();
- memset(&receive_codec_, 0, sizeof(VideoCodec));
- }
- ptr_decoder_ = CreateAndInitDecoder(frame, &receive_codec_);
- if (!ptr_decoder_) {
- return nullptr;
- }
- VCMReceiveCallback* callback = decoded_frame_callback->UserReceiveCallback();
- callback->OnIncomingPayloadType(receive_codec_.plType);
- if (ptr_decoder_->RegisterDecodeCompleteCallback(decoded_frame_callback) <
- 0) {
- ptr_decoder_.reset();
- memset(&receive_codec_, 0, sizeof(VideoCodec));
- return nullptr;
- }
- return ptr_decoder_.get();
-}
-
-VCMGenericDecoder* VCMCodecDataBase::GetCurrentDecoder() {
- return ptr_decoder_.get();
-}
-
-bool VCMCodecDataBase::PrefersLateDecoding() const {
- return ptr_decoder_ ? ptr_decoder_->PrefersLateDecoding() : true;
-}
-
-bool VCMCodecDataBase::MatchesCurrentResolution(int width, int height) const {
- return send_codec_.width == width && send_codec_.height == height;
-}
-
-std::unique_ptr<VCMGenericDecoder> VCMCodecDataBase::CreateAndInitDecoder(
- const VCMEncodedFrame& frame,
- VideoCodec* new_codec) const {
- uint8_t payload_type = frame.PayloadType();
- RTC_LOG(LS_INFO) << "Initializing decoder with payload type '"
- << static_cast<int>(payload_type) << "'.";
- RTC_DCHECK(new_codec);
- const VCMDecoderMapItem* decoder_item = FindDecoderItem(payload_type);
- if (!decoder_item) {
- RTC_LOG(LS_ERROR) << "Can't find a decoder associated with payload type: "
- << static_cast<int>(payload_type);
- return nullptr;
- }
- std::unique_ptr<VCMGenericDecoder> ptr_decoder;
- const VCMExtDecoderMapItem* external_dec_item =
- FindExternalDecoderItem(payload_type);
- if (external_dec_item) {
- // External codec.
- ptr_decoder.reset(new VCMGenericDecoder(
- external_dec_item->external_decoder_instance, true));
- } else {
-#if !defined(USE_BUILTIN_SW_CODECS)
- RTC_LOG(LS_ERROR) << "No decoder of this type exists.";
-#else
- // Create decoder.
- ptr_decoder = CreateDecoder(decoder_item->settings->codecType);
-#endif
- }
- if (!ptr_decoder)
- return nullptr;
-
- // Copy over input resolutions to prevent codec reinitialization due to
- // 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->settings->width = frame.EncodedImage()._encodedWidth;
- decoder_item->settings->height = frame.EncodedImage()._encodedHeight;
- }
- if (ptr_decoder->InitDecode(decoder_item->settings.get(),
- decoder_item->number_of_cores) < 0) {
- return nullptr;
- }
- memcpy(new_codec, decoder_item->settings.get(), sizeof(VideoCodec));
- return ptr_decoder;
-}
-
-void VCMCodecDataBase::DeleteEncoder() {
- if (!ptr_encoder_)
- return;
- ptr_encoder_->Release();
- ptr_encoder_.reset();
-}
-
-const VCMDecoderMapItem* VCMCodecDataBase::FindDecoderItem(
- uint8_t payload_type) const {
- DecoderMap::const_iterator it = dec_map_.find(payload_type);
- if (it != dec_map_.end()) {
- return (*it).second;
- }
- return nullptr;
-}
-
-const VCMExtDecoderMapItem* VCMCodecDataBase::FindExternalDecoderItem(
- uint8_t payload_type) const {
- ExternalDecoderMap::const_iterator it = dec_external_map_.find(payload_type);
- if (it != dec_external_map_.end()) {
- return (*it).second;
- }
- return nullptr;
-}
-} // namespace webrtc
diff --git a/modules/video_coding/codec_database.h b/modules/video_coding/codec_database.h
deleted file mode 100644
index 80b32b3..0000000
--- a/modules/video_coding/codec_database.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (c) 2012 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_CODEC_DATABASE_H_
-#define MODULES_VIDEO_CODING_CODEC_DATABASE_H_
-
-#include <map>
-#include <memory>
-
-#include "modules/video_coding/include/video_codec_interface.h"
-#include "modules/video_coding/include/video_coding.h"
-#include "modules/video_coding/generic_decoder.h"
-#include "modules/video_coding/generic_encoder.h"
-#include "typedefs.h" // NOLINT(build/include)
-
-namespace webrtc {
-
-struct VCMDecoderMapItem {
- public:
- VCMDecoderMapItem(VideoCodec* settings,
- int number_of_cores,
- bool require_key_frame);
-
- std::unique_ptr<VideoCodec> settings;
- int number_of_cores;
- bool require_key_frame;
-};
-
-struct VCMExtDecoderMapItem {
- public:
- VCMExtDecoderMapItem(VideoDecoder* external_decoder_instance,
- uint8_t payload_type);
-
- uint8_t payload_type;
- VideoDecoder* external_decoder_instance;
-};
-
-class VCMCodecDataBase {
- public:
- explicit VCMCodecDataBase(VCMEncodedFrameCallback* encoded_frame_callback);
- ~VCMCodecDataBase();
-
- // 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,
- uint8_t payload_type,
- bool internal_source);
-
- // Deregisters an external encoder. Returns true if the encoder was
- // found and deregistered, false otherwise. |was_send_codec| is set to true
- // if the external encoder was the send codec before being deregistered.
- bool DeregisterExternalEncoder(uint8_t payload_type, bool* was_send_codec);
-
- VCMGenericEncoder* GetEncoder();
-
- bool SetPeriodicKeyFrames(bool enable);
-
- // Deregisters an external decoder object specified by |payload_type|.
- bool DeregisterExternalDecoder(uint8_t payload_type);
-
- // Registers an external decoder object to the payload type |payload_type|.
- void RegisterExternalDecoder(VideoDecoder* external_decoder,
- uint8_t payload_type);
-
- bool DecoderRegistered() const;
-
- bool RegisterReceiveCodec(const VideoCodec* receive_codec,
- int number_of_cores,
- bool require_key_frame);
-
- bool DeregisterReceiveCodec(uint8_t payload_type);
-
- // Returns a decoder specified by |payload_type|. The decoded frame callback
- // of the encoder is set to |decoded_frame_callback|. If no such decoder
- // already exists an instance will be created and initialized.
- // NULL is returned if no encoder with the specified payload type was found
- // and the function failed to create one.
- VCMGenericDecoder* GetDecoder(
- const VCMEncodedFrame& frame,
- VCMDecodedFrameCallback* decoded_frame_callback);
-
- // Returns the current decoder (i.e. the same value as was last returned from
- // GetDecoder();
- VCMGenericDecoder* GetCurrentDecoder();
-
- // Returns true if the currently active decoder prefer to decode frames late.
- // That means that frames must be decoded near the render times stamp.
- bool PrefersLateDecoding() const;
-
- bool MatchesCurrentResolution(int width, int height) const;
-
- private:
- typedef std::map<uint8_t, VCMDecoderMapItem*> DecoderMap;
- typedef std::map<uint8_t, VCMExtDecoderMapItem*> ExternalDecoderMap;
-
- std::unique_ptr<VCMGenericDecoder> CreateAndInitDecoder(
- const VCMEncodedFrame& frame,
- VideoCodec* new_codec) const;
-
- // 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();
-
- const VCMDecoderMapItem* FindDecoderItem(uint8_t payload_type) const;
-
- const VCMExtDecoderMapItem* FindExternalDecoderItem(
- uint8_t payload_type) const;
-
- int number_of_cores_;
- size_t max_payload_size_;
- bool periodic_key_frames_;
- bool pending_encoder_reset_;
- VideoCodec send_codec_;
- VideoCodec receive_codec_;
- uint8_t encoder_payload_type_;
- VideoEncoder* external_encoder_;
- bool internal_source_;
- VCMEncodedFrameCallback* const encoded_frame_callback_;
- std::unique_ptr<VCMGenericEncoder> ptr_encoder_;
- std::unique_ptr<VCMGenericDecoder> ptr_decoder_;
- DecoderMap dec_map_;
- ExternalDecoderMap dec_external_map_;
-}; // VCMCodecDataBase
-
-} // namespace webrtc
-
-#endif // MODULES_VIDEO_CODING_CODEC_DATABASE_H_
diff --git a/modules/video_coding/decoder_database.cc b/modules/video_coding/decoder_database.cc
new file mode 100644
index 0000000..87609b8
--- /dev/null
+++ b/modules/video_coding/decoder_database.cc
@@ -0,0 +1,244 @@
+/*
+ * 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/decoder_database.h"
+#if defined(USE_BUILTIN_SW_CODECS)
+#include "modules/video_coding/codecs/h264/include/h264.h"
+#include "modules/video_coding/codecs/i420/include/i420.h" // nogncheck
+#include "modules/video_coding/codecs/vp8/include/vp8.h" // nogncheck
+#include "modules/video_coding/codecs/vp9/include/vp9.h" // nogncheck
+#endif
+#include "rtc_base/checks.h"
+#include "rtc_base/logging.h"
+
+namespace webrtc {
+
+#if defined(USE_BUILTIN_SW_CODECS)
+// Create an internal Decoder given a codec type
+static std::unique_ptr<VCMGenericDecoder> CreateDecoder(VideoCodecType type) {
+ switch (type) {
+ case kVideoCodecVP8:
+ return std::unique_ptr<VCMGenericDecoder>(
+ new VCMGenericDecoder(VP8Decoder::Create()));
+ case kVideoCodecVP9:
+ return std::unique_ptr<VCMGenericDecoder>(
+ new VCMGenericDecoder(VP9Decoder::Create()));
+ case kVideoCodecI420:
+ return std::unique_ptr<VCMGenericDecoder>(
+ new VCMGenericDecoder(new I420Decoder()));
+ case kVideoCodecH264:
+ if (H264Decoder::IsSupported()) {
+ return std::unique_ptr<VCMGenericDecoder>(
+ new VCMGenericDecoder(H264Decoder::Create()));
+ }
+ break;
+ default:
+ break;
+ }
+ RTC_LOG(LS_WARNING) << "No internal decoder of this type exists.";
+ return std::unique_ptr<VCMGenericDecoder>();
+}
+#endif
+
+VCMDecoderMapItem::VCMDecoderMapItem(VideoCodec* settings,
+ int number_of_cores,
+ bool require_key_frame)
+ : settings(settings),
+ number_of_cores(number_of_cores),
+ require_key_frame(require_key_frame) {
+ RTC_DCHECK_GE(number_of_cores, 0);
+}
+
+VCMExtDecoderMapItem::VCMExtDecoderMapItem(
+ VideoDecoder* external_decoder_instance,
+ uint8_t payload_type)
+ : payload_type(payload_type),
+ external_decoder_instance(external_decoder_instance) {}
+
+VCMDecoderDataBase::VCMDecoderDataBase()
+ : receive_codec_(), dec_map_(), dec_external_map_() {}
+
+VCMDecoderDataBase::~VCMDecoderDataBase() {
+ ptr_decoder_.reset();
+ for (auto& kv : dec_map_)
+ delete kv.second;
+ for (auto& kv : dec_external_map_)
+ delete kv.second;
+}
+
+bool VCMDecoderDataBase::DeregisterExternalDecoder(uint8_t payload_type) {
+ ExternalDecoderMap::iterator it = dec_external_map_.find(payload_type);
+ if (it == dec_external_map_.end()) {
+ // Not found
+ return false;
+ }
+ // We can't use payload_type to check if the decoder is currently in use,
+ // because payload type may be out of date (e.g. before we decode the first
+ // frame after RegisterReceiveCodec)
+ if (ptr_decoder_ &&
+ ptr_decoder_->IsSameDecoder((*it).second->external_decoder_instance)) {
+ // Release it if it was registered and in use.
+ ptr_decoder_.reset();
+ }
+ DeregisterReceiveCodec(payload_type);
+ delete it->second;
+ dec_external_map_.erase(it);
+ return true;
+}
+
+// Add the external encoder object to the list of external decoders.
+// Won't be registered as a receive codec until RegisterReceiveCodec is called.
+void VCMDecoderDataBase::RegisterExternalDecoder(VideoDecoder* external_decoder,
+ uint8_t payload_type) {
+ // Check if payload value already exists, if so - erase old and insert new.
+ VCMExtDecoderMapItem* ext_decoder =
+ new VCMExtDecoderMapItem(external_decoder, payload_type);
+ DeregisterExternalDecoder(payload_type);
+ dec_external_map_[payload_type] = ext_decoder;
+}
+
+bool VCMDecoderDataBase::DecoderRegistered() const {
+ return !dec_map_.empty();
+}
+
+bool VCMDecoderDataBase::RegisterReceiveCodec(const VideoCodec* receive_codec,
+ int number_of_cores,
+ bool require_key_frame) {
+ if (number_of_cores < 0) {
+ return false;
+ }
+ // Check if payload value already exists, if so - erase old and insert new.
+ DeregisterReceiveCodec(receive_codec->plType);
+ if (receive_codec->codecType == kVideoCodecUnknown) {
+ return false;
+ }
+ VideoCodec* new_receive_codec = new VideoCodec(*receive_codec);
+ dec_map_[receive_codec->plType] = new VCMDecoderMapItem(
+ new_receive_codec, number_of_cores, require_key_frame);
+ return true;
+}
+
+bool VCMDecoderDataBase::DeregisterReceiveCodec(uint8_t payload_type) {
+ DecoderMap::iterator it = dec_map_.find(payload_type);
+ if (it == dec_map_.end()) {
+ return false;
+ }
+ delete it->second;
+ dec_map_.erase(it);
+ if (receive_codec_.plType == payload_type) {
+ // This codec is currently in use.
+ memset(&receive_codec_, 0, sizeof(VideoCodec));
+ }
+ return true;
+}
+
+VCMGenericDecoder* VCMDecoderDataBase::GetDecoder(
+ const VCMEncodedFrame& frame,
+ VCMDecodedFrameCallback* decoded_frame_callback) {
+ RTC_DCHECK(decoded_frame_callback->UserReceiveCallback());
+ uint8_t payload_type = frame.PayloadType();
+ if (payload_type == receive_codec_.plType || payload_type == 0) {
+ return ptr_decoder_.get();
+ }
+ // Check for exisitng decoder, if exists - delete.
+ if (ptr_decoder_) {
+ ptr_decoder_.reset();
+ memset(&receive_codec_, 0, sizeof(VideoCodec));
+ }
+ ptr_decoder_ = CreateAndInitDecoder(frame, &receive_codec_);
+ if (!ptr_decoder_) {
+ return nullptr;
+ }
+ VCMReceiveCallback* callback = decoded_frame_callback->UserReceiveCallback();
+ callback->OnIncomingPayloadType(receive_codec_.plType);
+ if (ptr_decoder_->RegisterDecodeCompleteCallback(decoded_frame_callback) <
+ 0) {
+ ptr_decoder_.reset();
+ memset(&receive_codec_, 0, sizeof(VideoCodec));
+ return nullptr;
+ }
+ return ptr_decoder_.get();
+}
+
+VCMGenericDecoder* VCMDecoderDataBase::GetCurrentDecoder() {
+ return ptr_decoder_.get();
+}
+
+bool VCMDecoderDataBase::PrefersLateDecoding() const {
+ return ptr_decoder_ ? ptr_decoder_->PrefersLateDecoding() : true;
+}
+
+std::unique_ptr<VCMGenericDecoder> VCMDecoderDataBase::CreateAndInitDecoder(
+ const VCMEncodedFrame& frame,
+ VideoCodec* new_codec) const {
+ uint8_t payload_type = frame.PayloadType();
+ RTC_LOG(LS_INFO) << "Initializing decoder with payload type '"
+ << static_cast<int>(payload_type) << "'.";
+ RTC_DCHECK(new_codec);
+ const VCMDecoderMapItem* decoder_item = FindDecoderItem(payload_type);
+ if (!decoder_item) {
+ RTC_LOG(LS_ERROR) << "Can't find a decoder associated with payload type: "
+ << static_cast<int>(payload_type);
+ return nullptr;
+ }
+ std::unique_ptr<VCMGenericDecoder> ptr_decoder;
+ const VCMExtDecoderMapItem* external_dec_item =
+ FindExternalDecoderItem(payload_type);
+ if (external_dec_item) {
+ // External codec.
+ ptr_decoder.reset(new VCMGenericDecoder(
+ external_dec_item->external_decoder_instance, true));
+ } else {
+#if !defined(USE_BUILTIN_SW_CODECS)
+ RTC_LOG(LS_ERROR) << "No decoder of this type exists.";
+#else
+ // Create decoder.
+ ptr_decoder = CreateDecoder(decoder_item->settings->codecType);
+#endif
+ }
+ if (!ptr_decoder)
+ return nullptr;
+
+ // Copy over input resolutions to prevent codec reinitialization due to
+ // 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->settings->width = frame.EncodedImage()._encodedWidth;
+ decoder_item->settings->height = frame.EncodedImage()._encodedHeight;
+ }
+ if (ptr_decoder->InitDecode(decoder_item->settings.get(),
+ decoder_item->number_of_cores) < 0) {
+ return nullptr;
+ }
+ memcpy(new_codec, decoder_item->settings.get(), sizeof(VideoCodec));
+ return ptr_decoder;
+}
+
+const VCMDecoderMapItem* VCMDecoderDataBase::FindDecoderItem(
+ uint8_t payload_type) const {
+ DecoderMap::const_iterator it = dec_map_.find(payload_type);
+ if (it != dec_map_.end()) {
+ return (*it).second;
+ }
+ return nullptr;
+}
+
+const VCMExtDecoderMapItem* VCMDecoderDataBase::FindExternalDecoderItem(
+ uint8_t payload_type) const {
+ ExternalDecoderMap::const_iterator it = dec_external_map_.find(payload_type);
+ if (it != dec_external_map_.end()) {
+ return (*it).second;
+ }
+ return nullptr;
+}
+
+} // namespace webrtc
diff --git a/modules/video_coding/decoder_database.h b/modules/video_coding/decoder_database.h
new file mode 100644
index 0000000..8c03edb
--- /dev/null
+++ b/modules/video_coding/decoder_database.h
@@ -0,0 +1,96 @@
+/*
+ * 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_DECODER_DATABASE_H_
+#define MODULES_VIDEO_CODING_DECODER_DATABASE_H_
+
+#include <map>
+#include <memory>
+
+#include "modules/video_coding/generic_decoder.h"
+
+namespace webrtc {
+
+struct VCMDecoderMapItem {
+ public:
+ VCMDecoderMapItem(VideoCodec* settings,
+ int number_of_cores,
+ bool require_key_frame);
+
+ std::unique_ptr<VideoCodec> settings;
+ int number_of_cores;
+ bool require_key_frame;
+};
+
+struct VCMExtDecoderMapItem {
+ public:
+ VCMExtDecoderMapItem(VideoDecoder* external_decoder_instance,
+ uint8_t payload_type);
+
+ uint8_t payload_type;
+ VideoDecoder* external_decoder_instance;
+};
+
+class VCMDecoderDataBase {
+ public:
+ VCMDecoderDataBase();
+ ~VCMDecoderDataBase();
+
+ bool DeregisterExternalDecoder(uint8_t payload_type);
+ void RegisterExternalDecoder(VideoDecoder* external_decoder,
+ uint8_t payload_type);
+
+ bool DecoderRegistered() const;
+
+ bool RegisterReceiveCodec(const VideoCodec* receive_codec,
+ int number_of_cores,
+ bool require_key_frame);
+
+ bool DeregisterReceiveCodec(uint8_t payload_type);
+
+ // Returns a decoder specified by |payload_type|. The decoded frame callback
+ // of the encoder is set to |decoded_frame_callback|. If no such decoder
+ // already exists an instance will be created and initialized.
+ // NULL is returned if no encoder with the specified payload type was found
+ // and the function failed to create one.
+ VCMGenericDecoder* GetDecoder(
+ const VCMEncodedFrame& frame,
+ VCMDecodedFrameCallback* decoded_frame_callback);
+
+ // Returns the current decoder (i.e. the same value as was last returned from
+ // GetDecoder();
+ VCMGenericDecoder* GetCurrentDecoder();
+
+ // Returns true if the currently active decoder prefer to decode frames late.
+ // That means that frames must be decoded near the render times stamp.
+ bool PrefersLateDecoding() const;
+
+ private:
+ typedef std::map<uint8_t, VCMDecoderMapItem*> DecoderMap;
+ typedef std::map<uint8_t, VCMExtDecoderMapItem*> ExternalDecoderMap;
+
+ std::unique_ptr<VCMGenericDecoder> CreateAndInitDecoder(
+ const VCMEncodedFrame& frame,
+ VideoCodec* new_codec) const;
+
+ const VCMDecoderMapItem* FindDecoderItem(uint8_t payload_type) const;
+
+ const VCMExtDecoderMapItem* FindExternalDecoderItem(
+ uint8_t payload_type) const;
+
+ VideoCodec receive_codec_;
+ std::unique_ptr<VCMGenericDecoder> ptr_decoder_;
+ DecoderMap dec_map_;
+ ExternalDecoderMap dec_external_map_;
+};
+
+} // namespace webrtc
+
+#endif // MODULES_VIDEO_CODING_DECODER_DATABASE_H_
diff --git a/modules/video_coding/encoder_database.cc b/modules/video_coding/encoder_database.cc
new file mode 100644
index 0000000..60e640a
--- /dev/null
+++ b/modules/video_coding/encoder_database.cc
@@ -0,0 +1,233 @@
+/*
+ * 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 "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),
+ periodic_key_frames_(false),
+ pending_encoder_reset_(true),
+ send_codec_(),
+ encoder_payload_type_(0),
+ 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);
+ RTC_DCHECK_GE(send_codec->plType, 1);
+ // Make sure the start bit rate is sane...
+ RTC_DCHECK_LE(send_codec->startBitrate, 1000000);
+ RTC_DCHECK(send_codec->codecType != kVideoCodecUnknown);
+ 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();
+ RTC_DCHECK_EQ(encoder_payload_type_, send_codec_.plType)
+ << "Encoder not registered for payload type " << send_codec_.plType;
+ 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;
+ }
+
+ // Intentionally don't check return value since the encoder registration
+ // shouldn't fail because the codec doesn't support changing the periodic key
+ // frame setting.
+ ptr_encoder_->SetPeriodicKeyFrames(periodic_key_frames_);
+
+ pending_encoder_reset_ = false;
+
+ return true;
+}
+
+bool VCMEncoderDataBase::DeregisterExternalEncoder(uint8_t payload_type,
+ bool* was_send_codec) {
+ RTC_DCHECK(was_send_codec);
+ *was_send_codec = false;
+ if (encoder_payload_type_ != payload_type) {
+ return false;
+ }
+ if (send_codec_.plType == payload_type) {
+ // De-register as send codec if needed.
+ DeleteEncoder();
+ memset(&send_codec_, 0, sizeof(VideoCodec));
+ *was_send_codec = true;
+ }
+ encoder_payload_type_ = 0;
+ external_encoder_ = nullptr;
+ internal_source_ = false;
+ return true;
+}
+
+void VCMEncoderDataBase::RegisterExternalEncoder(VideoEncoder* external_encoder,
+ uint8_t payload_type,
+ bool internal_source) {
+ // Since only one encoder can be used at a given time, only one external
+ // encoder can be registered/used.
+ external_encoder_ = external_encoder;
+ encoder_payload_type_ = payload_type;
+ 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 or maxFramerate
+ if (new_send_codec.codecType != send_codec_.codecType ||
+ strcmp(new_send_codec.plName, send_codec_.plName) != 0 ||
+ new_send_codec.plType != send_codec_.plType ||
+ 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 (memcmp(&new_send_codec.VP8(), send_codec_.VP8(),
+ sizeof(new_send_codec.VP8())) != 0) {
+ return true;
+ }
+ break;
+ case kVideoCodecVP9:
+ if (memcmp(&new_send_codec.VP9(), send_codec_.VP9(),
+ sizeof(new_send_codec.VP9())) != 0) {
+ return true;
+ }
+ break;
+ case kVideoCodecH264:
+ if (memcmp(&new_send_codec.H264(), send_codec_.H264(),
+ sizeof(new_send_codec.H264())) != 0) {
+ return true;
+ }
+ break;
+ case kVideoCodecGeneric:
+ break;
+ // Known codecs without payload-specifics
+ case kVideoCodecI420:
+ case kVideoCodecRED:
+ case kVideoCodecULPFEC:
+ case kVideoCodecFlexfec:
+ case kVideoCodecMultiplex:
+ break;
+ // Unknown codec type, reset just to be sure.
+ case kVideoCodecUnknown:
+ return true;
+ }
+
+ if (new_send_codec.numberOfSimulcastStreams > 0) {
+ for (unsigned char i = 0; i < new_send_codec.numberOfSimulcastStreams;
+ ++i) {
+ if (memcmp(&new_send_codec.simulcastStream[i],
+ &send_codec_.simulcastStream[i],
+ sizeof(new_send_codec.simulcastStream[i])) != 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+VCMGenericEncoder* VCMEncoderDataBase::GetEncoder() {
+ return ptr_encoder_.get();
+}
+
+bool VCMEncoderDataBase::SetPeriodicKeyFrames(bool enable) {
+ periodic_key_frames_ = enable;
+ if (ptr_encoder_) {
+ return (ptr_encoder_->SetPeriodicKeyFrames(periodic_key_frames_) == 0);
+ }
+ return true;
+}
+
+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..34734ad
--- /dev/null
+++ b/modules/video_coding/encoder_database.h
@@ -0,0 +1,79 @@
+/*
+ * 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 <memory>
+
+#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,
+ uint8_t payload_type,
+ bool internal_source);
+
+ // Deregisters an external encoder. Returns true if the encoder was
+ // found and deregistered, false otherwise. |was_send_codec| is set to true
+ // if the external encoder was the send codec before being deregistered.
+ bool DeregisterExternalEncoder(uint8_t payload_type, bool* was_send_codec);
+
+ VCMGenericEncoder* GetEncoder();
+
+ bool SetPeriodicKeyFrames(bool enable);
+
+ // Deregisters an external decoder object specified by |payload_type|.
+ bool DeregisterExternalDecoder(uint8_t payload_type);
+
+ // Registers an external decoder object to the payload type |payload_type|.
+ void RegisterExternalDecoder(VideoDecoder* external_decoder,
+ uint8_t payload_type);
+
+ 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 periodic_key_frames_;
+ bool pending_encoder_reset_;
+ VideoCodec send_codec_;
+ uint8_t encoder_payload_type_;
+ 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 be9c09f..8a442c8 100644
--- a/modules/video_coding/video_coding_impl.h
+++ b/modules/video_coding/video_coding_impl.h
@@ -18,7 +18,8 @@
#include <vector>
#include "common_video/include/frame_callback.h"
-#include "modules/video_coding/codec_database.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"
@@ -121,7 +122,7 @@
media_optimization::MediaOptimization _mediaOpt;
VCMEncodedFrameCallback _encodedFrameCallback RTC_GUARDED_BY(encoder_crit_);
EncodedImageCallback* const post_encode_callback_;
- VCMCodecDataBase _codecDataBase RTC_GUARDED_BY(encoder_crit_);
+ VCMEncoderDataBase _codecDataBase RTC_GUARDED_BY(encoder_crit_);
bool frame_dropper_enabled_ RTC_GUARDED_BY(encoder_crit_);
// Must be accessed on the construction thread of VideoSender.
@@ -214,7 +215,7 @@
bool drop_frames_until_keyframe_ RTC_GUARDED_BY(process_crit_);
size_t max_nack_list_size_ RTC_GUARDED_BY(process_crit_);
- VCMCodecDataBase _codecDataBase RTC_GUARDED_BY(receive_crit_);
+ VCMDecoderDataBase _codecDataBase RTC_GUARDED_BY(receive_crit_);
EncodedImageCallback* pre_decode_image_callback_;
VCMProcessTimer _receiveStatsTimer;
diff --git a/modules/video_coding/video_receiver.cc b/modules/video_coding/video_receiver.cc
index 112edda..038c523 100644
--- a/modules/video_coding/video_receiver.cc
+++ b/modules/video_coding/video_receiver.cc
@@ -44,7 +44,7 @@
_scheduleKeyRequest(false),
drop_frames_until_keyframe_(false),
max_nack_list_size_(0),
- _codecDataBase(nullptr),
+ _codecDataBase(),
pre_decode_image_callback_(pre_decode_image_callback),
_receiveStatsTimer(1000, clock_),
_retransmissionTimer(10, clock_),