From 1e45cc6ee0b368f7cb8b90acc7fe4c1699bb4288 Mon Sep 17 00:00:00 2001 From: magjed Date: Fri, 28 Oct 2016 07:43:45 -0700 Subject: [PATCH] Replace WebRtcVideoEncoderFactory::VideoCodec with cricket::VideoCodec This CL introduces two new functions to the WebRtcVideoEncoderFactory interface based on cricket::VideoFormat instead of WebRtcVideoEncoderFactory::VideoCodec. The functions are: WebRtcVideoEncoderFactory::CreateVideoEncoder() and WebRtcVideoEncoderFactory::supported_codecs(). In order to make a smooth transition to the new interface, the old functions are kept, and default implementations are provided for both the old and new functions so that external clients can switch from the old to the new functions in peace. The default implementations will just convert between cricket::VideoFormat and WebRtcVideoEncoderFactory::VideoCodec. Once all external clients have updated their code, the plan is to remove the old functions and all default implementations to make WebRtcVideoEncoderFactory a pure interface again. BUG=webrtc:6402,webrtc:6337 Review-Url: https://codereview.webrtc.org/2449993003 Cr-Commit-Position: refs/heads/master@{#14826} --- .../android/jni/androidmediaencoder_jni.cc | 35 +++--- .../api/android/jni/androidmediaencoder_jni.h | 12 +- webrtc/media/BUILD.gn | 1 + webrtc/media/base/codec.cc | 28 ++++- webrtc/media/base/codec.h | 7 ++ webrtc/media/engine/fakewebrtcvideoengine.h | 20 ++-- .../media/engine/webrtcvideoencoderfactory.cc | 60 ++++++++++ .../media/engine/webrtcvideoencoderfactory.h | 44 +++++-- webrtc/media/engine/webrtcvideoengine2.cc | 109 ++++++------------ webrtc/media/engine/webrtcvideoengine2.h | 3 - .../engine/webrtcvideoengine2_unittest.cc | 41 ++++--- webrtc/media/media.gyp | 1 + 12 files changed, 214 insertions(+), 147 deletions(-) create mode 100644 webrtc/media/engine/webrtcvideoencoderfactory.cc diff --git a/webrtc/api/android/jni/androidmediaencoder_jni.cc b/webrtc/api/android/jni/androidmediaencoder_jni.cc index c5c84549d6..0e6e96a6c0 100644 --- a/webrtc/api/android/jni/androidmediaencoder_jni.cc +++ b/webrtc/api/android/jni/androidmediaencoder_jni.cc @@ -57,9 +57,6 @@ namespace webrtc_jni { #define H264_SC_LENGTH 4 // Maximum allowed NALUs in one output frame. #define MAX_NALUS_PERFRAME 32 -// Maximum supported HW video encoder resolution. -#define MAX_VIDEO_WIDTH 1280 -#define MAX_VIDEO_HEIGHT 1280 // Maximum supported HW video encoder fps. #define MAX_VIDEO_FPS 30 // Maximum allowed fps value in SetRates() call. @@ -1310,8 +1307,7 @@ MediaCodecVideoEncoderFactory::MediaCodecVideoEncoderFactory() CHECK_EXCEPTION(jni); if (is_vp8_hw_supported) { ALOGD << "VP8 HW Encoder supported."; - supported_codecs_.push_back(VideoCodec(kVideoCodecVP8, "VP8", - MAX_VIDEO_WIDTH, MAX_VIDEO_HEIGHT, MAX_VIDEO_FPS)); + supported_codecs_.push_back(cricket::VideoCodec("VP8")); } bool is_vp9_hw_supported = jni->CallStaticBooleanMethod( @@ -1320,8 +1316,7 @@ MediaCodecVideoEncoderFactory::MediaCodecVideoEncoderFactory() CHECK_EXCEPTION(jni); if (is_vp9_hw_supported) { ALOGD << "VP9 HW Encoder supported."; - supported_codecs_.push_back(VideoCodec(kVideoCodecVP9, "VP9", - MAX_VIDEO_WIDTH, MAX_VIDEO_HEIGHT, MAX_VIDEO_FPS)); + supported_codecs_.push_back(cricket::VideoCodec("VP9")); } bool is_h264_hw_supported = jni->CallStaticBooleanMethod( @@ -1330,8 +1325,7 @@ MediaCodecVideoEncoderFactory::MediaCodecVideoEncoderFactory() CHECK_EXCEPTION(jni); if (is_h264_hw_supported) { ALOGD << "H.264 HW Encoder supported."; - supported_codecs_.push_back(VideoCodec(kVideoCodecH264, "H264", - MAX_VIDEO_WIDTH, MAX_VIDEO_HEIGHT, MAX_VIDEO_FPS)); + supported_codecs_.push_back(cricket::VideoCodec("H264")); } } @@ -1357,26 +1351,23 @@ void MediaCodecVideoEncoderFactory::SetEGLContext( } webrtc::VideoEncoder* MediaCodecVideoEncoderFactory::CreateVideoEncoder( - VideoCodecType type) { + const cricket::VideoCodec& codec) { if (supported_codecs_.empty()) { - ALOGW << "No HW video encoder for type " << (int)type; + ALOGW << "No HW video encoder for codec " << codec.name; return nullptr; } - for (std::vector::const_iterator it = supported_codecs_.begin(); - it != supported_codecs_.end(); ++it) { - if (it->type == type) { - ALOGD << "Create HW video encoder for type " << (int)type << - " (" << it->name << ")."; - return new MediaCodecVideoEncoder(AttachCurrentThreadIfNeeded(), type, - egl_context_); - } + if (IsCodecSupported(supported_codecs_, codec)) { + ALOGD << "Create HW video encoder for " << codec.name; + const VideoCodecType type = cricket::CodecTypeFromName(codec.name); + return new MediaCodecVideoEncoder(AttachCurrentThreadIfNeeded(), type, + egl_context_); } - ALOGW << "Can not find HW video encoder for type " << (int)type; + ALOGW << "Can not find HW video encoder for type " << codec.name; return nullptr; } -const std::vector& -MediaCodecVideoEncoderFactory::codecs() const { +const std::vector& +MediaCodecVideoEncoderFactory::supported_codecs() const { return supported_codecs_; } diff --git a/webrtc/api/android/jni/androidmediaencoder_jni.h b/webrtc/api/android/jni/androidmediaencoder_jni.h index 460eac3193..74442ddfbc 100644 --- a/webrtc/api/android/jni/androidmediaencoder_jni.h +++ b/webrtc/api/android/jni/androidmediaencoder_jni.h @@ -28,16 +28,20 @@ class MediaCodecVideoEncoderFactory void SetEGLContext(JNIEnv* jni, jobject egl_context); // WebRtcVideoEncoderFactory implementation. - webrtc::VideoEncoder* CreateVideoEncoder(webrtc::VideoCodecType type) - override; - const std::vector& codecs() const override; + webrtc::VideoEncoder* CreateVideoEncoder( + const cricket::VideoCodec& codec) override; + const std::vector& supported_codecs() const override; void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) override; private: + // Disable overloaded virtual function warning. TODO(magjed): Remove once + // http://crbug/webrtc/6402 is fixed. + using cricket::WebRtcVideoEncoderFactory::CreateVideoEncoder; + jobject egl_context_; // Empty if platform support is lacking, const after ctor returns. - std::vector supported_codecs_; + std::vector supported_codecs_; }; } // namespace webrtc_jni diff --git a/webrtc/media/BUILD.gn b/webrtc/media/BUILD.gn index c87266517d..0cdd80496c 100644 --- a/webrtc/media/BUILD.gn +++ b/webrtc/media/BUILD.gn @@ -96,6 +96,7 @@ rtc_static_library("rtc_media") { "engine/webrtcvideocapturerfactory.cc", "engine/webrtcvideocapturerfactory.h", "engine/webrtcvideodecoderfactory.h", + "engine/webrtcvideoencoderfactory.cc", "engine/webrtcvideoencoderfactory.h", "engine/webrtcvideoengine2.cc", "engine/webrtcvideoengine2.h", diff --git a/webrtc/media/base/codec.cc b/webrtc/media/base/codec.cc index 1e06e8e595..0ece9dbe16 100644 --- a/webrtc/media/base/codec.cc +++ b/webrtc/media/base/codec.cc @@ -212,6 +212,9 @@ std::string VideoCodec::ToString() const { VideoCodec::VideoCodec(int id, const std::string& name) : Codec(id, name, kVideoCodecClockrate) {} +VideoCodec::VideoCodec(const std::string& name) + : VideoCodec(0 /* id */, name) {} + VideoCodec::VideoCodec() : Codec() { clockrate = kVideoCodecClockrate; } @@ -304,7 +307,30 @@ bool HasTransportCc(const Codec& codec) { } bool CodecNamesEq(const std::string& name1, const std::string& name2) { - return _stricmp(name1.c_str(), name2.c_str()) == 0; + return CodecNamesEq(name1.c_str(), name2.c_str()); +} + +bool CodecNamesEq(const char* name1, const char* name2) { + return _stricmp(name1, name2) == 0; +} + +webrtc::VideoCodecType CodecTypeFromName(const std::string& name) { + if (CodecNamesEq(name.c_str(), kVp8CodecName)) { + return webrtc::kVideoCodecVP8; + } else if (CodecNamesEq(name.c_str(), kVp9CodecName)) { + return webrtc::kVideoCodecVP9; + } else if (CodecNamesEq(name.c_str(), kH264CodecName)) { + return webrtc::kVideoCodecH264; + } + return webrtc::kVideoCodecUnknown; +} + +bool IsCodecSupported(const std::vector& supported_codecs, + const VideoCodec& codec) { + return std::any_of(supported_codecs.begin(), supported_codecs.end(), + [&codec](const VideoCodec& supported_codec) -> bool { + return CodecNamesEq(codec.name, supported_codec.name); + }); } } // namespace cricket diff --git a/webrtc/media/base/codec.h b/webrtc/media/base/codec.h index facdfefebc..84e63e82e9 100644 --- a/webrtc/media/base/codec.h +++ b/webrtc/media/base/codec.h @@ -17,6 +17,7 @@ #include #include "webrtc/api/rtpparameters.h" +#include "webrtc/common_types.h" #include "webrtc/media/base/mediaconstants.h" namespace cricket { @@ -141,6 +142,8 @@ struct AudioCodec : public Codec { struct VideoCodec : public Codec { // Creates a codec with the given parameters. VideoCodec(int id, const std::string& name); + // Creates a codec with the given name and empty id. + explicit VideoCodec(const std::string& name); // Creates an empty codec. VideoCodec(); VideoCodec(const VideoCodec& c); @@ -200,9 +203,13 @@ bool FindCodecById(const std::vector& codecs, } bool CodecNamesEq(const std::string& name1, const std::string& name2); +bool CodecNamesEq(const char* name1, const char* name2); +webrtc::VideoCodecType CodecTypeFromName(const std::string& name); bool HasNack(const Codec& codec); bool HasRemb(const Codec& codec); bool HasTransportCc(const Codec& codec); +bool IsCodecSupported(const std::vector& supported_codecs, + const VideoCodec& codec); } // namespace cricket diff --git a/webrtc/media/engine/fakewebrtcvideoengine.h b/webrtc/media/engine/fakewebrtcvideoengine.h index e954f90b1e..bbc93e0d40 100644 --- a/webrtc/media/engine/fakewebrtcvideoengine.h +++ b/webrtc/media/engine/fakewebrtcvideoengine.h @@ -193,11 +193,10 @@ class FakeWebRtcVideoEncoderFactory : public WebRtcVideoEncoderFactory { encoders_have_internal_sources_(false) {} webrtc::VideoEncoder* CreateVideoEncoder( - webrtc::VideoCodecType type) override { + const cricket::VideoCodec& codec) override { rtc::CritScope lock(&crit_); - if (supported_codec_types_.count(type) == 0) { - return NULL; - } + if (!IsCodecSupported(codecs_, codec)) + return nullptr; FakeWebRtcVideoEncoder* encoder = new FakeWebRtcVideoEncoder(); encoders_.push_back(encoder); num_created_encoders_++; @@ -221,8 +220,7 @@ class FakeWebRtcVideoEncoderFactory : public WebRtcVideoEncoderFactory { delete encoder; } - const std::vector& codecs() - const override { + const std::vector& supported_codecs() const override { return codecs_; } @@ -235,11 +233,8 @@ class FakeWebRtcVideoEncoderFactory : public WebRtcVideoEncoderFactory { encoders_have_internal_sources_ = internal_source; } - void AddSupportedVideoCodecType(webrtc::VideoCodecType type, - const std::string& name) { - supported_codec_types_.insert(type); - codecs_.push_back( - WebRtcVideoEncoderFactory::VideoCodec(type, name, 1280, 720, 30)); + void AddSupportedVideoCodecType(const std::string& name) { + codecs_.push_back(cricket::VideoCodec(name)); } int GetNumCreatedEncoders() { @@ -255,8 +250,7 @@ class FakeWebRtcVideoEncoderFactory : public WebRtcVideoEncoderFactory { private: rtc::CriticalSection crit_; rtc::Event created_video_encoder_event_; - std::set supported_codec_types_; - std::vector codecs_; + std::vector codecs_; std::vector encoders_ GUARDED_BY(crit_); int num_created_encoders_ GUARDED_BY(crit_); bool encoders_have_internal_sources_; diff --git a/webrtc/media/engine/webrtcvideoencoderfactory.cc b/webrtc/media/engine/webrtcvideoencoderfactory.cc new file mode 100644 index 0000000000..ccc32d894b --- /dev/null +++ b/webrtc/media/engine/webrtcvideoencoderfactory.cc @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2016 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 "webrtc/media/engine/webrtcvideoencoderfactory.h" + +#include "webrtc/media/base/mediaconstants.h" + +static const char* NameFromCodecType(webrtc::VideoCodecType type) { + switch (type) { + case webrtc::kVideoCodecVP8: + return cricket::kVp8CodecName; + case webrtc::kVideoCodecVP9: + return cricket::kVp9CodecName; + case webrtc::kVideoCodecH264: + return cricket::kH264CodecName; + default: + return "Unknown codec"; + } +} + +namespace cricket { + +webrtc::VideoEncoder* WebRtcVideoEncoderFactory::CreateVideoEncoder( + const cricket::VideoCodec& codec) { + return CreateVideoEncoder(CodecTypeFromName(codec.name)); +} + +const std::vector& +WebRtcVideoEncoderFactory::supported_codecs() const { + const std::vector& encoder_codecs = codecs(); + for (const VideoCodec& encoder_codec : encoder_codecs) { + codecs_.push_back(cricket::VideoCodec(encoder_codec.name)); + } + return codecs_; +} + +webrtc::VideoEncoder* WebRtcVideoEncoderFactory::CreateVideoEncoder( + webrtc::VideoCodecType type) { + const cricket::VideoCodec codec(NameFromCodecType(type)); + return CreateVideoEncoder(codec); +} + +const std::vector& +WebRtcVideoEncoderFactory::codecs() const { + const std::vector& codecs = supported_codecs(); + for (const cricket::VideoCodec& codec : codecs) { + encoder_codecs_.push_back( + VideoCodec(CodecTypeFromName(codec.name), codec.name)); + } + return encoder_codecs_; +} + +} // namespace cricket diff --git a/webrtc/media/engine/webrtcvideoencoderfactory.h b/webrtc/media/engine/webrtcvideoencoderfactory.h index e57a314352..35e4092028 100644 --- a/webrtc/media/engine/webrtcvideoencoderfactory.h +++ b/webrtc/media/engine/webrtcvideoencoderfactory.h @@ -11,7 +11,8 @@ #ifndef WEBRTC_MEDIA_ENGINE_WEBRTCVIDEOENCODERFACTORY_H_ #define WEBRTC_MEDIA_ENGINE_WEBRTCVIDEOENCODERFACTORY_H_ -#include "webrtc/base/refcount.h" +#include + #include "webrtc/common_types.h" #include "webrtc/media/base/codec.h" @@ -23,28 +24,46 @@ namespace cricket { class WebRtcVideoEncoderFactory { public: + // This VideoCodec class is deprecated. Use cricket::VideoCodec directly + // instead and the corresponding factory function. See + // http://crbug/webrtc/6402 for more info. struct VideoCodec { webrtc::VideoCodecType type; std::string name; - int max_width; - int max_height; - int max_fps; - VideoCodec(webrtc::VideoCodecType t, const std::string& nm, int w, int h, + VideoCodec(webrtc::VideoCodecType t, const std::string& nm) + : type(t), name(nm) {} + + VideoCodec(webrtc::VideoCodecType t, + const std::string& nm, + int w, + int h, int fr) - : type(t), name(nm), max_width(w), max_height(h), max_fps(fr) { - } + : type(t), name(nm) {} }; virtual ~WebRtcVideoEncoderFactory() {} + // TODO(magjed): Make these functions pure virtual when every external client + // implements it. See http://crbug/webrtc/6402 for more info. // Caller takes the ownership of the returned object and it should be released // by calling DestroyVideoEncoder(). virtual webrtc::VideoEncoder* CreateVideoEncoder( - webrtc::VideoCodecType type) = 0; + const cricket::VideoCodec& codec); // Returns a list of supported codecs in order of preference. - virtual const std::vector& codecs() const = 0; + virtual const std::vector& supported_codecs() const; + + // Caller takes the ownership of the returned object and it should be released + // by calling DestroyVideoEncoder(). + // Deprecated: Use cricket::VideoCodec as argument instead. See + // http://crbug/webrtc/6402 for more info. + virtual webrtc::VideoEncoder* CreateVideoEncoder(webrtc::VideoCodecType type); + + // Returns a list of supported codecs in order of preference. + // Deprecated: Return cricket::VideoCodecs instead. See + // http://crbug/webrtc/6402 for more info. + virtual const std::vector& codecs() const; // Returns true if encoders created by this factory of the given codec type // will use internal camera sources, meaning that they don't require/expect @@ -56,6 +75,13 @@ class WebRtcVideoEncoderFactory { } virtual void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) = 0; + + private: + // TODO(magjed): Remove these. They are necessary in order to return a const + // reference to a std::vector in the default implementations of codecs() and + // supported_codecs(). See http://crbug/webrtc/6402 for more info. + mutable std::vector encoder_codecs_; + mutable std::vector codecs_; }; } // namespace cricket diff --git a/webrtc/media/engine/webrtcvideoengine2.cc b/webrtc/media/engine/webrtcvideoengine2.cc index 490bbf4504..98b3adf18a 100644 --- a/webrtc/media/engine/webrtcvideoengine2.cc +++ b/webrtc/media/engine/webrtcvideoengine2.cc @@ -49,7 +49,7 @@ class EncoderFactoryAdapter : public webrtc::VideoEncoderFactory { // Implement webrtc::VideoEncoderFactory. webrtc::VideoEncoder* Create() override { - return factory_->CreateVideoEncoder(webrtc::kVideoCodecVP8); + return factory_->CreateVideoEncoder(VideoCodec(kVp8CodecName)); } void Destroy(webrtc::VideoEncoder* encoder) override { @@ -99,11 +99,11 @@ class WebRtcSimulcastEncoderFactory : factory_(factory) {} static bool UseSimulcastEncoderFactory( - const std::vector& codecs) { + const std::vector& 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 (codec.type == webrtc::kVideoCodecVP8) { + if (CodecNamesEq(codec.name.c_str(), kVp8CodecName)) { return true; } } @@ -111,22 +111,22 @@ class WebRtcSimulcastEncoderFactory } webrtc::VideoEncoder* CreateVideoEncoder( - webrtc::VideoCodecType type) override { + const cricket::VideoCodec& codec) override { RTC_DCHECK(factory_ != NULL); // If it's a codec type we can simulcast, create a wrapped encoder. - if (type == webrtc::kVideoCodecVP8) { + if (CodecNamesEq(codec.name.c_str(), kVp8CodecName)) { return new webrtc::SimulcastEncoderAdapter( new EncoderFactoryAdapter(factory_)); } - webrtc::VideoEncoder* encoder = factory_->CreateVideoEncoder(type); + webrtc::VideoEncoder* encoder = factory_->CreateVideoEncoder(codec); if (encoder) { non_simulcast_encoders_.push_back(encoder); } return encoder; } - const std::vector& codecs() const override { - return factory_->codecs(); + const std::vector& supported_codecs() const override { + return factory_->supported_codecs(); } bool EncoderTypeHasInternalSource( @@ -156,21 +156,6 @@ class WebRtcSimulcastEncoderFactory std::vector non_simulcast_encoders_; }; -bool CodecIsInternallySupported(const std::string& codec_name) { - if (CodecNamesEq(codec_name, kVp8CodecName)) { - return true; - } - if (CodecNamesEq(codec_name, kVp9CodecName)) { - return webrtc::VP9Encoder::IsSupported() && - webrtc::VP9Decoder::IsSupported(); - } - if (CodecNamesEq(codec_name, kH264CodecName)) { - return webrtc::H264Encoder::IsSupported() && - webrtc::H264Decoder::IsSupported(); - } - return false; -} - void AddDefaultFeedbackParams(VideoCodec* codec) { codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamCcm, kRtcpFbCcmParamFir)); codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kParamValueEmpty)); @@ -443,12 +428,13 @@ std::vector DefaultVideoCodecList() { AddCodecAndMaybeRtxCodec( MakeVideoCodecWithDefaultFeedbackParams(kDefaultVp8PlType, kVp8CodecName), &codecs); - if (CodecIsInternallySupported(kVp9CodecName)) { + if (webrtc::VP9Encoder::IsSupported() && webrtc::VP9Decoder::IsSupported()) { AddCodecAndMaybeRtxCodec(MakeVideoCodecWithDefaultFeedbackParams( kDefaultVp9PlType, kVp9CodecName), &codecs); } - if (CodecIsInternallySupported(kH264CodecName)) { + if (webrtc::H264Encoder::IsSupported() && + webrtc::H264Decoder::IsSupported()) { VideoCodec codec = MakeVideoCodecWithDefaultFeedbackParams( kDefaultH264PlType, kH264CodecName); // TODO(hta): Move all parameter generation for SDP into the codec @@ -468,6 +454,9 @@ std::vector DefaultVideoCodecList() { return codecs; } +static std::vector GetSupportedCodecs( + const WebRtcVideoEncoderFactory* external_encoder_factory); + rtc::scoped_refptr WebRtcVideoChannel2::WebRtcVideoSendStream::ConfigureVideoEncoderSettings( const VideoCodec& codec) { @@ -565,7 +554,7 @@ WebRtcVideoEngine2::WebRtcVideoEngine2() external_decoder_factory_(NULL), external_encoder_factory_(NULL) { LOG(LS_INFO) << "WebRtcVideoEngine2::WebRtcVideoEngine2()"; - video_codecs_ = GetSupportedCodecs(); + video_codecs_ = GetSupportedCodecs(external_encoder_factory_); } WebRtcVideoEngine2::~WebRtcVideoEngine2() { @@ -630,37 +619,38 @@ void WebRtcVideoEngine2::SetExternalEncoderFactory( if (encoder_factory && WebRtcSimulcastEncoderFactory::UseSimulcastEncoderFactory( - encoder_factory->codecs())) { + encoder_factory->supported_codecs())) { simulcast_encoder_factory_.reset( new WebRtcSimulcastEncoderFactory(encoder_factory)); encoder_factory = simulcast_encoder_factory_.get(); } external_encoder_factory_ = encoder_factory; - video_codecs_ = GetSupportedCodecs(); + video_codecs_ = GetSupportedCodecs(encoder_factory); } -std::vector WebRtcVideoEngine2::GetSupportedCodecs() const { +static std::vector GetSupportedCodecs( + const WebRtcVideoEncoderFactory* external_encoder_factory) { std::vector supported_codecs = DefaultVideoCodecList(); - if (external_encoder_factory_ == NULL) { + if (external_encoder_factory == nullptr) { LOG(LS_INFO) << "Supported codecs: " << CodecVectorToString(supported_codecs); return supported_codecs; } std::stringstream out; - const std::vector& codecs = - external_encoder_factory_->codecs(); + const std::vector& codecs = + external_encoder_factory->supported_codecs(); for (size_t i = 0; i < codecs.size(); ++i) { - out << codecs[i].name; + VideoCodec codec = codecs[i]; + out << codec.name; if (i != codecs.size() - 1) { out << ", "; } // Don't add internally-supported codecs twice. - if (CodecIsInternallySupported(codecs[i].name)) { + if (IsCodecSupported(supported_codecs, codec)) continue; - } // External video encoders are given payloads 120-127. This also means that // we only support up to 8 external payload types. @@ -673,7 +663,7 @@ std::vector WebRtcVideoEngine2::GetSupportedCodecs() const { const int kExternalVideoPayloadTypeBase = 120; size_t payload_type = kExternalVideoPayloadTypeBase + i; RTC_DCHECK(payload_type < 128); - VideoCodec codec(static_cast(payload_type), codecs[i].name); + codec.id = payload_type; AddDefaultFeedbackParams(&codec); AddCodecAndMaybeRtxCodec(codec, &supported_codecs); @@ -716,35 +706,17 @@ WebRtcVideoChannel2::~WebRtcVideoChannel2() { delete kv.second; } -bool WebRtcVideoChannel2::CodecIsExternallySupported( - const std::string& name) const { - if (external_encoder_factory_ == NULL) { - return false; - } - - const std::vector external_codecs = - external_encoder_factory_->codecs(); - for (size_t c = 0; c < external_codecs.size(); ++c) { - if (CodecNamesEq(name, external_codecs[c].name)) { - return true; - } - } - return false; -} - std::vector WebRtcVideoChannel2::FilterSupportedCodecs( - const std::vector& mapped_codecs) - const { - std::vector supported_codecs; - for (size_t i = 0; i < mapped_codecs.size(); ++i) { - const VideoCodecSettings& codec = mapped_codecs[i]; - if (CodecIsInternallySupported(codec.codec.name) || - CodecIsExternallySupported(codec.codec.name)) { - supported_codecs.push_back(codec); - } + const std::vector& mapped_codecs) const { + const std::vector supported_codecs = + GetSupportedCodecs(external_encoder_factory_); + std::vector filtered_codecs; + for (const VideoCodecSettings& mapped_codec : mapped_codecs) { + if (IsCodecSupported(supported_codecs, mapped_codec.codec)) + filtered_codecs.push_back(mapped_codec); } - return supported_codecs; + return filtered_codecs; } bool WebRtcVideoChannel2::ReceiveCodecsHaveChanged( @@ -1770,17 +1742,6 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::GetSsrcs() const { return ssrcs_; } -webrtc::VideoCodecType CodecTypeFromName(const std::string& name) { - if (CodecNamesEq(name, kVp8CodecName)) { - return webrtc::kVideoCodecVP8; - } else if (CodecNamesEq(name, kVp9CodecName)) { - return webrtc::kVideoCodecVP9; - } else if (CodecNamesEq(name, kH264CodecName)) { - return webrtc::kVideoCodecH264; - } - return webrtc::kVideoCodecUnknown; -} - WebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoder( const VideoCodec& codec) { @@ -1794,7 +1755,7 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoder( if (external_encoder_factory_ != NULL) { webrtc::VideoEncoder* encoder = - external_encoder_factory_->CreateVideoEncoder(type); + external_encoder_factory_->CreateVideoEncoder(codec); if (encoder != NULL) { return AllocatedEncoder(encoder, type, true); } diff --git a/webrtc/media/engine/webrtcvideoengine2.h b/webrtc/media/engine/webrtcvideoengine2.h index 716390557c..263e834a95 100644 --- a/webrtc/media/engine/webrtcvideoengine2.h +++ b/webrtc/media/engine/webrtcvideoengine2.h @@ -119,8 +119,6 @@ class WebRtcVideoEngine2 { WebRtcVideoEncoderFactory* encoder_factory); private: - std::vector GetSupportedCodecs() const; - std::vector video_codecs_; bool initialized_; @@ -226,7 +224,6 @@ class WebRtcVideoChannel2 : public VideoMediaChannel, public webrtc::Transport { void ConfigureReceiverRtp(webrtc::VideoReceiveStream::Config* config, const StreamParams& sp) const; - bool CodecIsExternallySupported(const std::string& name) const; bool ValidateSendSsrcAvailability(const StreamParams& sp) const EXCLUSIVE_LOCKS_REQUIRED(stream_crit_); bool ValidateReceiveSsrcAvailability(const StreamParams& sp) const diff --git a/webrtc/media/engine/webrtcvideoengine2_unittest.cc b/webrtc/media/engine/webrtcvideoengine2_unittest.cc index 4d86e6c6f4..5d7b2b3155 100644 --- a/webrtc/media/engine/webrtcvideoengine2_unittest.cc +++ b/webrtc/media/engine/webrtcvideoengine2_unittest.cc @@ -222,7 +222,7 @@ TEST_F(WebRtcVideoEngine2Test, CVOSetHeaderExtensionBeforeCapturer) { cricket::FakeVideoCapturer capturer; cricket::FakeWebRtcVideoEncoderFactory encoder_factory; - encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); + encoder_factory.AddSupportedVideoCodecType("VP8"); cricket::VideoSendParameters parameters; parameters.codecs.push_back(kVp8Codec); @@ -254,7 +254,7 @@ TEST_F(WebRtcVideoEngine2Test, CVOSetHeaderExtensionBeforeAddSendStream) { cricket::FakeVideoCapturer capturer; cricket::FakeWebRtcVideoEncoderFactory encoder_factory; - encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); + encoder_factory.AddSupportedVideoCodecType("VP8"); cricket::VideoSendParameters parameters; parameters.codecs.push_back(kVp8Codec); @@ -278,8 +278,8 @@ TEST_F(WebRtcVideoEngine2Test, CVOSetHeaderExtensionAfterCapturer) { cricket::FakeVideoCapturer capturer; cricket::FakeWebRtcVideoEncoderFactory encoder_factory; - encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); - encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP9, "VP9"); + encoder_factory.AddSupportedVideoCodecType("VP8"); + encoder_factory.AddSupportedVideoCodecType("VP9"); cricket::VideoSendParameters parameters; parameters.codecs.push_back(kVp8Codec); parameters.codecs.push_back(kVp9Codec); @@ -335,7 +335,7 @@ TEST_F(WebRtcVideoEngine2Test, GetStatsWithoutSendCodecsSetDoesNotCrash) { TEST_F(WebRtcVideoEngine2Test, UseExternalFactoryForVp8WhenSupported) { cricket::FakeWebRtcVideoEncoderFactory encoder_factory; - encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); + encoder_factory.AddSupportedVideoCodecType("VP8"); cricket::VideoSendParameters parameters; parameters.codecs.push_back(kVp8Codec); @@ -376,7 +376,7 @@ TEST_F(WebRtcVideoEngine2Test, UseExternalFactoryForVp8WhenSupported) { // if/when we start adding RTX codecs for unrecognized codec names. TEST_F(WebRtcVideoEngine2Test, RtxCodecAddedForExternalCodec) { cricket::FakeWebRtcVideoEncoderFactory encoder_factory; - encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264"); + encoder_factory.AddSupportedVideoCodecType("H264"); engine_.SetExternalEncoderFactory(&encoder_factory); engine_.Init(); @@ -400,7 +400,7 @@ TEST_F(WebRtcVideoEngine2Test, RtxCodecAddedForExternalCodec) { void WebRtcVideoEngine2Test::TestExtendedEncoderOveruse( bool use_external_encoder) { cricket::FakeWebRtcVideoEncoderFactory encoder_factory; - encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); + encoder_factory.AddSupportedVideoCodecType("VP8"); cricket::VideoSendParameters parameters; parameters.codecs.push_back(kVp8Codec); std::unique_ptr channel; @@ -437,7 +437,7 @@ TEST_F(WebRtcVideoEngine2Test, DisablesFullEncoderTimeForNonExternalEncoders) { #if !defined(RTC_DISABLE_VP9) TEST_F(WebRtcVideoEngine2Test, CanConstructDecoderForVp9EncoderFactory) { cricket::FakeWebRtcVideoEncoderFactory encoder_factory; - encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP9, "VP9"); + encoder_factory.AddSupportedVideoCodecType("VP9"); std::vector codecs; codecs.push_back(kVp9Codec); @@ -451,7 +451,7 @@ TEST_F(WebRtcVideoEngine2Test, CanConstructDecoderForVp9EncoderFactory) { TEST_F(WebRtcVideoEngine2Test, PropagatesInputFrameTimestamp) { cricket::FakeWebRtcVideoEncoderFactory encoder_factory; - encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); + encoder_factory.AddSupportedVideoCodecType("VP8"); std::vector codecs; codecs.push_back(kVp8Codec); FakeCall* fake_call = new FakeCall(webrtc::Call::Config(&event_log_)); @@ -539,7 +539,7 @@ VideoMediaChannel* WebRtcVideoEngine2Test::SetUpForExternalDecoderFactory( TEST_F(WebRtcVideoEngine2Test, UsesSimulcastAdapterForVp8Factories) { cricket::FakeWebRtcVideoEncoderFactory encoder_factory; - encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); + encoder_factory.AddSupportedVideoCodecType("VP8"); std::vector codecs; codecs.push_back(kVp8Codec); @@ -580,7 +580,7 @@ TEST_F(WebRtcVideoEngine2Test, UsesSimulcastAdapterForVp8Factories) { TEST_F(WebRtcVideoEngine2Test, ChannelWithExternalH264CanChangeToInternalVp8) { cricket::FakeWebRtcVideoEncoderFactory encoder_factory; - encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264"); + encoder_factory.AddSupportedVideoCodecType("H264"); std::vector codecs; codecs.push_back(kH264Codec); @@ -600,7 +600,7 @@ TEST_F(WebRtcVideoEngine2Test, ChannelWithExternalH264CanChangeToInternalVp8) { TEST_F(WebRtcVideoEngine2Test, DontUseExternalEncoderFactoryForUnsupportedCodecs) { cricket::FakeWebRtcVideoEncoderFactory encoder_factory; - encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264"); + encoder_factory.AddSupportedVideoCodecType("H264"); std::vector codecs; codecs.push_back(kVp8Codec); @@ -616,8 +616,8 @@ TEST_F(WebRtcVideoEngine2Test, TEST_F(WebRtcVideoEngine2Test, UsesSimulcastAdapterForVp8WithCombinedVP8AndH264Factory) { cricket::FakeWebRtcVideoEncoderFactory encoder_factory; - encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); - encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264"); + encoder_factory.AddSupportedVideoCodecType("VP8"); + encoder_factory.AddSupportedVideoCodecType("H264"); std::vector codecs; codecs.push_back(kVp8Codec); @@ -653,8 +653,8 @@ TEST_F(WebRtcVideoEngine2Test, TEST_F(WebRtcVideoEngine2Test, DestroysNonSimulcastEncoderFromCombinedVP8AndH264Factory) { cricket::FakeWebRtcVideoEncoderFactory encoder_factory; - encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); - encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264"); + encoder_factory.AddSupportedVideoCodecType("VP8"); + encoder_factory.AddSupportedVideoCodecType("H264"); std::vector codecs; codecs.push_back(kH264Codec); @@ -684,7 +684,7 @@ TEST_F(WebRtcVideoEngine2Test, TEST_F(WebRtcVideoEngine2Test, SimulcastDisabledForH264) { cricket::FakeWebRtcVideoEncoderFactory encoder_factory; - encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264"); + encoder_factory.AddSupportedVideoCodecType("H264"); std::vector codecs; codecs.push_back(kH264Codec); @@ -714,8 +714,7 @@ TEST_F(WebRtcVideoEngine2Test, SimulcastDisabledForH264) { // Test that external codecs are added to the end of the supported codec list. TEST_F(WebRtcVideoEngine2Test, ReportSupportedExternalCodecs) { cricket::FakeWebRtcVideoEncoderFactory encoder_factory; - encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecUnknown, - "FakeExternalCodec"); + encoder_factory.AddSupportedVideoCodecType("FakeExternalCodec"); engine_.SetExternalEncoderFactory(&encoder_factory); engine_.Init(); @@ -758,7 +757,7 @@ TEST_F(WebRtcVideoEngine2Test, RegisterExternalH264DecoderIfSupported) { // For now we add a FakeWebRtcVideoEncoderFactory to add H264 to supported // codecs. cricket::FakeWebRtcVideoEncoderFactory encoder_factory; - encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264"); + encoder_factory.AddSupportedVideoCodecType("H264"); engine_.SetExternalEncoderFactory(&encoder_factory); cricket::FakeWebRtcVideoDecoderFactory decoder_factory; decoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264); @@ -1817,7 +1816,7 @@ class Vp9SettingsTest : public WebRtcVideoChannel2Test { Vp9SettingsTest() : Vp9SettingsTest("") {} explicit Vp9SettingsTest(const char* field_trials) : WebRtcVideoChannel2Test(field_trials) { - encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP9, "VP9"); + encoder_factory_.AddSupportedVideoCodecType("VP9"); } virtual ~Vp9SettingsTest() {} diff --git a/webrtc/media/media.gyp b/webrtc/media/media.gyp index ffc6419143..f022ffca81 100644 --- a/webrtc/media/media.gyp +++ b/webrtc/media/media.gyp @@ -76,6 +76,7 @@ 'engine/webrtcvideocapturerfactory.h', 'engine/webrtcvideocapturerfactory.cc', 'engine/webrtcvideodecoderfactory.h', + 'engine/webrtcvideoencoderfactory.cc', 'engine/webrtcvideoencoderfactory.h', 'engine/webrtcvideoengine2.cc', 'engine/webrtcvideoengine2.h',