Index: webrtc/modules/video_coding/codec_database.cc |
diff --git a/webrtc/modules/video_coding/codec_database.cc b/webrtc/modules/video_coding/codec_database.cc |
index 29899fccaae6bb1b242ebaafe1c8d7c6958f72e4..4d5e20215caa090aebff54ef3b387ff39ee56dd6 100644 |
--- a/webrtc/modules/video_coding/codec_database.cc |
+++ b/webrtc/modules/video_coding/codec_database.cc |
@@ -69,31 +69,6 @@ |
h264_settings.profile = H264::kProfileConstrainedBaseline; |
return h264_settings; |
-} |
- |
-// 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; |
- } |
- LOG(LS_WARNING) << "No internal decoder of this type exists."; |
- return std::unique_ptr<VCMGenericDecoder>(); |
} |
VCMDecoderMapItem::VCMDecoderMapItem(VideoCodec* settings, |
@@ -123,12 +98,13 @@ |
external_encoder_(nullptr), |
internal_source_(false), |
encoded_frame_callback_(encoded_frame_callback), |
+ ptr_decoder_(nullptr), |
dec_map_(), |
dec_external_map_() {} |
VCMCodecDataBase::~VCMCodecDataBase() { |
DeleteEncoder(); |
- ptr_decoder_.reset(); |
+ ReleaseDecoder(ptr_decoder_); |
for (auto& kv : dec_map_) |
delete kv.second; |
for (auto& kv : dec_external_map_) |
@@ -415,10 +391,11 @@ |
// 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 (ptr_decoder_ != nullptr && |
+ ptr_decoder_->_decoder == (*it).second->external_decoder_instance) { |
// Release it if it was registered and in use. |
- ptr_decoder_.reset(); |
+ ReleaseDecoder(ptr_decoder_); |
+ ptr_decoder_ = nullptr; |
} |
DeregisterReceiveCodec(payload_type); |
delete it->second; |
@@ -478,11 +455,12 @@ |
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(); |
+ return ptr_decoder_; |
} |
// Check for exisitng decoder, if exists - delete. |
if (ptr_decoder_) { |
- ptr_decoder_.reset(); |
+ ReleaseDecoder(ptr_decoder_); |
+ ptr_decoder_ = nullptr; |
memset(&receive_codec_, 0, sizeof(VideoCodec)); |
} |
ptr_decoder_ = CreateAndInitDecoder(frame, &receive_codec_); |
@@ -493,26 +471,36 @@ |
callback->OnIncomingPayloadType(receive_codec_.plType); |
if (ptr_decoder_->RegisterDecodeCompleteCallback(decoded_frame_callback) < |
0) { |
- ptr_decoder_.reset(); |
+ ReleaseDecoder(ptr_decoder_); |
+ ptr_decoder_ = nullptr; |
memset(&receive_codec_, 0, sizeof(VideoCodec)); |
return nullptr; |
} |
- return ptr_decoder_.get(); |
-} |
- |
-VCMGenericDecoder* VCMCodecDataBase::GetCurrentDecoder() { |
- return ptr_decoder_.get(); |
+ return ptr_decoder_; |
+} |
+ |
+void VCMCodecDataBase::ReleaseDecoder(VCMGenericDecoder* decoder) const { |
+ if (decoder) { |
+ RTC_DCHECK(decoder->_decoder); |
+ decoder->Release(); |
+ if (!decoder->External()) { |
+ delete decoder->_decoder; |
+ } |
+ delete decoder; |
+ } |
} |
bool VCMCodecDataBase::PrefersLateDecoding() const { |
- return ptr_decoder_ ? ptr_decoder_->PrefersLateDecoding() : true; |
+ if (!ptr_decoder_) |
+ return true; |
+ return ptr_decoder_->PrefersLateDecoding(); |
} |
bool VCMCodecDataBase::MatchesCurrentResolution(int width, int height) const { |
return send_codec_.width == width && send_codec_.height == height; |
} |
-std::unique_ptr<VCMGenericDecoder> VCMCodecDataBase::CreateAndInitDecoder( |
+VCMGenericDecoder* VCMCodecDataBase::CreateAndInitDecoder( |
const VCMEncodedFrame& frame, |
VideoCodec* new_codec) const { |
uint8_t payload_type = frame.PayloadType(); |
@@ -525,13 +513,13 @@ |
<< static_cast<int>(payload_type); |
return nullptr; |
} |
- std::unique_ptr<VCMGenericDecoder> ptr_decoder; |
+ VCMGenericDecoder* ptr_decoder = nullptr; |
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)); |
+ ptr_decoder = new VCMGenericDecoder( |
+ external_dec_item->external_decoder_instance, true); |
} else { |
// Create decoder. |
ptr_decoder = CreateDecoder(decoder_item->settings->codecType); |
@@ -550,6 +538,7 @@ |
} |
if (ptr_decoder->InitDecode(decoder_item->settings.get(), |
decoder_item->number_of_cores) < 0) { |
+ ReleaseDecoder(ptr_decoder); |
return nullptr; |
} |
memcpy(new_codec, decoder_item->settings.get(), sizeof(VideoCodec)); |
@@ -563,6 +552,26 @@ |
ptr_encoder_.reset(); |
} |
+VCMGenericDecoder* VCMCodecDataBase::CreateDecoder(VideoCodecType type) const { |
+ switch (type) { |
+ case kVideoCodecVP8: |
+ return new VCMGenericDecoder(VP8Decoder::Create()); |
+ case kVideoCodecVP9: |
+ return new VCMGenericDecoder(VP9Decoder::Create()); |
+ case kVideoCodecI420: |
+ return new VCMGenericDecoder(new I420Decoder()); |
+ case kVideoCodecH264: |
+ if (H264Decoder::IsSupported()) { |
+ return new VCMGenericDecoder(H264Decoder::Create()); |
+ } |
+ break; |
+ default: |
+ break; |
+ } |
+ LOG(LS_WARNING) << "No internal decoder of this type exists."; |
+ return nullptr; |
+} |
+ |
const VCMDecoderMapItem* VCMCodecDataBase::FindDecoderItem( |
uint8_t payload_type) const { |
DecoderMap::const_iterator it = dec_map_.find(payload_type); |