diff --git a/media/BUILD.gn b/media/BUILD.gn index 5079b7f396..ac6c378c64 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -7,6 +7,7 @@ # be found in the AUTHORS file in the root of the source tree. import("//build/config/linux/pkg_config.gni") +import("//third_party/libaom/options.gni") import("../webrtc.gni") group("media") { @@ -208,24 +209,32 @@ rtc_library("rtc_internal_video_codecs") { "../api/video:video_rtp_headers", "../api/video_codecs:rtc_software_fallback_wrappers", "../api/video_codecs:video_codecs_api", + "../api/video_codecs:video_encoder_factory_template", + "../api/video_codecs:video_encoder_factory_template_libvpx_vp8_adapter", + "../api/video_codecs:video_encoder_factory_template_libvpx_vp9_adapter", + "../api/video_codecs:video_encoder_factory_template_open_h264_adapter", "../call:call_interfaces", "../call:video_stream_api", "../modules/video_coding:video_codec_interface", "../modules/video_coding:webrtc_h264", "../modules/video_coding:webrtc_multiplex", "../modules/video_coding:webrtc_vp8", - "../modules/video_coding:webrtc_vp8_scalability", "../modules/video_coding:webrtc_vp9", - "../modules/video_coding/codecs/av1:av1_svc_config", "../modules/video_coding/codecs/av1:libaom_av1_decoder", - "../modules/video_coding/codecs/av1:libaom_av1_encoder_if_supported", - "../modules/video_coding/svc:scalability_mode_util", "../rtc_base:checks", "../rtc_base:logging", "../rtc_base/system:rtc_export", "../system_wrappers:field_trial", "../test:fake_video_codecs", ] + + if (enable_libaom) { + defines += [ "RTC_USE_LIBAOM_AV1_ENCODER" ] + deps += [ + "../api/video_codecs:video_encoder_factory_template_libaom_av1_adapter", + ] + } + if (rtc_include_dav1d_in_internal_decoder_factory) { deps += [ "../modules/video_coding/codecs/av1:dav1d_decoder" ] } @@ -616,7 +625,6 @@ if (rtc_include_tests) { "../modules/video_coding:webrtc_h264", "../modules/video_coding:webrtc_vp8", "../modules/video_coding/codecs/av1:libaom_av1_decoder", - "../modules/video_coding/codecs/av1:libaom_av1_encoder_if_supported", "../p2p:p2p_test_utils", "../rtc_base", "../rtc_base:byte_order", @@ -645,6 +653,11 @@ if (rtc_include_tests) { "../test:video_test_common", "../test/time_controller", ] + + if (enable_libaom) { + defines += [ "RTC_USE_LIBAOM_AV1_ENCODER" ] + } + absl_deps = [ "//third_party/abseil-cpp/absl/algorithm:container", "//third_party/abseil-cpp/absl/memory", diff --git a/media/engine/internal_encoder_factory.cc b/media/engine/internal_encoder_factory.cc index 03d51a5526..4243f52481 100644 --- a/media/engine/internal_encoder_factory.cc +++ b/media/engine/internal_encoder_factory.cc @@ -10,92 +10,81 @@ #include "media/engine/internal_encoder_factory.h" +#include #include +#include #include "absl/strings/match.h" -#include "api/video_codecs/sdp_video_format.h" -#include "media/base/codec.h" -#include "media/base/media_constants.h" -#include "modules/video_coding/codecs/av1/av1_svc_config.h" -#include "modules/video_coding/codecs/av1/libaom_av1_encoder_supported.h" -#include "modules/video_coding/codecs/h264/include/h264.h" -#include "modules/video_coding/codecs/vp8/include/vp8.h" -#include "modules/video_coding/codecs/vp8/vp8_scalability.h" -#include "modules/video_coding/codecs/vp9/include/vp9.h" -#include "modules/video_coding/svc/scalability_mode_util.h" -#include "rtc_base/logging.h" +#include "api/video_codecs/video_encoder_factory.h" +#include "api/video_codecs/video_encoder_factory_template.h" +#if defined(RTC_USE_LIBAOM_AV1_ENCODER) +#include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h" // nogncheck +#endif +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h" +#if defined(WEBRTC_USE_H264) +#include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h" // nogncheck +#endif namespace webrtc { +namespace { -std::vector InternalEncoderFactory::SupportedFormats() { - std::vector supported_codecs; - supported_codecs.push_back(SdpVideoFormat(cricket::kVp8CodecName)); - for (const webrtc::SdpVideoFormat& format : webrtc::SupportedVP9Codecs()) - supported_codecs.push_back(format); - for (const webrtc::SdpVideoFormat& format : webrtc::SupportedH264Codecs()) - supported_codecs.push_back(format); - if (kIsLibaomAv1EncoderSupported) - supported_codecs.push_back(SdpVideoFormat(cricket::kAv1CodecName)); - return supported_codecs; +using Factory = + VideoEncoderFactoryTemplate; + +absl::optional MatchOriginalFormat( + const SdpVideoFormat& format) { + const auto supported_formats = Factory().GetSupportedFormats(); + + absl::optional res; + int best_parameter_match = 0; + for (const auto& supported_format : supported_formats) { + if (absl::EqualsIgnoreCase(supported_format.name, format.name)) { + int matching_parameters = 0; + for (const auto& kv : supported_format.parameters) { + auto it = format.parameters.find(kv.first); + if (it != format.parameters.end() && it->second == kv.second) { + matching_parameters += 1; + } + } + + if (!res || matching_parameters > best_parameter_match) { + res = supported_format; + best_parameter_match = matching_parameters; + } + } + } + + return res; } +} // namespace std::vector InternalEncoderFactory::GetSupportedFormats() const { - return SupportedFormats(); + return Factory().GetSupportedFormats(); } std::unique_ptr InternalEncoderFactory::CreateVideoEncoder( const SdpVideoFormat& format) { - if (absl::EqualsIgnoreCase(format.name, cricket::kVp8CodecName)) - return VP8Encoder::Create(); - if (absl::EqualsIgnoreCase(format.name, cricket::kVp9CodecName)) - return VP9Encoder::Create(cricket::VideoCodec(format)); - if (absl::EqualsIgnoreCase(format.name, cricket::kH264CodecName)) - return H264Encoder::Create(cricket::VideoCodec(format)); - if (kIsLibaomAv1EncoderSupported && - absl::EqualsIgnoreCase(format.name, cricket::kAv1CodecName)) - return CreateLibaomAv1EncoderIfSupported(); - RTC_LOG(LS_ERROR) << "Trying to created encoder of unsupported format " - << format.name; - return nullptr; + auto original_format = MatchOriginalFormat(format); + return original_format ? Factory().CreateVideoEncoder(*original_format) + : nullptr; } VideoEncoderFactory::CodecSupport InternalEncoderFactory::QueryCodecSupport( const SdpVideoFormat& format, - absl::optional scalability_mode_string) const { - // Query for supported formats and check if the specified format is supported. - // Begin with filtering out unsupported scalability modes. - if (scalability_mode_string) { - static constexpr VideoEncoderFactory::CodecSupport kUnsupported = { - .is_supported = false, .is_power_efficient = false}; - absl::optional scalability_mode = - ScalabilityModeFromString(*scalability_mode_string); - if (!scalability_mode.has_value()) { - return kUnsupported; - } - if (absl::EqualsIgnoreCase(format.name, cricket::kVp8CodecName)) { - if (!VP8SupportsScalabilityMode(*scalability_mode)) { - return kUnsupported; - } - } else if (absl::EqualsIgnoreCase(format.name, cricket::kVp9CodecName)) { - if (!VP9Encoder::SupportsScalabilityMode(*scalability_mode)) { - return kUnsupported; - } - } else if (absl::EqualsIgnoreCase(format.name, cricket::kH264CodecName)) { - if (!H264Encoder::SupportsScalabilityMode(*scalability_mode)) { - return kUnsupported; - } - } else if (kIsLibaomAv1EncoderSupported && - absl::EqualsIgnoreCase(format.name, cricket::kAv1CodecName)) { - if (!LibaomAv1EncoderSupportsScalabilityMode(*scalability_mode)) { - return kUnsupported; - } - } else { - return kUnsupported; - } - } - - return {.is_supported = format.IsCodecInList(GetSupportedFormats())}; + absl::optional scalability_mode) const { + auto original_format = MatchOriginalFormat(format); + return original_format + ? Factory().QueryCodecSupport(*original_format, scalability_mode) + : VideoEncoderFactory::CodecSupport{.is_supported = false}; } } // namespace webrtc diff --git a/media/engine/internal_encoder_factory.h b/media/engine/internal_encoder_factory.h index e12810cd30..25480d088f 100644 --- a/media/engine/internal_encoder_factory.h +++ b/media/engine/internal_encoder_factory.h @@ -15,17 +15,12 @@ #include #include -#include "absl/types/optional.h" -#include "api/video_codecs/sdp_video_format.h" -#include "api/video_codecs/video_encoder.h" #include "api/video_codecs/video_encoder_factory.h" #include "rtc_base/system/rtc_export.h" namespace webrtc { - class RTC_EXPORT InternalEncoderFactory : public VideoEncoderFactory { public: - static std::vector SupportedFormats(); std::vector GetSupportedFormats() const override; CodecSupport QueryCodecSupport( const SdpVideoFormat& format, diff --git a/media/engine/internal_encoder_factory_unittest.cc b/media/engine/internal_encoder_factory_unittest.cc index c3a667e733..a1c90b8cf4 100644 --- a/media/engine/internal_encoder_factory_unittest.cc +++ b/media/engine/internal_encoder_factory_unittest.cc @@ -14,7 +14,6 @@ #include "api/video_codecs/video_encoder.h" #include "api/video_codecs/vp9_profile.h" #include "media/base/media_constants.h" -#include "modules/video_coding/codecs/av1/libaom_av1_encoder_supported.h" #include "test/gmock.h" #include "test/gtest.h" @@ -79,34 +78,6 @@ TEST(InternalEncoderFactoryTest, H264) { } } -TEST(InternalEncoderFactoryTest, Av1) { - InternalEncoderFactory factory; - if (kIsLibaomAv1EncoderSupported) { - EXPECT_THAT(factory.GetSupportedFormats(), - Contains(Field(&SdpVideoFormat::name, cricket::kAv1CodecName))); - EXPECT_TRUE( - factory.CreateVideoEncoder(SdpVideoFormat(cricket::kAv1CodecName))); - } else { - EXPECT_THAT( - factory.GetSupportedFormats(), - Not(Contains(Field(&SdpVideoFormat::name, cricket::kAv1CodecName)))); - } -} - -TEST(InternalEncoderFactoryTest, QueryCodecSupportNoScalabilityMode) { - InternalEncoderFactory factory; - EXPECT_THAT(factory.QueryCodecSupport(SdpVideoFormat(cricket::kVp8CodecName), - /*scalability_mode=*/absl::nullopt), - Support(kSupported)); - EXPECT_THAT(factory.QueryCodecSupport(SdpVideoFormat(cricket::kVp9CodecName), - /*scalability_mode=*/absl::nullopt), - Support(kVp9Enabled ? kSupported : kUnsupported)); - EXPECT_THAT( - factory.QueryCodecSupport(SdpVideoFormat(cricket::kAv1CodecName), - /*scalability_mode=*/absl::nullopt), - Support(kIsLibaomAv1EncoderSupported ? kSupported : kUnsupported)); -} - TEST(InternalEncoderFactoryTest, QueryCodecSupportWithScalabilityMode) { InternalEncoderFactory factory; // VP8 and VP9 supported for singles spatial layers. @@ -122,10 +93,6 @@ TEST(InternalEncoderFactoryTest, QueryCodecSupportWithScalabilityMode) { factory.QueryCodecSupport(SdpVideoFormat(cricket::kVp9CodecName), "L3T3"), Support(kVp9Enabled ? kSupported : kUnsupported)); - EXPECT_THAT( - factory.QueryCodecSupport(SdpVideoFormat(cricket::kAv1CodecName), "L2T1"), - Support(kIsLibaomAv1EncoderSupported ? kSupported : kUnsupported)); - // Invalid scalability modes even though VP8 and H264 are supported. EXPECT_THAT(factory.QueryCodecSupport(SdpVideoFormat(cricket::kH264CodecName), "L2T2"), @@ -135,5 +102,39 @@ TEST(InternalEncoderFactoryTest, QueryCodecSupportWithScalabilityMode) { Support(kUnsupported)); } +#if defined(RTC_USE_LIBAOM_AV1_ENCODER) +TEST(InternalEncoderFactoryTest, Av1) { + InternalEncoderFactory factory; + EXPECT_THAT(factory.GetSupportedFormats(), + Contains(Field(&SdpVideoFormat::name, cricket::kAv1CodecName))); + EXPECT_TRUE( + factory.CreateVideoEncoder(SdpVideoFormat(cricket::kAv1CodecName))); +} + +TEST(InternalEncoderFactoryTest, QueryCodecSupportNoScalabilityModeAv1) { + InternalEncoderFactory factory; + EXPECT_THAT(factory.QueryCodecSupport(SdpVideoFormat(cricket::kAv1CodecName), + /*scalability_mode=*/absl::nullopt), + Support(kSupported)); +} + +TEST(InternalEncoderFactoryTest, QueryCodecSupportNoScalabilityMode) { + InternalEncoderFactory factory; + EXPECT_THAT(factory.QueryCodecSupport(SdpVideoFormat(cricket::kVp8CodecName), + /*scalability_mode=*/absl::nullopt), + Support(kSupported)); + EXPECT_THAT(factory.QueryCodecSupport(SdpVideoFormat(cricket::kVp9CodecName), + /*scalability_mode=*/absl::nullopt), + Support(kVp9Enabled ? kSupported : kUnsupported)); +} + +TEST(InternalEncoderFactoryTest, QueryCodecSupportWithScalabilityModeAv1) { + InternalEncoderFactory factory; + EXPECT_THAT( + factory.QueryCodecSupport(SdpVideoFormat(cricket::kAv1CodecName), "L2T1"), + Support(kSupported)); +} +#endif // defined(RTC_USE_LIBAOM_AV1_ENCODER) + } // namespace } // namespace webrtc