Add factory functions to pass Environment to VideoEncoders
Bug: webrtc:15860 Change-Id: I4a9d2678dcfe5b0f178863242e27600fcc95325d Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/342480 Reviewed-by: Philip Eliasson <philipel@webrtc.org> Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/main@{#41879}
This commit is contained in:
parent
83d29d5988
commit
b4913a549f
@ -474,6 +474,7 @@ rtc_library("webrtc_h264") {
|
||||
deps = [
|
||||
":video_codec_interface",
|
||||
":video_coding_utility",
|
||||
"../../api/environment",
|
||||
"../../api/transport/rtp:dependency_descriptor",
|
||||
"../../api/video:video_codec_constants",
|
||||
"../../api/video:video_frame",
|
||||
@ -497,6 +498,7 @@ rtc_library("webrtc_h264") {
|
||||
"//third_party/libyuv",
|
||||
]
|
||||
absl_deps = [
|
||||
"//third_party/abseil-cpp/absl/base:nullability",
|
||||
"//third_party/abseil-cpp/absl/container:inlined_vector",
|
||||
"//third_party/abseil-cpp/absl/strings",
|
||||
"//third_party/abseil-cpp/absl/types:optional",
|
||||
@ -584,6 +586,7 @@ rtc_library("webrtc_vp8") {
|
||||
]
|
||||
absl_deps = [
|
||||
"//third_party/abseil-cpp/absl/algorithm:container",
|
||||
"//third_party/abseil-cpp/absl/base:nullability",
|
||||
"//third_party/abseil-cpp/absl/strings:strings",
|
||||
"//third_party/abseil-cpp/absl/types:optional",
|
||||
]
|
||||
@ -679,6 +682,7 @@ rtc_library("webrtc_vp9") {
|
||||
"../../api:field_trials_view",
|
||||
"../../api:refcountedbase",
|
||||
"../../api:scoped_refptr",
|
||||
"../../api/environment",
|
||||
"../../api/transport:field_trial_based_config",
|
||||
"../../api/video:video_frame",
|
||||
"../../api/video:video_frame_i010",
|
||||
@ -700,7 +704,6 @@ rtc_library("webrtc_vp9") {
|
||||
"../../rtc_base/experiments:field_trial_parser",
|
||||
"../../rtc_base/experiments:rate_control_settings",
|
||||
"../../rtc_base/synchronization:mutex",
|
||||
"../../system_wrappers:field_trial",
|
||||
"../rtp_rtcp:rtp_rtcp_format",
|
||||
"svc:scalability_mode_util",
|
||||
"svc:scalability_structures",
|
||||
@ -710,6 +713,7 @@ rtc_library("webrtc_vp9") {
|
||||
]
|
||||
absl_deps = [
|
||||
"//third_party/abseil-cpp/absl/algorithm:container",
|
||||
"//third_party/abseil-cpp/absl/base:nullability",
|
||||
"//third_party/abseil-cpp/absl/container:inlined_vector",
|
||||
"//third_party/abseil-cpp/absl/memory",
|
||||
"//third_party/abseil-cpp/absl/strings:strings",
|
||||
@ -829,6 +833,8 @@ if (rtc_include_tests) {
|
||||
"../../api:scoped_refptr",
|
||||
"../../api:sequence_checker",
|
||||
"../../api:videocodec_test_fixture_api",
|
||||
"../../api/environment",
|
||||
"../../api/environment:environment_factory",
|
||||
"../../api/numerics:numerics",
|
||||
"../../api/task_queue",
|
||||
"../../api/task_queue:default_task_queue_factory",
|
||||
@ -1080,6 +1086,7 @@ if (rtc_include_tests) {
|
||||
"../../test:explicit_key_value_config",
|
||||
"../../test:field_trial",
|
||||
"../../test:fileutils",
|
||||
"../../test:scoped_key_value_config",
|
||||
"../../test:test_support",
|
||||
"../../test:video_test_common",
|
||||
"../rtp_rtcp:rtp_rtcp_format",
|
||||
|
||||
@ -56,6 +56,7 @@ rtc_library("libaom_av1_encoder") {
|
||||
"../..:video_codec_interface",
|
||||
"../../../../api:field_trials_view",
|
||||
"../../../../api:scoped_refptr",
|
||||
"../../../../api/environment",
|
||||
"../../../../api/transport:field_trial_based_config",
|
||||
"../../../../api/video:encoded_image",
|
||||
"../../../../api/video:video_frame",
|
||||
@ -73,6 +74,7 @@ rtc_library("libaom_av1_encoder") {
|
||||
absl_deps = [
|
||||
"//third_party/abseil-cpp/absl/algorithm:container",
|
||||
"//third_party/abseil-cpp/absl/base:core_headers",
|
||||
"//third_party/abseil-cpp/absl/base:nullability",
|
||||
"//third_party/abseil-cpp/absl/strings:strings",
|
||||
"//third_party/abseil-cpp/absl/types:optional",
|
||||
]
|
||||
@ -102,10 +104,12 @@ if (rtc_include_tests) {
|
||||
"../../../../api:create_frame_generator",
|
||||
"../../../../api:frame_generator_api",
|
||||
"../../../../api:mock_video_encoder",
|
||||
"../../../../api/environment",
|
||||
"../../../../api/environment:environment_factory",
|
||||
"../../../../api/units:data_size",
|
||||
"../../../../api/units:time_delta",
|
||||
"../../../../api/video:video_frame",
|
||||
"../../../../test:field_trial",
|
||||
"../../../../test:scoped_key_value_config",
|
||||
"../../svc:scalability_mode_util",
|
||||
"../../svc:scalability_structures",
|
||||
"../../svc:scalable_video_controller",
|
||||
|
||||
@ -18,8 +18,10 @@
|
||||
|
||||
#include "absl/algorithm/container.h"
|
||||
#include "absl/base/macros.h"
|
||||
#include "absl/base/nullability.h"
|
||||
#include "absl/strings/match.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/environment/environment.h"
|
||||
#include "api/field_trials_view.h"
|
||||
#include "api/scoped_refptr.h"
|
||||
#include "api/transport/field_trial_based_config.h"
|
||||
@ -872,6 +874,17 @@ VideoEncoder::EncoderInfo LibaomAv1Encoder::GetEncoderInfo() const {
|
||||
|
||||
} // namespace
|
||||
|
||||
absl::Nonnull<std::unique_ptr<VideoEncoder>> CreateLibaomAv1Encoder(
|
||||
const Environment& env,
|
||||
LibaomAv1EncoderSettings settings) {
|
||||
if (settings.max_pixel_count_to_cpu_speed.empty()) {
|
||||
return std::make_unique<LibaomAv1Encoder>(absl::nullopt,
|
||||
env.field_trials());
|
||||
} else {
|
||||
return std::make_unique<LibaomAv1Encoder>(settings, env.field_trials());
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<VideoEncoder> CreateLibaomAv1Encoder() {
|
||||
return std::make_unique<LibaomAv1Encoder>(absl::nullopt,
|
||||
FieldTrialBasedConfig());
|
||||
|
||||
@ -13,15 +13,22 @@
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/base/nullability.h"
|
||||
#include "api/environment/environment.h"
|
||||
#include "api/video_codecs/video_encoder.h"
|
||||
|
||||
namespace webrtc {
|
||||
struct LibaomAv1EncoderAuxConfig {
|
||||
|
||||
struct LibaomAv1EncoderSettings {
|
||||
// A map of max pixel count --> cpu speed.
|
||||
std::map<int, int> max_pixel_count_to_cpu_speed;
|
||||
};
|
||||
absl::Nonnull<std::unique_ptr<VideoEncoder>> CreateLibaomAv1Encoder(
|
||||
const Environment& env,
|
||||
LibaomAv1EncoderSettings settings = {});
|
||||
|
||||
// Deprecated, Use CreateLibaomAv1Encoder above, bugs.webrtc.org/15860
|
||||
using LibaomAv1EncoderAuxConfig = LibaomAv1EncoderSettings;
|
||||
std::unique_ptr<VideoEncoder> CreateLibaomAv1Encoder();
|
||||
std::unique_ptr<VideoEncoder> CreateLibaomAv1Encoder(
|
||||
const LibaomAv1EncoderAuxConfig& aux_config);
|
||||
|
||||
@ -12,22 +12,26 @@
|
||||
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/environment/environment.h"
|
||||
#include "api/environment/environment_factory.h"
|
||||
#include "api/test/create_frame_generator.h"
|
||||
#include "api/test/frame_generator_interface.h"
|
||||
#include "api/video_codecs/video_codec.h"
|
||||
#include "api/video_codecs/video_encoder.h"
|
||||
#include "modules/video_coding/codecs/test/encoded_video_frame_producer.h"
|
||||
#include "modules/video_coding/include/video_error_codes.h"
|
||||
#include "test/field_trial.h"
|
||||
#include "test/gmock.h"
|
||||
#include "test/gtest.h"
|
||||
#include "test/scoped_key_value_config.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace {
|
||||
|
||||
using test::ScopedKeyValueConfig;
|
||||
using ::testing::ElementsAre;
|
||||
using ::testing::Eq;
|
||||
using ::testing::Field;
|
||||
@ -52,12 +56,14 @@ VideoEncoder::Settings DefaultEncoderSettings() {
|
||||
}
|
||||
|
||||
TEST(LibaomAv1EncoderTest, CanCreate) {
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
|
||||
std::unique_ptr<VideoEncoder> encoder =
|
||||
CreateLibaomAv1Encoder(CreateEnvironment());
|
||||
EXPECT_TRUE(encoder);
|
||||
}
|
||||
|
||||
TEST(LibaomAv1EncoderTest, InitAndRelease) {
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
|
||||
std::unique_ptr<VideoEncoder> encoder =
|
||||
CreateLibaomAv1Encoder(CreateEnvironment());
|
||||
ASSERT_TRUE(encoder);
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
EXPECT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
|
||||
@ -67,7 +73,8 @@ TEST(LibaomAv1EncoderTest, InitAndRelease) {
|
||||
|
||||
TEST(LibaomAv1EncoderTest, NoBitrateOnTopLayerRefecltedInActiveDecodeTargets) {
|
||||
// Configure encoder with 2 temporal layers.
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
|
||||
std::unique_ptr<VideoEncoder> encoder =
|
||||
CreateLibaomAv1Encoder(CreateEnvironment());
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
codec_settings.SetScalabilityMode(ScalabilityMode::kL1T2);
|
||||
ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
|
||||
@ -93,7 +100,8 @@ TEST(LibaomAv1EncoderTest, NoBitrateOnTopLayerRefecltedInActiveDecodeTargets) {
|
||||
|
||||
TEST(LibaomAv1EncoderTest,
|
||||
SpatialScalabilityInTemporalUnitReportedAsDeltaFrame) {
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
|
||||
std::unique_ptr<VideoEncoder> encoder =
|
||||
CreateLibaomAv1Encoder(CreateEnvironment());
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
codec_settings.SetScalabilityMode(ScalabilityMode::kL2T1);
|
||||
ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
|
||||
@ -115,7 +123,8 @@ TEST(LibaomAv1EncoderTest,
|
||||
}
|
||||
|
||||
TEST(LibaomAv1EncoderTest, NoBitrateOnTopSpatialLayerProduceDeltaFrames) {
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
|
||||
std::unique_ptr<VideoEncoder> encoder =
|
||||
CreateLibaomAv1Encoder(CreateEnvironment());
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
codec_settings.SetScalabilityMode(ScalabilityMode::kL2T1);
|
||||
ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
|
||||
@ -142,7 +151,8 @@ TEST(LibaomAv1EncoderTest, SetsEndOfPictureForLastFrameInTemporalUnit) {
|
||||
allocation.SetBitrate(1, 0, 40000);
|
||||
allocation.SetBitrate(2, 0, 30000);
|
||||
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
|
||||
std::unique_ptr<VideoEncoder> encoder =
|
||||
CreateLibaomAv1Encoder(CreateEnvironment());
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
// Configure encoder with 3 spatial layers.
|
||||
codec_settings.SetScalabilityMode(ScalabilityMode::kL3T1);
|
||||
@ -169,7 +179,8 @@ TEST(LibaomAv1EncoderTest, CheckOddDimensionsWithSpatialLayers) {
|
||||
allocation.SetBitrate(0, 0, 30000);
|
||||
allocation.SetBitrate(1, 0, 40000);
|
||||
allocation.SetBitrate(2, 0, 30000);
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
|
||||
std::unique_ptr<VideoEncoder> encoder =
|
||||
CreateLibaomAv1Encoder(CreateEnvironment());
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
// Configure encoder with 3 spatial layers.
|
||||
codec_settings.SetScalabilityMode(ScalabilityMode::kL3T1);
|
||||
@ -189,11 +200,12 @@ TEST(LibaomAv1EncoderTest, CheckOddDimensionsWithSpatialLayers) {
|
||||
}
|
||||
|
||||
TEST(LibaomAv1EncoderTest, WithMaximumConsecutiveFrameDrop) {
|
||||
test::ScopedFieldTrials field_trials(
|
||||
auto field_trials = std::make_unique<ScopedKeyValueConfig>(
|
||||
"WebRTC-LibaomAv1Encoder-MaxConsecFrameDrop/maxdrop:2/");
|
||||
const Environment env = CreateEnvironment(std::move(field_trials));
|
||||
VideoBitrateAllocation allocation;
|
||||
allocation.SetBitrate(0, 0, 1000); // some very low bitrate
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder(env);
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
codec_settings.SetFrameDropEnabled(true);
|
||||
codec_settings.SetScalabilityMode(ScalabilityMode::kL1T1);
|
||||
@ -214,18 +226,20 @@ TEST(LibaomAv1EncoderTest, WithMaximumConsecutiveFrameDrop) {
|
||||
}
|
||||
|
||||
TEST(LibaomAv1EncoderTest, EncoderInfoWithoutResolutionBitrateLimits) {
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
|
||||
std::unique_ptr<VideoEncoder> encoder =
|
||||
CreateLibaomAv1Encoder(CreateEnvironment());
|
||||
EXPECT_TRUE(encoder->GetEncoderInfo().resolution_bitrate_limits.empty());
|
||||
}
|
||||
|
||||
TEST(LibaomAv1EncoderTest, EncoderInfoWithBitrateLimitsFromFieldTrial) {
|
||||
test::ScopedFieldTrials field_trials(
|
||||
auto field_trials = std::make_unique<ScopedKeyValueConfig>(
|
||||
"WebRTC-Av1-GetEncoderInfoOverride/"
|
||||
"frame_size_pixels:123|456|789,"
|
||||
"min_start_bitrate_bps:11000|22000|33000,"
|
||||
"min_bitrate_bps:44000|55000|66000,"
|
||||
"max_bitrate_bps:77000|88000|99000/");
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
|
||||
const Environment env = CreateEnvironment(std::move(field_trials));
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder(env);
|
||||
|
||||
EXPECT_THAT(
|
||||
encoder->GetEncoderInfo().resolution_bitrate_limits,
|
||||
@ -236,7 +250,8 @@ TEST(LibaomAv1EncoderTest, EncoderInfoWithBitrateLimitsFromFieldTrial) {
|
||||
}
|
||||
|
||||
TEST(LibaomAv1EncoderTest, EncoderInfoProvidesFpsAllocation) {
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
|
||||
std::unique_ptr<VideoEncoder> encoder =
|
||||
CreateLibaomAv1Encoder(CreateEnvironment());
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
codec_settings.SetScalabilityMode(ScalabilityMode::kL3T3);
|
||||
codec_settings.maxFramerate = 60;
|
||||
@ -258,7 +273,8 @@ TEST(LibaomAv1EncoderTest, PopulatesEncodedFrameSize) {
|
||||
allocation.SetBitrate(0, 0, 30000);
|
||||
allocation.SetBitrate(1, 0, 40000);
|
||||
allocation.SetBitrate(2, 0, 30000);
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
|
||||
std::unique_ptr<VideoEncoder> encoder =
|
||||
CreateLibaomAv1Encoder(CreateEnvironment());
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
codec_settings.startBitrate = allocation.get_sum_kbps();
|
||||
ASSERT_GT(codec_settings.width, 4);
|
||||
@ -291,7 +307,8 @@ TEST(LibaomAv1EncoderTest, PopulatesEncodedFrameSize) {
|
||||
}
|
||||
|
||||
TEST(LibaomAv1EncoderTest, RtpTimestampWrap) {
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
|
||||
std::unique_ptr<VideoEncoder> encoder =
|
||||
CreateLibaomAv1Encoder(CreateEnvironment());
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
codec_settings.SetScalabilityMode(ScalabilityMode::kL1T1);
|
||||
ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
|
||||
@ -315,7 +332,8 @@ TEST(LibaomAv1EncoderTest, RtpTimestampWrap) {
|
||||
}
|
||||
|
||||
TEST(LibaomAv1EncoderTest, TestCaptureTimeId) {
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
|
||||
std::unique_ptr<VideoEncoder> encoder =
|
||||
CreateLibaomAv1Encoder(CreateEnvironment());
|
||||
const Timestamp capture_time_id = Timestamp::Micros(2000);
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
codec_settings.SetScalabilityMode(ScalabilityMode::kL2T1);
|
||||
@ -347,7 +365,8 @@ TEST(LibaomAv1EncoderTest, TestCaptureTimeId) {
|
||||
}
|
||||
|
||||
TEST(LibaomAv1EncoderTest, AdheresToTargetBitrateDespiteUnevenFrameTiming) {
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
|
||||
std::unique_ptr<VideoEncoder> encoder =
|
||||
CreateLibaomAv1Encoder(CreateEnvironment());
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
codec_settings.SetScalabilityMode(ScalabilityMode::kL1T1);
|
||||
codec_settings.startBitrate = 300; // kbps
|
||||
@ -425,7 +444,8 @@ TEST(LibaomAv1EncoderTest, AdheresToTargetBitrateDespiteUnevenFrameTiming) {
|
||||
}
|
||||
|
||||
TEST(LibaomAv1EncoderTest, DisableAutomaticResize) {
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
|
||||
std::unique_ptr<VideoEncoder> encoder =
|
||||
CreateLibaomAv1Encoder(CreateEnvironment());
|
||||
ASSERT_TRUE(encoder);
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
codec_settings.AV1()->automatic_resize_on = false;
|
||||
|
||||
@ -18,6 +18,8 @@
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/environment/environment.h"
|
||||
#include "api/environment/environment_factory.h"
|
||||
#include "api/units/data_size.h"
|
||||
#include "api/units/time_delta.h"
|
||||
#include "api/video_codecs/video_codec.h"
|
||||
@ -134,8 +136,9 @@ class TestAv1Decoder {
|
||||
};
|
||||
|
||||
TEST(LibaomAv1Test, EncodeDecode) {
|
||||
const Environment env = CreateEnvironment();
|
||||
TestAv1Decoder decoder(0);
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder(env);
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
|
||||
WEBRTC_VIDEO_CODEC_OK);
|
||||
@ -216,7 +219,8 @@ TEST_P(LibaomAv1SvcTest, EncodeAndDecodeAllDecodeTargets) {
|
||||
size_t num_decode_targets =
|
||||
svc_controller->DependencyStructure().num_decode_targets;
|
||||
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
|
||||
std::unique_ptr<VideoEncoder> encoder =
|
||||
CreateLibaomAv1Encoder(CreateEnvironment());
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
codec_settings.SetScalabilityMode(GetParam().GetScalabilityMode());
|
||||
ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
|
||||
@ -287,7 +291,8 @@ TEST_P(LibaomAv1SvcTest, SetRatesMatchMeasuredBitrate) {
|
||||
kv.second.bps());
|
||||
}
|
||||
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
|
||||
std::unique_ptr<VideoEncoder> encoder =
|
||||
CreateLibaomAv1Encoder(CreateEnvironment());
|
||||
ASSERT_TRUE(encoder);
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
codec_settings.SetScalabilityMode(param.GetScalabilityMode());
|
||||
|
||||
@ -121,6 +121,18 @@ std::vector<SdpVideoFormat> SupportedH264DecoderCodecs() {
|
||||
return supportedCodecs;
|
||||
}
|
||||
|
||||
absl::Nonnull<std::unique_ptr<VideoEncoder>> CreateH264Encoder(
|
||||
const Environment& env,
|
||||
H264EncoderSettings settings) {
|
||||
#if defined(WEBRTC_USE_H264)
|
||||
RTC_CHECK(g_rtc_use_h264);
|
||||
RTC_LOG(LS_INFO) << "Creating H264EncoderImpl.";
|
||||
return std::make_unique<H264EncoderImpl>(env, settings);
|
||||
#else
|
||||
RTC_CHECK_NOTREACHED();
|
||||
#endif
|
||||
}
|
||||
|
||||
std::unique_ptr<H264Encoder> H264Encoder::Create() {
|
||||
return Create(cricket::CreateVideoCodec(cricket::kH264CodecName));
|
||||
}
|
||||
|
||||
@ -170,20 +170,31 @@ static void RtpFragmentize(EncodedImage* encoded_image, SFrameBSInfo* info) {
|
||||
}
|
||||
}
|
||||
|
||||
H264EncoderImpl::H264EncoderImpl(const Environment& env,
|
||||
H264EncoderSettings settings)
|
||||
: H264EncoderImpl(settings.packetization_mode) {}
|
||||
|
||||
H264EncoderImpl::H264EncoderImpl(const cricket::VideoCodec& codec)
|
||||
: packetization_mode_(H264PacketizationMode::SingleNalUnit),
|
||||
: H264EncoderImpl([&] {
|
||||
std::string packetization_mode_string;
|
||||
if (codec.GetParam(cricket::kH264FmtpPacketizationMode,
|
||||
&packetization_mode_string) &&
|
||||
packetization_mode_string == "1") {
|
||||
return H264PacketizationMode::NonInterleaved;
|
||||
} else {
|
||||
return H264PacketizationMode::SingleNalUnit;
|
||||
}
|
||||
}()) {
|
||||
RTC_CHECK(absl::EqualsIgnoreCase(codec.name, cricket::kH264CodecName));
|
||||
}
|
||||
|
||||
H264EncoderImpl::H264EncoderImpl(H264PacketizationMode packetization_mode)
|
||||
: packetization_mode_(packetization_mode),
|
||||
max_payload_size_(0),
|
||||
number_of_cores_(0),
|
||||
encoded_image_callback_(nullptr),
|
||||
has_reported_init_(false),
|
||||
has_reported_error_(false) {
|
||||
RTC_CHECK(absl::EqualsIgnoreCase(codec.name, cricket::kH264CodecName));
|
||||
std::string packetization_mode_string;
|
||||
if (codec.GetParam(cricket::kH264FmtpPacketizationMode,
|
||||
&packetization_mode_string) &&
|
||||
packetization_mode_string == "1") {
|
||||
packetization_mode_ = H264PacketizationMode::NonInterleaved;
|
||||
}
|
||||
downscaled_buffers_.reserve(kMaxSimulcastStreams - 1);
|
||||
encoded_images_.reserve(kMaxSimulcastStreams);
|
||||
encoders_.reserve(kMaxSimulcastStreams);
|
||||
|
||||
@ -58,7 +58,9 @@ class H264EncoderImpl : public H264Encoder {
|
||||
void SetStreamState(bool send_stream);
|
||||
};
|
||||
|
||||
public:
|
||||
H264EncoderImpl(const Environment& env, H264EncoderSettings settings);
|
||||
|
||||
// Deprecated, bugs.webrtc.org/15860
|
||||
explicit H264EncoderImpl(const cricket::VideoCodec& codec);
|
||||
~H264EncoderImpl() override;
|
||||
|
||||
@ -90,6 +92,8 @@ class H264EncoderImpl : public H264Encoder {
|
||||
}
|
||||
|
||||
private:
|
||||
explicit H264EncoderImpl(H264PacketizationMode packetization_mode);
|
||||
|
||||
SEncParamExt CreateEncoderParams(size_t i) const;
|
||||
|
||||
webrtc::H264BitstreamParser h264_bitstream_parser_;
|
||||
|
||||
@ -16,8 +16,11 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/base/nullability.h"
|
||||
#include "api/environment/environment.h"
|
||||
#include "api/video_codecs/h264_profile_level_id.h"
|
||||
#include "api/video_codecs/scalability_mode.h"
|
||||
#include "api/video_codecs/video_encoder.h"
|
||||
#include "media/base/codec.h"
|
||||
#include "modules/video_coding/include/video_codec_interface.h"
|
||||
#include "rtc_base/system/rtc_export.h"
|
||||
@ -60,6 +63,14 @@ class RTC_EXPORT H264Encoder : public VideoEncoder {
|
||||
~H264Encoder() override {}
|
||||
};
|
||||
|
||||
struct H264EncoderSettings {
|
||||
H264PacketizationMode packetization_mode =
|
||||
H264PacketizationMode::NonInterleaved;
|
||||
};
|
||||
absl::Nonnull<std::unique_ptr<VideoEncoder>> CreateH264Encoder(
|
||||
const Environment& env,
|
||||
H264EncoderSettings settings = {});
|
||||
|
||||
class RTC_EXPORT H264Decoder : public VideoDecoder {
|
||||
public:
|
||||
static std::unique_ptr<H264Decoder> Create();
|
||||
|
||||
@ -34,7 +34,7 @@ namespace webrtc {
|
||||
class TestH264Impl : public VideoCodecUnitTest {
|
||||
protected:
|
||||
std::unique_ptr<VideoEncoder> CreateEncoder() override {
|
||||
return H264Encoder::Create();
|
||||
return CreateH264Encoder(env_);
|
||||
}
|
||||
|
||||
std::unique_ptr<VideoDecoder> CreateDecoder() override {
|
||||
|
||||
@ -14,6 +14,8 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "api/environment/environment.h"
|
||||
#include "api/environment/environment_factory.h"
|
||||
#include "api/test/frame_generator_interface.h"
|
||||
#include "api/video_codecs/video_decoder.h"
|
||||
#include "api/video_codecs/video_encoder.h"
|
||||
@ -30,7 +32,8 @@ namespace webrtc {
|
||||
class VideoCodecUnitTest : public ::testing::Test {
|
||||
public:
|
||||
VideoCodecUnitTest()
|
||||
: encode_complete_callback_(this),
|
||||
: env_(CreateEnvironment()),
|
||||
encode_complete_callback_(this),
|
||||
decode_complete_callback_(this),
|
||||
wait_for_encoded_frames_threshold_(1),
|
||||
last_input_frame_timestamp_(0) {}
|
||||
@ -96,6 +99,7 @@ class VideoCodecUnitTest : public ::testing::Test {
|
||||
|
||||
size_t GetNumEncodedFrames();
|
||||
|
||||
const Environment env_;
|
||||
VideoCodec codec_settings_;
|
||||
|
||||
std::unique_ptr<VideoEncoder> encoder_;
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/base/nullability.h"
|
||||
#include "api/environment/environment.h"
|
||||
#include "api/video_codecs/video_encoder.h"
|
||||
#include "api/video_codecs/vp8_frame_buffer_controller.h"
|
||||
@ -21,21 +22,25 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// TODO(brandtr): Move these interfaces to the api/ folder.
|
||||
class VP8Encoder {
|
||||
public:
|
||||
struct Settings {
|
||||
struct Vp8EncoderSettings {
|
||||
// Allows for overriding the Vp8FrameBufferController used by the encoder.
|
||||
// If unset, a default Vp8FrameBufferController will be instantiated
|
||||
// internally.
|
||||
std::unique_ptr<Vp8FrameBufferControllerFactory>
|
||||
frame_buffer_controller_factory = nullptr;
|
||||
absl::Nullable<std::unique_ptr<Vp8FrameBufferControllerFactory>>
|
||||
frame_buffer_controller_factory;
|
||||
|
||||
// Allows for overriding the resolution/bitrate limits exposed through
|
||||
// VideoEncoder::GetEncoderInfo(). No override is done if empty.
|
||||
std::vector<VideoEncoder::ResolutionBitrateLimits>
|
||||
resolution_bitrate_limits = {};
|
||||
};
|
||||
std::vector<VideoEncoder::ResolutionBitrateLimits> resolution_bitrate_limits;
|
||||
};
|
||||
absl::Nonnull<std::unique_ptr<VideoEncoder>> CreateVp8Encoder(
|
||||
const Environment& env,
|
||||
Vp8EncoderSettings settings = {});
|
||||
|
||||
// Deprecated, use CreateVp8Encoder above, bugs.webrtc.org/15860
|
||||
class VP8Encoder {
|
||||
public:
|
||||
using Settings = Vp8EncoderSettings;
|
||||
|
||||
static std::unique_ptr<VideoEncoder> Create();
|
||||
static std::unique_ptr<VideoEncoder> Create(Settings settings);
|
||||
|
||||
@ -264,6 +264,12 @@ absl::optional<TimeDelta> ParseFrameDropInterval() {
|
||||
|
||||
} // namespace
|
||||
|
||||
std::unique_ptr<VideoEncoder> CreateVp8Encoder(const Environment& env,
|
||||
Vp8EncoderSettings settings) {
|
||||
return std::make_unique<LibvpxVp8Encoder>(env, std::move(settings),
|
||||
LibvpxInterface::Create());
|
||||
}
|
||||
|
||||
std::unique_ptr<VideoEncoder> VP8Encoder::Create() {
|
||||
return std::make_unique<LibvpxVp8Encoder>(LibvpxInterface::Create(),
|
||||
VP8Encoder::Settings());
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "api/fec_controller_override.h"
|
||||
@ -38,6 +39,14 @@ namespace webrtc {
|
||||
|
||||
class LibvpxVp8Encoder : public VideoEncoder {
|
||||
public:
|
||||
LibvpxVp8Encoder(const Environment& env,
|
||||
Vp8EncoderSettings settings,
|
||||
std::unique_ptr<LibvpxInterface> interface)
|
||||
// TODO: bugs.webrtc.org/15860 - Save `env` and use field trials from it
|
||||
// when constructor below can be removed.
|
||||
: LibvpxVp8Encoder(std::move(interface), std::move(settings)) {}
|
||||
|
||||
// Deprecated, bugs.webrtc.org/15860
|
||||
LibvpxVp8Encoder(std::unique_ptr<LibvpxInterface> interface,
|
||||
VP8Encoder::Settings settings);
|
||||
~LibvpxVp8Encoder() override;
|
||||
|
||||
@ -67,11 +67,11 @@ const VideoEncoder::Settings kSettings(kCapabilities,
|
||||
class TestVp8Impl : public VideoCodecUnitTest {
|
||||
protected:
|
||||
std::unique_ptr<VideoEncoder> CreateEncoder() override {
|
||||
return VP8Encoder::Create();
|
||||
return CreateVp8Encoder(env_);
|
||||
}
|
||||
|
||||
std::unique_ptr<VideoDecoder> CreateDecoder() override {
|
||||
return CreateVp8Decoder(CreateEnvironment());
|
||||
return CreateVp8Decoder(env_);
|
||||
}
|
||||
|
||||
void ModifyCodecSettings(VideoCodec* codec_settings) override {
|
||||
|
||||
@ -15,8 +15,12 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/base/nullability.h"
|
||||
#include "api/environment/environment.h"
|
||||
#include "api/video_codecs/scalability_mode.h"
|
||||
#include "api/video_codecs/sdp_video_format.h"
|
||||
#include "api/video_codecs/video_encoder.h"
|
||||
#include "api/video_codecs/vp9_profile.h"
|
||||
#include "media/base/codec.h"
|
||||
#include "modules/video_coding/include/video_codec_interface.h"
|
||||
|
||||
@ -31,13 +35,19 @@ std::vector<SdpVideoFormat> SupportedVP9Codecs(
|
||||
// preference. These will be availble for receive-only connections.
|
||||
std::vector<SdpVideoFormat> SupportedVP9DecoderCodecs();
|
||||
|
||||
struct Vp9EncoderSettings {
|
||||
VP9Profile profile = VP9Profile::kProfile0;
|
||||
};
|
||||
absl::Nonnull<std::unique_ptr<VideoEncoder>> CreateVp9Encoder(
|
||||
const Environment& env,
|
||||
Vp9EncoderSettings settings = {});
|
||||
|
||||
class VP9Encoder : public VideoEncoder {
|
||||
public:
|
||||
// Deprecated. Returns default implementation using VP9 Profile 0.
|
||||
// TODO(emircan): Remove once this is no longer used.
|
||||
// Deprecated. Use CreateVp9Encoder above, bugs.webrtc.org/15860
|
||||
static std::unique_ptr<VP9Encoder> Create();
|
||||
// Parses VP9 Profile from `codec` and returns the appropriate implementation.
|
||||
static std::unique_ptr<VP9Encoder> Create(const cricket::VideoCodec& codec);
|
||||
|
||||
static bool SupportsScalabilityMode(ScalabilityMode scalability_mode);
|
||||
|
||||
~VP9Encoder() override {}
|
||||
|
||||
@ -223,14 +223,28 @@ void LibvpxVp9Encoder::EncoderOutputCodedPacketCallback(vpx_codec_cx_pkt* pkt,
|
||||
enc->GetEncodedLayerFrame(pkt);
|
||||
}
|
||||
|
||||
LibvpxVp9Encoder::LibvpxVp9Encoder(const Environment& env,
|
||||
Vp9EncoderSettings settings,
|
||||
std::unique_ptr<LibvpxInterface> interface)
|
||||
: LibvpxVp9Encoder(std::move(interface),
|
||||
settings.profile,
|
||||
env.field_trials()) {}
|
||||
|
||||
LibvpxVp9Encoder::LibvpxVp9Encoder(const cricket::VideoCodec& codec,
|
||||
std::unique_ptr<LibvpxInterface> interface,
|
||||
const FieldTrialsView& trials)
|
||||
: LibvpxVp9Encoder(
|
||||
std::move(interface),
|
||||
ParseSdpForVP9Profile(codec.params).value_or(VP9Profile::kProfile0),
|
||||
trials) {}
|
||||
|
||||
LibvpxVp9Encoder::LibvpxVp9Encoder(std::unique_ptr<LibvpxInterface> interface,
|
||||
VP9Profile profile,
|
||||
const FieldTrialsView& trials)
|
||||
: libvpx_(std::move(interface)),
|
||||
encoded_image_(),
|
||||
encoded_complete_callback_(nullptr),
|
||||
profile_(
|
||||
ParseSdpForVP9Profile(codec.params).value_or(VP9Profile::kProfile0)),
|
||||
profile_(profile),
|
||||
inited_(false),
|
||||
timestamp_(0),
|
||||
rc_max_intra_target_(0),
|
||||
|
||||
@ -37,6 +37,11 @@ namespace webrtc {
|
||||
|
||||
class LibvpxVp9Encoder : public VP9Encoder {
|
||||
public:
|
||||
LibvpxVp9Encoder(const Environment& env,
|
||||
Vp9EncoderSettings settings,
|
||||
std::unique_ptr<LibvpxInterface> interface);
|
||||
|
||||
// Deprecated, bugs.webrtc.org/15860
|
||||
LibvpxVp9Encoder(const cricket::VideoCodec& codec,
|
||||
std::unique_ptr<LibvpxInterface> interface,
|
||||
const FieldTrialsView& trials);
|
||||
@ -61,6 +66,10 @@ class LibvpxVp9Encoder : public VP9Encoder {
|
||||
EncoderInfo GetEncoderInfo() const override;
|
||||
|
||||
private:
|
||||
LibvpxVp9Encoder(std::unique_ptr<LibvpxInterface> interface,
|
||||
VP9Profile profile,
|
||||
const FieldTrialsView& trials);
|
||||
|
||||
// Determine number of encoder threads to use.
|
||||
int NumberOfThreads(int width, int height, int number_of_cores);
|
||||
|
||||
|
||||
@ -102,7 +102,7 @@ void ConfigureSvc(VideoCodec& codec_settings,
|
||||
class TestVp9Impl : public VideoCodecUnitTest {
|
||||
protected:
|
||||
std::unique_ptr<VideoEncoder> CreateEncoder() override {
|
||||
return VP9Encoder::Create();
|
||||
return CreateVp9Encoder(env_);
|
||||
}
|
||||
|
||||
std::unique_ptr<VideoDecoder> CreateDecoder() override {
|
||||
@ -255,7 +255,7 @@ TEST_F(TestVp9Impl, SwitchInputPixelFormatsWithoutReconfigure) {
|
||||
}
|
||||
|
||||
TEST(Vp9ImplTest, ParserQpEqualsEncodedQp) {
|
||||
std::unique_ptr<VideoEncoder> encoder = VP9Encoder::Create();
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateVp9Encoder(CreateEnvironment());
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
encoder->InitEncode(&codec_settings, kSettings);
|
||||
|
||||
@ -272,7 +272,7 @@ TEST(Vp9ImplTest, ParserQpEqualsEncodedQp) {
|
||||
}
|
||||
|
||||
TEST(Vp9ImplTest, EncodeAttachesTemplateStructureWithSvcController) {
|
||||
std::unique_ptr<VideoEncoder> encoder = VP9Encoder::Create();
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateVp9Encoder(CreateEnvironment());
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
EXPECT_EQ(encoder->InitEncode(&codec_settings, kSettings),
|
||||
WEBRTC_VIDEO_CODEC_OK);
|
||||
@ -292,7 +292,7 @@ TEST(Vp9ImplTest, EncodeAttachesTemplateStructureWithSvcController) {
|
||||
}
|
||||
|
||||
TEST(Vp9ImplTest, EncoderWith2TemporalLayers) {
|
||||
std::unique_ptr<VideoEncoder> encoder = VP9Encoder::Create();
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateVp9Encoder(CreateEnvironment());
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
codec_settings.VP9()->numberOfTemporalLayers = 2;
|
||||
// Tl0PidIdx is only used in non-flexible mode.
|
||||
@ -314,7 +314,7 @@ TEST(Vp9ImplTest, EncoderWith2TemporalLayers) {
|
||||
}
|
||||
|
||||
TEST(Vp9ImplTest, EncodeTemporalLayersWithSvcController) {
|
||||
std::unique_ptr<VideoEncoder> encoder = VP9Encoder::Create();
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateVp9Encoder(CreateEnvironment());
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
codec_settings.VP9()->numberOfTemporalLayers = 2;
|
||||
EXPECT_EQ(encoder->InitEncode(&codec_settings, kSettings),
|
||||
@ -343,7 +343,7 @@ TEST(Vp9ImplTest, EncodeTemporalLayersWithSvcController) {
|
||||
}
|
||||
|
||||
TEST(Vp9ImplTest, EncoderWith2SpatialLayers) {
|
||||
std::unique_ptr<VideoEncoder> encoder = VP9Encoder::Create();
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateVp9Encoder(CreateEnvironment());
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
codec_settings.VP9()->numberOfSpatialLayers = 2;
|
||||
EXPECT_EQ(encoder->InitEncode(&codec_settings, kSettings),
|
||||
@ -361,7 +361,7 @@ TEST(Vp9ImplTest, EncoderWith2SpatialLayers) {
|
||||
}
|
||||
|
||||
TEST(Vp9ImplTest, EncodeSpatialLayersWithSvcController) {
|
||||
std::unique_ptr<VideoEncoder> encoder = VP9Encoder::Create();
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateVp9Encoder(CreateEnvironment());
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
codec_settings.VP9()->numberOfSpatialLayers = 2;
|
||||
EXPECT_EQ(encoder->InitEncode(&codec_settings, kSettings),
|
||||
@ -503,7 +503,7 @@ TEST(Vp9ImplTest, EnableDisableSpatialLayersWithSvcController) {
|
||||
// Note: bit rate allocation is high to avoid frame dropping due to rate
|
||||
// control, the encoder should always produce a frame. A dropped
|
||||
// frame indicates a problem and the test will fail.
|
||||
std::unique_ptr<VideoEncoder> encoder = VP9Encoder::Create();
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateVp9Encoder(CreateEnvironment());
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
ConfigureSvc(codec_settings, num_spatial_layers);
|
||||
codec_settings.SetFrameDropEnabled(true);
|
||||
@ -570,7 +570,7 @@ MATCHER_P2(GenericLayerIs, spatial_id, temporal_id, "") {
|
||||
}
|
||||
|
||||
TEST(Vp9ImplTest, SpatialUpswitchNotAtGOFBoundary) {
|
||||
std::unique_ptr<VideoEncoder> encoder = VP9Encoder::Create();
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateVp9Encoder(CreateEnvironment());
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
ConfigureSvc(codec_settings, /*num_spatial_layers=*/3,
|
||||
/*num_temporal_layers=*/3);
|
||||
@ -774,7 +774,7 @@ TEST(Vp9ImplTest,
|
||||
// Must not be multiple of temporal period to exercise all code paths.
|
||||
const size_t num_frames_to_encode = 5;
|
||||
|
||||
std::unique_ptr<VideoEncoder> encoder = VP9Encoder::Create();
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateVp9Encoder(CreateEnvironment());
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
ConfigureSvc(codec_settings, num_spatial_layers, num_temporal_layers);
|
||||
codec_settings.SetFrameDropEnabled(false);
|
||||
@ -1851,7 +1851,7 @@ TEST_P(Vp9ImplWithLayeringTest, FlexibleMode) {
|
||||
// encoder and writes it into RTP payload descriptor. Check that reference
|
||||
// list in payload descriptor matches the predefined one, which is used
|
||||
// in non-flexible mode.
|
||||
std::unique_ptr<VideoEncoder> encoder = VP9Encoder::Create();
|
||||
std::unique_ptr<VideoEncoder> encoder = CreateVp9Encoder(CreateEnvironment());
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
codec_settings.VP9()->flexibleMode = true;
|
||||
codec_settings.SetFrameDropEnabled(false);
|
||||
@ -2040,11 +2040,7 @@ class TestVp9ImplProfile2 : public TestVp9Impl {
|
||||
}
|
||||
|
||||
std::unique_ptr<VideoEncoder> CreateEncoder() override {
|
||||
cricket::VideoCodec profile2_codec =
|
||||
cricket::CreateVideoCodec(cricket::kVp9CodecName);
|
||||
profile2_codec.SetParam(kVP9FmtpProfileId,
|
||||
VP9ProfileToString(VP9Profile::kProfile2));
|
||||
return VP9Encoder::Create(profile2_codec);
|
||||
return CreateVp9Encoder(env_, {.profile = VP9Profile::kProfile2});
|
||||
}
|
||||
|
||||
std::unique_ptr<VideoDecoder> CreateDecoder() override {
|
||||
|
||||
@ -81,6 +81,17 @@ std::vector<SdpVideoFormat> SupportedVP9DecoderCodecs() {
|
||||
#endif
|
||||
}
|
||||
|
||||
absl::Nonnull<std::unique_ptr<VideoEncoder>> CreateVp9Encoder(
|
||||
const Environment& env,
|
||||
Vp9EncoderSettings settings) {
|
||||
#ifdef RTC_ENABLE_VP9
|
||||
return std::make_unique<LibvpxVp9Encoder>(env, settings,
|
||||
LibvpxInterface::Create());
|
||||
#else
|
||||
RTC_CHECK_NOTREACHED();
|
||||
#endif
|
||||
}
|
||||
|
||||
std::unique_ptr<VP9Encoder> VP9Encoder::Create() {
|
||||
#ifdef RTC_ENABLE_VP9
|
||||
return std::make_unique<LibvpxVp9Encoder>(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user