| Index: webrtc/media/engine/webrtcvideoengine.cc
|
| diff --git a/webrtc/media/engine/webrtcvideoengine.cc b/webrtc/media/engine/webrtcvideoengine.cc
|
| index 00d138ab4db60a4bd116b047f450134593bb7ac4..dd0a7b029a18938373b736681a5f4ac5fa08d112 100644
|
| --- a/webrtc/media/engine/webrtcvideoengine.cc
|
| +++ b/webrtc/media/engine/webrtcvideoengine.cc
|
| @@ -24,6 +24,7 @@
|
| #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"
|
| @@ -71,6 +72,17 @@ class EncoderFactoryAdapter {
|
| 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
|
| @@ -104,6 +116,31 @@ class CricketEncoderFactoryAdapter : public EncoderFactoryAdapter {
|
| 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
|
| // sending ULPFEC whenever the former has been negotiated in the SDPs.
|
| bool IsFlexfecFieldTrialEnabled() {
|
| @@ -367,7 +404,8 @@ void DefaultUnsignalledSsrcHandler::SetDefaultSink(
|
|
|
| WebRtcVideoEngine::WebRtcVideoEngine()
|
| : initialized_(false),
|
| - external_decoder_factory_(NULL),
|
| + decoder_factory_(new CricketDecoderFactoryAdapter(
|
| + nullptr /* external_decoder_factory */)),
|
| encoder_factory_(new CricketEncoderFactoryAdapter(
|
| nullptr /* external_encoder_factory */)) {
|
| LOG(LS_INFO) << "WebRtcVideoEngine::WebRtcVideoEngine()";
|
| @@ -389,7 +427,7 @@ WebRtcVideoChannel* WebRtcVideoEngine::CreateChannel(
|
| RTC_DCHECK(initialized_);
|
| LOG(LS_INFO) << "CreateChannel. Options: " << options.ToString();
|
| return new WebRtcVideoChannel(call, config, options, *encoder_factory_,
|
| - external_decoder_factory_);
|
| + *decoder_factory_);
|
| }
|
|
|
| std::vector<VideoCodec> WebRtcVideoEngine::codecs() const {
|
| @@ -425,7 +463,7 @@ RtpCapabilities WebRtcVideoEngine::GetCapabilities() const {
|
| void WebRtcVideoEngine::SetExternalDecoderFactory(
|
| WebRtcVideoDecoderFactory* decoder_factory) {
|
| RTC_DCHECK(!initialized_);
|
| - external_decoder_factory_ = decoder_factory;
|
| + decoder_factory_.reset(new CricketDecoderFactoryAdapter(decoder_factory));
|
| }
|
|
|
| void WebRtcVideoEngine::SetExternalEncoderFactory(
|
| @@ -503,13 +541,13 @@ WebRtcVideoChannel::WebRtcVideoChannel(
|
| const MediaConfig& config,
|
| const VideoOptions& options,
|
| const EncoderFactoryAdapter& encoder_factory,
|
| - WebRtcVideoDecoderFactory* external_decoder_factory)
|
| + const DecoderFactoryAdapter& decoder_factory)
|
| : VideoMediaChannel(config),
|
| call_(call),
|
| unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_),
|
| video_config_(config.video),
|
| encoder_factory_(encoder_factory.clone()),
|
| - external_decoder_factory_(external_decoder_factory),
|
| + decoder_factory_(decoder_factory.clone()),
|
| default_send_options_(options),
|
| last_stats_log_ms_(-1) {
|
| RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
| @@ -1125,7 +1163,7 @@ bool WebRtcVideoChannel::AddRecvStream(const StreamParams& sp,
|
| config.sync_group = sp.sync_label;
|
|
|
| receive_streams_[ssrc] = new WebRtcVideoReceiveStream(
|
| - call_, sp, std::move(config), external_decoder_factory_, default_stream,
|
| + call_, sp, std::move(config), *decoder_factory_, default_stream,
|
| recv_codecs_, flexfec_config);
|
|
|
| return true;
|
| @@ -2063,7 +2101,7 @@ WebRtcVideoChannel::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream(
|
| webrtc::Call* call,
|
| const StreamParams& sp,
|
| webrtc::VideoReceiveStream::Config config,
|
| - WebRtcVideoDecoderFactory* external_decoder_factory,
|
| + const DecoderFactoryAdapter& decoder_factory,
|
| bool default_stream,
|
| const std::vector<VideoCodecSettings>& recv_codecs,
|
| const webrtc::FlexfecReceiveStream::Config& flexfec_config)
|
| @@ -2074,12 +2112,13 @@ WebRtcVideoChannel::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream(
|
| config_(std::move(config)),
|
| flexfec_config_(flexfec_config),
|
| flexfec_stream_(nullptr),
|
| - external_decoder_factory_(external_decoder_factory),
|
| + decoder_factory_(decoder_factory.clone()),
|
| sink_(NULL),
|
| first_frame_timestamp_(-1),
|
| estimated_remote_start_ntp_time_ms_(0) {
|
| config_.renderer = this;
|
| - std::vector<AllocatedDecoder> old_decoders;
|
| + std::map<webrtc::VideoCodecType, std::unique_ptr<webrtc::VideoDecoder>>
|
| + old_decoders;
|
| ConfigureCodecs(recv_codecs, &old_decoders);
|
| ConfigureFlexfecCodec(flexfec_config.payload_type);
|
| MaybeRecreateWebRtcFlexfecStream();
|
| @@ -2087,28 +2126,13 @@ WebRtcVideoChannel::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream(
|
| 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_);
|
| - ClearDecoders(&allocated_decoders_);
|
| + allocated_decoders_.clear();
|
| }
|
|
|
| const std::vector<uint32_t>&
|
| @@ -2129,53 +2153,59 @@ WebRtcVideoChannel::WebRtcVideoReceiveStream::GetFirstPrimarySsrc() const {
|
| }
|
| }
|
|
|
| -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 */);
|
| +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;
|
| }
|
| }
|
|
|
| - InternalDecoderFactory internal_decoder_factory;
|
| - return AllocatedDecoder(internal_decoder_factory.CreateVideoDecoderWithParams(
|
| - type, {stream_params_.id}),
|
| - type, false /* is_external */);
|
| + std::unique_ptr<webrtc::VideoDecoder> internal_decoder(
|
| + internal_decoder_factory_->CreateVideoDecoderWithParams(type,
|
| + decoder_params));
|
| + return internal_decoder;
|
| }
|
|
|
| void WebRtcVideoChannel::WebRtcVideoReceiveStream::ConfigureCodecs(
|
| const std::vector<VideoCodecSettings>& recv_codecs,
|
| - std::vector<AllocatedDecoder>* old_decoders) {
|
| - *old_decoders = allocated_decoders_;
|
| + std::map<webrtc::VideoCodecType, std::unique_ptr<webrtc::VideoDecoder>>*
|
| + old_decoders) {
|
| + *old_decoders = std::move(allocated_decoders_);
|
| allocated_decoders_.clear();
|
| config_.decoders.clear();
|
| for (size_t i = 0; i < recv_codecs.size(); ++i) {
|
| - AllocatedDecoder allocated_decoder =
|
| - CreateOrReuseVideoDecoder(old_decoders, recv_codecs[i].codec);
|
| - allocated_decoders_.push_back(allocated_decoder);
|
| + 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});
|
| + }
|
|
|
| webrtc::VideoReceiveStream::Decoder decoder;
|
| - decoder.decoder = allocated_decoder.decoder;
|
| + decoder.decoder = new_decoder.get();
|
| 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();
|
| @@ -2253,7 +2283,8 @@ void WebRtcVideoChannel::WebRtcVideoReceiveStream::SetRecvParameters(
|
| const ChangedRecvParameters& params) {
|
| bool video_needs_recreation = false;
|
| bool flexfec_needs_recreation = false;
|
| - std::vector<AllocatedDecoder> old_decoders;
|
| + std::map<webrtc::VideoCodecType, std::unique_ptr<webrtc::VideoDecoder>>
|
| + old_decoders;
|
| if (params.codec_settings) {
|
| ConfigureCodecs(*params.codec_settings, &old_decoders);
|
| video_needs_recreation = true;
|
| @@ -2277,7 +2308,6 @@ void WebRtcVideoChannel::WebRtcVideoReceiveStream::SetRecvParameters(
|
| LOG(LS_INFO)
|
| << "RecreateWebRtcVideoStream (recv) because of SetRecvParameters";
|
| RecreateWebRtcVideoStream();
|
| - ClearDecoders(&old_decoders);
|
| }
|
| }
|
|
|
| @@ -2322,18 +2352,6 @@ void WebRtcVideoChannel::WebRtcVideoReceiveStream::
|
| }
|
| }
|
|
|
| -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(
|
| const webrtc::VideoFrame& frame) {
|
| rtc::CritScope crit(&sink_lock_);
|
|
|