Cleanup VCMDecoderDataBase and neigbour VCMGenericDecoder classes

Remove private members that are no longer used or always have same value
Use less allocations

Bug: None
Change-Id: I5430c2356f0039212baf8b248b92775e8852ce1b
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/227765
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34665}
This commit is contained in:
Danil Chapovalov
2021-08-06 12:30:02 +02:00
committed by WebRTC LUCI CQ
parent 5c3c103c41
commit 7b78a3142d
7 changed files with 83 additions and 172 deletions

View File

@ -15,94 +15,62 @@
namespace webrtc {
VCMDecoderMapItem::VCMDecoderMapItem(VideoCodec* settings, int number_of_cores)
: settings(settings), number_of_cores(number_of_cores) {
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) {}
VCMDecoderMapItem::~VCMDecoderMapItem() {}
VCMDecoderDataBase::VCMDecoderDataBase()
: current_payload_type_(0),
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()) {
auto it = decoders_.find(payload_type);
if (it == decoders_.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)) {
if (current_decoder_ && current_decoder_->IsSameDecoder(it->second)) {
// Release it if it was registered and in use.
ptr_decoder_.reset();
current_decoder_ = absl::nullopt;
}
delete it->second;
dec_external_map_.erase(it);
decoders_.erase(it);
return true;
}
// Add the external decoder 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) {
void VCMDecoderDataBase::RegisterExternalDecoder(
uint8_t payload_type,
VideoDecoder* external_decoder) {
// If payload value already exists, erase old and insert new.
VCMExtDecoderMapItem* ext_decoder =
new VCMExtDecoderMapItem(external_decoder, payload_type);
DeregisterExternalDecoder(payload_type);
dec_external_map_[payload_type] = ext_decoder;
decoders_[payload_type] = external_decoder;
}
bool VCMDecoderDataBase::IsExternalDecoderRegistered(
uint8_t payload_type) const {
return payload_type == current_payload_type_ ||
FindExternalDecoderItem(payload_type);
decoders_.find(payload_type) != decoders_.end();
}
bool VCMDecoderDataBase::RegisterReceiveCodec(uint8_t payload_type,
const VideoCodec* receive_codec,
const VideoCodec& receive_codec,
int number_of_cores) {
if (number_of_cores < 0) {
return false;
}
// If payload value already exists, erase old and insert new.
DeregisterReceiveCodec(payload_type);
VideoCodec* new_receive_codec = new VideoCodec(*receive_codec);
dec_map_[payload_type] =
new VCMDecoderMapItem(new_receive_codec, number_of_cores);
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;
return true;
}
bool VCMDecoderDataBase::DeregisterReceiveCodec(uint8_t payload_type) {
DecoderMap::iterator it = dec_map_.find(payload_type);
if (it == dec_map_.end()) {
if (decoder_settings_.erase(payload_type) == 0) {
return false;
}
delete it->second;
dec_map_.erase(it);
if (payload_type == current_payload_type_) {
// This codec is currently in use.
receive_codec_ = {};
current_payload_type_ = 0;
current_payload_type_ = absl::nullopt;
}
return true;
}
@ -113,56 +81,47 @@ VCMGenericDecoder* VCMDecoderDataBase::GetDecoder(
RTC_DCHECK(decoded_frame_callback->UserReceiveCallback());
uint8_t payload_type = frame.PayloadType();
if (payload_type == current_payload_type_ || payload_type == 0) {
return ptr_decoder_.get();
return current_decoder_.has_value() ? &*current_decoder_ : nullptr;
}
// If decoder exists - delete.
if (ptr_decoder_) {
ptr_decoder_.reset();
receive_codec_ = {};
current_payload_type_ = 0;
if (current_decoder_.has_value()) {
current_decoder_ = absl::nullopt;
current_payload_type_ = absl::nullopt;
}
ptr_decoder_ = CreateAndInitDecoder(frame, &receive_codec_);
if (!ptr_decoder_) {
CreateAndInitDecoder(frame);
if (current_decoder_ == absl::nullopt) {
return nullptr;
}
current_payload_type_ = frame.PayloadType();
VCMReceiveCallback* callback = decoded_frame_callback->UserReceiveCallback();
callback->OnIncomingPayloadType(current_payload_type_);
if (ptr_decoder_->RegisterDecodeCompleteCallback(decoded_frame_callback) <
callback->OnIncomingPayloadType(payload_type);
if (current_decoder_->RegisterDecodeCompleteCallback(decoded_frame_callback) <
0) {
ptr_decoder_.reset();
receive_codec_ = {};
current_payload_type_ = 0;
current_decoder_ = absl::nullopt;
return nullptr;
}
return ptr_decoder_.get();
current_payload_type_ = payload_type;
return &*current_decoder_;
}
std::unique_ptr<VCMGenericDecoder> VCMDecoderDataBase::CreateAndInitDecoder(
const VCMEncodedFrame& frame,
VideoCodec* new_codec) const {
void VCMDecoderDataBase::CreateAndInitDecoder(const VCMEncodedFrame& frame) {
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) {
<< int{payload_type} << "'.";
auto decoder_item = decoder_settings_.find(payload_type);
if (decoder_item == decoder_settings_.end()) {
RTC_LOG(LS_ERROR) << "Can't find a decoder associated with payload type: "
<< static_cast<int>(payload_type);
return nullptr;
<< int{payload_type};
return;
}
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 {
auto external_dec_item = decoders_.find(payload_type);
if (external_dec_item == decoders_.end()) {
RTC_LOG(LS_ERROR) << "No decoder of this type exists.";
return;
}
if (!ptr_decoder)
return nullptr;
current_decoder_.emplace(external_dec_item->second);
// Copy over input resolutions to prevent codec reinitialization due to
// the first frame being of a different resolution than the database values.
@ -170,35 +129,15 @@ std::unique_ptr<VCMGenericDecoder> VCMDecoderDataBase::CreateAndInitDecoder(
// 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;
decoder_item->second.settings.width = frame.EncodedImage()._encodedWidth;
decoder_item->second.settings.height = frame.EncodedImage()._encodedHeight;
}
int err = ptr_decoder->InitDecode(decoder_item->settings.get(),
decoder_item->number_of_cores);
int err = current_decoder_->InitDecode(&decoder_item->second.settings,
decoder_item->second.number_of_cores);
if (err < 0) {
current_decoder_ = absl::nullopt;
RTC_LOG(LS_ERROR) << "Failed to initialize decoder. Error code: " << err;
return nullptr;
}
*new_codec = *decoder_item->settings.get();
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