From 1c9623c70db42550d152c127e01434004087f743 Mon Sep 17 00:00:00 2001 From: Magnus Jedvert Date: Mon, 30 Oct 2017 14:26:20 +0100 Subject: [PATCH] Add helper functions for migrating to new video codec factories This CL adds helper functions in media/engine/convert_legacy_video_factory.h to convert from the old WebRtcVideoEncoder and WebRtcVideoDecoder to the new webrtc::VideoEncoder and webrtc::VideoDecoder. The purpose is to make it as easy as possible for clients to migrate to the new API and allow us to stop depending on the internal SW codecs as soon as possible. There still exists an ugly decoder adapter class in the video engine. The reason is that we need to continue to pass in the |receive_stream_id| decoder params to some legacy clients. Bug: webrtc:7925 Change-Id: I43ff03e036411a85d4940fe517a34489f171d698 Reviewed-on: https://webrtc-review.googlesource.com/15181 Commit-Queue: Magnus Jedvert Reviewed-by: Anders Carlsson Cr-Commit-Position: refs/heads/master@{#20475} --- media/BUILD.gn | 2 + media/engine/convert_legacy_video_factory.cc | 191 ++++++++++ media/engine/convert_legacy_video_factory.h | 38 ++ media/engine/webrtcvideodecoderfactory.cc | 2 + media/engine/webrtcvideodecoderfactory.h | 1 + media/engine/webrtcvideoengine.cc | 373 ++++++------------- media/engine/webrtcvideoengine.h | 19 +- 7 files changed, 357 insertions(+), 269 deletions(-) create mode 100644 media/engine/convert_legacy_video_factory.cc create mode 100644 media/engine/convert_legacy_video_factory.h diff --git a/media/BUILD.gn b/media/BUILD.gn index e98001a4b7..595670327e 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -143,6 +143,8 @@ rtc_static_library("rtc_audio_video") { "engine/apm_helpers.cc", "engine/apm_helpers.h", "engine/constants.h", + "engine/convert_legacy_video_factory.cc", + "engine/convert_legacy_video_factory.h", "engine/internaldecoderfactory.cc", "engine/internaldecoderfactory.h", "engine/internalencoderfactory.cc", diff --git a/media/engine/convert_legacy_video_factory.cc b/media/engine/convert_legacy_video_factory.cc new file mode 100644 index 0000000000..cb017894cc --- /dev/null +++ b/media/engine/convert_legacy_video_factory.cc @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "media/engine/convert_legacy_video_factory.h" + +#include +#include + +#include "api/video_codecs/video_decoder_factory.h" +#include "api/video_codecs/video_encoder_factory.h" +#include "media/engine/internaldecoderfactory.h" +#include "media/engine/internalencoderfactory.h" +#include "media/engine/scopedvideodecoder.h" +#include "media/engine/scopedvideoencoder.h" +#include "media/engine/simulcast_encoder_adapter.h" +#include "media/engine/videodecodersoftwarefallbackwrapper.h" +#include "media/engine/videoencodersoftwarefallbackwrapper.h" +#include "media/engine/vp8_encoder_simulcast_proxy.h" +#include "media/engine/webrtcvideodecoderfactory.h" +#include "media/engine/webrtcvideoencoderfactory.h" +#include "rtc_base/checks.h" + +namespace cricket { + +namespace { + +class EncoderAdapter : public webrtc::VideoEncoderFactory { + public: + explicit EncoderAdapter( + std::unique_ptr external_encoder_factory) + : internal_encoder_factory_(new InternalEncoderFactory()), + external_encoder_factory_(std::move(external_encoder_factory)) {} + + webrtc::VideoEncoderFactory::CodecInfo QueryVideoEncoder( + const webrtc::SdpVideoFormat& format) const { + const VideoCodec codec(format); + if (external_encoder_factory_ != nullptr && + FindMatchingCodec(external_encoder_factory_->supported_codecs(), + codec)) { + // Format is supported by the external factory. + const webrtc::VideoCodecType codec_type = + webrtc::PayloadStringToCodecType(codec.name); + webrtc::VideoEncoderFactory::CodecInfo info; + info.has_internal_source = + external_encoder_factory_->EncoderTypeHasInternalSource(codec_type); + info.is_hardware_accelerated = true; + return info; + } + + // Format must be one of the internal formats. + RTC_DCHECK(FindMatchingCodec(internal_encoder_factory_->supported_codecs(), + codec)); + webrtc::VideoEncoderFactory::CodecInfo info; + info.has_internal_source = false; + info.is_hardware_accelerated = false; + return info; + } + + std::unique_ptr CreateVideoEncoder( + const webrtc::SdpVideoFormat& format) { + const VideoCodec codec(format); + // Try creating external encoder. + if (external_encoder_factory_ != nullptr && + FindMatchingCodec(external_encoder_factory_->supported_codecs(), + codec)) { + std::unique_ptr 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( + new webrtc::SimulcastEncoderAdapter( + external_encoder_factory_.get())); + } else { + external_encoder = + CreateScopedVideoEncoder(external_encoder_factory_.get(), codec); + } + if (external_encoder) { + return std::unique_ptr( + new webrtc::VideoEncoderSoftwareFallbackWrapper( + codec, std::move(external_encoder))); + } + } + + // Try creating internal encoder. + if (FindMatchingCodec(internal_encoder_factory_->supported_codecs(), + codec)) { + if (CodecNamesEq(codec.name.c_str(), kVp8CodecName)) { + return std::unique_ptr( + new webrtc::VP8EncoderSimulcastProxy( + internal_encoder_factory_.get())); + } else { + return std::unique_ptr( + internal_encoder_factory_->CreateVideoEncoder(codec)); + } + } + + // This shouldn't happen, we should not be trying to create something we + // don't support. + RTC_NOTREACHED(); + return nullptr; + } + + std::vector GetSupportedFormats() const { + std::vector codecs = + InternalEncoderFactory().supported_codecs(); + + // Add external codecs. + if (external_encoder_factory_ != nullptr) { + const std::vector& external_codecs = + external_encoder_factory_->supported_codecs(); + for (const VideoCodec& codec : external_codecs) { + // Don't add same codec twice. + if (!FindMatchingCodec(codecs, codec)) + codecs.push_back(codec); + } + } + + std::vector formats; + for (const VideoCodec& codec : codecs) { + formats.push_back(webrtc::SdpVideoFormat(codec.name, codec.params)); + } + + return formats; + } + + private: + const std::unique_ptr internal_encoder_factory_; + const std::unique_ptr external_encoder_factory_; +}; + +class DecoderAdapter : public webrtc::VideoDecoderFactory { + public: + explicit DecoderAdapter( + std::unique_ptr external_decoder_factory) + : internal_decoder_factory_(new InternalDecoderFactory()), + external_decoder_factory_(std::move(external_decoder_factory)) {} + + std::unique_ptr CreateVideoDecoder( + const webrtc::SdpVideoFormat& format) override { + const VideoCodec codec(format); + const VideoDecoderParams params; + if (external_decoder_factory_ != nullptr) { + std::unique_ptr external_decoder = + CreateScopedVideoDecoder(external_decoder_factory_.get(), codec, + params); + if (external_decoder) { + webrtc::VideoCodecType type = + webrtc::PayloadStringToCodecType(codec.name); + std::unique_ptr internal_decoder( + new webrtc::VideoDecoderSoftwareFallbackWrapper( + type, std::move(external_decoder))); + return internal_decoder; + } + } + std::unique_ptr internal_decoder( + internal_decoder_factory_->CreateVideoDecoderWithParams(codec, params)); + return internal_decoder; + } + + std::vector GetSupportedFormats() const override { + // This is not implemented for the legacy decoder factory. + RTC_NOTREACHED(); + return std::vector(); + } + + private: + const std::unique_ptr internal_decoder_factory_; + const std::unique_ptr external_decoder_factory_; +}; + +} // namespace + +std::unique_ptr ConvertVideoEncoderFactory( + std::unique_ptr external_encoder_factory) { + return std::unique_ptr( + new EncoderAdapter(std::move(external_encoder_factory))); +} + +std::unique_ptr ConvertVideoDecoderFactory( + std::unique_ptr external_decoder_factory) { + return std::unique_ptr( + new DecoderAdapter(std::move(external_decoder_factory))); +} + +} // namespace cricket diff --git a/media/engine/convert_legacy_video_factory.h b/media/engine/convert_legacy_video_factory.h new file mode 100644 index 0000000000..5bd3580a6f --- /dev/null +++ b/media/engine/convert_legacy_video_factory.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef MEDIA_ENGINE_CONVERT_LEGACY_VIDEO_FACTORY_H_ +#define MEDIA_ENGINE_CONVERT_LEGACY_VIDEO_FACTORY_H_ + +#include + +namespace webrtc { +class VideoEncoderFactory; +class VideoDecoderFactory; +} // namespace webrtc + +namespace cricket { + +class WebRtcVideoEncoderFactory; +class WebRtcVideoDecoderFactory; + +// Adds internal SW codecs, simulcast, SW fallback wrappers, and converts to the +// new type of codec factories. The purpose of these functions is to provide an +// easy way for clients to migrate to the API with new factory types. +// TODO(magjed): Remove once old factories are gone, webrtc:7925. +std::unique_ptr ConvertVideoEncoderFactory( + std::unique_ptr external_encoder_factory); + +std::unique_ptr ConvertVideoDecoderFactory( + std::unique_ptr external_decoder_factory); + +} // namespace cricket + +#endif // MEDIA_ENGINE_CONVERT_LEGACY_VIDEO_FACTORY_H_ diff --git a/media/engine/webrtcvideodecoderfactory.cc b/media/engine/webrtcvideodecoderfactory.cc index 5eee788d8f..24922226f2 100644 --- a/media/engine/webrtcvideodecoderfactory.cc +++ b/media/engine/webrtcvideodecoderfactory.cc @@ -12,6 +12,8 @@ namespace cricket { +VideoDecoderParams::VideoDecoderParams() = default; + webrtc::VideoDecoder* WebRtcVideoDecoderFactory::CreateVideoDecoderWithParams( const VideoCodec& codec, VideoDecoderParams params) { diff --git a/media/engine/webrtcvideodecoderfactory.h b/media/engine/webrtcvideodecoderfactory.h index 4032aa2a5d..5facbbd63c 100644 --- a/media/engine/webrtcvideodecoderfactory.h +++ b/media/engine/webrtcvideodecoderfactory.h @@ -22,6 +22,7 @@ class VideoDecoder; namespace cricket { struct VideoDecoderParams { + VideoDecoderParams(); std::string receive_stream_id; }; diff --git a/media/engine/webrtcvideoengine.cc b/media/engine/webrtcvideoengine.cc index 9767aadbc2..3a99fc3db4 100644 --- a/media/engine/webrtcvideoengine.cc +++ b/media/engine/webrtcvideoengine.cc @@ -25,16 +25,9 @@ #include "call/call.h" #include "common_video/h264/profile_level_id.h" #include "media/engine/constants.h" -#include "media/engine/internaldecoderfactory.h" -#include "media/engine/internalencoderfactory.h" -#include "media/engine/scopedvideodecoder.h" -#include "media/engine/scopedvideoencoder.h" +#include "media/engine/convert_legacy_video_factory.h" #include "media/engine/simulcast.h" -#include "media/engine/simulcast_encoder_adapter.h" -#include "media/engine/videodecodersoftwarefallbackwrapper.h" -#include "media/engine/videoencodersoftwarefallbackwrapper.h" #include "media/engine/webrtcmediaengine.h" -#include "media/engine/webrtcvideoencoderfactory.h" #include "media/engine/webrtcvoiceengine.h" #include "rtc_base/copyonwritebuffer.h" #include "rtc_base/logging.h" @@ -42,141 +35,103 @@ #include "rtc_base/timeutils.h" #include "rtc_base/trace_event.h" #include "system_wrappers/include/field_trial.h" -#include "vp8_encoder_simulcast_proxy.h" 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 + +// Hack in order to pass in |receive_stream_id| to legacy clients. +// TODO(magjed): Remove once WebRtcVideoDecoderFactory 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) const = 0; - - virtual std::vector GetSupportedCodecs() const = 0; -}; - class DecoderFactoryAdapter { public: - virtual ~DecoderFactoryAdapter() {} + explicit DecoderFactoryAdapter( + std::unique_ptr external_video_decoder_factory) + : cricket_decoder_with_params_(new CricketDecoderWithParams( + std::move(external_video_decoder_factory))), + decoder_factory_(ConvertVideoDecoderFactory( + std::unique_ptr( + cricket_decoder_with_params_))) {} - virtual std::unique_ptr CreateVideoDecoder( - const VideoCodec& codec, - const VideoDecoderParams& decoder_params) const = 0; + explicit DecoderFactoryAdapter( + std::unique_ptr video_decoder_factory) + : cricket_decoder_with_params_(nullptr), + decoder_factory_(std::move(video_decoder_factory)) {} + + void SetReceiveStreamId(const std::string& receive_stream_id) { + if (cricket_decoder_with_params_) + cricket_decoder_with_params_->SetReceiveStreamId(receive_stream_id); + } + + std::vector GetSupportedFormats() const { + return decoder_factory_->GetSupportedFormats(); + } + + std::unique_ptr CreateVideoDecoder( + const webrtc::SdpVideoFormat& format) { + return decoder_factory_->CreateVideoDecoder(format); + } + + private: + // WebRtcVideoDecoderFactory implementation that allows to override + // |receive_stream_id|. + class CricketDecoderWithParams : public WebRtcVideoDecoderFactory { + public: + explicit CricketDecoderWithParams( + std::unique_ptr external_decoder_factory) + : external_decoder_factory_(std::move(external_decoder_factory)) {} + + void SetReceiveStreamId(const std::string& receive_stream_id) { + receive_stream_id_ = receive_stream_id; + } + + private: + webrtc::VideoDecoder* CreateVideoDecoderWithParams( + const VideoCodec& codec, + VideoDecoderParams params) override { + if (!external_decoder_factory_) + return nullptr; + params.receive_stream_id = receive_stream_id_; + return external_decoder_factory_->CreateVideoDecoderWithParams(codec, + params); + } + + webrtc::VideoDecoder* CreateVideoDecoderWithParams( + webrtc::VideoCodecType type, + VideoDecoderParams params) override { + RTC_NOTREACHED(); + return nullptr; + } + + void DestroyVideoDecoder(webrtc::VideoDecoder* decoder) override { + if (external_decoder_factory_) { + external_decoder_factory_->DestroyVideoDecoder(decoder); + } else { + delete decoder; + } + } + + const std::unique_ptr external_decoder_factory_; + std::string receive_stream_id_; + }; + + // If |cricket_decoder_with_params_| is non-null, it's owned by + // |decoder_factory_|. + CricketDecoderWithParams* const cricket_decoder_with_params_; + std::unique_ptr decoder_factory_; }; namespace { std::vector AssignPayloadTypesAndAddAssociatedRtxCodecs( - const std::vector& input_codecs); + const std::vector& input_formats); -// Wraps cricket::WebRtcVideoEncoderFactory into common EncoderFactoryAdapter -// interface. -// TODO(magjed): Remove once WebRtcVideoEncoderFactory is deprecated and -// webrtc:7925 is fixed. -class CricketEncoderFactoryAdapter : public EncoderFactoryAdapter { - public: - explicit CricketEncoderFactoryAdapter( - std::unique_ptr external_encoder_factory) - : internal_encoder_factory_(new InternalEncoderFactory()), - external_encoder_factory_(std::move(external_encoder_factory)) {} - - private: - AllocatedEncoder CreateVideoEncoder(const VideoCodec& codec) const override; - - std::vector GetSupportedCodecs() const override; - - const std::unique_ptr internal_encoder_factory_; - const std::unique_ptr external_encoder_factory_; -}; - -class CricketDecoderFactoryAdapter : public DecoderFactoryAdapter { - public: - explicit CricketDecoderFactoryAdapter( - std::unique_ptr external_decoder_factory) - : internal_decoder_factory_(new InternalDecoderFactory()), - external_decoder_factory_(std::move(external_decoder_factory)) {} - - private: - std::unique_ptr CreateVideoDecoder( - const VideoCodec& codec, - const VideoDecoderParams& decoder_params) const override; - - const std::unique_ptr internal_decoder_factory_; - const std::unique_ptr external_decoder_factory_; -}; - -// Wraps webrtc::VideoEncoderFactory into common EncoderFactoryAdapter -// interface. -class WebRtcEncoderFactoryAdapter : public EncoderFactoryAdapter { - public: - explicit WebRtcEncoderFactoryAdapter( - std::unique_ptr encoder_factory) - : encoder_factory_(std::move(encoder_factory)) {} - - private: - AllocatedEncoder CreateVideoEncoder(const VideoCodec& codec) const override { - if (!encoder_factory_) - return AllocatedEncoder(); - const webrtc::SdpVideoFormat format(codec.name, codec.params); - const webrtc::VideoEncoderFactory::CodecInfo info = - encoder_factory_->QueryVideoEncoder(format); - return AllocatedEncoder(encoder_factory_->CreateVideoEncoder(format), - info.is_hardware_accelerated, - info.has_internal_source); - } - - std::vector GetSupportedCodecs() const override { - if (!encoder_factory_) - return std::vector(); - std::vector codecs; - for (const webrtc::SdpVideoFormat& format : - encoder_factory_->GetSupportedFormats()) { - codecs.push_back(VideoCodec(format)); - } - return AssignPayloadTypesAndAddAssociatedRtxCodecs(codecs); - } - - std::unique_ptr encoder_factory_; -}; - -// Wraps webrtc::VideoDecoderFactory into common DecoderFactoryAdapter -// interface. -class WebRtcDecoderFactoryAdapter : public DecoderFactoryAdapter { - public: - explicit WebRtcDecoderFactoryAdapter( - std::unique_ptr decoder_factory) - : decoder_factory_(std::move(decoder_factory)) {} - - private: - std::unique_ptr CreateVideoDecoder( - const VideoCodec& codec, - const VideoDecoderParams& decoder_params) const override { - return decoder_factory_ - ? decoder_factory_->CreateVideoDecoder( - webrtc::SdpVideoFormat(codec.name, codec.params)) - : nullptr; - } - - std::unique_ptr decoder_factory_; -}; +std::vector AssignPayloadTypesAndAddAssociatedRtxCodecs( + const webrtc::VideoEncoderFactory* encoder_factory) { + return encoder_factory ? AssignPayloadTypesAndAddAssociatedRtxCodecs( + encoder_factory->GetSupportedFormats()) + : std::vector(); +} // If this field trial is enabled, we will enable sending FlexFEC and disable // sending ULPFEC whenever the former has been negotiated in the SDPs. @@ -448,9 +403,9 @@ void DefaultUnsignalledSsrcHandler::SetDefaultSink( WebRtcVideoEngine::WebRtcVideoEngine( std::unique_ptr external_video_encoder_factory, std::unique_ptr external_video_decoder_factory) - : decoder_factory_(new CricketDecoderFactoryAdapter( - std::move(external_video_decoder_factory))), - encoder_factory_(new CricketEncoderFactoryAdapter( + : decoder_factory_( + new DecoderFactoryAdapter(std::move(external_video_decoder_factory))), + encoder_factory_(ConvertVideoEncoderFactory( std::move(external_video_encoder_factory))) { LOG(LS_INFO) << "WebRtcVideoEngine::WebRtcVideoEngine()"; } @@ -459,9 +414,8 @@ WebRtcVideoEngine::WebRtcVideoEngine( std::unique_ptr video_encoder_factory, std::unique_ptr video_decoder_factory) : decoder_factory_( - new WebRtcDecoderFactoryAdapter(std::move(video_decoder_factory))), - encoder_factory_( - new WebRtcEncoderFactoryAdapter(std::move(video_encoder_factory))) { + new DecoderFactoryAdapter(std::move(video_decoder_factory))), + encoder_factory_(std::move(video_encoder_factory)) { LOG(LS_INFO) << "WebRtcVideoEngine::WebRtcVideoEngine()"; } @@ -479,7 +433,7 @@ WebRtcVideoChannel* WebRtcVideoEngine::CreateChannel( } std::vector WebRtcVideoEngine::codecs() const { - return encoder_factory_->GetSupportedCodecs(); + return AssignPayloadTypesAndAddAssociatedRtxCodecs(encoder_factory_.get()); } RtpCapabilities WebRtcVideoEngine::GetCapabilities() const { @@ -514,12 +468,13 @@ namespace { // (VP8, VP9, H264, and RED). It will also add default feedback params to the // codecs. std::vector AssignPayloadTypesAndAddAssociatedRtxCodecs( - const std::vector& input_codecs) { + const std::vector& input_formats) { static const int kFirstDynamicPayloadType = 96; static const int kLastDynamicPayloadType = 127; int payload_type = kFirstDynamicPayloadType; std::vector output_codecs; - for (VideoCodec codec : input_codecs) { + for (const webrtc::SdpVideoFormat& format : input_formats) { + VideoCodec codec(format); codec.id = payload_type; AddDefaultFeedbackParams(&codec); output_codecs.push_back(codec); @@ -549,34 +504,12 @@ std::vector AssignPayloadTypesAndAddAssociatedRtxCodecs( } } // namespace -std::vector CricketEncoderFactoryAdapter::GetSupportedCodecs() - const { - std::vector codecs = InternalEncoderFactory().supported_codecs(); - LOG(LS_INFO) << "Internally supported codecs: " - << CodecVectorToString(codecs); - - // Add external codecs. - if (external_encoder_factory_ != nullptr) { - const std::vector& external_codecs = - external_encoder_factory_->supported_codecs(); - for (const VideoCodec& codec : external_codecs) { - // Don't add same codec twice. - if (!FindMatchingCodec(codecs, codec)) - codecs.push_back(codec); - } - LOG(LS_INFO) << "Codecs supported by the external encoder factory: " - << CodecVectorToString(external_codecs); - } - - return AssignPayloadTypesAndAddAssociatedRtxCodecs(codecs); -} - WebRtcVideoChannel::WebRtcVideoChannel( webrtc::Call* call, const MediaConfig& config, const VideoOptions& options, - const EncoderFactoryAdapter* encoder_factory, - const DecoderFactoryAdapter* decoder_factory) + webrtc::VideoEncoderFactory* encoder_factory, + DecoderFactoryAdapter* decoder_factory) : VideoMediaChannel(config), call_(call), unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_), @@ -589,7 +522,8 @@ WebRtcVideoChannel::WebRtcVideoChannel( rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc; sending_ = false; - recv_codecs_ = MapCodecs(encoder_factory_->GetSupportedCodecs()); + recv_codecs_ = + MapCodecs(AssignPayloadTypesAndAddAssociatedRtxCodecs(encoder_factory_)); recv_flexfec_payload_type_ = recv_codecs_.front().flexfec_payload_type; } @@ -604,7 +538,7 @@ rtc::Optional WebRtcVideoChannel::SelectSendVideoCodec( const std::vector& remote_mapped_codecs) const { const std::vector local_supported_codecs = - encoder_factory_->GetSupportedCodecs(); + AssignPayloadTypesAndAddAssociatedRtxCodecs(encoder_factory_); // 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 @@ -916,7 +850,7 @@ bool WebRtcVideoChannel::GetChangedRecvParameters( // Verify that every mapped codec is supported locally. const std::vector local_supported_codecs = - encoder_factory_->GetSupportedCodecs(); + AssignPayloadTypesAndAddAssociatedRtxCodecs(encoder_factory_); for (const VideoCodecSettings& mapped_codec : mapped_codecs) { if (!FindMatchingCodec(local_supported_codecs, mapped_codec.codec)) { LOG(LS_ERROR) << "SetRecvParameters called with unsupported video codec: " @@ -1524,20 +1458,12 @@ WebRtcVideoChannel::WebRtcVideoSendStream::VideoSendStreamParameters:: conference_mode(false), codec_settings(codec_settings) {} -EncoderFactoryAdapter::AllocatedEncoder::AllocatedEncoder( - std::unique_ptr encoder, - bool is_hardware_accelerated, - bool has_internal_source) - : 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, - const EncoderFactoryAdapter* encoder_factory, + webrtc::VideoEncoderFactory* encoder_factory, bool enable_cpu_overuse_detection, int max_bitrate_bps, const rtc::Optional& codec_settings, @@ -1685,57 +1611,6 @@ WebRtcVideoChannel::WebRtcVideoSendStream::GetSsrcs() const { return ssrcs_; } -EncoderFactoryAdapter::AllocatedEncoder -CricketEncoderFactoryAdapter::CreateVideoEncoder( - const VideoCodec& codec) const { - // Try creating external encoder. - if (external_encoder_factory_ != nullptr && - FindMatchingCodec(external_encoder_factory_->supported_codecs(), codec)) { - std::unique_ptr 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( - new webrtc::SimulcastEncoderAdapter(external_encoder_factory_.get())); - } else { - external_encoder = - CreateScopedVideoEncoder(external_encoder_factory_.get(), codec); - } - if (external_encoder) { - std::unique_ptr internal_encoder( - new webrtc::VideoEncoderSoftwareFallbackWrapper( - codec, std::move(external_encoder))); - 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), - true /* is_hardware_accelerated */, - has_internal_source); - } - } - - // Try creating internal encoder. - std::unique_ptr internal_encoder; - if (FindMatchingCodec(internal_encoder_factory_->supported_codecs(), codec)) { - if (CodecNamesEq(codec.name.c_str(), kVp8CodecName)) { - internal_encoder = std::unique_ptr( - new webrtc::VP8EncoderSimulcastProxy( - internal_encoder_factory_.get())); - } else { - internal_encoder = std::unique_ptr( - internal_encoder_factory_->CreateVideoEncoder(codec)); - } - return AllocatedEncoder(std::move(internal_encoder), - false /* is_hardware_accelerated */, - false /* has_internal_source */); - } - - // This shouldn't happen, we should not be trying to create something we don't - // support. - RTC_NOTREACHED(); - return AllocatedEncoder(); -} - void WebRtcVideoChannel::WebRtcVideoSendStream::SetCodec( const VideoCodecSettings& codec_settings, bool force_encoder_allocation) { @@ -1749,15 +1624,18 @@ void WebRtcVideoChannel::WebRtcVideoSendStream::SetCodec( std::unique_ptr new_encoder; if (force_encoder_allocation || !allocated_encoder_ || allocated_codec_ != codec_settings.codec) { - EncoderFactoryAdapter::AllocatedEncoder new_allocated_encoder = - encoder_factory_->CreateVideoEncoder(codec_settings.codec); - new_encoder = std::unique_ptr( - std::move(new_allocated_encoder.encoder)); + const webrtc::SdpVideoFormat format(codec_settings.codec.name, + codec_settings.codec.params); + new_encoder = encoder_factory_->CreateVideoEncoder(format); + parameters_.config.encoder_settings.encoder = new_encoder.get(); + + const webrtc::VideoEncoderFactory::CodecInfo info = + encoder_factory_->QueryVideoEncoder(format); parameters_.config.encoder_settings.full_overuse_time = - new_allocated_encoder.is_hardware_accelerated; + info.is_hardware_accelerated; parameters_.config.encoder_settings.internal_source = - new_allocated_encoder.has_internal_source; + info.has_internal_source; } else { new_encoder = std::move(allocated_encoder_); } @@ -2131,7 +2009,7 @@ WebRtcVideoChannel::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( webrtc::Call* call, const StreamParams& sp, webrtc::VideoReceiveStream::Config config, - const DecoderFactoryAdapter* decoder_factory, + DecoderFactoryAdapter* decoder_factory, bool default_stream, const std::vector& recv_codecs, const webrtc::FlexfecReceiveStream::Config& flexfec_config) @@ -2182,30 +2060,6 @@ WebRtcVideoChannel::WebRtcVideoReceiveStream::GetFirstPrimarySsrc() const { } } -std::unique_ptr -CricketDecoderFactoryAdapter::CreateVideoDecoder( - const VideoCodec& codec, - const VideoDecoderParams& decoder_params) const { - if (external_decoder_factory_ != nullptr) { - std::unique_ptr external_decoder = - CreateScopedVideoDecoder(external_decoder_factory_.get(), codec, - decoder_params); - if (external_decoder) { - webrtc::VideoCodecType type = - webrtc::PayloadStringToCodecType(codec.name); - std::unique_ptr internal_decoder( - new webrtc::VideoDecoderSoftwareFallbackWrapper( - type, std::move(external_decoder))); - return internal_decoder; - } - } - - std::unique_ptr internal_decoder( - internal_decoder_factory_->CreateVideoDecoderWithParams(codec, - decoder_params)); - return internal_decoder; -} - void WebRtcVideoChannel::WebRtcVideoReceiveStream::ConfigureCodecs( const std::vector& recv_codecs, DecoderMap* old_decoders) { @@ -2224,9 +2078,10 @@ void WebRtcVideoChannel::WebRtcVideoReceiveStream::ConfigureCodecs( old_decoders->erase(it); } - if (!new_decoder) { - new_decoder = decoder_factory_->CreateVideoDecoder(recv_codec.codec, - {stream_params_.id}); + if (!new_decoder && decoder_factory_) { + decoder_factory_->SetReceiveStreamId(stream_params_.id); + new_decoder = decoder_factory_->CreateVideoDecoder(webrtc::SdpVideoFormat( + recv_codec.codec.name, recv_codec.codec.params)); } webrtc::VideoReceiveStream::Decoder decoder; diff --git a/media/engine/webrtcvideoengine.h b/media/engine/webrtcvideoengine.h index 86aae6b12e..f9c053a096 100644 --- a/media/engine/webrtcvideoengine.h +++ b/media/engine/webrtcvideoengine.h @@ -51,7 +51,6 @@ class Thread; namespace cricket { class DecoderFactoryAdapter; -class EncoderFactoryAdapter; class VideoCapturer; class VideoProcessor; class VideoRenderer; @@ -122,7 +121,7 @@ class WebRtcVideoEngine { private: const std::unique_ptr decoder_factory_; - const std::unique_ptr encoder_factory_; + const std::unique_ptr encoder_factory_; }; class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport { @@ -130,8 +129,8 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport { WebRtcVideoChannel(webrtc::Call* call, const MediaConfig& config, const VideoOptions& options, - const EncoderFactoryAdapter* encoder_factory, - const DecoderFactoryAdapter* decoder_factory); + webrtc::VideoEncoderFactory* encoder_factory, + DecoderFactoryAdapter* decoder_factory); ~WebRtcVideoChannel() override; // VideoMediaChannel implementation @@ -259,7 +258,7 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport { const StreamParams& sp, webrtc::VideoSendStream::Config config, const VideoOptions& options, - const EncoderFactoryAdapter* encoder_factory, + webrtc::VideoEncoderFactory* encoder_factory, bool enable_cpu_overuse_detection, int max_bitrate_bps, const rtc::Optional& codec_settings, @@ -337,7 +336,7 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport { const bool enable_cpu_overuse_detection_; rtc::VideoSourceInterface* source_ RTC_ACCESS_ON(&thread_checker_); - const EncoderFactoryAdapter* const encoder_factory_ + webrtc::VideoEncoderFactory* const encoder_factory_ RTC_ACCESS_ON(&thread_checker_); webrtc::VideoSendStream* stream_ RTC_ACCESS_ON(&thread_checker_); @@ -369,7 +368,7 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport { webrtc::Call* call, const StreamParams& sp, webrtc::VideoReceiveStream::Config config, - const DecoderFactoryAdapter* decoder_factory, + DecoderFactoryAdapter* decoder_factory, bool default_stream, const std::vector& recv_codecs, const webrtc::FlexfecReceiveStream::Config& flexfec_config); @@ -430,7 +429,7 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport { webrtc::FlexfecReceiveStream::Config flexfec_config_; webrtc::FlexfecReceiveStream* flexfec_stream_; - const DecoderFactoryAdapter* decoder_factory_; + DecoderFactoryAdapter* decoder_factory_; DecoderMap allocated_decoders_; rtc::CriticalSection sink_lock_; @@ -494,8 +493,8 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport { rtc::Optional send_codec_; rtc::Optional> send_rtp_extensions_; - const EncoderFactoryAdapter* const encoder_factory_; - const DecoderFactoryAdapter* const decoder_factory_; + webrtc::VideoEncoderFactory* const encoder_factory_; + DecoderFactoryAdapter* const decoder_factory_; std::vector recv_codecs_; std::vector recv_rtp_extensions_; // See reason for keeping track of the FlexFEC payload type separately in