| Index: webrtc/media/engine/webrtcvideoengine.cc
|
| diff --git a/webrtc/media/engine/webrtcvideoengine.cc b/webrtc/media/engine/webrtcvideoengine.cc
|
| index 6808f2c59afedc7d468b9326cc3350510244206a..9c11bb946930a5b5f09a48c4a65c617fc302702d 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/scopedvideoencoder.h"
|
| #include "webrtc/media/engine/simulcast.h"
|
| #include "webrtc/media/engine/simulcast_encoder_adapter.h"
|
| #include "webrtc/media/engine/videodecodersoftwarefallbackwrapper.h"
|
| @@ -55,75 +56,6 @@ bool IsFlexfecAdvertisedFieldTrialEnabled() {
|
| return webrtc::field_trial::IsEnabled("WebRTC-FlexFEC-03-Advertised");
|
| }
|
|
|
| -// An encoder factory that wraps Create requests for simulcastable codec types
|
| -// with a webrtc::SimulcastEncoderAdapter. Non simulcastable codec type
|
| -// requests are just passed through to the contained encoder factory.
|
| -class WebRtcSimulcastEncoderFactory
|
| - : public cricket::WebRtcVideoEncoderFactory {
|
| - public:
|
| - // WebRtcSimulcastEncoderFactory doesn't take ownership of |factory|, which is
|
| - // owned by e.g. PeerConnectionFactory.
|
| - explicit WebRtcSimulcastEncoderFactory(
|
| - cricket::WebRtcVideoEncoderFactory* factory)
|
| - : factory_(factory) {}
|
| -
|
| - static bool UseSimulcastEncoderFactory(
|
| - const std::vector<cricket::VideoCodec>& codecs) {
|
| - // If any codec is VP8, use the simulcast factory. If asked to create a
|
| - // non-VP8 codec, we'll just return a contained factory encoder directly.
|
| - for (const auto& codec : codecs) {
|
| - if (CodecNamesEq(codec.name.c_str(), kVp8CodecName)) {
|
| - return true;
|
| - }
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - webrtc::VideoEncoder* CreateVideoEncoder(
|
| - const cricket::VideoCodec& codec) override {
|
| - RTC_DCHECK(factory_ != NULL);
|
| - // If it's a codec type we can simulcast, create a wrapped encoder.
|
| - if (CodecNamesEq(codec.name.c_str(), kVp8CodecName)) {
|
| - return new webrtc::SimulcastEncoderAdapter(factory_);
|
| - }
|
| - webrtc::VideoEncoder* encoder = factory_->CreateVideoEncoder(codec);
|
| - if (encoder) {
|
| - non_simulcast_encoders_.push_back(encoder);
|
| - }
|
| - return encoder;
|
| - }
|
| -
|
| - const std::vector<cricket::VideoCodec>& supported_codecs() const override {
|
| - return factory_->supported_codecs();
|
| - }
|
| -
|
| - bool EncoderTypeHasInternalSource(
|
| - webrtc::VideoCodecType type) const override {
|
| - return factory_->EncoderTypeHasInternalSource(type);
|
| - }
|
| -
|
| - void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) override {
|
| - // Check first to see if the encoder wasn't wrapped in a
|
| - // SimulcastEncoderAdapter. In that case, ask the factory to destroy it.
|
| - if (std::remove(non_simulcast_encoders_.begin(),
|
| - non_simulcast_encoders_.end(),
|
| - encoder) != non_simulcast_encoders_.end()) {
|
| - factory_->DestroyVideoEncoder(encoder);
|
| - return;
|
| - }
|
| -
|
| - // Otherwise, SimulcastEncoderAdapter can be deleted directly, and will call
|
| - // DestroyVideoEncoder on the factory for individual encoder instances.
|
| - delete encoder;
|
| - }
|
| -
|
| - private:
|
| - cricket::WebRtcVideoEncoderFactory* factory_;
|
| - // A list of encoders that were created without being wrapped in a
|
| - // SimulcastEncoderAdapter.
|
| - std::vector<webrtc::VideoEncoder*> non_simulcast_encoders_;
|
| -};
|
| -
|
| void AddDefaultFeedbackParams(VideoCodec* codec) {
|
| codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamCcm, kRtcpFbCcmParamFir));
|
| codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kParamValueEmpty));
|
| @@ -441,20 +373,6 @@ void WebRtcVideoEngine::SetExternalDecoderFactory(
|
| void WebRtcVideoEngine::SetExternalEncoderFactory(
|
| WebRtcVideoEncoderFactory* encoder_factory) {
|
| RTC_DCHECK(!initialized_);
|
| - if (external_encoder_factory_ == encoder_factory)
|
| - return;
|
| -
|
| - // No matter what happens we shouldn't hold on to a stale
|
| - // WebRtcSimulcastEncoderFactory.
|
| - simulcast_encoder_factory_.reset();
|
| -
|
| - if (encoder_factory &&
|
| - WebRtcSimulcastEncoderFactory::UseSimulcastEncoderFactory(
|
| - encoder_factory->supported_codecs())) {
|
| - simulcast_encoder_factory_.reset(
|
| - new WebRtcSimulcastEncoderFactory(encoder_factory));
|
| - encoder_factory = simulcast_encoder_factory_.get();
|
| - }
|
| external_encoder_factory_ = encoder_factory;
|
| }
|
|
|
| @@ -1496,18 +1414,19 @@ WebRtcVideoChannel::WebRtcVideoSendStream::VideoSendStreamParameters::
|
| codec_settings(codec_settings) {}
|
|
|
| WebRtcVideoChannel::WebRtcVideoSendStream::AllocatedEncoder::AllocatedEncoder(
|
| - webrtc::VideoEncoder* encoder,
|
| + std::unique_ptr<webrtc::VideoEncoder> encoder,
|
| + std::unique_ptr<webrtc::VideoEncoder> external_encoder,
|
| const cricket::VideoCodec& codec,
|
| - bool external)
|
| - : encoder(encoder),
|
| - external_encoder(nullptr),
|
| - codec(codec),
|
| - external(external) {
|
| - if (external) {
|
| - external_encoder = encoder;
|
| - this->encoder =
|
| - new webrtc::VideoEncoderSoftwareFallbackWrapper(codec, encoder);
|
| - }
|
| + bool has_internal_source)
|
| + : encoder_(std::move(encoder)),
|
| + external_encoder_(std::move(external_encoder)),
|
| + codec_(codec),
|
| + has_internal_source_(has_internal_source) {}
|
| +
|
| +void WebRtcVideoChannel::WebRtcVideoSendStream::AllocatedEncoder::Reset() {
|
| + external_encoder_.reset();
|
| + encoder_.reset();
|
| + codec_ = cricket::VideoCodec();
|
| }
|
|
|
| WebRtcVideoChannel::WebRtcVideoSendStream::WebRtcVideoSendStream(
|
| @@ -1535,7 +1454,6 @@ WebRtcVideoChannel::WebRtcVideoSendStream::WebRtcVideoSendStream(
|
| encoder_sink_(nullptr),
|
| parameters_(std::move(config), options, max_bitrate_bps, codec_settings),
|
| rtp_parameters_(CreateRtpParametersWithOneEncoding()),
|
| - allocated_encoder_(nullptr, cricket::VideoCodec(), false),
|
| sending_(false) {
|
| parameters_.config.rtp.max_packet_size = kVideoMtu;
|
| parameters_.conference_mode = send_params.conference_mode;
|
| @@ -1592,7 +1510,8 @@ WebRtcVideoChannel::WebRtcVideoSendStream::~WebRtcVideoSendStream() {
|
| if (stream_ != NULL) {
|
| call_->DestroyVideoSendStream(stream_);
|
| }
|
| - DestroyVideoEncoder(&allocated_encoder_);
|
| + // Release |allocated_encoder_|.
|
| + allocated_encoder_.Reset();
|
| }
|
|
|
| bool WebRtcVideoChannel::WebRtcVideoSendStream::SetVideoSend(
|
| @@ -1665,54 +1584,59 @@ WebRtcVideoChannel::WebRtcVideoSendStream::GetSsrcs() const {
|
|
|
| WebRtcVideoChannel::WebRtcVideoSendStream::AllocatedEncoder
|
| WebRtcVideoChannel::WebRtcVideoSendStream::CreateVideoEncoder(
|
| - const VideoCodec& codec,
|
| - bool force_encoder_allocation) {
|
| + const VideoCodec& codec) {
|
| RTC_DCHECK_RUN_ON(&thread_checker_);
|
| - // Do not re-create encoders of the same type.
|
| - if (!force_encoder_allocation && codec == allocated_encoder_.codec &&
|
| - allocated_encoder_.encoder != nullptr) {
|
| - return allocated_encoder_;
|
| - }
|
|
|
| // Try creating external encoder.
|
| if (external_encoder_factory_ != nullptr &&
|
| FindMatchingCodec(external_encoder_factory_->supported_codecs(), codec)) {
|
| - webrtc::VideoEncoder* encoder =
|
| - external_encoder_factory_->CreateVideoEncoder(codec);
|
| - if (encoder != nullptr)
|
| - return AllocatedEncoder(encoder, codec, true /* is_external */);
|
| + std::unique_ptr<webrtc::VideoEncoder> external_encoder;
|
| + if (CodecNamesEq(codec.name.c_str(), kVp8CodecName)) {
|
| + // If it's a codec type we can simulcast, create a wrapped encoder.
|
| + external_encoder = std::unique_ptr<webrtc::VideoEncoder>(
|
| + new webrtc::SimulcastEncoderAdapter(external_encoder_factory_));
|
| + } else {
|
| + external_encoder =
|
| + CreateScopedVideoEncoder(external_encoder_factory_, codec);
|
| + }
|
| + if (external_encoder) {
|
| + std::unique_ptr<webrtc::VideoEncoder> internal_encoder(
|
| + new webrtc::VideoEncoderSoftwareFallbackWrapper(
|
| + codec, external_encoder.get()));
|
| + const webrtc::VideoCodecType codec_type =
|
| + webrtc::PayloadStringToCodecType(codec.name);
|
| + const bool has_internal_source =
|
| + external_encoder_factory_->EncoderTypeHasInternalSource(codec_type);
|
| + return AllocatedEncoder(std::move(internal_encoder),
|
| + std::move(external_encoder), codec,
|
| + has_internal_source);
|
| + }
|
| }
|
|
|
| // Try creating internal encoder.
|
| + std::unique_ptr<webrtc::VideoEncoder> internal_encoder;
|
| if (FindMatchingCodec(internal_encoder_factory_->supported_codecs(), codec)) {
|
| - if (parameters_.encoder_config.content_type ==
|
| + if (CodecNamesEq(codec.name.c_str(), kVp8CodecName) &&
|
| + parameters_.encoder_config.content_type ==
|
| webrtc::VideoEncoderConfig::ContentType::kScreen &&
|
| parameters_.conference_mode && UseSimulcastScreenshare()) {
|
| // TODO(sprang): Remove this adapter once libvpx supports simulcast with
|
| // same-resolution substreams.
|
| - WebRtcSimulcastEncoderFactory adapter_factory(
|
| - internal_encoder_factory_.get());
|
| - return AllocatedEncoder(adapter_factory.CreateVideoEncoder(codec), codec,
|
| - false /* is_external */);
|
| + internal_encoder = std::unique_ptr<webrtc::VideoEncoder>(
|
| + new webrtc::SimulcastEncoderAdapter(internal_encoder_factory_.get()));
|
| + } else {
|
| + internal_encoder = std::unique_ptr<webrtc::VideoEncoder>(
|
| + internal_encoder_factory_->CreateVideoEncoder(codec));
|
| }
|
| - return AllocatedEncoder(
|
| - internal_encoder_factory_->CreateVideoEncoder(codec), codec,
|
| - false /* is_external */);
|
| + return AllocatedEncoder(std::move(internal_encoder),
|
| + nullptr /* external_encoder */, codec,
|
| + false /* has_internal_source */);
|
| }
|
|
|
| // This shouldn't happen, we should not be trying to create something we don't
|
| // support.
|
| RTC_NOTREACHED();
|
| - return AllocatedEncoder(NULL, cricket::VideoCodec(), false);
|
| -}
|
| -
|
| -void WebRtcVideoChannel::WebRtcVideoSendStream::DestroyVideoEncoder(
|
| - AllocatedEncoder* encoder) {
|
| - RTC_DCHECK_RUN_ON(&thread_checker_);
|
| - if (encoder->external) {
|
| - external_encoder_factory_->DestroyVideoEncoder(encoder->external_encoder);
|
| - }
|
| - delete encoder->encoder;
|
| + return AllocatedEncoder();
|
| }
|
|
|
| void WebRtcVideoChannel::WebRtcVideoSendStream::SetCodec(
|
| @@ -1722,20 +1646,23 @@ void WebRtcVideoChannel::WebRtcVideoSendStream::SetCodec(
|
| parameters_.encoder_config = CreateVideoEncoderConfig(codec_settings.codec);
|
| RTC_DCHECK_GT(parameters_.encoder_config.number_of_streams, 0);
|
|
|
| - AllocatedEncoder new_encoder =
|
| - CreateVideoEncoder(codec_settings.codec, force_encoder_allocation);
|
| - parameters_.config.encoder_settings.encoder = new_encoder.encoder;
|
| - parameters_.config.encoder_settings.full_overuse_time = new_encoder.external;
|
| - parameters_.config.encoder_settings.payload_name = codec_settings.codec.name;
|
| - parameters_.config.encoder_settings.payload_type = codec_settings.codec.id;
|
| - if (new_encoder.external) {
|
| - webrtc::VideoCodecType type =
|
| - webrtc::PayloadStringToCodecType(codec_settings.codec.name);
|
| - parameters_.config.encoder_settings.internal_source =
|
| - external_encoder_factory_->EncoderTypeHasInternalSource(type);
|
| + // 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);
|
| } else {
|
| - parameters_.config.encoder_settings.internal_source = false;
|
| + 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;
|
| @@ -1759,10 +1686,7 @@ void WebRtcVideoChannel::WebRtcVideoSendStream::SetCodec(
|
|
|
| LOG(LS_INFO) << "RecreateWebRtcStream (send) because of SetCodec.";
|
| RecreateWebRtcStream();
|
| - if (allocated_encoder_.encoder != new_encoder.encoder) {
|
| - DestroyVideoEncoder(&allocated_encoder_);
|
| - allocated_encoder_ = new_encoder;
|
| - }
|
| + allocated_encoder_ = std::move(new_encoder);
|
| }
|
|
|
| void WebRtcVideoChannel::WebRtcVideoSendStream::SetSendParameters(
|
|
|