Replace InternalVideoEncoderFactory implementation with VideoEncoderFactoryTemplate.
Bug: webrtc:13573 Change-Id: Iae649e7922a67f70c53d33f3b87ea62bb6a3490c Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/262812 Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Commit-Queue: Philip Eliasson <philipel@webrtc.org> Cr-Commit-Position: refs/heads/main@{#36940}
This commit is contained in:
@ -7,6 +7,7 @@
|
|||||||
# be found in the AUTHORS file in the root of the source tree.
|
# be found in the AUTHORS file in the root of the source tree.
|
||||||
|
|
||||||
import("//build/config/linux/pkg_config.gni")
|
import("//build/config/linux/pkg_config.gni")
|
||||||
|
import("//third_party/libaom/options.gni")
|
||||||
import("../webrtc.gni")
|
import("../webrtc.gni")
|
||||||
|
|
||||||
group("media") {
|
group("media") {
|
||||||
@ -208,24 +209,31 @@ rtc_library("rtc_internal_video_codecs") {
|
|||||||
"../api/video:video_rtp_headers",
|
"../api/video:video_rtp_headers",
|
||||||
"../api/video_codecs:rtc_software_fallback_wrappers",
|
"../api/video_codecs:rtc_software_fallback_wrappers",
|
||||||
"../api/video_codecs:video_codecs_api",
|
"../api/video_codecs:video_codecs_api",
|
||||||
|
"../api/video_codecs:video_encoder_factory_template",
|
||||||
|
"../api/video_codecs:video_encoder_factory_template_libaom_av1_adapter",
|
||||||
|
"../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:call_interfaces",
|
||||||
"../call:video_stream_api",
|
"../call:video_stream_api",
|
||||||
"../modules/video_coding:video_codec_interface",
|
"../modules/video_coding:video_codec_interface",
|
||||||
"../modules/video_coding:webrtc_h264",
|
"../modules/video_coding:webrtc_h264",
|
||||||
"../modules/video_coding:webrtc_multiplex",
|
"../modules/video_coding:webrtc_multiplex",
|
||||||
"../modules/video_coding:webrtc_vp8",
|
"../modules/video_coding:webrtc_vp8",
|
||||||
"../modules/video_coding:webrtc_vp8_scalability",
|
|
||||||
"../modules/video_coding:webrtc_vp9",
|
"../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_decoder",
|
||||||
"../modules/video_coding/codecs/av1:libaom_av1_encoder_if_supported",
|
|
||||||
"../modules/video_coding/svc:scalability_mode_util",
|
|
||||||
"../rtc_base:checks",
|
"../rtc_base:checks",
|
||||||
"../rtc_base:logging",
|
"../rtc_base:logging",
|
||||||
"../rtc_base/system:rtc_export",
|
"../rtc_base/system:rtc_export",
|
||||||
"../system_wrappers:field_trial",
|
"../system_wrappers:field_trial",
|
||||||
"../test:fake_video_codecs",
|
"../test:fake_video_codecs",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if (enable_libaom) {
|
||||||
|
defines += [ "RTC_USE_LIBAOM_AV1_ENCODER" ]
|
||||||
|
deps += [ "../modules/video_coding/codecs/av1:libaom_av1_encoder" ]
|
||||||
|
}
|
||||||
|
|
||||||
if (rtc_include_dav1d_in_internal_decoder_factory) {
|
if (rtc_include_dav1d_in_internal_decoder_factory) {
|
||||||
deps += [ "../modules/video_coding/codecs/av1:dav1d_decoder" ]
|
deps += [ "../modules/video_coding/codecs/av1:dav1d_decoder" ]
|
||||||
}
|
}
|
||||||
@ -616,7 +624,6 @@ if (rtc_include_tests) {
|
|||||||
"../modules/video_coding:webrtc_h264",
|
"../modules/video_coding:webrtc_h264",
|
||||||
"../modules/video_coding:webrtc_vp8",
|
"../modules/video_coding:webrtc_vp8",
|
||||||
"../modules/video_coding/codecs/av1:libaom_av1_decoder",
|
"../modules/video_coding/codecs/av1:libaom_av1_decoder",
|
||||||
"../modules/video_coding/codecs/av1:libaom_av1_encoder_if_supported",
|
|
||||||
"../p2p:p2p_test_utils",
|
"../p2p:p2p_test_utils",
|
||||||
"../rtc_base",
|
"../rtc_base",
|
||||||
"../rtc_base:byte_order",
|
"../rtc_base:byte_order",
|
||||||
@ -645,6 +652,11 @@ if (rtc_include_tests) {
|
|||||||
"../test:video_test_common",
|
"../test:video_test_common",
|
||||||
"../test/time_controller",
|
"../test/time_controller",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if (enable_libaom) {
|
||||||
|
defines += [ "RTC_USE_LIBAOM_AV1_ENCODER" ]
|
||||||
|
}
|
||||||
|
|
||||||
absl_deps = [
|
absl_deps = [
|
||||||
"//third_party/abseil-cpp/absl/algorithm:container",
|
"//third_party/abseil-cpp/absl/algorithm:container",
|
||||||
"//third_party/abseil-cpp/absl/memory",
|
"//third_party/abseil-cpp/absl/memory",
|
||||||
|
@ -10,92 +10,81 @@
|
|||||||
|
|
||||||
#include "media/engine/internal_encoder_factory.h"
|
#include "media/engine/internal_encoder_factory.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "absl/strings/match.h"
|
#include "absl/strings/match.h"
|
||||||
#include "api/video_codecs/sdp_video_format.h"
|
#include "api/video_codecs/video_encoder_factory.h"
|
||||||
#include "media/base/codec.h"
|
#include "api/video_codecs/video_encoder_factory_template.h"
|
||||||
#include "media/base/media_constants.h"
|
#if defined(RTC_USE_LIBAOM_AV1_ENCODER)
|
||||||
#include "modules/video_coding/codecs/av1/av1_svc_config.h"
|
#include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h" // nogncheck
|
||||||
#include "modules/video_coding/codecs/av1/libaom_av1_encoder_supported.h"
|
#endif
|
||||||
#include "modules/video_coding/codecs/h264/include/h264.h"
|
#include "api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h"
|
||||||
#include "modules/video_coding/codecs/vp8/include/vp8.h"
|
#include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h"
|
||||||
#include "modules/video_coding/codecs/vp8/vp8_scalability.h"
|
#if defined(WEBRTC_USE_H264)
|
||||||
#include "modules/video_coding/codecs/vp9/include/vp9.h"
|
#include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h" // nogncheck
|
||||||
#include "modules/video_coding/svc/scalability_mode_util.h"
|
#endif
|
||||||
#include "rtc_base/logging.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
namespace {
|
||||||
|
|
||||||
std::vector<SdpVideoFormat> InternalEncoderFactory::SupportedFormats() {
|
using Factory =
|
||||||
std::vector<SdpVideoFormat> supported_codecs;
|
VideoEncoderFactoryTemplate<webrtc::LibvpxVp8EncoderTemplateAdapter,
|
||||||
supported_codecs.push_back(SdpVideoFormat(cricket::kVp8CodecName));
|
#if defined(WEBRTC_USE_H264)
|
||||||
for (const webrtc::SdpVideoFormat& format : webrtc::SupportedVP9Codecs())
|
webrtc::OpenH264EncoderTemplateAdapter,
|
||||||
supported_codecs.push_back(format);
|
#endif
|
||||||
for (const webrtc::SdpVideoFormat& format : webrtc::SupportedH264Codecs())
|
#if defined(RTC_USE_LIBAOM_AV1_ENCODER)
|
||||||
supported_codecs.push_back(format);
|
webrtc::LibaomAv1EncoderTemplateAdapter,
|
||||||
if (kIsLibaomAv1EncoderSupported)
|
#endif
|
||||||
supported_codecs.push_back(SdpVideoFormat(cricket::kAv1CodecName));
|
webrtc::LibvpxVp9EncoderTemplateAdapter>;
|
||||||
return supported_codecs;
|
|
||||||
|
absl::optional<SdpVideoFormat> MatchOriginalFormat(
|
||||||
|
const SdpVideoFormat& format) {
|
||||||
|
const auto supported_formats = Factory().GetSupportedFormats();
|
||||||
|
|
||||||
|
absl::optional<SdpVideoFormat> 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<SdpVideoFormat> InternalEncoderFactory::GetSupportedFormats()
|
std::vector<SdpVideoFormat> InternalEncoderFactory::GetSupportedFormats()
|
||||||
const {
|
const {
|
||||||
return SupportedFormats();
|
return Factory().GetSupportedFormats();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<VideoEncoder> InternalEncoderFactory::CreateVideoEncoder(
|
std::unique_ptr<VideoEncoder> InternalEncoderFactory::CreateVideoEncoder(
|
||||||
const SdpVideoFormat& format) {
|
const SdpVideoFormat& format) {
|
||||||
if (absl::EqualsIgnoreCase(format.name, cricket::kVp8CodecName))
|
auto original_format = MatchOriginalFormat(format);
|
||||||
return VP8Encoder::Create();
|
return original_format ? Factory().CreateVideoEncoder(*original_format)
|
||||||
if (absl::EqualsIgnoreCase(format.name, cricket::kVp9CodecName))
|
: nullptr;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoEncoderFactory::CodecSupport InternalEncoderFactory::QueryCodecSupport(
|
VideoEncoderFactory::CodecSupport InternalEncoderFactory::QueryCodecSupport(
|
||||||
const SdpVideoFormat& format,
|
const SdpVideoFormat& format,
|
||||||
absl::optional<std::string> scalability_mode_string) const {
|
absl::optional<std::string> scalability_mode) const {
|
||||||
// Query for supported formats and check if the specified format is supported.
|
auto original_format = MatchOriginalFormat(format);
|
||||||
// Begin with filtering out unsupported scalability modes.
|
return original_format
|
||||||
if (scalability_mode_string) {
|
? Factory().QueryCodecSupport(*original_format, scalability_mode)
|
||||||
static constexpr VideoEncoderFactory::CodecSupport kUnsupported = {
|
: VideoEncoderFactory::CodecSupport{.is_supported = false};
|
||||||
.is_supported = false, .is_power_efficient = false};
|
|
||||||
absl::optional<ScalabilityMode> 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())};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -15,17 +15,12 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#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 "api/video_codecs/video_encoder_factory.h"
|
||||||
#include "rtc_base/system/rtc_export.h"
|
#include "rtc_base/system/rtc_export.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
class RTC_EXPORT InternalEncoderFactory : public VideoEncoderFactory {
|
class RTC_EXPORT InternalEncoderFactory : public VideoEncoderFactory {
|
||||||
public:
|
public:
|
||||||
static std::vector<SdpVideoFormat> SupportedFormats();
|
|
||||||
std::vector<SdpVideoFormat> GetSupportedFormats() const override;
|
std::vector<SdpVideoFormat> GetSupportedFormats() const override;
|
||||||
CodecSupport QueryCodecSupport(
|
CodecSupport QueryCodecSupport(
|
||||||
const SdpVideoFormat& format,
|
const SdpVideoFormat& format,
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
#include "api/video_codecs/video_encoder.h"
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "api/video_codecs/vp9_profile.h"
|
#include "api/video_codecs/vp9_profile.h"
|
||||||
#include "media/base/media_constants.h"
|
#include "media/base/media_constants.h"
|
||||||
#include "modules/video_coding/codecs/av1/libaom_av1_encoder_supported.h"
|
|
||||||
#include "test/gmock.h"
|
#include "test/gmock.h"
|
||||||
#include "test/gtest.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) {
|
TEST(InternalEncoderFactoryTest, QueryCodecSupportWithScalabilityMode) {
|
||||||
InternalEncoderFactory factory;
|
InternalEncoderFactory factory;
|
||||||
// VP8 and VP9 supported for singles spatial layers.
|
// VP8 and VP9 supported for singles spatial layers.
|
||||||
@ -122,10 +93,6 @@ TEST(InternalEncoderFactoryTest, QueryCodecSupportWithScalabilityMode) {
|
|||||||
factory.QueryCodecSupport(SdpVideoFormat(cricket::kVp9CodecName), "L3T3"),
|
factory.QueryCodecSupport(SdpVideoFormat(cricket::kVp9CodecName), "L3T3"),
|
||||||
Support(kVp9Enabled ? kSupported : kUnsupported));
|
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.
|
// Invalid scalability modes even though VP8 and H264 are supported.
|
||||||
EXPECT_THAT(factory.QueryCodecSupport(SdpVideoFormat(cricket::kH264CodecName),
|
EXPECT_THAT(factory.QueryCodecSupport(SdpVideoFormat(cricket::kH264CodecName),
|
||||||
"L2T2"),
|
"L2T2"),
|
||||||
@ -135,5 +102,39 @@ TEST(InternalEncoderFactoryTest, QueryCodecSupportWithScalabilityMode) {
|
|||||||
Support(kUnsupported));
|
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
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
Reference in New Issue
Block a user