Index: webrtc/media/engine/webrtcvideoengine.cc |
diff --git a/webrtc/media/engine/webrtcvideoengine.cc b/webrtc/media/engine/webrtcvideoengine.cc |
index dd0a7b029a18938373b736681a5f4ac5fa08d112..00d138ab4db60a4bd116b047f450134593bb7ac4 100644 |
--- a/webrtc/media/engine/webrtcvideoengine.cc |
+++ b/webrtc/media/engine/webrtcvideoengine.cc |
@@ -24,7 +24,6 @@ |
#include "webrtc/media/engine/constants.h" |
#include "webrtc/media/engine/internaldecoderfactory.h" |
#include "webrtc/media/engine/internalencoderfactory.h" |
-#include "webrtc/media/engine/scopedvideodecoder.h" |
#include "webrtc/media/engine/scopedvideoencoder.h" |
#include "webrtc/media/engine/simulcast.h" |
#include "webrtc/media/engine/simulcast_encoder_adapter.h" |
@@ -72,17 +71,6 @@ |
virtual std::unique_ptr<EncoderFactoryAdapter> clone() const = 0; |
}; |
-class DecoderFactoryAdapter { |
- public: |
- virtual ~DecoderFactoryAdapter() {} |
- |
- virtual std::unique_ptr<webrtc::VideoDecoder> CreateVideoDecoder( |
- webrtc::VideoCodecType type, |
- const VideoDecoderParams& decoder_params) const = 0; |
- |
- virtual std::unique_ptr<DecoderFactoryAdapter> clone() const = 0; |
-}; |
- |
namespace { |
// Wraps cricket::WebRtcVideoEncoderFactory* into common EncoderFactoryAdapter |
@@ -114,31 +102,6 @@ |
const std::unique_ptr<WebRtcVideoEncoderFactory> internal_encoder_factory_; |
WebRtcVideoEncoderFactory* const external_encoder_factory_; |
-}; |
- |
-class CricketDecoderFactoryAdapter : public DecoderFactoryAdapter { |
- public: |
- explicit CricketDecoderFactoryAdapter( |
- WebRtcVideoDecoderFactory* external_decoder_factory) |
- : internal_decoder_factory_(new InternalDecoderFactory()), |
- external_decoder_factory_(external_decoder_factory) {} |
- |
- private: |
- explicit CricketDecoderFactoryAdapter( |
- const CricketDecoderFactoryAdapter& other) |
- : CricketDecoderFactoryAdapter(other.external_decoder_factory_) {} |
- |
- std::unique_ptr<webrtc::VideoDecoder> CreateVideoDecoder( |
- webrtc::VideoCodecType type, |
- const VideoDecoderParams& decoder_params) const override; |
- |
- std::unique_ptr<DecoderFactoryAdapter> clone() const override { |
- return std::unique_ptr<DecoderFactoryAdapter>( |
- new CricketDecoderFactoryAdapter(*this)); |
- } |
- |
- const std::unique_ptr<WebRtcVideoDecoderFactory> internal_decoder_factory_; |
- WebRtcVideoDecoderFactory* const external_decoder_factory_; |
}; |
// If this field trial is enabled, we will enable sending FlexFEC and disable |
@@ -404,8 +367,7 @@ |
WebRtcVideoEngine::WebRtcVideoEngine() |
: initialized_(false), |
- decoder_factory_(new CricketDecoderFactoryAdapter( |
- nullptr /* external_decoder_factory */)), |
+ external_decoder_factory_(NULL), |
encoder_factory_(new CricketEncoderFactoryAdapter( |
nullptr /* external_encoder_factory */)) { |
LOG(LS_INFO) << "WebRtcVideoEngine::WebRtcVideoEngine()"; |
@@ -427,7 +389,7 @@ |
RTC_DCHECK(initialized_); |
LOG(LS_INFO) << "CreateChannel. Options: " << options.ToString(); |
return new WebRtcVideoChannel(call, config, options, *encoder_factory_, |
- *decoder_factory_); |
+ external_decoder_factory_); |
} |
std::vector<VideoCodec> WebRtcVideoEngine::codecs() const { |
@@ -463,7 +425,7 @@ |
void WebRtcVideoEngine::SetExternalDecoderFactory( |
WebRtcVideoDecoderFactory* decoder_factory) { |
RTC_DCHECK(!initialized_); |
- decoder_factory_.reset(new CricketDecoderFactoryAdapter(decoder_factory)); |
+ external_decoder_factory_ = decoder_factory; |
} |
void WebRtcVideoEngine::SetExternalEncoderFactory( |
@@ -541,13 +503,13 @@ |
const MediaConfig& config, |
const VideoOptions& options, |
const EncoderFactoryAdapter& encoder_factory, |
- const DecoderFactoryAdapter& decoder_factory) |
+ WebRtcVideoDecoderFactory* external_decoder_factory) |
: VideoMediaChannel(config), |
call_(call), |
unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_), |
video_config_(config.video), |
encoder_factory_(encoder_factory.clone()), |
- decoder_factory_(decoder_factory.clone()), |
+ external_decoder_factory_(external_decoder_factory), |
default_send_options_(options), |
last_stats_log_ms_(-1) { |
RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
@@ -1163,7 +1125,7 @@ |
config.sync_group = sp.sync_label; |
receive_streams_[ssrc] = new WebRtcVideoReceiveStream( |
- call_, sp, std::move(config), *decoder_factory_, default_stream, |
+ call_, sp, std::move(config), external_decoder_factory_, default_stream, |
recv_codecs_, flexfec_config); |
return true; |
@@ -2101,7 +2063,7 @@ |
webrtc::Call* call, |
const StreamParams& sp, |
webrtc::VideoReceiveStream::Config config, |
- const DecoderFactoryAdapter& decoder_factory, |
+ WebRtcVideoDecoderFactory* external_decoder_factory, |
bool default_stream, |
const std::vector<VideoCodecSettings>& recv_codecs, |
const webrtc::FlexfecReceiveStream::Config& flexfec_config) |
@@ -2112,13 +2074,12 @@ |
config_(std::move(config)), |
flexfec_config_(flexfec_config), |
flexfec_stream_(nullptr), |
- decoder_factory_(decoder_factory.clone()), |
+ external_decoder_factory_(external_decoder_factory), |
sink_(NULL), |
first_frame_timestamp_(-1), |
estimated_remote_start_ntp_time_ms_(0) { |
config_.renderer = this; |
- std::map<webrtc::VideoCodecType, std::unique_ptr<webrtc::VideoDecoder>> |
- old_decoders; |
+ std::vector<AllocatedDecoder> old_decoders; |
ConfigureCodecs(recv_codecs, &old_decoders); |
ConfigureFlexfecCodec(flexfec_config.payload_type); |
MaybeRecreateWebRtcFlexfecStream(); |
@@ -2126,13 +2087,28 @@ |
RTC_DCHECK(old_decoders.empty()); |
} |
+WebRtcVideoChannel::WebRtcVideoReceiveStream::AllocatedDecoder:: |
+ AllocatedDecoder(webrtc::VideoDecoder* decoder, |
+ webrtc::VideoCodecType type, |
+ bool external) |
+ : decoder(decoder), |
+ external_decoder(nullptr), |
+ type(type), |
+ external(external) { |
+ if (external) { |
+ external_decoder = decoder; |
+ this->decoder = |
+ new webrtc::VideoDecoderSoftwareFallbackWrapper(type, external_decoder); |
+ } |
+} |
+ |
WebRtcVideoChannel::WebRtcVideoReceiveStream::~WebRtcVideoReceiveStream() { |
if (flexfec_stream_) { |
MaybeDissociateFlexfecFromVideo(); |
call_->DestroyFlexfecReceiveStream(flexfec_stream_); |
} |
call_->DestroyVideoReceiveStream(stream_); |
- allocated_decoders_.clear(); |
+ ClearDecoders(&allocated_decoders_); |
} |
const std::vector<uint32_t>& |
@@ -2153,59 +2129,53 @@ |
} |
} |
-std::unique_ptr<webrtc::VideoDecoder> |
-CricketDecoderFactoryAdapter::CreateVideoDecoder( |
- webrtc::VideoCodecType type, |
- const VideoDecoderParams& decoder_params) const { |
- if (external_decoder_factory_ != nullptr) { |
- std::unique_ptr<webrtc::VideoDecoder> external_decoder = |
- CreateScopedVideoDecoder(external_decoder_factory_, type, |
- decoder_params); |
- if (external_decoder) { |
- std::unique_ptr<webrtc::VideoDecoder> internal_decoder( |
- new webrtc::VideoDecoderSoftwareFallbackWrapper( |
- type, std::move(external_decoder))); |
- return internal_decoder; |
- } |
- } |
- |
- std::unique_ptr<webrtc::VideoDecoder> internal_decoder( |
- internal_decoder_factory_->CreateVideoDecoderWithParams(type, |
- decoder_params)); |
- return internal_decoder; |
+WebRtcVideoChannel::WebRtcVideoReceiveStream::AllocatedDecoder |
+WebRtcVideoChannel::WebRtcVideoReceiveStream::CreateOrReuseVideoDecoder( |
+ std::vector<AllocatedDecoder>* old_decoders, |
+ const VideoCodec& codec) { |
+ webrtc::VideoCodecType type = webrtc::PayloadStringToCodecType(codec.name); |
+ |
+ for (size_t i = 0; i < old_decoders->size(); ++i) { |
+ if ((*old_decoders)[i].type == type) { |
+ AllocatedDecoder decoder = (*old_decoders)[i]; |
+ (*old_decoders)[i] = old_decoders->back(); |
+ old_decoders->pop_back(); |
+ return decoder; |
+ } |
+ } |
+ |
+ if (external_decoder_factory_ != NULL) { |
+ webrtc::VideoDecoder* decoder = |
+ external_decoder_factory_->CreateVideoDecoderWithParams( |
+ type, {stream_params_.id}); |
+ if (decoder != NULL) { |
+ return AllocatedDecoder(decoder, type, true /* is_external */); |
+ } |
+ } |
+ |
+ InternalDecoderFactory internal_decoder_factory; |
+ return AllocatedDecoder(internal_decoder_factory.CreateVideoDecoderWithParams( |
+ type, {stream_params_.id}), |
+ type, false /* is_external */); |
} |
void WebRtcVideoChannel::WebRtcVideoReceiveStream::ConfigureCodecs( |
const std::vector<VideoCodecSettings>& recv_codecs, |
- std::map<webrtc::VideoCodecType, std::unique_ptr<webrtc::VideoDecoder>>* |
- old_decoders) { |
- *old_decoders = std::move(allocated_decoders_); |
+ std::vector<AllocatedDecoder>* old_decoders) { |
+ *old_decoders = allocated_decoders_; |
allocated_decoders_.clear(); |
config_.decoders.clear(); |
for (size_t i = 0; i < recv_codecs.size(); ++i) { |
- webrtc::VideoCodecType type = |
- webrtc::PayloadStringToCodecType(recv_codecs[i].codec.name); |
- std::unique_ptr<webrtc::VideoDecoder> new_decoder; |
- |
- auto it = old_decoders->find(type); |
- if (it != old_decoders->end()) { |
- new_decoder = std::move(it->second); |
- old_decoders->erase(it); |
- } |
- |
- if (!new_decoder) { |
- new_decoder = |
- decoder_factory_->CreateVideoDecoder(type, {stream_params_.id}); |
- } |
+ AllocatedDecoder allocated_decoder = |
+ CreateOrReuseVideoDecoder(old_decoders, recv_codecs[i].codec); |
+ allocated_decoders_.push_back(allocated_decoder); |
webrtc::VideoReceiveStream::Decoder decoder; |
- decoder.decoder = new_decoder.get(); |
+ decoder.decoder = allocated_decoder.decoder; |
decoder.payload_type = recv_codecs[i].codec.id; |
decoder.payload_name = recv_codecs[i].codec.name; |
decoder.codec_params = recv_codecs[i].codec.params; |
config_.decoders.push_back(decoder); |
- |
- allocated_decoders_.insert(std::make_pair(type, std::move(new_decoder))); |
} |
config_.rtp.rtx_associated_payload_types.clear(); |
@@ -2283,8 +2253,7 @@ |
const ChangedRecvParameters& params) { |
bool video_needs_recreation = false; |
bool flexfec_needs_recreation = false; |
- std::map<webrtc::VideoCodecType, std::unique_ptr<webrtc::VideoDecoder>> |
- old_decoders; |
+ std::vector<AllocatedDecoder> old_decoders; |
if (params.codec_settings) { |
ConfigureCodecs(*params.codec_settings, &old_decoders); |
video_needs_recreation = true; |
@@ -2308,6 +2277,7 @@ |
LOG(LS_INFO) |
<< "RecreateWebRtcVideoStream (recv) because of SetRecvParameters"; |
RecreateWebRtcVideoStream(); |
+ ClearDecoders(&old_decoders); |
} |
} |
@@ -2350,6 +2320,18 @@ |
if (stream_ && flexfec_stream_) { |
stream_->RemoveSecondarySink(flexfec_stream_); |
} |
+} |
+ |
+void WebRtcVideoChannel::WebRtcVideoReceiveStream::ClearDecoders( |
+ std::vector<AllocatedDecoder>* allocated_decoders) { |
+ for (size_t i = 0; i < allocated_decoders->size(); ++i) { |
+ if ((*allocated_decoders)[i].external) { |
+ external_decoder_factory_->DestroyVideoDecoder( |
+ (*allocated_decoders)[i].external_decoder); |
+ } |
+ delete (*allocated_decoders)[i].decoder; |
+ } |
+ allocated_decoders->clear(); |
} |
void WebRtcVideoChannel::WebRtcVideoReceiveStream::OnFrame( |