diff --git a/webrtc/media/engine/webrtcvideoengine.cc b/webrtc/media/engine/webrtcvideoengine.cc index 274b801625..030544461a 100644 --- a/webrtc/media/engine/webrtcvideoengine.cc +++ b/webrtc/media/engine/webrtcvideoengine.cc @@ -42,7 +42,68 @@ using DegradationPreference = webrtc::VideoSendStream::DegradationPreference; namespace cricket { +// This class represents all encoders, i.e. both internal and external. It +// serves as a temporary adapter between WebRtcVideoEncoderFactory* and the new +// factory interface that is being developed. +// TODO(magjed): Remove once WebRtcVideoEncoderFactory* is deprecated and +// webrtc:7925 is fixed. +class EncoderFactoryAdapter { + public: + struct AllocatedEncoder { + AllocatedEncoder() = default; + AllocatedEncoder(std::unique_ptr encoder, + bool is_hardware_accelerated, + bool has_internal_source); + + std::unique_ptr encoder; + bool is_hardware_accelerated; + bool has_internal_source; + }; + + virtual ~EncoderFactoryAdapter() {} + + virtual AllocatedEncoder CreateVideoEncoder( + const VideoCodec& codec, + bool is_conference_mode_screenshare) const = 0; + + virtual std::vector GetSupportedCodecs() const = 0; + + virtual std::unique_ptr clone() const = 0; +}; + namespace { + +// Wraps cricket::WebRtcVideoEncoderFactory* into common EncoderFactoryAdapter +// interface. +// TODO(magjed): Add wrapper class for future webrtc::VideoEncoderFactory +// interface, https://bugs.chromium.org/p/webrtc/issues/detail?id=7925. +class CricketEncoderFactoryAdapter : public EncoderFactoryAdapter { + public: + explicit CricketEncoderFactoryAdapter( + WebRtcVideoEncoderFactory* external_encoder_factory) + : internal_encoder_factory_(new InternalEncoderFactory()), + external_encoder_factory_(external_encoder_factory) {} + + private: + explicit CricketEncoderFactoryAdapter( + const CricketEncoderFactoryAdapter& other) + : CricketEncoderFactoryAdapter(other.external_encoder_factory_) {} + + AllocatedEncoder CreateVideoEncoder( + const VideoCodec& codec, + bool is_conference_mode_screenshare) const override; + + std::vector GetSupportedCodecs() const override; + + std::unique_ptr clone() const override { + return std::unique_ptr( + new CricketEncoderFactoryAdapter(*this)); + } + + const std::unique_ptr internal_encoder_factory_; + WebRtcVideoEncoderFactory* const external_encoder_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() { @@ -206,9 +267,6 @@ static const int kDefaultRtcpReceiverReportSsrc = 1; // Minimum time interval for logging stats. static const int64_t kStatsLogIntervalMs = 10000; -static std::vector GetSupportedCodecs( - const WebRtcVideoEncoderFactory* external_encoder_factory); - rtc::scoped_refptr WebRtcVideoChannel::WebRtcVideoSendStream::ConfigureVideoEncoderSettings( const VideoCodec& codec) { @@ -310,7 +368,8 @@ void DefaultUnsignalledSsrcHandler::SetDefaultSink( WebRtcVideoEngine::WebRtcVideoEngine() : initialized_(false), external_decoder_factory_(NULL), - external_encoder_factory_(NULL) { + encoder_factory_(new CricketEncoderFactoryAdapter( + nullptr /* external_encoder_factory */)) { LOG(LS_INFO) << "WebRtcVideoEngine::WebRtcVideoEngine()"; } @@ -329,13 +388,12 @@ WebRtcVideoChannel* WebRtcVideoEngine::CreateChannel( const VideoOptions& options) { RTC_DCHECK(initialized_); LOG(LS_INFO) << "CreateChannel. Options: " << options.ToString(); - return new WebRtcVideoChannel(call, config, options, - external_encoder_factory_, + return new WebRtcVideoChannel(call, config, options, *encoder_factory_, external_decoder_factory_); } std::vector WebRtcVideoEngine::codecs() const { - return GetSupportedCodecs(external_encoder_factory_); + return encoder_factory_->GetSupportedCodecs(); } RtpCapabilities WebRtcVideoEngine::GetCapabilities() const { @@ -373,7 +431,7 @@ void WebRtcVideoEngine::SetExternalDecoderFactory( void WebRtcVideoEngine::SetExternalEncoderFactory( WebRtcVideoEncoderFactory* encoder_factory) { RTC_DCHECK(!initialized_); - external_encoder_factory_ = encoder_factory; + encoder_factory_.reset(new CricketEncoderFactoryAdapter(encoder_factory)); } // This is a helper function for AppendVideoCodecs below. It will return the @@ -439,8 +497,8 @@ static void AppendVideoCodecs(const std::vector& input_codecs, } } -static std::vector GetSupportedCodecs( - const WebRtcVideoEncoderFactory* external_encoder_factory) { +std::vector CricketEncoderFactoryAdapter::GetSupportedCodecs() + const { const std::vector internal_codecs = InternalEncoderFactory().supported_codecs(); LOG(LS_INFO) << "Internally supported codecs: " @@ -449,9 +507,9 @@ static std::vector GetSupportedCodecs( std::vector unified_codecs; AppendVideoCodecs(internal_codecs, &unified_codecs); - if (external_encoder_factory != nullptr) { + if (external_encoder_factory_ != nullptr) { const std::vector& external_codecs = - external_encoder_factory->supported_codecs(); + external_encoder_factory_->supported_codecs(); AppendVideoCodecs(external_codecs, &unified_codecs); LOG(LS_INFO) << "Codecs supported by the external encoder factory: " << CodecVectorToString(external_codecs); @@ -464,13 +522,13 @@ WebRtcVideoChannel::WebRtcVideoChannel( webrtc::Call* call, const MediaConfig& config, const VideoOptions& options, - WebRtcVideoEncoderFactory* external_encoder_factory, + const EncoderFactoryAdapter& encoder_factory, WebRtcVideoDecoderFactory* external_decoder_factory) : VideoMediaChannel(config), call_(call), unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_), video_config_(config.video), - external_encoder_factory_(external_encoder_factory), + encoder_factory_(encoder_factory.clone()), external_decoder_factory_(external_decoder_factory), default_send_options_(options), last_stats_log_ms_(-1) { @@ -478,7 +536,7 @@ WebRtcVideoChannel::WebRtcVideoChannel( rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc; sending_ = false; - recv_codecs_ = MapCodecs(GetSupportedCodecs(external_encoder_factory)); + recv_codecs_ = MapCodecs(encoder_factory_->GetSupportedCodecs()); recv_flexfec_payload_type_ = recv_codecs_.front().flexfec_payload_type; } @@ -493,7 +551,7 @@ rtc::Optional WebRtcVideoChannel::SelectSendVideoCodec( const std::vector& remote_mapped_codecs) const { const std::vector local_supported_codecs = - GetSupportedCodecs(external_encoder_factory_); + encoder_factory_->GetSupportedCodecs(); // Select the first remote codec that is supported locally. for (const VideoCodecSettings& remote_mapped_codec : remote_mapped_codecs) { // For H264, we will limit the encode level to the remote offered level @@ -805,7 +863,7 @@ bool WebRtcVideoChannel::GetChangedRecvParameters( // Verify that every mapped codec is supported locally. const std::vector local_supported_codecs = - GetSupportedCodecs(external_encoder_factory_); + encoder_factory_->GetSupportedCodecs(); for (const VideoCodecSettings& mapped_codec : mapped_codecs) { if (!FindMatchingCodec(local_supported_codecs, mapped_codec.codec)) { LOG(LS_ERROR) << "SetRecvParameters called with unsupported video codec: " @@ -976,8 +1034,8 @@ bool WebRtcVideoChannel::AddSendStream(const StreamParams& sp) { config.periodic_alr_bandwidth_probing = video_config_.periodic_alr_bandwidth_probing; WebRtcVideoSendStream* stream = new WebRtcVideoSendStream( - call_, sp, std::move(config), default_send_options_, - external_encoder_factory_, video_config_.enable_cpu_overuse_detection, + call_, sp, std::move(config), default_send_options_, *encoder_factory_, + video_config_.enable_cpu_overuse_detection, bitrate_config_.max_bitrate_bps, send_codec_, send_rtp_extensions_, send_params_); @@ -1413,27 +1471,20 @@ WebRtcVideoChannel::WebRtcVideoSendStream::VideoSendStreamParameters:: conference_mode(false), codec_settings(codec_settings) {} -WebRtcVideoChannel::WebRtcVideoSendStream::AllocatedEncoder::AllocatedEncoder( +EncoderFactoryAdapter::AllocatedEncoder::AllocatedEncoder( std::unique_ptr encoder, - bool is_external, - const cricket::VideoCodec& codec, + bool is_hardware_accelerated, bool has_internal_source) - : encoder_(std::move(encoder)), - is_external_(is_external), - codec_(codec), - has_internal_source_(has_internal_source) {} - -void WebRtcVideoChannel::WebRtcVideoSendStream::AllocatedEncoder::Reset() { - encoder_.reset(); - codec_ = cricket::VideoCodec(); -} + : encoder(std::move(encoder)), + is_hardware_accelerated(is_hardware_accelerated), + has_internal_source(has_internal_source) {} WebRtcVideoChannel::WebRtcVideoSendStream::WebRtcVideoSendStream( webrtc::Call* call, const StreamParams& sp, webrtc::VideoSendStream::Config config, const VideoOptions& options, - WebRtcVideoEncoderFactory* external_encoder_factory, + const EncoderFactoryAdapter& encoder_factory, bool enable_cpu_overuse_detection, int max_bitrate_bps, const rtc::Optional& codec_settings, @@ -1447,8 +1498,7 @@ WebRtcVideoChannel::WebRtcVideoSendStream::WebRtcVideoSendStream( call_(call), enable_cpu_overuse_detection_(enable_cpu_overuse_detection), source_(nullptr), - external_encoder_factory_(external_encoder_factory), - internal_encoder_factory_(new InternalEncoderFactory()), + encoder_factory_(encoder_factory.clone()), stream_(nullptr), encoder_sink_(nullptr), parameters_(std::move(config), options, max_bitrate_bps, codec_settings), @@ -1510,7 +1560,7 @@ WebRtcVideoChannel::WebRtcVideoSendStream::~WebRtcVideoSendStream() { call_->DestroyVideoSendStream(stream_); } // Release |allocated_encoder_|. - allocated_encoder_.Reset(); + allocated_encoder_.reset(); } bool WebRtcVideoChannel::WebRtcVideoSendStream::SetVideoSend( @@ -1581,11 +1631,10 @@ WebRtcVideoChannel::WebRtcVideoSendStream::GetSsrcs() const { return ssrcs_; } -WebRtcVideoChannel::WebRtcVideoSendStream::AllocatedEncoder -WebRtcVideoChannel::WebRtcVideoSendStream::CreateVideoEncoder( - const VideoCodec& codec) { - RTC_DCHECK_RUN_ON(&thread_checker_); - +EncoderFactoryAdapter::AllocatedEncoder +CricketEncoderFactoryAdapter::CreateVideoEncoder( + const VideoCodec& codec, + bool is_conference_mode_screenshare) const { // Try creating external encoder. if (external_encoder_factory_ != nullptr && FindMatchingCodec(external_encoder_factory_->supported_codecs(), codec)) { @@ -1607,7 +1656,7 @@ WebRtcVideoChannel::WebRtcVideoSendStream::CreateVideoEncoder( const bool has_internal_source = external_encoder_factory_->EncoderTypeHasInternalSource(codec_type); return AllocatedEncoder(std::move(internal_encoder), - true /* is_external */, codec, + true /* is_hardware_accelerated */, has_internal_source); } } @@ -1616,9 +1665,7 @@ WebRtcVideoChannel::WebRtcVideoSendStream::CreateVideoEncoder( std::unique_ptr internal_encoder; if (FindMatchingCodec(internal_encoder_factory_->supported_codecs(), codec)) { if (CodecNamesEq(codec.name.c_str(), kVp8CodecName) && - parameters_.encoder_config.content_type == - webrtc::VideoEncoderConfig::ContentType::kScreen && - parameters_.conference_mode && UseSimulcastScreenshare()) { + is_conference_mode_screenshare && UseSimulcastScreenshare()) { // TODO(sprang): Remove this adapter once libvpx supports simulcast with // same-resolution substreams. internal_encoder = std::unique_ptr( @@ -1628,7 +1675,7 @@ WebRtcVideoChannel::WebRtcVideoSendStream::CreateVideoEncoder( internal_encoder_factory_->CreateVideoEncoder(codec)); } return AllocatedEncoder(std::move(internal_encoder), - false /* is_external */, codec, + false /* is_hardware_accelerated */, false /* has_internal_source */); } @@ -1648,20 +1695,28 @@ void WebRtcVideoChannel::WebRtcVideoSendStream::SetCodec( // Do not re-create encoders of the same type. We can't overwrite // |allocated_encoder_| immediately, because we need to release it after the // RecreateWebRtcStream() call. - AllocatedEncoder new_encoder; - if (force_encoder_allocation || !allocated_encoder_.encoder() || - allocated_encoder_.codec() != codec_settings.codec) { - new_encoder = CreateVideoEncoder(codec_settings.codec); + std::unique_ptr new_encoder; + if (force_encoder_allocation || !allocated_encoder_ || + allocated_codec_ != codec_settings.codec) { + const bool is_conference_mode_screenshare = + parameters_.encoder_config.content_type == + webrtc::VideoEncoderConfig::ContentType::kScreen && + parameters_.conference_mode; + EncoderFactoryAdapter::AllocatedEncoder new_allocated_encoder = + encoder_factory_->CreateVideoEncoder(codec_settings.codec, + is_conference_mode_screenshare); + new_encoder = std::unique_ptr( + std::move(new_allocated_encoder.encoder)); + parameters_.config.encoder_settings.encoder = new_encoder.get(); + parameters_.config.encoder_settings.full_overuse_time = + new_allocated_encoder.is_hardware_accelerated; + parameters_.config.encoder_settings.internal_source = + new_allocated_encoder.has_internal_source; } else { new_encoder = std::move(allocated_encoder_); } - parameters_.config.encoder_settings.encoder = new_encoder.encoder(); - parameters_.config.encoder_settings.full_overuse_time = - new_encoder.IsExternal(); parameters_.config.encoder_settings.payload_name = codec_settings.codec.name; parameters_.config.encoder_settings.payload_type = codec_settings.codec.id; - parameters_.config.encoder_settings.internal_source = - new_encoder.HasInternalSource(); parameters_.config.rtp.ulpfec = codec_settings.ulpfec; parameters_.config.rtp.flexfec.payload_type = codec_settings.flexfec_payload_type; @@ -1686,6 +1741,7 @@ void WebRtcVideoChannel::WebRtcVideoSendStream::SetCodec( LOG(LS_INFO) << "RecreateWebRtcStream (send) because of SetCodec."; RecreateWebRtcStream(); allocated_encoder_ = std::move(new_encoder); + allocated_codec_ = codec_settings.codec; } void WebRtcVideoChannel::WebRtcVideoSendStream::SetSendParameters( diff --git a/webrtc/media/engine/webrtcvideoengine.h b/webrtc/media/engine/webrtcvideoengine.h index deb13b1d2c..3224d0027f 100644 --- a/webrtc/media/engine/webrtcvideoengine.h +++ b/webrtc/media/engine/webrtcvideoengine.h @@ -47,6 +47,7 @@ class Thread; namespace cricket { +class EncoderFactoryAdapter; class VideoCapturer; class VideoProcessor; class VideoRenderer; @@ -121,7 +122,7 @@ class WebRtcVideoEngine { bool initialized_; WebRtcVideoDecoderFactory* external_decoder_factory_; - WebRtcVideoEncoderFactory* external_encoder_factory_; + std::unique_ptr encoder_factory_; }; class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport { @@ -129,7 +130,7 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport { WebRtcVideoChannel(webrtc::Call* call, const MediaConfig& config, const VideoOptions& options, - WebRtcVideoEncoderFactory* external_encoder_factory, + const EncoderFactoryAdapter& encoder_factory, WebRtcVideoDecoderFactory* external_decoder_factory); ~WebRtcVideoChannel() override; @@ -258,7 +259,7 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport { const StreamParams& sp, webrtc::VideoSendStream::Config config, const VideoOptions& options, - WebRtcVideoEncoderFactory* external_encoder_factory, + const EncoderFactoryAdapter& encoder_factory, bool enable_cpu_overuse_detection, int max_bitrate_bps, const rtc::Optional& codec_settings, @@ -310,42 +311,8 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport { webrtc::VideoEncoderConfig encoder_config; }; - class AllocatedEncoder { - public: - AllocatedEncoder() = default; - AllocatedEncoder(AllocatedEncoder&&) = default; - AllocatedEncoder& operator=(AllocatedEncoder&&) = default; - - AllocatedEncoder(std::unique_ptr encoder, - bool is_external, - const cricket::VideoCodec& codec, - bool has_internal_source); - - // Returns a raw pointer to the allocated encoder. This object still has - // ownership of the encoder and is responsible for deleting it. - webrtc::VideoEncoder* encoder() { return encoder_.get(); } - - // Returns true if the encoder is external. - bool IsExternal() { return is_external_; } - - cricket::VideoCodec codec() { return codec_; } - - bool HasInternalSource() { return has_internal_source_; } - - // Release the encoders this object manages. - void Reset(); - - private: - std::unique_ptr encoder_; - bool is_external_; - cricket::VideoCodec codec_; - bool has_internal_source_; - }; - rtc::scoped_refptr ConfigureVideoEncoderSettings(const VideoCodec& codec); - // Creates and returns a new AllocatedEncoder of the specified codec type. - AllocatedEncoder CreateVideoEncoder(const VideoCodec& codec); void SetCodec(const VideoCodecSettings& codec, bool force_encoder_allocation); void RecreateWebRtcStream(); @@ -370,9 +337,7 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport { const bool enable_cpu_overuse_detection_; rtc::VideoSourceInterface* source_ ACCESS_ON(&thread_checker_); - WebRtcVideoEncoderFactory* const external_encoder_factory_ - ACCESS_ON(&thread_checker_); - const std::unique_ptr internal_encoder_factory_ + std::unique_ptr encoder_factory_ ACCESS_ON(&thread_checker_); webrtc::VideoSendStream* stream_ ACCESS_ON(&thread_checker_); @@ -388,7 +353,9 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport { // TODO(skvlad): Combine parameters_ and rtp_parameters_ once we have only // one stream per MediaChannel. webrtc::RtpParameters rtp_parameters_ ACCESS_ON(&thread_checker_); - AllocatedEncoder allocated_encoder_ ACCESS_ON(&thread_checker_); + std::unique_ptr allocated_encoder_ + ACCESS_ON(&thread_checker_); + VideoCodec allocated_codec_ ACCESS_ON(&thread_checker_); bool sending_ ACCESS_ON(&thread_checker_); }; @@ -529,7 +496,7 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport { rtc::Optional send_codec_; rtc::Optional> send_rtp_extensions_; - WebRtcVideoEncoderFactory* const external_encoder_factory_; + std::unique_ptr encoder_factory_; WebRtcVideoDecoderFactory* const external_decoder_factory_; std::vector recv_codecs_; std::vector recv_rtp_extensions_;