Reland "Move creating encoder to VideoStreamEncoder."
This is a reland of fb82fcc7f9c414dc8ba1ddd314e9524fee54cb80 Original change's description: > Move creating encoder to VideoStreamEncoder. > > This used to be in WebRtcVideoChannel::WebRtcVideoSendStream. > One implication is that encoder is not created until the first > frame arrives, and some of the tests needed updates to emit a > frame or two. > > Bug: webrtc:8830 > Change-Id: I78169b2bb4dfa4197b4b4229af9fd69d0f747835 > Reviewed-on: https://webrtc-review.googlesource.com/64885 > Commit-Queue: Niels Moller <nisse@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#22905} TBR=magjed@webrtc.org,kwiberg@webrtc.org Bug: webrtc:8830 Change-Id: I9565095ea1880fb49d15111198c08b2fcb84f18c Reviewed-on: https://webrtc-review.googlesource.com/70740 Commit-Queue: Niels Moller <nisse@webrtc.org> Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Cr-Commit-Position: refs/heads/master@{#22930}
This commit is contained in:
parent
5396232d03
commit
4db138e889
@ -116,8 +116,8 @@ class BitrateEstimatorTest : public test::CallTest {
|
||||
|
||||
video_send_config_ = VideoSendStream::Config(send_transport_.get());
|
||||
video_send_config_.rtp.ssrcs.push_back(kVideoSendSsrcs[0]);
|
||||
// Encoders will be set separately per stream.
|
||||
video_send_config_.encoder_settings.encoder = nullptr;
|
||||
video_send_config_.encoder_settings.encoder_factory =
|
||||
&fake_encoder_factory_;
|
||||
video_send_config_.rtp.payload_name = "FAKE";
|
||||
video_send_config_.rtp.payload_type = kFakeVideoSendPayloadType;
|
||||
test::FillEncoderConfiguration(kVideoCodecVP8, 1, &video_encoder_config_);
|
||||
@ -162,10 +162,8 @@ class BitrateEstimatorTest : public test::CallTest {
|
||||
is_sending_receiving_(false),
|
||||
send_stream_(nullptr),
|
||||
frame_generator_capturer_(),
|
||||
fake_encoder_(Clock::GetRealTimeClock()),
|
||||
fake_decoder_() {
|
||||
test_->video_send_config_.rtp.ssrcs[0]++;
|
||||
test_->video_send_config_.encoder_settings.encoder = &fake_encoder_;
|
||||
send_stream_ = test_->sender_call_->CreateVideoSendStream(
|
||||
test_->video_send_config_.Copy(),
|
||||
test_->video_encoder_config_.Copy());
|
||||
@ -223,7 +221,6 @@ class BitrateEstimatorTest : public test::CallTest {
|
||||
VideoSendStream* send_stream_;
|
||||
VideoReceiveStream* video_receive_stream_;
|
||||
std::unique_ptr<test::FrameGeneratorCapturer> frame_generator_capturer_;
|
||||
test::FakeEncoder fake_encoder_;
|
||||
test::FakeDecoder fake_decoder_;
|
||||
};
|
||||
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
#include "test/call_test.h"
|
||||
#include "test/direct_transport.h"
|
||||
#include "test/drifting_clock.h"
|
||||
#include "test/encoder_proxy_factory.h"
|
||||
#include "test/encoder_settings.h"
|
||||
#include "test/fake_encoder.h"
|
||||
#include "test/field_trial.h"
|
||||
@ -637,7 +638,7 @@ void CallPerfTest::TestMinTransmitBitrate(bool pad_to_min_bitrate) {
|
||||
std::vector<double> bitrate_kbps_list_;
|
||||
} test(pad_to_min_bitrate);
|
||||
|
||||
fake_encoder_.SetMaxBitrate(kMaxEncodeBitrateKbps);
|
||||
fake_encoder_max_bitrate_ = kMaxEncodeBitrateKbps;
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
@ -686,7 +687,8 @@ TEST_F(CallPerfTest, MAYBE_KeepsHighBitrateWhenReconfiguringSender) {
|
||||
encoder_inits_(0),
|
||||
last_set_bitrate_kbps_(0),
|
||||
send_stream_(nullptr),
|
||||
frame_generator_(nullptr) {}
|
||||
frame_generator_(nullptr),
|
||||
encoder_factory_(this) {}
|
||||
|
||||
int32_t InitEncode(const VideoCodec* config,
|
||||
int32_t number_of_cores,
|
||||
@ -735,7 +737,7 @@ TEST_F(CallPerfTest, MAYBE_KeepsHighBitrateWhenReconfiguringSender) {
|
||||
VideoSendStream::Config* send_config,
|
||||
std::vector<VideoReceiveStream::Config>* receive_configs,
|
||||
VideoEncoderConfig* encoder_config) override {
|
||||
send_config->encoder_settings.encoder = this;
|
||||
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
||||
encoder_config->max_bitrate_bps = 2 * kReconfigureThresholdKbps * 1000;
|
||||
encoder_config->video_stream_factory =
|
||||
new rtc::RefCountedObject<VideoStreamFactory>();
|
||||
@ -770,6 +772,7 @@ TEST_F(CallPerfTest, MAYBE_KeepsHighBitrateWhenReconfiguringSender) {
|
||||
uint32_t last_set_bitrate_kbps_;
|
||||
VideoSendStream* send_stream_;
|
||||
test::FrameGeneratorCapturer* frame_generator_;
|
||||
test::EncoderProxyFactory encoder_factory_;
|
||||
VideoEncoderConfig encoder_config_;
|
||||
} test;
|
||||
|
||||
|
||||
@ -93,7 +93,6 @@ std::string VideoSendStream::Config::EncoderSettings::ToString() const {
|
||||
rtc::SimpleStringBuilder ss(buf);
|
||||
ss << "{encoder_factory: "
|
||||
<< (encoder_factory ? "(VideoEncoderFactory)" : "(nullptr)");
|
||||
ss << ", encoder: " << (encoder ? "(VideoEncoder)" : "nullptr");
|
||||
ss << '}';
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
@ -113,18 +113,8 @@ class VideoSendStream {
|
||||
|
||||
struct EncoderSettings {
|
||||
EncoderSettings() = default;
|
||||
explicit EncoderSettings(VideoEncoder* encoder) : encoder(encoder) {}
|
||||
std::string ToString() const;
|
||||
|
||||
// TODO(sophiechang): Delete this field when no one is using internal
|
||||
// sources anymore.
|
||||
bool internal_source = false;
|
||||
|
||||
// Allow 100% encoder utilization. Used for HW encoders where CPU isn't
|
||||
// expected to be the limiting factor, but a chip could be running at
|
||||
// 30fps (for example) exactly.
|
||||
bool full_overuse_time = false;
|
||||
|
||||
// Enables the new method to estimate the cpu load from encoding, used for
|
||||
// cpu adaptation.
|
||||
bool experiment_cpu_load_estimator = false;
|
||||
@ -132,9 +122,8 @@ class VideoSendStream {
|
||||
// Ownership stays with WebrtcVideoEngine (delegated from PeerConnection).
|
||||
VideoEncoderFactory* encoder_factory = nullptr;
|
||||
|
||||
// TODO(nisse): Delete, let VideoStreamEncoder create the encoder.
|
||||
// Uninitialized VideoEncoder instance to be used for encoding. Will be
|
||||
// initialized from inside the VideoSendStream.
|
||||
// TODO(nisse): Unused! But kept temporarily to transition downstream
|
||||
// projects.
|
||||
VideoEncoder* encoder = nullptr;
|
||||
} encoder_settings;
|
||||
|
||||
|
||||
@ -123,7 +123,7 @@ FakeVideoSendStream::FakeVideoSendStream(
|
||||
framerate_scaling_enabled_(false),
|
||||
source_(nullptr),
|
||||
num_swapped_frames_(0) {
|
||||
RTC_DCHECK(config.encoder_settings.encoder != NULL);
|
||||
RTC_DCHECK(config.encoder_settings.encoder_factory != nullptr);
|
||||
ReconfigureVideoEncoder(std::move(encoder_config));
|
||||
}
|
||||
|
||||
|
||||
@ -1656,8 +1656,6 @@ WebRtcVideoChannel::WebRtcVideoSendStream::~WebRtcVideoSendStream() {
|
||||
if (stream_ != NULL) {
|
||||
call_->DestroyVideoSendStream(stream_);
|
||||
}
|
||||
// Release |allocated_encoder_|.
|
||||
allocated_encoder_.reset();
|
||||
}
|
||||
|
||||
bool WebRtcVideoChannel::WebRtcVideoSendStream::SetVideoSend(
|
||||
@ -1729,26 +1727,6 @@ void WebRtcVideoChannel::WebRtcVideoSendStream::SetCodec(
|
||||
parameters_.encoder_config = CreateVideoEncoderConfig(codec_settings.codec);
|
||||
RTC_DCHECK_GT(parameters_.encoder_config.number_of_streams, 0);
|
||||
|
||||
const webrtc::SdpVideoFormat format(codec_settings.codec.name,
|
||||
codec_settings.codec.params);
|
||||
|
||||
// We can't overwrite |allocated_encoder_| immediately, because we
|
||||
// need to release it after the RecreateWebRtcStream() call.
|
||||
std::unique_ptr<webrtc::VideoEncoder> new_encoder =
|
||||
// TODO(nisse): Leave to VideoStreamEncoder.
|
||||
parameters_.config.encoder_settings.encoder_factory->CreateVideoEncoder(
|
||||
format);
|
||||
|
||||
parameters_.config.encoder_settings.encoder = new_encoder.get();
|
||||
|
||||
const webrtc::VideoEncoderFactory::CodecInfo info =
|
||||
parameters_.config.encoder_settings.encoder_factory->QueryVideoEncoder(
|
||||
format);
|
||||
parameters_.config.encoder_settings.full_overuse_time =
|
||||
info.is_hardware_accelerated;
|
||||
parameters_.config.encoder_settings.internal_source =
|
||||
info.has_internal_source;
|
||||
|
||||
parameters_.config.rtp.payload_name = codec_settings.codec.name;
|
||||
parameters_.config.rtp.payload_type = codec_settings.codec.id;
|
||||
parameters_.config.rtp.ulpfec = codec_settings.ulpfec;
|
||||
@ -1772,9 +1750,10 @@ void WebRtcVideoChannel::WebRtcVideoSendStream::SetCodec(
|
||||
|
||||
parameters_.codec_settings = codec_settings;
|
||||
|
||||
// TODO(nisse): Avoid recreation, it should be enough to call
|
||||
// ReconfigureEncoder.
|
||||
RTC_LOG(LS_INFO) << "RecreateWebRtcStream (send) because of SetCodec.";
|
||||
RecreateWebRtcStream();
|
||||
allocated_encoder_ = std::move(new_encoder);
|
||||
}
|
||||
|
||||
void WebRtcVideoChannel::WebRtcVideoSendStream::SetSendParameters(
|
||||
@ -1907,6 +1886,8 @@ WebRtcVideoChannel::WebRtcVideoSendStream::CreateVideoEncoderConfig(
|
||||
RTC_DCHECK_RUN_ON(&thread_checker_);
|
||||
webrtc::VideoEncoderConfig encoder_config;
|
||||
encoder_config.codec_type = webrtc::PayloadStringToCodecType(codec.name);
|
||||
encoder_config.video_format =
|
||||
webrtc::SdpVideoFormat(codec.name, codec.params);
|
||||
|
||||
bool is_screencast = parameters_.options.is_screencast.value_or(false);
|
||||
if (is_screencast) {
|
||||
|
||||
@ -350,8 +350,6 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport {
|
||||
// TODO(skvlad): Combine parameters_ and rtp_parameters_ once we have only
|
||||
// one stream per MediaChannel.
|
||||
webrtc::RtpParameters rtp_parameters_ RTC_GUARDED_BY(&thread_checker_);
|
||||
std::unique_ptr<webrtc::VideoEncoder> allocated_encoder_
|
||||
RTC_GUARDED_BY(&thread_checker_);
|
||||
|
||||
bool sending_ RTC_GUARDED_BY(&thread_checker_);
|
||||
};
|
||||
|
||||
@ -496,40 +496,6 @@ TEST_F(WebRtcVideoEngineTest, RtxCodecAddedForExternalCodec) {
|
||||
codecs, FindMatchingCodec(codecs, h264_high)->id));
|
||||
}
|
||||
|
||||
void WebRtcVideoEngineTest::TestExtendedEncoderOveruse(
|
||||
bool use_external_encoder) {
|
||||
std::unique_ptr<VideoMediaChannel> channel;
|
||||
FakeCall* fake_call = new FakeCall();
|
||||
call_.reset(fake_call);
|
||||
if (use_external_encoder) {
|
||||
encoder_factory_->AddSupportedVideoCodecType("VP8");
|
||||
channel.reset(SetUpForExternalEncoderFactory());
|
||||
} else {
|
||||
channel.reset(
|
||||
engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions()));
|
||||
}
|
||||
ASSERT_TRUE(
|
||||
channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
|
||||
cricket::VideoSendParameters parameters;
|
||||
parameters.codecs.push_back(GetEngineCodec("VP8"));
|
||||
EXPECT_TRUE(channel->SetSendParameters(parameters));
|
||||
EXPECT_TRUE(channel->SetSend(true));
|
||||
FakeVideoSendStream* stream = fake_call->GetVideoSendStreams()[0];
|
||||
|
||||
EXPECT_EQ(use_external_encoder,
|
||||
stream->GetConfig().encoder_settings.full_overuse_time);
|
||||
// Remove stream previously added to free the external encoder instance.
|
||||
EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
|
||||
}
|
||||
|
||||
TEST_F(WebRtcVideoEngineTest, EnablesFullEncoderTimeForExternalEncoders) {
|
||||
TestExtendedEncoderOveruse(true);
|
||||
}
|
||||
|
||||
TEST_F(WebRtcVideoEngineTest, DisablesFullEncoderTimeForNonExternalEncoders) {
|
||||
TestExtendedEncoderOveruse(false);
|
||||
}
|
||||
|
||||
#if !defined(RTC_DISABLE_VP9)
|
||||
TEST_F(WebRtcVideoEngineTest, CanConstructDecoderForVp9EncoderFactory) {
|
||||
encoder_factory_->AddSupportedVideoCodecType("VP9");
|
||||
@ -688,16 +654,29 @@ TEST_F(WebRtcVideoEngineTest, UsesSimulcastAdapterForVp8Factories) {
|
||||
TEST_F(WebRtcVideoEngineTest, ChannelWithExternalH264CanChangeToInternalVp8) {
|
||||
encoder_factory_->AddSupportedVideoCodecType("H264");
|
||||
|
||||
// Set capturer.
|
||||
FakeVideoCapturerWithTaskQueue capturer;
|
||||
EXPECT_EQ(cricket::CS_RUNNING,
|
||||
capturer.Start(capturer.GetSupportedFormats()->front()));
|
||||
|
||||
std::unique_ptr<VideoMediaChannel> channel(SetUpForExternalEncoderFactory());
|
||||
|
||||
EXPECT_TRUE(
|
||||
channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
|
||||
ASSERT_EQ(1u, encoder_factory_->encoders().size());
|
||||
EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &capturer));
|
||||
// Sending one frame will have allocate the encoder.
|
||||
EXPECT_TRUE(capturer.CaptureFrame());
|
||||
|
||||
ASSERT_EQ_WAIT(1u, encoder_factory_->encoders().size(), kTimeout);
|
||||
|
||||
cricket::VideoSendParameters parameters;
|
||||
parameters.codecs.push_back(GetEngineCodec("VP8"));
|
||||
EXPECT_TRUE(channel->SetSendParameters(parameters));
|
||||
ASSERT_EQ(0u, encoder_factory_->encoders().size());
|
||||
|
||||
// Sending one frame will switch encoder.
|
||||
EXPECT_TRUE(capturer.CaptureFrame());
|
||||
|
||||
EXPECT_EQ_WAIT(0u, encoder_factory_->encoders().size(), kTimeout);
|
||||
}
|
||||
|
||||
TEST_F(WebRtcVideoEngineTest,
|
||||
@ -765,7 +744,6 @@ TEST_F(WebRtcVideoEngineTest,
|
||||
|
||||
EXPECT_TRUE(
|
||||
channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
|
||||
ASSERT_EQ(1u, encoder_factory_->encoders().size());
|
||||
|
||||
// Send a frame of 720p. This should trigger a "real" encoder initialization.
|
||||
cricket::VideoFormat format(
|
||||
@ -774,6 +752,8 @@ TEST_F(WebRtcVideoEngineTest,
|
||||
EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &capturer));
|
||||
EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(format));
|
||||
EXPECT_TRUE(capturer.CaptureFrame());
|
||||
ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
|
||||
ASSERT_EQ(1u, encoder_factory_->encoders().size());
|
||||
ASSERT_TRUE(encoder_factory_->encoders()[0]->WaitForInitEncode());
|
||||
EXPECT_EQ(webrtc::kVideoCodecH264,
|
||||
encoder_factory_->encoders()[0]->GetCodecSettings().codecType);
|
||||
@ -800,6 +780,7 @@ TEST_F(WebRtcVideoEngineTest, SimulcastDisabledForH264) {
|
||||
EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(format));
|
||||
EXPECT_TRUE(capturer.CaptureFrame());
|
||||
|
||||
ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
|
||||
ASSERT_EQ(1u, encoder_factory_->encoders().size());
|
||||
FakeWebRtcVideoEncoder* encoder = encoder_factory_->encoders()[0];
|
||||
ASSERT_TRUE(encoder_factory_->encoders()[0]->WaitForInitEncode());
|
||||
@ -988,8 +969,12 @@ TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, Vp8) {
|
||||
EXPECT_CALL(*encoder_factory, QueryVideoEncoder(format))
|
||||
.WillRepeatedly(testing::Return(codec_info));
|
||||
FakeWebRtcVideoEncoder* const encoder = new FakeWebRtcVideoEncoder();
|
||||
rtc::Event encoder_created(false, false);
|
||||
EXPECT_CALL(*encoder_factory, CreateVideoEncoderProxy(format))
|
||||
.WillOnce(testing::Return(encoder));
|
||||
.WillOnce(
|
||||
::testing::DoAll(::testing::InvokeWithoutArgs(
|
||||
[&encoder_created]() { encoder_created.Set(); }),
|
||||
::testing::Return(encoder)));
|
||||
|
||||
// Mock decoder creation. |engine| take ownership of the decoder.
|
||||
FakeWebRtcVideoDecoder* const decoder = new FakeWebRtcVideoDecoder();
|
||||
@ -1013,6 +998,15 @@ TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, Vp8) {
|
||||
send_channel->AddSendStream(StreamParams::CreateLegacy(send_ssrc)));
|
||||
EXPECT_TRUE(send_channel->SetSend(true));
|
||||
|
||||
// Set capturer.
|
||||
FakeVideoCapturerWithTaskQueue capturer;
|
||||
EXPECT_EQ(cricket::CS_RUNNING,
|
||||
capturer.Start(capturer.GetSupportedFormats()->front()));
|
||||
EXPECT_TRUE(send_channel->SetVideoSend(send_ssrc, nullptr, &capturer));
|
||||
// Sending one frame will allocate the encoder.
|
||||
EXPECT_TRUE(capturer.CaptureFrame());
|
||||
encoder_created.Wait(kTimeout);
|
||||
|
||||
// Create recv channel.
|
||||
const int recv_ssrc = 321;
|
||||
std::unique_ptr<VideoMediaChannel> recv_channel(
|
||||
|
||||
@ -509,6 +509,7 @@ rtc_source_set("test_common") {
|
||||
"constants.h",
|
||||
"drifting_clock.cc",
|
||||
"drifting_clock.h",
|
||||
"encoder_proxy_factory.h",
|
||||
"encoder_settings.cc",
|
||||
"encoder_settings.h",
|
||||
"fake_decoder.cc",
|
||||
@ -516,6 +517,7 @@ rtc_source_set("test_common") {
|
||||
"fake_encoder.cc",
|
||||
"fake_encoder.h",
|
||||
"fake_videorenderer.h",
|
||||
"function_video_encoder_factory.h",
|
||||
"layer_filtering_transport.cc",
|
||||
"layer_filtering_transport.h",
|
||||
"mock_transport.cc",
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/event.h"
|
||||
#include "rtc_base/ptr_util.h"
|
||||
#include "test/fake_encoder.h"
|
||||
#include "test/testsupport/fileutils.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -37,7 +38,11 @@ CallTest::CallTest()
|
||||
video_send_stream_(nullptr),
|
||||
audio_send_config_(nullptr),
|
||||
audio_send_stream_(nullptr),
|
||||
fake_encoder_(clock_),
|
||||
fake_encoder_factory_([this]() {
|
||||
auto encoder = rtc::MakeUnique<test::FakeEncoder>(clock_);
|
||||
encoder->SetMaxBitrate(fake_encoder_max_bitrate_);
|
||||
return encoder;
|
||||
}),
|
||||
num_video_streams_(1),
|
||||
num_audio_streams_(0),
|
||||
num_flexfec_streams_(0),
|
||||
@ -193,7 +198,7 @@ void CallTest::CreateVideoSendConfig(VideoSendStream::Config* video_config,
|
||||
Transport* send_transport) {
|
||||
RTC_DCHECK_LE(num_video_streams + num_used_ssrcs, kNumSsrcs);
|
||||
*video_config = VideoSendStream::Config(send_transport);
|
||||
video_config->encoder_settings.encoder = &fake_encoder_;
|
||||
video_config->encoder_settings.encoder_factory = &fake_encoder_factory_;
|
||||
video_config->rtp.payload_name = "FAKE";
|
||||
video_config->rtp.payload_type = kFakeVideoSendPayloadType;
|
||||
video_config->rtp.extensions.push_back(
|
||||
|
||||
@ -19,9 +19,9 @@
|
||||
#include "modules/audio_device/include/test_audio_device.h"
|
||||
#include "test/encoder_settings.h"
|
||||
#include "test/fake_decoder.h"
|
||||
#include "test/fake_encoder.h"
|
||||
#include "test/fake_videorenderer.h"
|
||||
#include "test/frame_generator_capturer.h"
|
||||
#include "test/function_video_encoder_factory.h"
|
||||
#include "test/rtp_rtcp_observer.h"
|
||||
#include "test/single_threaded_task_queue.h"
|
||||
|
||||
@ -138,7 +138,8 @@ class CallTest : public ::testing::Test {
|
||||
std::vector<FlexfecReceiveStream*> flexfec_receive_streams_;
|
||||
|
||||
std::unique_ptr<test::FrameGeneratorCapturer> frame_generator_capturer_;
|
||||
test::FakeEncoder fake_encoder_;
|
||||
test::FunctionVideoEncoderFactory fake_encoder_factory_;
|
||||
int fake_encoder_max_bitrate_ = -1;
|
||||
std::vector<std::unique_ptr<VideoDecoder>> allocated_decoders_;
|
||||
size_t num_video_streams_;
|
||||
size_t num_audio_streams_;
|
||||
|
||||
103
test/encoder_proxy_factory.h
Normal file
103
test/encoder_proxy_factory.h
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef TEST_ENCODER_PROXY_FACTORY_H_
|
||||
#define TEST_ENCODER_PROXY_FACTORY_H_
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "api/video_codecs/video_encoder.h"
|
||||
#include "api/video_codecs/video_encoder_factory.h"
|
||||
#include "rtc_base/ptr_util.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace test {
|
||||
|
||||
// An encoder factory with a single underlying VideoEncoder object,
|
||||
// intended for test purposes. Each call to CreateVideoEncoder returns
|
||||
// a proxy for the same encoder, typically an instance of FakeEncoder.
|
||||
class EncoderProxyFactory final : public VideoEncoderFactory {
|
||||
public:
|
||||
explicit EncoderProxyFactory(VideoEncoder* encoder) : encoder_(encoder) {
|
||||
codec_info_.is_hardware_accelerated = false;
|
||||
codec_info_.has_internal_source = false;
|
||||
}
|
||||
|
||||
// Unused by tests.
|
||||
std::vector<SdpVideoFormat> GetSupportedFormats() const override {
|
||||
RTC_NOTREACHED();
|
||||
return {};
|
||||
}
|
||||
|
||||
CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override {
|
||||
return codec_info_;
|
||||
}
|
||||
|
||||
std::unique_ptr<VideoEncoder> CreateVideoEncoder(
|
||||
const SdpVideoFormat& format) override {
|
||||
return rtc::MakeUnique<EncoderProxy>(encoder_);
|
||||
}
|
||||
|
||||
void SetIsHardwareAccelerated(bool is_hardware_accelerated) {
|
||||
codec_info_.is_hardware_accelerated = is_hardware_accelerated;
|
||||
}
|
||||
void SetHasInternalSource(bool has_internal_source) {
|
||||
codec_info_.has_internal_source = has_internal_source;
|
||||
}
|
||||
|
||||
private:
|
||||
// Wrapper class, since CreateVideoEncoder needs to surrender
|
||||
// ownership to the object it returns.
|
||||
class EncoderProxy final : public VideoEncoder {
|
||||
public:
|
||||
explicit EncoderProxy(VideoEncoder* encoder) : encoder_(encoder) {}
|
||||
|
||||
private:
|
||||
int32_t Encode(const VideoFrame& input_image,
|
||||
const CodecSpecificInfo* codec_specific_info,
|
||||
const std::vector<FrameType>* frame_types) override {
|
||||
return encoder_->Encode(input_image, codec_specific_info, frame_types);
|
||||
}
|
||||
int32_t InitEncode(const VideoCodec* config,
|
||||
int32_t number_of_cores,
|
||||
size_t max_payload_size) override {
|
||||
return encoder_->InitEncode(config, number_of_cores, max_payload_size);
|
||||
}
|
||||
VideoEncoder::ScalingSettings GetScalingSettings() const override {
|
||||
return encoder_->GetScalingSettings();
|
||||
}
|
||||
int32_t RegisterEncodeCompleteCallback(
|
||||
EncodedImageCallback* callback) override {
|
||||
return encoder_->RegisterEncodeCompleteCallback(callback);
|
||||
}
|
||||
int32_t Release() override { return encoder_->Release(); }
|
||||
int32_t SetChannelParameters(uint32_t packet_loss, int64_t rtt) override {
|
||||
return encoder_->SetChannelParameters(packet_loss, rtt);
|
||||
}
|
||||
int32_t SetRateAllocation(const BitrateAllocation& rate_allocation,
|
||||
uint32_t framerate) override {
|
||||
return encoder_->SetRateAllocation(rate_allocation, framerate);
|
||||
}
|
||||
const char* ImplementationName() const override {
|
||||
return encoder_->ImplementationName();
|
||||
}
|
||||
|
||||
VideoEncoder* const encoder_;
|
||||
};
|
||||
|
||||
VideoEncoder* const encoder_;
|
||||
CodecInfo codec_info_;
|
||||
};
|
||||
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // TEST_ENCODER_PROXY_FACTORY_H_
|
||||
59
test/function_video_encoder_factory.h
Normal file
59
test/function_video_encoder_factory.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef TEST_FUNCTION_VIDEO_ENCODER_FACTORY_H_
|
||||
#define TEST_FUNCTION_VIDEO_ENCODER_FACTORY_H_
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "api/video_codecs/video_encoder_factory.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace test {
|
||||
|
||||
// An encoder factory producing encoders by calling a supplied create
|
||||
// function.
|
||||
class FunctionVideoEncoderFactory final : public VideoEncoderFactory {
|
||||
public:
|
||||
explicit FunctionVideoEncoderFactory(
|
||||
std::function<std::unique_ptr<VideoEncoder>()> create)
|
||||
: create_(std::move(create)) {
|
||||
codec_info_.is_hardware_accelerated = false;
|
||||
codec_info_.has_internal_source = false;
|
||||
}
|
||||
|
||||
// Unused by tests.
|
||||
std::vector<SdpVideoFormat> GetSupportedFormats() const override {
|
||||
RTC_NOTREACHED();
|
||||
return {};
|
||||
}
|
||||
|
||||
CodecInfo QueryVideoEncoder(
|
||||
const SdpVideoFormat& /* format */) const override {
|
||||
return codec_info_;
|
||||
}
|
||||
|
||||
std::unique_ptr<VideoEncoder> CreateVideoEncoder(
|
||||
const SdpVideoFormat& /* format */) override {
|
||||
return create_();
|
||||
}
|
||||
|
||||
private:
|
||||
const std::function<std::unique_ptr<VideoEncoder>()> create_;
|
||||
CodecInfo codec_info_;
|
||||
};
|
||||
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // TEST_FUNCTION_VIDEO_ENCODER_FACTORY_H_
|
||||
@ -24,10 +24,9 @@ namespace webrtc {
|
||||
class MockVideoStreamEncoder : public VideoStreamEncoder {
|
||||
public:
|
||||
explicit MockVideoStreamEncoder(SendStatisticsProxy* send_stats_proxy)
|
||||
: VideoStreamEncoder(
|
||||
1,
|
||||
: VideoStreamEncoder(1,
|
||||
send_stats_proxy,
|
||||
VideoSendStream::Config::EncoderSettings(nullptr),
|
||||
VideoSendStream::Config::EncoderSettings(),
|
||||
nullptr,
|
||||
rtc::MakeUnique<OveruseFrameDetector>(nullptr)) {}
|
||||
~MockVideoStreamEncoder() { Stop(); }
|
||||
|
||||
@ -12,6 +12,8 @@
|
||||
#include "rtc_base/rate_limiter.h"
|
||||
#include "system_wrappers/include/sleep.h"
|
||||
#include "test/call_test.h"
|
||||
#include "test/encoder_proxy_factory.h"
|
||||
#include "test/fake_encoder.h"
|
||||
#include "test/field_trial.h"
|
||||
#include "test/gtest.h"
|
||||
#include "test/rtcp_packet_parser.h"
|
||||
@ -280,6 +282,7 @@ TEST_P(BandwidthEndToEndTest, ReportsSetEncoderRates) {
|
||||
FakeEncoder(Clock::GetRealTimeClock()),
|
||||
task_queue_(task_queue),
|
||||
send_stream_(nullptr),
|
||||
encoder_factory_(this),
|
||||
bitrate_kbps_(0) {}
|
||||
|
||||
void OnVideoStreamsCreated(
|
||||
@ -292,7 +295,7 @@ TEST_P(BandwidthEndToEndTest, ReportsSetEncoderRates) {
|
||||
VideoSendStream::Config* send_config,
|
||||
std::vector<VideoReceiveStream::Config>* receive_configs,
|
||||
VideoEncoderConfig* encoder_config) override {
|
||||
send_config->encoder_settings.encoder = this;
|
||||
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
||||
RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
|
||||
}
|
||||
|
||||
@ -350,6 +353,7 @@ TEST_P(BandwidthEndToEndTest, ReportsSetEncoderRates) {
|
||||
test::SingleThreadedTaskQueueForTesting* const task_queue_;
|
||||
rtc::CriticalSection crit_;
|
||||
VideoSendStream* send_stream_;
|
||||
test::EncoderProxyFactory encoder_factory_;
|
||||
uint32_t bitrate_kbps_ RTC_GUARDED_BY(crit_);
|
||||
} test(&task_queue_);
|
||||
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
#include "test/call_test.h"
|
||||
#include "test/encoder_settings.h"
|
||||
#include "test/field_trial.h"
|
||||
#include "test/function_video_encoder_factory.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -47,7 +48,7 @@ class CodecObserver : public test::EndToEndTest,
|
||||
CodecObserver(int no_frames_to_wait_for,
|
||||
VideoRotation rotation_to_test,
|
||||
const std::string& payload_name,
|
||||
std::unique_ptr<webrtc::VideoEncoder> encoder,
|
||||
VideoEncoderFactory* encoder_factory,
|
||||
std::unique_ptr<webrtc::VideoDecoder> decoder)
|
||||
: EndToEndTest(4 * CodecEndToEndTest::kDefaultTimeoutMs),
|
||||
// TODO(hta): This timeout (120 seconds) is excessive.
|
||||
@ -55,7 +56,7 @@ class CodecObserver : public test::EndToEndTest,
|
||||
no_frames_to_wait_for_(no_frames_to_wait_for),
|
||||
expected_rotation_(rotation_to_test),
|
||||
payload_name_(payload_name),
|
||||
encoder_(std::move(encoder)),
|
||||
encoder_factory_(encoder_factory),
|
||||
decoder_(std::move(decoder)),
|
||||
frame_counter_(0) {}
|
||||
|
||||
@ -69,7 +70,7 @@ class CodecObserver : public test::EndToEndTest,
|
||||
std::vector<VideoReceiveStream::Config>* receive_configs,
|
||||
VideoEncoderConfig* encoder_config) override {
|
||||
encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
|
||||
send_config->encoder_settings.encoder = encoder_.get();
|
||||
send_config->encoder_settings.encoder_factory = encoder_factory_;
|
||||
send_config->rtp.payload_name = payload_name_;
|
||||
send_config->rtp.payload_type = test::CallTest::kVideoSendPayloadType;
|
||||
|
||||
@ -97,56 +98,70 @@ class CodecObserver : public test::EndToEndTest,
|
||||
int no_frames_to_wait_for_;
|
||||
VideoRotation expected_rotation_;
|
||||
std::string payload_name_;
|
||||
std::unique_ptr<webrtc::VideoEncoder> encoder_;
|
||||
VideoEncoderFactory* encoder_factory_;
|
||||
std::unique_ptr<webrtc::VideoDecoder> decoder_;
|
||||
int frame_counter_;
|
||||
};
|
||||
|
||||
TEST_P(CodecEndToEndTest, SendsAndReceivesVP8) {
|
||||
CodecObserver test(5, kVideoRotation_0, "VP8", VP8Encoder::Create(),
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[]() { return VP8Encoder::Create(); });
|
||||
CodecObserver test(5, kVideoRotation_0, "VP8", &encoder_factory,
|
||||
VP8Decoder::Create());
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_P(CodecEndToEndTest, SendsAndReceivesVP8Rotation90) {
|
||||
CodecObserver test(5, kVideoRotation_90, "VP8", VP8Encoder::Create(),
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[]() { return VP8Encoder::Create(); });
|
||||
CodecObserver test(5, kVideoRotation_90, "VP8", &encoder_factory,
|
||||
VP8Decoder::Create());
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
#if !defined(RTC_DISABLE_VP9)
|
||||
TEST_P(CodecEndToEndTest, SendsAndReceivesVP9) {
|
||||
CodecObserver test(500, kVideoRotation_0, "VP9", VP9Encoder::Create(),
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[]() { return VP9Encoder::Create(); });
|
||||
CodecObserver test(500, kVideoRotation_0, "VP9", &encoder_factory,
|
||||
VP9Decoder::Create());
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_P(CodecEndToEndTest, SendsAndReceivesVP9VideoRotation90) {
|
||||
CodecObserver test(5, kVideoRotation_90, "VP9", VP9Encoder::Create(),
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[]() { return VP9Encoder::Create(); });
|
||||
CodecObserver test(5, kVideoRotation_90, "VP9", &encoder_factory,
|
||||
VP9Decoder::Create());
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
// Mutiplex tests are using VP9 as the underlying implementation.
|
||||
TEST_P(CodecEndToEndTest, SendsAndReceivesMultiplex) {
|
||||
InternalEncoderFactory encoder_factory;
|
||||
InternalEncoderFactory internal_encoder_factory;
|
||||
InternalDecoderFactory decoder_factory;
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[&internal_encoder_factory]() {
|
||||
return rtc::MakeUnique<MultiplexEncoderAdapter>(
|
||||
&internal_encoder_factory, SdpVideoFormat(cricket::kVp9CodecName));
|
||||
});
|
||||
CodecObserver test(
|
||||
5, kVideoRotation_0, "multiplex",
|
||||
rtc::MakeUnique<MultiplexEncoderAdapter>(
|
||||
&encoder_factory, SdpVideoFormat(cricket::kVp9CodecName)),
|
||||
5, kVideoRotation_0, "multiplex", &encoder_factory,
|
||||
rtc::MakeUnique<MultiplexDecoderAdapter>(
|
||||
&decoder_factory, SdpVideoFormat(cricket::kVp9CodecName)));
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_P(CodecEndToEndTest, SendsAndReceivesMultiplexVideoRotation90) {
|
||||
InternalEncoderFactory encoder_factory;
|
||||
InternalEncoderFactory internal_encoder_factory;
|
||||
InternalDecoderFactory decoder_factory;
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[&internal_encoder_factory]() {
|
||||
return rtc::MakeUnique<MultiplexEncoderAdapter>(
|
||||
&internal_encoder_factory, SdpVideoFormat(cricket::kVp9CodecName));
|
||||
});
|
||||
CodecObserver test(
|
||||
5, kVideoRotation_90, "multiplex",
|
||||
rtc::MakeUnique<MultiplexEncoderAdapter>(
|
||||
&encoder_factory, SdpVideoFormat(cricket::kVp9CodecName)),
|
||||
5, kVideoRotation_90, "multiplex", &encoder_factory,
|
||||
rtc::MakeUnique<MultiplexDecoderAdapter>(
|
||||
&decoder_factory, SdpVideoFormat(cricket::kVp9CodecName)));
|
||||
RunBaseTest(&test);
|
||||
@ -167,15 +182,17 @@ INSTANTIATE_TEST_CASE_P(SpsPpsIdrIsKeyframe,
|
||||
h264_field_trial_combinations);
|
||||
|
||||
TEST_P(EndToEndTestH264, SendsAndReceivesH264) {
|
||||
CodecObserver test(500, kVideoRotation_0, "H264",
|
||||
H264Encoder::Create(cricket::VideoCodec("H264")),
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[]() { return H264Encoder::Create(cricket::VideoCodec("H264")); });
|
||||
CodecObserver test(500, kVideoRotation_0, "H264", &encoder_factory,
|
||||
H264Decoder::Create());
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_P(EndToEndTestH264, SendsAndReceivesH264VideoRotation90) {
|
||||
CodecObserver test(5, kVideoRotation_90, "H264",
|
||||
H264Encoder::Create(cricket::VideoCodec("H264")),
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[]() { return H264Encoder::Create(cricket::VideoCodec("H264")); });
|
||||
CodecObserver test(5, kVideoRotation_90, "H264", &encoder_factory,
|
||||
H264Decoder::Create());
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
@ -183,7 +200,9 @@ TEST_P(EndToEndTestH264, SendsAndReceivesH264VideoRotation90) {
|
||||
TEST_P(EndToEndTestH264, SendsAndReceivesH264PacketizationMode0) {
|
||||
cricket::VideoCodec codec = cricket::VideoCodec("H264");
|
||||
codec.SetParam(cricket::kH264FmtpPacketizationMode, "0");
|
||||
CodecObserver test(500, kVideoRotation_0, "H264", H264Encoder::Create(codec),
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[codec]() { return H264Encoder::Create(codec); });
|
||||
CodecObserver test(500, kVideoRotation_0, "H264", &encoder_factory,
|
||||
H264Decoder::Create());
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
@ -191,7 +210,9 @@ TEST_P(EndToEndTestH264, SendsAndReceivesH264PacketizationMode0) {
|
||||
TEST_P(EndToEndTestH264, SendsAndReceivesH264PacketizationMode1) {
|
||||
cricket::VideoCodec codec = cricket::VideoCodec("H264");
|
||||
codec.SetParam(cricket::kH264FmtpPacketizationMode, "1");
|
||||
CodecObserver test(500, kVideoRotation_0, "H264", H264Encoder::Create(codec),
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[codec]() { return H264Encoder::Create(codec); });
|
||||
CodecObserver test(500, kVideoRotation_0, "H264", &encoder_factory,
|
||||
H264Decoder::Create());
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8.h"
|
||||
#include "test/call_test.h"
|
||||
#include "test/field_trial.h"
|
||||
#include "test/function_video_encoder_factory.h"
|
||||
#include "test/gtest.h"
|
||||
#include "test/rtcp_packet_parser.h"
|
||||
|
||||
@ -42,7 +43,7 @@ TEST_P(FecEndToEndTest, ReceivesUlpfec) {
|
||||
public:
|
||||
UlpfecRenderObserver()
|
||||
: EndToEndTest(kDefaultTimeoutMs),
|
||||
encoder_(VP8Encoder::Create()),
|
||||
encoder_factory_([]() { return VP8Encoder::Create(); }),
|
||||
random_(0xcafef00d1),
|
||||
num_packets_sent_(0) {}
|
||||
|
||||
@ -102,7 +103,7 @@ TEST_P(FecEndToEndTest, ReceivesUlpfec) {
|
||||
VideoEncoderConfig* encoder_config) override {
|
||||
// Use VP8 instead of FAKE, since the latter does not have PictureID
|
||||
// in the packetization headers.
|
||||
send_config->encoder_settings.encoder = encoder_.get();
|
||||
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
||||
send_config->rtp.payload_name = "VP8";
|
||||
send_config->rtp.payload_type = kVideoSendPayloadType;
|
||||
encoder_config->codec_type = kVideoCodecVP8;
|
||||
@ -128,6 +129,7 @@ TEST_P(FecEndToEndTest, ReceivesUlpfec) {
|
||||
|
||||
rtc::CriticalSection crit_;
|
||||
std::unique_ptr<VideoEncoder> encoder_;
|
||||
test::FunctionVideoEncoderFactory encoder_factory_;
|
||||
std::unique_ptr<VideoDecoder> decoder_;
|
||||
std::set<uint32_t> dropped_sequence_numbers_ RTC_GUARDED_BY(crit_);
|
||||
// Several packets can have the same timestamp.
|
||||
@ -335,7 +337,7 @@ TEST_P(FecEndToEndTest, ReceivedUlpfecPacketsNotNacked) {
|
||||
ulpfec_sequence_number_(0),
|
||||
has_last_sequence_number_(false),
|
||||
last_sequence_number_(0),
|
||||
encoder_(VP8Encoder::Create()),
|
||||
encoder_factory_([]() { return VP8Encoder::Create(); }),
|
||||
decoder_(VP8Decoder::Create()) {}
|
||||
|
||||
private:
|
||||
@ -452,7 +454,7 @@ TEST_P(FecEndToEndTest, ReceivedUlpfecPacketsNotNacked) {
|
||||
send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
|
||||
send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
|
||||
// Set codec to VP8, otherwise NACK/FEC hybrid will be disabled.
|
||||
send_config->encoder_settings.encoder = encoder_.get();
|
||||
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
||||
send_config->rtp.payload_name = "VP8";
|
||||
send_config->rtp.payload_type = kFakeVideoSendPayloadType;
|
||||
encoder_config->codec_type = kVideoCodecVP8;
|
||||
@ -488,6 +490,7 @@ TEST_P(FecEndToEndTest, ReceivedUlpfecPacketsNotNacked) {
|
||||
bool has_last_sequence_number_;
|
||||
uint16_t last_sequence_number_;
|
||||
std::unique_ptr<webrtc::VideoEncoder> encoder_;
|
||||
test::FunctionVideoEncoderFactory encoder_factory_;
|
||||
std::unique_ptr<webrtc::VideoDecoder> decoder_;
|
||||
} test;
|
||||
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#include "system_wrappers/include/metrics.h"
|
||||
#include "system_wrappers/include/metrics_default.h"
|
||||
#include "test/call_test.h"
|
||||
#include "test/function_video_encoder_factory.h"
|
||||
#include "test/gtest.h"
|
||||
#include "test/rtcp_packet_parser.h"
|
||||
|
||||
@ -34,7 +35,7 @@ void HistogramTest::VerifyHistogramStats(bool use_rtx,
|
||||
use_fec_(use_fec),
|
||||
screenshare_(screenshare),
|
||||
// This test uses NACK, so to send FEC we can't use a fake encoder.
|
||||
vp8_encoder_(use_fec ? VP8Encoder::Create() : nullptr),
|
||||
encoder_factory_([]() { return VP8Encoder::Create(); }),
|
||||
sender_call_(nullptr),
|
||||
receiver_call_(nullptr),
|
||||
start_runtime_ms_(-1),
|
||||
@ -88,7 +89,7 @@ void HistogramTest::VerifyHistogramStats(bool use_rtx,
|
||||
if (use_fec_) {
|
||||
send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
|
||||
send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
|
||||
send_config->encoder_settings.encoder = vp8_encoder_.get();
|
||||
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
||||
send_config->rtp.payload_name = "VP8";
|
||||
encoder_config->codec_type = kVideoCodecVP8;
|
||||
(*receive_configs)[0].decoders[0].payload_name = "VP8";
|
||||
@ -130,7 +131,7 @@ void HistogramTest::VerifyHistogramStats(bool use_rtx,
|
||||
const bool use_rtx_;
|
||||
const bool use_fec_;
|
||||
const bool screenshare_;
|
||||
const std::unique_ptr<VideoEncoder> vp8_encoder_;
|
||||
test::FunctionVideoEncoderFactory encoder_factory_;
|
||||
Call* sender_call_;
|
||||
Call* receiver_call_;
|
||||
int64_t start_runtime_ms_;
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8.h"
|
||||
#include "rtc_base/file.h"
|
||||
#include "test/call_test.h"
|
||||
#include "test/function_video_encoder_factory.h"
|
||||
#include "test/testsupport/fileutils.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -61,6 +62,7 @@ TEST_F(LogEndToEndTest, LogsEncodedFramesWhenRequested) {
|
||||
explicit LogEncodingObserver(LogEndToEndTest* fixture)
|
||||
: EndToEndTest(kDefaultTimeoutMs),
|
||||
fixture_(fixture),
|
||||
encoder_factory_([]() { return VP8Encoder::Create(); }),
|
||||
recorded_frames_(0) {}
|
||||
|
||||
void PerformTest() override {
|
||||
@ -73,12 +75,11 @@ TEST_F(LogEndToEndTest, LogsEncodedFramesWhenRequested) {
|
||||
VideoSendStream::Config* send_config,
|
||||
std::vector<VideoReceiveStream::Config>* receive_configs,
|
||||
VideoEncoderConfig* encoder_config) override {
|
||||
encoder_ = VP8Encoder::Create();
|
||||
decoder_ = VP8Decoder::Create();
|
||||
|
||||
send_config->post_encode_callback = this;
|
||||
send_config->rtp.payload_name = "VP8";
|
||||
send_config->encoder_settings.encoder = encoder_.get();
|
||||
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
||||
encoder_config->codec_type = kVideoCodecVP8;
|
||||
|
||||
(*receive_configs)[0].decoders.resize(1);
|
||||
@ -107,7 +108,7 @@ TEST_F(LogEndToEndTest, LogsEncodedFramesWhenRequested) {
|
||||
|
||||
private:
|
||||
LogEndToEndTest* const fixture_;
|
||||
std::unique_ptr<VideoEncoder> encoder_;
|
||||
test::FunctionVideoEncoderFactory encoder_factory_;
|
||||
std::unique_ptr<VideoDecoder> decoder_;
|
||||
rtc::CriticalSection crit_;
|
||||
int recorded_frames_ RTC_GUARDED_BY(crit_);
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8.h"
|
||||
#include "test/call_test.h"
|
||||
#include "test/encoder_settings.h"
|
||||
#include "test/function_video_encoder_factory.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -48,7 +49,8 @@ void MultiStreamTester::RunTest() {
|
||||
VideoReceiveStream* receive_streams[kNumStreams];
|
||||
test::FrameGeneratorCapturer* frame_generators[kNumStreams];
|
||||
std::vector<std::unique_ptr<VideoDecoder>> allocated_decoders;
|
||||
std::unique_ptr<VideoEncoder> encoders[kNumStreams];
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[]() { return VP8Encoder::Create(); });
|
||||
|
||||
task_queue_->SendTask([&]() {
|
||||
sender_call = rtc::WrapUnique(Call::Create(config));
|
||||
@ -61,9 +63,6 @@ void MultiStreamTester::RunTest() {
|
||||
sender_transport->SetReceiver(receiver_call->Receiver());
|
||||
receiver_transport->SetReceiver(sender_call->Receiver());
|
||||
|
||||
for (size_t i = 0; i < kNumStreams; ++i)
|
||||
encoders[i] = VP8Encoder::Create();
|
||||
|
||||
for (size_t i = 0; i < kNumStreams; ++i) {
|
||||
uint32_t ssrc = codec_settings[i].ssrc;
|
||||
int width = codec_settings[i].width;
|
||||
@ -71,7 +70,7 @@ void MultiStreamTester::RunTest() {
|
||||
|
||||
VideoSendStream::Config send_config(sender_transport.get());
|
||||
send_config.rtp.ssrcs.push_back(ssrc);
|
||||
send_config.encoder_settings.encoder = encoders[i].get();
|
||||
send_config.encoder_settings.encoder_factory = &encoder_factory;
|
||||
send_config.rtp.payload_name = "VP8";
|
||||
send_config.rtp.payload_type = kVideoPayloadType;
|
||||
VideoEncoderConfig encoder_config;
|
||||
|
||||
@ -10,6 +10,8 @@
|
||||
|
||||
#include "system_wrappers/include/sleep.h"
|
||||
#include "test/call_test.h"
|
||||
#include "test/encoder_proxy_factory.h"
|
||||
#include "test/fake_encoder.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -77,12 +79,15 @@ void NetworkStateEndToEndTest::VerifyNewVideoSendStreamsRespectNetworkState(
|
||||
MediaType network_to_bring_up,
|
||||
VideoEncoder* encoder,
|
||||
Transport* transport) {
|
||||
task_queue_.SendTask([this, network_to_bring_up, encoder, transport]() {
|
||||
test::EncoderProxyFactory encoder_factory(encoder);
|
||||
|
||||
task_queue_.SendTask([this, network_to_bring_up, &encoder_factory,
|
||||
transport]() {
|
||||
CreateSenderCall(Call::Config(event_log_.get()));
|
||||
sender_call_->SignalChannelNetworkState(network_to_bring_up, kNetworkUp);
|
||||
|
||||
CreateSendConfig(1, 0, 0, transport);
|
||||
video_send_config_.encoder_settings.encoder = encoder;
|
||||
video_send_config_.encoder_settings.encoder_factory = &encoder_factory;
|
||||
CreateVideoStreams();
|
||||
CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
|
||||
kDefaultHeight);
|
||||
@ -151,6 +156,7 @@ TEST_F(NetworkStateEndToEndTest, RespectsNetworkState) {
|
||||
packet_event_(false, false),
|
||||
sender_call_(nullptr),
|
||||
receiver_call_(nullptr),
|
||||
encoder_factory_(this),
|
||||
sender_state_(kNetworkUp),
|
||||
sender_rtp_(0),
|
||||
sender_padding_(0),
|
||||
@ -197,7 +203,7 @@ TEST_F(NetworkStateEndToEndTest, RespectsNetworkState) {
|
||||
VideoSendStream::Config* send_config,
|
||||
std::vector<VideoReceiveStream::Config>* receive_configs,
|
||||
VideoEncoderConfig* encoder_config) override {
|
||||
send_config->encoder_settings.encoder = this;
|
||||
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
||||
}
|
||||
|
||||
void PerformTest() override {
|
||||
@ -329,6 +335,7 @@ TEST_F(NetworkStateEndToEndTest, RespectsNetworkState) {
|
||||
rtc::Event packet_event_;
|
||||
Call* sender_call_;
|
||||
Call* receiver_call_;
|
||||
test::EncoderProxyFactory encoder_factory_;
|
||||
NetworkState sender_state_ RTC_GUARDED_BY(test_crit_);
|
||||
int sender_rtp_ RTC_GUARDED_BY(test_crit_);
|
||||
int sender_padding_ RTC_GUARDED_BY(test_crit_);
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#include "system_wrappers/include/sleep.h"
|
||||
#include "test/call_test.h"
|
||||
#include "test/field_trial.h"
|
||||
#include "test/function_video_encoder_factory.h"
|
||||
#include "test/gtest.h"
|
||||
#include "test/rtcp_packet_parser.h"
|
||||
|
||||
@ -339,7 +340,7 @@ void RetransmissionEndToEndTest::DecodesRetransmittedFrame(bool enable_rtx,
|
||||
retransmission_ssrc_(enable_rtx ? kSendRtxSsrcs[0]
|
||||
: kVideoSendSsrcs[0]),
|
||||
retransmission_payload_type_(GetPayloadType(enable_rtx, enable_red)),
|
||||
encoder_(VP8Encoder::Create()),
|
||||
encoder_factory_([]() { return VP8Encoder::Create(); }),
|
||||
marker_bits_observed_(0),
|
||||
retransmitted_timestamp_(0) {}
|
||||
|
||||
@ -437,7 +438,7 @@ void RetransmissionEndToEndTest::DecodesRetransmittedFrame(bool enable_rtx,
|
||||
// Configure encoding and decoding with VP8, since generic packetization
|
||||
// doesn't support FEC with NACK.
|
||||
RTC_DCHECK_EQ(1, (*receive_configs)[0].decoders.size());
|
||||
send_config->encoder_settings.encoder = encoder_.get();
|
||||
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
||||
send_config->rtp.payload_name = "VP8";
|
||||
encoder_config->codec_type = kVideoCodecVP8;
|
||||
(*receive_configs)[0].decoders[0].payload_name = "VP8";
|
||||
@ -469,7 +470,7 @@ void RetransmissionEndToEndTest::DecodesRetransmittedFrame(bool enable_rtx,
|
||||
const int payload_type_;
|
||||
const uint32_t retransmission_ssrc_;
|
||||
const int retransmission_payload_type_;
|
||||
std::unique_ptr<VideoEncoder> encoder_;
|
||||
test::FunctionVideoEncoderFactory encoder_factory_;
|
||||
const std::string payload_name_;
|
||||
int marker_bits_observed_;
|
||||
uint32_t retransmitted_timestamp_ RTC_GUARDED_BY(&crit_);
|
||||
|
||||
@ -468,7 +468,8 @@ TEST_F(RtpRtcpEndToEndTest, TestFlexfecRtpStatePreservation) {
|
||||
|
||||
std::unique_ptr<test::PacketTransport> send_transport;
|
||||
std::unique_ptr<test::PacketTransport> receive_transport;
|
||||
std::unique_ptr<VideoEncoder> encoder;
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[]() { return VP8Encoder::Create(); });
|
||||
|
||||
task_queue_.SendTask([&]() {
|
||||
CreateCalls(config, config);
|
||||
@ -494,8 +495,8 @@ TEST_F(RtpRtcpEndToEndTest, TestFlexfecRtpStatePreservation) {
|
||||
const int kNumFlexfecStreams = 1;
|
||||
CreateSendConfig(kNumVideoStreams, 0, kNumFlexfecStreams,
|
||||
send_transport.get());
|
||||
encoder = VP8Encoder::Create();
|
||||
video_send_config_.encoder_settings.encoder = encoder.get();
|
||||
|
||||
video_send_config_.encoder_settings.encoder_factory = &encoder_factory;
|
||||
video_send_config_.rtp.payload_name = "VP8";
|
||||
video_send_config_.rtp.payload_type = kVideoSendPayloadType;
|
||||
video_send_config_.rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
|
||||
|
||||
@ -14,6 +14,8 @@
|
||||
#include "system_wrappers/include/metrics_default.h"
|
||||
#include "system_wrappers/include/sleep.h"
|
||||
#include "test/call_test.h"
|
||||
#include "test/fake_encoder.h"
|
||||
#include "test/function_video_encoder_factory.h"
|
||||
#include "test/gtest.h"
|
||||
#include "test/rtcp_packet_parser.h"
|
||||
|
||||
@ -37,7 +39,10 @@ TEST_F(StatsEndToEndTest, GetStats) {
|
||||
public:
|
||||
StatsObserver()
|
||||
: EndToEndTest(kLongTimeoutMs),
|
||||
encoder_(Clock::GetRealTimeClock(), 10),
|
||||
encoder_factory_([]() {
|
||||
return rtc::MakeUnique<test::DelayedEncoder>(
|
||||
Clock::GetRealTimeClock(), 10);
|
||||
}),
|
||||
send_stream_(nullptr),
|
||||
expected_send_ssrcs_(),
|
||||
check_stats_event_(false, false) {}
|
||||
@ -297,7 +302,7 @@ TEST_F(StatsEndToEndTest, GetStats) {
|
||||
|
||||
// Use a delayed encoder to make sure we see CpuOveruseMetrics stats that
|
||||
// are non-zero.
|
||||
send_config->encoder_settings.encoder = &encoder_;
|
||||
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
||||
}
|
||||
|
||||
size_t GetNumVideoStreams() const override { return kNumSimulcastStreams; }
|
||||
@ -349,7 +354,7 @@ TEST_F(StatsEndToEndTest, GetStats) {
|
||||
}
|
||||
}
|
||||
|
||||
test::DelayedEncoder encoder_;
|
||||
test::FunctionVideoEncoderFactory encoder_factory_;
|
||||
std::vector<VideoReceiveStream*> receive_streams_;
|
||||
std::map<std::string, bool> receive_stats_filled_;
|
||||
|
||||
|
||||
@ -543,8 +543,10 @@ void OveruseFrameDetector::StartCheckForOveruse(
|
||||
}
|
||||
void OveruseFrameDetector::StopCheckForOveruse() {
|
||||
RTC_DCHECK_CALLED_SEQUENTIALLY(&task_checker_);
|
||||
if (check_overuse_task_) {
|
||||
check_overuse_task_->Stop();
|
||||
check_overuse_task_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void OveruseFrameDetector::EncodedFrameTimeMeasured(int encode_duration_ms) {
|
||||
|
||||
@ -118,6 +118,8 @@ class OveruseFrameDetector {
|
||||
void CheckForOveruse(AdaptationObserverInterface* overuse_observer);
|
||||
void SetOptions(const CpuOveruseOptions& options);
|
||||
|
||||
CpuOveruseOptions options_;
|
||||
|
||||
private:
|
||||
class CheckOveruseTask;
|
||||
|
||||
@ -137,8 +139,6 @@ class OveruseFrameDetector {
|
||||
// Owned by the task queue from where StartCheckForOveruse is called.
|
||||
CheckOveruseTask* check_overuse_task_;
|
||||
|
||||
CpuOveruseOptions options_;
|
||||
|
||||
// Stats metrics.
|
||||
CpuOveruseMetricsObserver* const metrics_observer_;
|
||||
rtc::Optional<CpuOveruseMetrics> metrics_ RTC_GUARDED_BY(task_checker_);
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
#include "rtc_base/numerics/safe_conversions.h"
|
||||
#include "rtc_base/numerics/sequence_number_util.h"
|
||||
#include "test/call_test.h"
|
||||
#include "test/function_video_encoder_factory.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace {
|
||||
@ -235,7 +236,8 @@ class PictureIdTest : public test::CallTest,
|
||||
});
|
||||
}
|
||||
|
||||
void SetupEncoder(VideoEncoder* encoder, const std::string& payload_name);
|
||||
void SetupEncoder(VideoEncoderFactory* encoder_factory,
|
||||
const std::string& payload_name);
|
||||
void TestPictureIdContinuousAfterReconfigure(
|
||||
const std::vector<int>& ssrc_counts);
|
||||
void TestPictureIdIncreaseAfterRecreateStreams(
|
||||
@ -292,12 +294,12 @@ class VideoStreamFactory
|
||||
const size_t num_of_temporal_layers_;
|
||||
};
|
||||
|
||||
void PictureIdTest::SetupEncoder(VideoEncoder* encoder,
|
||||
void PictureIdTest::SetupEncoder(VideoEncoderFactory* encoder_factory,
|
||||
const std::string& payload_name) {
|
||||
observer_.reset(
|
||||
new PictureIdObserver(PayloadNameToRtpVideoCodecType(payload_name)));
|
||||
|
||||
task_queue_.SendTask([this, &encoder, payload_name]() {
|
||||
task_queue_.SendTask([this, encoder_factory, payload_name]() {
|
||||
Call::Config config(event_log_.get());
|
||||
CreateCalls(config, config);
|
||||
|
||||
@ -307,7 +309,7 @@ void PictureIdTest::SetupEncoder(VideoEncoder* encoder,
|
||||
FakeNetworkPipe::Config()));
|
||||
|
||||
CreateSendConfig(kNumSimulcastStreams, 0, 0, send_transport_.get());
|
||||
video_send_config_.encoder_settings.encoder = encoder;
|
||||
video_send_config_.encoder_settings.encoder_factory = encoder_factory;
|
||||
video_send_config_.rtp.payload_name = payload_name;
|
||||
video_encoder_config_.codec_type = PayloadStringToCodecType(payload_name);
|
||||
video_encoder_config_.video_stream_factory =
|
||||
@ -390,51 +392,67 @@ void PictureIdTest::TestPictureIdIncreaseAfterRecreateStreams(
|
||||
}
|
||||
|
||||
TEST_P(PictureIdTest, ContinuousAfterReconfigureVp8) {
|
||||
std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
|
||||
SetupEncoder(encoder.get(), "VP8");
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[]() { return VP8Encoder::Create(); });
|
||||
SetupEncoder(&encoder_factory, "VP8");
|
||||
TestPictureIdContinuousAfterReconfigure({1, 3, 3, 1, 1});
|
||||
}
|
||||
|
||||
TEST_P(PictureIdTest, IncreasingAfterRecreateStreamVp8) {
|
||||
std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
|
||||
SetupEncoder(encoder.get(), "VP8");
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[]() { return VP8Encoder::Create(); });
|
||||
SetupEncoder(&encoder_factory, "VP8");
|
||||
TestPictureIdIncreaseAfterRecreateStreams({1, 3, 3, 1, 1});
|
||||
}
|
||||
|
||||
TEST_P(PictureIdTest, ContinuousAfterStreamCountChangeVp8) {
|
||||
std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[]() { return VP8Encoder::Create(); });
|
||||
// Make sure that the picture id is not reset if the stream count goes
|
||||
// down and then up.
|
||||
SetupEncoder(encoder.get(), "VP8");
|
||||
SetupEncoder(&encoder_factory, "VP8");
|
||||
TestPictureIdContinuousAfterReconfigure({3, 1, 3});
|
||||
}
|
||||
|
||||
TEST_P(PictureIdTest, ContinuousAfterReconfigureSimulcastEncoderAdapter) {
|
||||
InternalEncoderFactory internal_encoder_factory;
|
||||
SimulcastEncoderAdapter simulcast_encoder_adapter(&internal_encoder_factory);
|
||||
SetupEncoder(&simulcast_encoder_adapter, "VP8");
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[&internal_encoder_factory]() {
|
||||
return rtc::MakeUnique<SimulcastEncoderAdapter>(
|
||||
&internal_encoder_factory);
|
||||
});
|
||||
SetupEncoder(&encoder_factory, "VP8");
|
||||
TestPictureIdContinuousAfterReconfigure({1, 3, 3, 1, 1});
|
||||
}
|
||||
|
||||
TEST_P(PictureIdTest, IncreasingAfterRecreateStreamSimulcastEncoderAdapter) {
|
||||
InternalEncoderFactory internal_encoder_factory;
|
||||
SimulcastEncoderAdapter simulcast_encoder_adapter(&internal_encoder_factory);
|
||||
SetupEncoder(&simulcast_encoder_adapter, "VP8");
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[&internal_encoder_factory]() {
|
||||
return rtc::MakeUnique<SimulcastEncoderAdapter>(
|
||||
&internal_encoder_factory);
|
||||
});
|
||||
SetupEncoder(&encoder_factory, "VP8");
|
||||
TestPictureIdIncreaseAfterRecreateStreams({1, 3, 3, 1, 1});
|
||||
}
|
||||
|
||||
TEST_P(PictureIdTest, ContinuousAfterStreamCountChangeSimulcastEncoderAdapter) {
|
||||
InternalEncoderFactory internal_encoder_factory;
|
||||
SimulcastEncoderAdapter simulcast_encoder_adapter(&internal_encoder_factory);
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[&internal_encoder_factory]() {
|
||||
return rtc::MakeUnique<SimulcastEncoderAdapter>(
|
||||
&internal_encoder_factory);
|
||||
});
|
||||
// Make sure that the picture id is not reset if the stream count goes
|
||||
// down and then up.
|
||||
SetupEncoder(&simulcast_encoder_adapter, "VP8");
|
||||
SetupEncoder(&encoder_factory, "VP8");
|
||||
TestPictureIdContinuousAfterReconfigure({3, 1, 3});
|
||||
}
|
||||
|
||||
TEST_P(PictureIdTest, IncreasingAfterRecreateStreamVp9) {
|
||||
std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
|
||||
SetupEncoder(encoder.get(), "VP9");
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[]() { return VP9Encoder::Create(); });
|
||||
SetupEncoder(&encoder_factory, "VP9");
|
||||
TestPictureIdIncreaseAfterRecreateStreams({1, 1});
|
||||
}
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#include "modules/rtp_rtcp/source/rtp_utility.h"
|
||||
#include "modules/video_coding/codecs/h264/include/h264.h"
|
||||
#include "modules/video_coding/codecs/multiplex/include/multiplex_encoder_adapter.h"
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8.h"
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8_common_types.h"
|
||||
#include "modules/video_coding/codecs/vp9/include/vp9.h"
|
||||
#include "rtc_base/cpu_time.h"
|
||||
@ -1074,6 +1075,36 @@ class VideoAnalyzer : public PacketReceiver,
|
||||
const int64_t start_ms_;
|
||||
};
|
||||
|
||||
// Not used by these tests.
|
||||
std::vector<SdpVideoFormat>
|
||||
VideoQualityTest::TestVideoEncoderFactory::GetSupportedFormats() const {
|
||||
RTC_NOTREACHED();
|
||||
return {};
|
||||
}
|
||||
|
||||
VideoEncoderFactory::CodecInfo
|
||||
VideoQualityTest::TestVideoEncoderFactory::QueryVideoEncoder(
|
||||
const SdpVideoFormat& format) const {
|
||||
CodecInfo codec_info;
|
||||
codec_info.is_hardware_accelerated = false;
|
||||
codec_info.has_internal_source = false;
|
||||
return codec_info;
|
||||
}
|
||||
|
||||
std::unique_ptr<VideoEncoder>
|
||||
VideoQualityTest::TestVideoEncoderFactory::CreateVideoEncoder(
|
||||
const SdpVideoFormat& format) {
|
||||
if (format.name == "VP8") {
|
||||
return rtc::MakeUnique<VP8EncoderSimulcastProxy>(
|
||||
&internal_encoder_factory_);
|
||||
} else if (format.name == "multiplex") {
|
||||
return rtc::MakeUnique<MultiplexEncoderAdapter>(
|
||||
&internal_encoder_factory_, SdpVideoFormat(cricket::kVp9CodecName));
|
||||
} else {
|
||||
return internal_encoder_factory_.CreateVideoEncoder(format);
|
||||
}
|
||||
}
|
||||
|
||||
VideoQualityTest::VideoQualityTest()
|
||||
: clock_(Clock::GetRealTimeClock()), receive_logs_(0), send_logs_(0) {
|
||||
payload_type_map_ = test::CallTest::payload_type_map_;
|
||||
@ -1354,7 +1385,6 @@ void VideoQualityTest::SetupVideo(Transport* send_transport,
|
||||
CreateMatchingAudioAndFecConfigs(recv_transport);
|
||||
video_receive_configs_.clear();
|
||||
video_send_configs_.clear();
|
||||
video_encoders_.clear();
|
||||
video_encoder_configs_.clear();
|
||||
allocated_decoders_.clear();
|
||||
bool decode_all_receive_streams = true;
|
||||
@ -1363,7 +1393,6 @@ void VideoQualityTest::SetupVideo(Transport* send_transport,
|
||||
video_encoder_configs_.resize(num_video_streams_);
|
||||
for (size_t video_idx = 0; video_idx < num_video_streams_; ++video_idx) {
|
||||
video_send_configs_.push_back(VideoSendStream::Config(send_transport));
|
||||
video_encoders_.push_back(nullptr);
|
||||
video_encoder_configs_.push_back(VideoEncoderConfig());
|
||||
num_video_substreams = params_.ss[video_idx].streams.size();
|
||||
RTC_CHECK_GT(num_video_substreams, 0);
|
||||
@ -1372,26 +1401,20 @@ void VideoQualityTest::SetupVideo(Transport* send_transport,
|
||||
|
||||
int payload_type;
|
||||
if (params_.video[video_idx].codec == "H264") {
|
||||
video_encoders_[video_idx] =
|
||||
H264Encoder::Create(cricket::VideoCodec("H264"));
|
||||
payload_type = kPayloadTypeH264;
|
||||
} else if (params_.video[video_idx].codec == "VP8") {
|
||||
video_encoders_[video_idx] =
|
||||
rtc::MakeUnique<VP8EncoderSimulcastProxy>(&internal_encoder_factory_);
|
||||
payload_type = kPayloadTypeVP8;
|
||||
} else if (params_.video[video_idx].codec == "VP9") {
|
||||
video_encoders_[video_idx] = VP9Encoder::Create();
|
||||
payload_type = kPayloadTypeVP9;
|
||||
} else if (params_.video[video_idx].codec == "multiplex") {
|
||||
video_encoders_[video_idx] = rtc::MakeUnique<MultiplexEncoderAdapter>(
|
||||
&internal_encoder_factory_, SdpVideoFormat(cricket::kVp9CodecName));
|
||||
payload_type = kPayloadTypeVP9;
|
||||
} else {
|
||||
RTC_NOTREACHED() << "Codec not supported!";
|
||||
return;
|
||||
}
|
||||
video_send_configs_[video_idx].encoder_settings.encoder =
|
||||
video_encoders_[video_idx].get();
|
||||
video_send_configs_[video_idx].encoder_settings.encoder_factory =
|
||||
&video_encoder_factory_;
|
||||
|
||||
video_send_configs_[video_idx].rtp.payload_name =
|
||||
params_.video[video_idx].codec;
|
||||
video_send_configs_[video_idx].rtp.payload_type = payload_type;
|
||||
@ -1416,6 +1439,9 @@ void VideoQualityTest::SetupVideo(Transport* send_transport,
|
||||
video_send_configs_[video_idx].rtp.extensions.push_back(RtpExtension(
|
||||
RtpExtension::kVideoTimingUri, test::kVideoTimingExtensionId));
|
||||
|
||||
video_encoder_configs_[video_idx].video_format.name =
|
||||
params_.video[video_idx].codec;
|
||||
|
||||
video_encoder_configs_[video_idx].codec_type =
|
||||
PayloadStringToCodecType(params_.video[video_idx].codec);
|
||||
|
||||
@ -1600,14 +1626,13 @@ void VideoQualityTest::SetupVideo(Transport* send_transport,
|
||||
void VideoQualityTest::SetupThumbnails(Transport* send_transport,
|
||||
Transport* recv_transport) {
|
||||
for (int i = 0; i < params_.call.num_thumbnails; ++i) {
|
||||
thumbnail_encoders_.emplace_back(VP8Encoder::Create());
|
||||
|
||||
// Thumbnails will be send in the other way: from receiver_call to
|
||||
// sender_call.
|
||||
VideoSendStream::Config thumbnail_send_config(recv_transport);
|
||||
thumbnail_send_config.rtp.ssrcs.push_back(kThumbnailSendSsrcStart + i);
|
||||
thumbnail_send_config.encoder_settings.encoder =
|
||||
thumbnail_encoders_.back().get();
|
||||
// TODO(nisse): Could use a simpler VP8-only encoder factory.
|
||||
thumbnail_send_config.encoder_settings.encoder_factory =
|
||||
&video_encoder_factory_;
|
||||
thumbnail_send_config.rtp.payload_name = params_.video[0].codec;
|
||||
thumbnail_send_config.rtp.payload_type = kPayloadTypeVP8;
|
||||
thumbnail_send_config.rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
|
||||
@ -1625,6 +1650,7 @@ void VideoQualityTest::SetupThumbnails(Transport* send_transport,
|
||||
|
||||
VideoEncoderConfig thumbnail_encoder_config;
|
||||
thumbnail_encoder_config.codec_type = kVideoCodecVP8;
|
||||
thumbnail_encoder_config.video_format.name = "VP8";
|
||||
thumbnail_encoder_config.min_transmit_bitrate_bps = 7500;
|
||||
thumbnail_send_config.suspend_below_min_bitrate =
|
||||
params_.video[0].suspend_below_min_bitrate;
|
||||
|
||||
@ -112,6 +112,18 @@ class VideoQualityTest : public test::CallTest {
|
||||
const std::vector<std::string>& sl_descriptors);
|
||||
|
||||
protected:
|
||||
class TestVideoEncoderFactory : public VideoEncoderFactory {
|
||||
std::vector<SdpVideoFormat> GetSupportedFormats() const override;
|
||||
|
||||
CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override;
|
||||
|
||||
std::unique_ptr<VideoEncoder> CreateVideoEncoder(
|
||||
const SdpVideoFormat& format) override;
|
||||
|
||||
private:
|
||||
InternalEncoderFactory internal_encoder_factory_;
|
||||
};
|
||||
|
||||
std::map<uint8_t, webrtc::MediaType> payload_type_map_;
|
||||
std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory_;
|
||||
|
||||
@ -148,10 +160,8 @@ class VideoQualityTest : public test::CallTest {
|
||||
|
||||
std::vector<std::unique_ptr<test::VideoCapturer>> video_capturers_;
|
||||
std::vector<std::unique_ptr<test::VideoCapturer>> thumbnail_capturers_;
|
||||
InternalEncoderFactory internal_encoder_factory_;
|
||||
std::vector<std::unique_ptr<VideoEncoder>> video_encoders_;
|
||||
TestVideoEncoderFactory video_encoder_factory_;
|
||||
|
||||
std::vector<std::unique_ptr<VideoEncoder>> thumbnail_encoders_;
|
||||
std::vector<VideoSendStream::Config> thumbnail_send_configs_;
|
||||
std::vector<VideoEncoderConfig> thumbnail_encoder_configs_;
|
||||
std::vector<VideoSendStream*> thumbnail_send_streams_;
|
||||
|
||||
@ -77,6 +77,8 @@ VideoSendStream::VideoSendStream(
|
||||
encoder_config.content_type),
|
||||
config_(std::move(config)),
|
||||
content_type_(encoder_config.content_type) {
|
||||
RTC_DCHECK(config_.encoder_settings.encoder_factory);
|
||||
|
||||
video_stream_encoder_ = rtc::MakeUnique<VideoStreamEncoder>(
|
||||
num_cpu_cores, &stats_proxy_,
|
||||
config_.encoder_settings,
|
||||
|
||||
@ -444,7 +444,6 @@ VideoSendStreamImpl::VideoSendStreamImpl(
|
||||
transport_->RegisterPacketFeedbackObserver(this);
|
||||
}
|
||||
|
||||
RTC_DCHECK(config_->encoder_settings.encoder);
|
||||
RTC_DCHECK_GE(config_->rtp.payload_type, 0);
|
||||
RTC_DCHECK_LE(config_->rtp.payload_type, 127);
|
||||
|
||||
|
||||
@ -33,6 +33,8 @@
|
||||
#include "system_wrappers/include/sleep.h"
|
||||
#include "test/call_test.h"
|
||||
#include "test/configurable_frame_size_encoder.h"
|
||||
#include "test/encoder_proxy_factory.h"
|
||||
#include "test/fake_encoder.h"
|
||||
#include "test/fake_texture_frame.h"
|
||||
#include "test/field_trial.h"
|
||||
#include "test/frame_generator.h"
|
||||
@ -198,8 +200,10 @@ TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
|
||||
class TransmissionTimeOffsetObserver : public test::SendTest {
|
||||
public:
|
||||
TransmissionTimeOffsetObserver()
|
||||
: SendTest(kDefaultTimeoutMs),
|
||||
encoder_(Clock::GetRealTimeClock(), kEncodeDelayMs) {
|
||||
: SendTest(kDefaultTimeoutMs), encoder_factory_([]() {
|
||||
return rtc::MakeUnique<test::DelayedEncoder>(
|
||||
Clock::GetRealTimeClock(), kEncodeDelayMs);
|
||||
}) {
|
||||
EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
|
||||
kRtpExtensionTransmissionTimeOffset, test::kTOffsetExtensionId));
|
||||
}
|
||||
@ -222,7 +226,7 @@ TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
|
||||
VideoSendStream::Config* send_config,
|
||||
std::vector<VideoReceiveStream::Config>* receive_configs,
|
||||
VideoEncoderConfig* encoder_config) override {
|
||||
send_config->encoder_settings.encoder = &encoder_;
|
||||
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
||||
send_config->rtp.extensions.clear();
|
||||
send_config->rtp.extensions.push_back(RtpExtension(
|
||||
RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
|
||||
@ -232,7 +236,7 @@ TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
|
||||
EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
|
||||
}
|
||||
|
||||
test::DelayedEncoder encoder_;
|
||||
test::FunctionVideoEncoderFactory encoder_factory_;
|
||||
} test;
|
||||
|
||||
RunBaseTest(&test);
|
||||
@ -243,7 +247,10 @@ TEST_F(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) {
|
||||
class TransportWideSequenceNumberObserver : public test::SendTest {
|
||||
public:
|
||||
TransportWideSequenceNumberObserver()
|
||||
: SendTest(kDefaultTimeoutMs), encoder_(Clock::GetRealTimeClock()) {
|
||||
: SendTest(kDefaultTimeoutMs), encoder_factory_([]() {
|
||||
return rtc::MakeUnique<test::FakeEncoder>(
|
||||
Clock::GetRealTimeClock());
|
||||
}) {
|
||||
EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
|
||||
kRtpExtensionTransportSequenceNumber, kExtensionId));
|
||||
}
|
||||
@ -266,14 +273,14 @@ TEST_F(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) {
|
||||
VideoSendStream::Config* send_config,
|
||||
std::vector<VideoReceiveStream::Config>* receive_configs,
|
||||
VideoEncoderConfig* encoder_config) override {
|
||||
send_config->encoder_settings.encoder = &encoder_;
|
||||
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
||||
}
|
||||
|
||||
void PerformTest() override {
|
||||
EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
|
||||
}
|
||||
|
||||
test::FakeEncoder encoder_;
|
||||
test::FunctionVideoEncoderFactory encoder_factory_;
|
||||
} test;
|
||||
|
||||
RunBaseTest(&test);
|
||||
@ -431,9 +438,9 @@ class UlpfecObserver : public test::EndToEndTest {
|
||||
bool expect_red,
|
||||
bool expect_ulpfec,
|
||||
const std::string& codec,
|
||||
VideoEncoder* encoder)
|
||||
VideoEncoderFactory* encoder_factory)
|
||||
: EndToEndTest(kTimeoutMs),
|
||||
encoder_(encoder),
|
||||
encoder_factory_(encoder_factory),
|
||||
payload_name_(codec),
|
||||
use_nack_(use_nack),
|
||||
expect_red_(expect_red),
|
||||
@ -531,7 +538,7 @@ class UlpfecObserver : public test::EndToEndTest {
|
||||
(*receive_configs)[0].rtp.nack.rtp_history_ms =
|
||||
VideoSendStreamTest::kNackRtpHistoryMs;
|
||||
}
|
||||
send_config->encoder_settings.encoder = encoder_;
|
||||
send_config->encoder_settings.encoder_factory = encoder_factory_;
|
||||
send_config->rtp.payload_name = payload_name_;
|
||||
send_config->rtp.ulpfec.red_payload_type =
|
||||
VideoSendStreamTest::kRedPayloadType;
|
||||
@ -556,7 +563,7 @@ class UlpfecObserver : public test::EndToEndTest {
|
||||
<< "Timed out waiting for ULPFEC and/or media packets.";
|
||||
}
|
||||
|
||||
VideoEncoder* const encoder_;
|
||||
VideoEncoderFactory* encoder_factory_;
|
||||
std::string payload_name_;
|
||||
const bool use_nack_;
|
||||
const bool expect_red_;
|
||||
@ -568,14 +575,16 @@ class UlpfecObserver : public test::EndToEndTest {
|
||||
};
|
||||
|
||||
TEST_F(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
|
||||
std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
|
||||
UlpfecObserver test(true, false, true, true, "VP8", encoder.get());
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[]() { return VP8Encoder::Create(); });
|
||||
UlpfecObserver test(true, false, true, true, "VP8", &encoder_factory);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_F(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
|
||||
std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
|
||||
UlpfecObserver test(false, false, true, true, "VP8", encoder.get());
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[]() { return VP8Encoder::Create(); });
|
||||
UlpfecObserver test(false, false, true, true, "VP8", &encoder_factory);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
@ -588,8 +597,9 @@ class VideoSendStreamWithoutUlpfecTest : public VideoSendStreamTest {
|
||||
};
|
||||
|
||||
TEST_F(VideoSendStreamWithoutUlpfecTest, NoUlpfecIfDisabledThroughFieldTrial) {
|
||||
std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
|
||||
UlpfecObserver test(false, false, true, false, "VP8", encoder.get());
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[]() { return VP8Encoder::Create(); });
|
||||
UlpfecObserver test(false, false, true, false, "VP8", &encoder_factory);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
@ -598,40 +608,46 @@ TEST_F(VideoSendStreamWithoutUlpfecTest, NoUlpfecIfDisabledThroughFieldTrial) {
|
||||
// bandwidth since the receiver has to wait for FEC retransmissions to determine
|
||||
// that the received state is actually decodable.
|
||||
TEST_F(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
|
||||
std::unique_ptr<VideoEncoder> encoder(
|
||||
new test::FakeH264Encoder(Clock::GetRealTimeClock()));
|
||||
UlpfecObserver test(false, true, true, false, "H264", encoder.get());
|
||||
test::FunctionVideoEncoderFactory encoder_factory([]() {
|
||||
return rtc::MakeUnique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
|
||||
});
|
||||
UlpfecObserver test(false, true, true, false, "H264", &encoder_factory);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
// Without retransmissions FEC for H264 is fine.
|
||||
TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForH264WithoutNackEnabled) {
|
||||
std::unique_ptr<VideoEncoder> encoder(
|
||||
new test::FakeH264Encoder(Clock::GetRealTimeClock()));
|
||||
UlpfecObserver test(false, false, true, true, "H264", encoder.get());
|
||||
test::FunctionVideoEncoderFactory encoder_factory([]() {
|
||||
return rtc::MakeUnique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
|
||||
});
|
||||
UlpfecObserver test(false, false, true, true, "H264", &encoder_factory);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
|
||||
TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp8WithNackEnabled) {
|
||||
std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
|
||||
UlpfecObserver test(false, true, true, true, "VP8", encoder.get());
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[]() { return VP8Encoder::Create(); });
|
||||
UlpfecObserver test(false, true, true, true, "VP8", &encoder_factory);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
#if !defined(RTC_DISABLE_VP9)
|
||||
// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
|
||||
TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp9WithNackEnabled) {
|
||||
std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
|
||||
UlpfecObserver test(false, true, true, true, "VP9", encoder.get());
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[]() { return VP9Encoder::Create(); });
|
||||
UlpfecObserver test(false, true, true, true, "VP9", &encoder_factory);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
#endif // !defined(RTC_DISABLE_VP9)
|
||||
|
||||
TEST_F(VideoSendStreamTest, SupportsUlpfecWithMultithreadedH264) {
|
||||
std::unique_ptr<VideoEncoder> encoder(
|
||||
new test::MultithreadedFakeH264Encoder(Clock::GetRealTimeClock()));
|
||||
UlpfecObserver test(false, false, true, true, "H264", encoder.get());
|
||||
test::FunctionVideoEncoderFactory encoder_factory([]() {
|
||||
return rtc::MakeUnique<test::MultithreadedFakeH264Encoder>(
|
||||
Clock::GetRealTimeClock());
|
||||
});
|
||||
UlpfecObserver test(false, false, true, true, "H264", &encoder_factory);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
@ -642,10 +658,10 @@ class FlexfecObserver : public test::EndToEndTest {
|
||||
FlexfecObserver(bool header_extensions_enabled,
|
||||
bool use_nack,
|
||||
const std::string& codec,
|
||||
VideoEncoder* encoder,
|
||||
VideoEncoderFactory* encoder_factory,
|
||||
size_t num_video_streams)
|
||||
: EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
|
||||
encoder_(encoder),
|
||||
encoder_factory_(encoder_factory),
|
||||
payload_name_(codec),
|
||||
use_nack_(use_nack),
|
||||
sent_media_(false),
|
||||
@ -709,7 +725,7 @@ class FlexfecObserver : public test::EndToEndTest {
|
||||
(*receive_configs)[0].rtp.nack.rtp_history_ms =
|
||||
VideoSendStreamTest::kNackRtpHistoryMs;
|
||||
}
|
||||
send_config->encoder_settings.encoder = encoder_;
|
||||
send_config->encoder_settings.encoder_factory = encoder_factory_;
|
||||
send_config->rtp.payload_name = payload_name_;
|
||||
if (header_extensions_enabled_) {
|
||||
send_config->rtp.extensions.push_back(RtpExtension(
|
||||
@ -727,7 +743,7 @@ class FlexfecObserver : public test::EndToEndTest {
|
||||
<< "Timed out waiting for FlexFEC and/or media packets.";
|
||||
}
|
||||
|
||||
VideoEncoder* const encoder_;
|
||||
VideoEncoderFactory* encoder_factory_;
|
||||
std::string payload_name_;
|
||||
const bool use_nack_;
|
||||
bool sent_media_;
|
||||
@ -737,61 +753,72 @@ class FlexfecObserver : public test::EndToEndTest {
|
||||
};
|
||||
|
||||
TEST_F(VideoSendStreamTest, SupportsFlexfecVp8) {
|
||||
std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
|
||||
FlexfecObserver test(false, false, "VP8", encoder.get(), 1);
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[]() { return VP8Encoder::Create(); });
|
||||
FlexfecObserver test(false, false, "VP8", &encoder_factory, 1);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_F(VideoSendStreamTest, SupportsFlexfecSimulcastVp8) {
|
||||
std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
|
||||
FlexfecObserver test(false, false, "VP8", encoder.get(), 2);
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[]() { return VP8Encoder::Create(); });
|
||||
FlexfecObserver test(false, false, "VP8", &encoder_factory, 2);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp8) {
|
||||
std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
|
||||
FlexfecObserver test(false, true, "VP8", encoder.get(), 1);
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[]() { return VP8Encoder::Create(); });
|
||||
FlexfecObserver test(false, true, "VP8", &encoder_factory, 1);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_F(VideoSendStreamTest, SupportsFlexfecWithRtpExtensionsVp8) {
|
||||
std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
|
||||
FlexfecObserver test(true, false, "VP8", encoder.get(), 1);
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[]() { return VP8Encoder::Create(); });
|
||||
FlexfecObserver test(true, false, "VP8", &encoder_factory, 1);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
#if !defined(RTC_DISABLE_VP9)
|
||||
TEST_F(VideoSendStreamTest, SupportsFlexfecVp9) {
|
||||
std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
|
||||
FlexfecObserver test(false, false, "VP9", encoder.get(), 1);
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[]() { return VP9Encoder::Create(); });
|
||||
FlexfecObserver test(false, false, "VP9", &encoder_factory, 1);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp9) {
|
||||
std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
|
||||
FlexfecObserver test(false, true, "VP9", encoder.get(), 1);
|
||||
test::FunctionVideoEncoderFactory encoder_factory(
|
||||
[]() { return VP9Encoder::Create(); });
|
||||
FlexfecObserver test(false, true, "VP9", &encoder_factory, 1);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
#endif // defined(RTC_DISABLE_VP9)
|
||||
|
||||
TEST_F(VideoSendStreamTest, SupportsFlexfecH264) {
|
||||
std::unique_ptr<VideoEncoder> encoder(
|
||||
new test::FakeH264Encoder(Clock::GetRealTimeClock()));
|
||||
FlexfecObserver test(false, false, "H264", encoder.get(), 1);
|
||||
test::FunctionVideoEncoderFactory encoder_factory([]() {
|
||||
return rtc::MakeUnique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
|
||||
});
|
||||
FlexfecObserver test(false, false, "H264", &encoder_factory, 1);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackH264) {
|
||||
std::unique_ptr<VideoEncoder> encoder(
|
||||
new test::FakeH264Encoder(Clock::GetRealTimeClock()));
|
||||
FlexfecObserver test(false, true, "H264", encoder.get(), 1);
|
||||
test::FunctionVideoEncoderFactory encoder_factory([]() {
|
||||
return rtc::MakeUnique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
|
||||
});
|
||||
FlexfecObserver test(false, true, "H264", &encoder_factory, 1);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
TEST_F(VideoSendStreamTest, SupportsFlexfecWithMultithreadedH264) {
|
||||
std::unique_ptr<VideoEncoder> encoder(
|
||||
new test::MultithreadedFakeH264Encoder(Clock::GetRealTimeClock()));
|
||||
FlexfecObserver test(false, false, "H264", encoder.get(), 1);
|
||||
test::FunctionVideoEncoderFactory encoder_factory([]() {
|
||||
return rtc::MakeUnique<test::MultithreadedFakeH264Encoder>(
|
||||
Clock::GetRealTimeClock());
|
||||
});
|
||||
|
||||
FlexfecObserver test(false, false, "H264", &encoder_factory, 1);
|
||||
RunBaseTest(&test);
|
||||
}
|
||||
|
||||
@ -921,6 +948,7 @@ void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
|
||||
bool use_fec)
|
||||
: SendTest(kLongTimeoutMs),
|
||||
encoder_(stop),
|
||||
encoder_factory_(&encoder_),
|
||||
max_packet_size_(max_packet_size),
|
||||
stop_size_(stop_size),
|
||||
test_generic_packetization_(test_generic_packetization),
|
||||
@ -1076,8 +1104,7 @@ void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
|
||||
|
||||
if (!test_generic_packetization_)
|
||||
send_config->rtp.payload_name = "VP8";
|
||||
|
||||
send_config->encoder_settings.encoder = &encoder_;
|
||||
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
||||
send_config->rtp.max_packet_size = kMaxPacketSize;
|
||||
send_config->post_encode_callback = this;
|
||||
|
||||
@ -1120,6 +1147,7 @@ void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
|
||||
|
||||
std::unique_ptr<internal::TransportAdapter> transport_adapter_;
|
||||
test::ConfigurableFrameSizeEncoder encoder_;
|
||||
test::EncoderProxyFactory encoder_factory_;
|
||||
|
||||
const size_t max_packet_size_;
|
||||
const size_t stop_size_;
|
||||
@ -1908,11 +1936,12 @@ TEST_F(VideoSendStreamTest,
|
||||
|
||||
test::NullTransport transport;
|
||||
EncoderObserver encoder;
|
||||
test::EncoderProxyFactory encoder_factory(&encoder);
|
||||
|
||||
task_queue_.SendTask([this, &transport, &encoder]() {
|
||||
task_queue_.SendTask([this, &transport, &encoder_factory]() {
|
||||
CreateSenderCall(Call::Config(event_log_.get()));
|
||||
CreateSendConfig(1, 0, 0, &transport);
|
||||
video_send_config_.encoder_settings.encoder = &encoder;
|
||||
video_send_config_.encoder_settings.encoder_factory = &encoder_factory;
|
||||
CreateVideoStreams();
|
||||
CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
|
||||
kDefaultHeight);
|
||||
@ -1984,10 +2013,11 @@ TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
|
||||
bitrate_config);
|
||||
|
||||
StartBitrateObserver encoder;
|
||||
video_send_config_.encoder_settings.encoder = &encoder;
|
||||
test::EncoderProxyFactory encoder_factory(&encoder);
|
||||
// Since this test does not use a capturer, set |internal_source| = true.
|
||||
// Encoder configuration is otherwise updated on the next video frame.
|
||||
video_send_config_.encoder_settings.internal_source = true;
|
||||
encoder_factory.SetHasInternalSource(true);
|
||||
video_send_config_.encoder_settings.encoder_factory = &encoder_factory;
|
||||
|
||||
CreateVideoStreams();
|
||||
|
||||
@ -2066,17 +2096,24 @@ class StartStopBitrateObserver : public test::FakeEncoder {
|
||||
TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
|
||||
test::NullTransport transport;
|
||||
StartStopBitrateObserver encoder;
|
||||
test::EncoderProxyFactory encoder_factory(&encoder);
|
||||
encoder_factory.SetHasInternalSource(true);
|
||||
test::FrameForwarder forwarder;
|
||||
|
||||
task_queue_.SendTask([this, &transport, &encoder]() {
|
||||
task_queue_.SendTask([this, &transport, &encoder_factory, &forwarder]() {
|
||||
CreateSenderCall(Call::Config(event_log_.get()));
|
||||
CreateSendConfig(1, 0, 0, &transport);
|
||||
|
||||
sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
|
||||
|
||||
video_send_config_.encoder_settings.encoder = &encoder;
|
||||
video_send_config_.encoder_settings.internal_source = true;
|
||||
video_send_config_.encoder_settings.encoder_factory = &encoder_factory;
|
||||
|
||||
CreateVideoStreams();
|
||||
// Inject a frame, to force encoder creation.
|
||||
video_send_stream_->Start();
|
||||
video_send_stream_->SetSource(
|
||||
&forwarder,
|
||||
VideoSendStream::DegradationPreference::kDegradationDisabled);
|
||||
forwarder.IncomingCapturedFrame(CreateVideoFrame(640, 480, 4));
|
||||
});
|
||||
|
||||
EXPECT_TRUE(encoder.WaitForEncoderInit());
|
||||
@ -2109,19 +2146,28 @@ TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
|
||||
TEST_F(VideoSendStreamTest, VideoSendStreamUpdateActiveSimulcastLayers) {
|
||||
test::NullTransport transport;
|
||||
StartStopBitrateObserver encoder;
|
||||
test::EncoderProxyFactory encoder_factory(&encoder);
|
||||
encoder_factory.SetHasInternalSource(true);
|
||||
test::FrameForwarder forwarder;
|
||||
|
||||
task_queue_.SendTask([this, &transport, &encoder]() {
|
||||
task_queue_.SendTask([this, &transport, &encoder_factory, &forwarder]() {
|
||||
CreateSenderCall(Call::Config(event_log_.get()));
|
||||
// Create two simulcast streams.
|
||||
CreateSendConfig(2, 0, 0, &transport);
|
||||
|
||||
sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
|
||||
video_send_config_.encoder_settings.encoder_factory = &encoder_factory;
|
||||
|
||||
video_send_config_.encoder_settings.encoder = &encoder;
|
||||
video_send_config_.encoder_settings.internal_source = true;
|
||||
video_send_config_.rtp.payload_name = "VP8";
|
||||
|
||||
CreateVideoStreams();
|
||||
|
||||
// Inject a frame, to force encoder creation.
|
||||
video_send_stream_->Start();
|
||||
video_send_stream_->SetSource(
|
||||
&forwarder,
|
||||
VideoSendStream::DegradationPreference::kDegradationDisabled);
|
||||
forwarder.IncomingCapturedFrame(CreateVideoFrame(640, 480, 4));
|
||||
});
|
||||
|
||||
EXPECT_TRUE(encoder.WaitForEncoderInit());
|
||||
@ -2270,7 +2316,8 @@ TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
|
||||
initialized_(false),
|
||||
callback_registered_(false),
|
||||
num_releases_(0),
|
||||
released_(false) {}
|
||||
released_(false),
|
||||
encoder_factory_(this) {}
|
||||
|
||||
bool IsReleased() {
|
||||
rtc::CritScope lock(&crit_);
|
||||
@ -2346,7 +2393,7 @@ TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
|
||||
VideoSendStream::Config* send_config,
|
||||
std::vector<VideoReceiveStream::Config>* receive_configs,
|
||||
VideoEncoderConfig* encoder_config) override {
|
||||
send_config->encoder_settings.encoder = this;
|
||||
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
||||
encoder_config_ = encoder_config->Copy();
|
||||
}
|
||||
|
||||
@ -2375,6 +2422,7 @@ TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
|
||||
bool callback_registered_ RTC_GUARDED_BY(crit_);
|
||||
size_t num_releases_ RTC_GUARDED_BY(crit_);
|
||||
bool released_ RTC_GUARDED_BY(crit_);
|
||||
test::EncoderProxyFactory encoder_factory_;
|
||||
VideoEncoderConfig encoder_config_;
|
||||
} test_encoder(&task_queue_);
|
||||
|
||||
@ -2393,14 +2441,15 @@ TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
|
||||
FakeEncoder(Clock::GetRealTimeClock()),
|
||||
init_encode_event_(false, false),
|
||||
num_initializations_(0),
|
||||
stream_(nullptr) {}
|
||||
stream_(nullptr),
|
||||
encoder_factory_(this) {}
|
||||
|
||||
private:
|
||||
void ModifyVideoConfigs(
|
||||
VideoSendStream::Config* send_config,
|
||||
std::vector<VideoReceiveStream::Config>* receive_configs,
|
||||
VideoEncoderConfig* encoder_config) override {
|
||||
send_config->encoder_settings.encoder = this;
|
||||
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
||||
encoder_config->max_bitrate_bps = kFirstMaxBitrateBps;
|
||||
encoder_config_ = encoder_config->Copy();
|
||||
}
|
||||
@ -2444,6 +2493,7 @@ TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
|
||||
rtc::Event init_encode_event_;
|
||||
size_t num_initializations_;
|
||||
VideoSendStream* stream_;
|
||||
test::EncoderProxyFactory encoder_factory_;
|
||||
VideoEncoderConfig encoder_config_;
|
||||
} test;
|
||||
|
||||
@ -2463,7 +2513,8 @@ class VideoCodecConfigObserver : public test::SendTest,
|
||||
codec_name_(codec_name),
|
||||
init_encode_event_(false, false),
|
||||
num_initializations_(0),
|
||||
stream_(nullptr) {
|
||||
stream_(nullptr),
|
||||
encoder_factory_(this) {
|
||||
InitCodecSpecifics();
|
||||
}
|
||||
|
||||
@ -2492,7 +2543,7 @@ class VideoCodecConfigObserver : public test::SendTest,
|
||||
VideoSendStream::Config* send_config,
|
||||
std::vector<VideoReceiveStream::Config>* receive_configs,
|
||||
VideoEncoderConfig* encoder_config) override {
|
||||
send_config->encoder_settings.encoder = this;
|
||||
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
||||
send_config->rtp.payload_name = codec_name_;
|
||||
|
||||
encoder_config->codec_type = video_codec_type_;
|
||||
@ -2552,6 +2603,7 @@ class VideoCodecConfigObserver : public test::SendTest,
|
||||
rtc::Event init_encode_event_;
|
||||
size_t num_initializations_;
|
||||
VideoSendStream* stream_;
|
||||
test::EncoderProxyFactory encoder_factory_;
|
||||
VideoEncoderConfig encoder_config_;
|
||||
};
|
||||
|
||||
@ -2738,7 +2790,8 @@ TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
|
||||
public:
|
||||
ScreencastTargetBitrateTest()
|
||||
: SendTest(kDefaultTimeoutMs),
|
||||
test::FakeEncoder(Clock::GetRealTimeClock()) {}
|
||||
test::FakeEncoder(Clock::GetRealTimeClock()),
|
||||
encoder_factory_(this) {}
|
||||
|
||||
private:
|
||||
int32_t InitEncode(const VideoCodec* config,
|
||||
@ -2754,7 +2807,7 @@ TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
|
||||
VideoSendStream::Config* send_config,
|
||||
std::vector<VideoReceiveStream::Config>* receive_configs,
|
||||
VideoEncoderConfig* encoder_config) override {
|
||||
send_config->encoder_settings.encoder = this;
|
||||
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
||||
EXPECT_EQ(1u, encoder_config->number_of_streams);
|
||||
encoder_config->video_stream_factory =
|
||||
new rtc::RefCountedObject<VideoStreamFactory>();
|
||||
@ -2765,6 +2818,7 @@ TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
|
||||
EXPECT_TRUE(Wait())
|
||||
<< "Timed out while waiting for the encoder to be initialized.";
|
||||
}
|
||||
test::EncoderProxyFactory encoder_factory_;
|
||||
} test;
|
||||
|
||||
RunBaseTest(&test);
|
||||
@ -2792,7 +2846,8 @@ TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
|
||||
target_bitrate_(0),
|
||||
num_initializations_(0),
|
||||
call_(nullptr),
|
||||
send_stream_(nullptr) {}
|
||||
send_stream_(nullptr),
|
||||
encoder_factory_(this) {}
|
||||
|
||||
private:
|
||||
int32_t InitEncode(const VideoCodec* codecSettings,
|
||||
@ -2882,7 +2937,7 @@ TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
|
||||
VideoSendStream::Config* send_config,
|
||||
std::vector<VideoReceiveStream::Config>* receive_configs,
|
||||
VideoEncoderConfig* encoder_config) override {
|
||||
send_config->encoder_settings.encoder = this;
|
||||
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
||||
// Set bitrates lower/higher than min/max to make sure they are properly
|
||||
// capped.
|
||||
encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
|
||||
@ -2945,6 +3000,7 @@ TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
|
||||
int num_initializations_;
|
||||
webrtc::Call* call_;
|
||||
webrtc::VideoSendStream* send_stream_;
|
||||
test::EncoderProxyFactory encoder_factory_;
|
||||
webrtc::VideoEncoderConfig encoder_config_;
|
||||
} test(&task_queue_);
|
||||
|
||||
@ -2965,7 +3021,8 @@ TEST_F(VideoSendStreamTest, ReportsSentResolution) {
|
||||
ScreencastTargetBitrateTest()
|
||||
: SendTest(kDefaultTimeoutMs),
|
||||
test::FakeEncoder(Clock::GetRealTimeClock()),
|
||||
send_stream_(nullptr) {}
|
||||
send_stream_(nullptr),
|
||||
encoder_factory_(this) {}
|
||||
|
||||
private:
|
||||
int32_t Encode(const VideoFrame& input_image,
|
||||
@ -3003,7 +3060,7 @@ TEST_F(VideoSendStreamTest, ReportsSentResolution) {
|
||||
VideoSendStream::Config* send_config,
|
||||
std::vector<VideoReceiveStream::Config>* receive_configs,
|
||||
VideoEncoderConfig* encoder_config) override {
|
||||
send_config->encoder_settings.encoder = this;
|
||||
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
||||
EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
|
||||
}
|
||||
|
||||
@ -3033,6 +3090,7 @@ TEST_F(VideoSendStreamTest, ReportsSentResolution) {
|
||||
}
|
||||
|
||||
VideoSendStream* send_stream_;
|
||||
test::EncoderProxyFactory encoder_factory_;
|
||||
} test;
|
||||
|
||||
RunBaseTest(&test);
|
||||
@ -3043,7 +3101,7 @@ class Vp9HeaderObserver : public test::SendTest {
|
||||
public:
|
||||
Vp9HeaderObserver()
|
||||
: SendTest(VideoSendStreamTest::kLongTimeoutMs),
|
||||
vp9_encoder_(VP9Encoder::Create()),
|
||||
encoder_factory_([]() { return VP9Encoder::Create(); }),
|
||||
vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
|
||||
packets_sent_(0),
|
||||
frames_sent_(0),
|
||||
@ -3084,7 +3142,7 @@ class Vp9HeaderObserver : public test::SendTest {
|
||||
VideoSendStream::Config* send_config,
|
||||
std::vector<VideoReceiveStream::Config>* receive_configs,
|
||||
VideoEncoderConfig* encoder_config) override {
|
||||
send_config->encoder_settings.encoder = vp9_encoder_.get();
|
||||
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
||||
send_config->rtp.payload_name = "VP9";
|
||||
send_config->rtp.payload_type = kVp9PayloadType;
|
||||
ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
|
||||
@ -3346,7 +3404,7 @@ class Vp9HeaderObserver : public test::SendTest {
|
||||
VerifyTl0Idx(vp9);
|
||||
}
|
||||
|
||||
std::unique_ptr<VP9Encoder> vp9_encoder_;
|
||||
test::FunctionVideoEncoderFactory encoder_factory_;
|
||||
VideoCodecVP9 vp9_settings_;
|
||||
webrtc::VideoEncoderConfig encoder_config_;
|
||||
RTPHeader last_header_;
|
||||
@ -3593,6 +3651,7 @@ TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
|
||||
: EndToEndTest(test::CallTest::kDefaultTimeoutMs),
|
||||
FakeEncoder(Clock::GetRealTimeClock()),
|
||||
task_queue_(task_queue),
|
||||
encoder_factory_(this),
|
||||
call_(nullptr),
|
||||
max_bitrate_bps_(0),
|
||||
first_packet_sent_(false),
|
||||
@ -3619,7 +3678,7 @@ TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
|
||||
std::vector<VideoReceiveStream::Config>* receive_configs,
|
||||
VideoEncoderConfig* encoder_config) override {
|
||||
send_config->rtp.max_packet_size = 1200;
|
||||
send_config->encoder_settings.encoder = this;
|
||||
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
||||
EXPECT_FALSE(send_config->rtp.extensions.empty());
|
||||
}
|
||||
|
||||
@ -3646,7 +3705,8 @@ TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
|
||||
// At a bitrate of 60kbps with a packet size of 1200B video and an
|
||||
// overhead of 40B per packet video produces 2240bps overhead.
|
||||
// So the encoder BW should be set to 57760bps.
|
||||
bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
|
||||
EXPECT_TRUE(
|
||||
bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
|
||||
{
|
||||
rtc::CritScope lock(&crit_);
|
||||
EXPECT_LE(max_bitrate_bps_, 57760u);
|
||||
@ -3655,6 +3715,7 @@ TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
|
||||
|
||||
private:
|
||||
test::SingleThreadedTaskQueueForTesting* const task_queue_;
|
||||
test::EncoderProxyFactory encoder_factory_;
|
||||
Call* call_;
|
||||
rtc::CriticalSection crit_;
|
||||
uint32_t max_bitrate_bps_ RTC_GUARDED_BY(&crit_);
|
||||
|
||||
@ -91,10 +91,11 @@ bool IsFramerateScalingEnabled(
|
||||
// out). This should effectively turn off CPU adaptations for systems that
|
||||
// remotely cope with the load right now.
|
||||
CpuOveruseOptions GetCpuOveruseOptions(
|
||||
const VideoSendStream::Config::EncoderSettings& settings) {
|
||||
const VideoSendStream::Config::EncoderSettings& settings,
|
||||
bool full_overuse_time) {
|
||||
CpuOveruseOptions options;
|
||||
|
||||
if (settings.full_overuse_time) {
|
||||
if (full_overuse_time) {
|
||||
options.low_encode_usage_threshold_percent = 150;
|
||||
options.high_encode_usage_threshold_percent = 200;
|
||||
}
|
||||
@ -338,6 +339,7 @@ VideoStreamEncoder::VideoStreamEncoder(
|
||||
pre_encode_callback_(pre_encode_callback),
|
||||
max_framerate_(-1),
|
||||
pending_encoder_reconfiguration_(false),
|
||||
pending_encoder_creation_(false),
|
||||
encoder_start_bitrate_bps_(0),
|
||||
max_data_payload_length_(0),
|
||||
nack_enabled_(false),
|
||||
@ -357,13 +359,6 @@ VideoStreamEncoder::VideoStreamEncoder(
|
||||
encoder_queue_("EncoderQueue") {
|
||||
RTC_DCHECK(stats_proxy);
|
||||
RTC_DCHECK(overuse_detector_);
|
||||
encoder_queue_.PostTask([this] {
|
||||
RTC_DCHECK_RUN_ON(&encoder_queue_);
|
||||
overuse_detector_->StartCheckForOveruse(GetCpuOveruseOptions(settings_),
|
||||
this);
|
||||
video_sender_.RegisterExternalEncoder(
|
||||
settings_.encoder, settings_.internal_source);
|
||||
});
|
||||
}
|
||||
|
||||
VideoStreamEncoder::~VideoStreamEncoder() {
|
||||
@ -422,7 +417,10 @@ void VideoStreamEncoder::SetSource(
|
||||
degradation_preference_ = degradation_preference;
|
||||
bool allow_scaling = IsResolutionScalingEnabled(degradation_preference_);
|
||||
initial_rampup_ = allow_scaling ? 0 : kMaxInitialFramedrop;
|
||||
ConfigureQualityScaler();
|
||||
|
||||
stats_proxy_->SetAdaptationStats(GetActiveCounts(kCpu),
|
||||
GetActiveCounts(kQuality));
|
||||
|
||||
if (!IsFramerateScalingEnabled(degradation_preference) &&
|
||||
max_framerate_ != -1) {
|
||||
// If frame rate scaling is no longer allowed, remove any potential
|
||||
@ -476,6 +474,8 @@ void VideoStreamEncoder::ConfigureEncoderOnTaskQueue(
|
||||
|
||||
max_data_payload_length_ = max_data_payload_length;
|
||||
nack_enabled_ = nack_enabled;
|
||||
pending_encoder_creation_ =
|
||||
(!encoder_ || encoder_config_.video_format != config.video_format);
|
||||
encoder_config_ = std::move(config);
|
||||
pending_encoder_reconfiguration_ = true;
|
||||
|
||||
@ -485,7 +485,8 @@ void VideoStreamEncoder::ConfigureEncoderOnTaskQueue(
|
||||
// The codec configuration depends on incoming video frame size.
|
||||
if (last_frame_info_) {
|
||||
ReconfigureEncoder();
|
||||
} else if (settings_.internal_source) {
|
||||
} else if (settings_.encoder_factory->QueryVideoEncoder(
|
||||
encoder_config_.video_format).has_internal_source) {
|
||||
last_frame_info_ = VideoFrameInfo(176, 144, false);
|
||||
ReconfigureEncoder();
|
||||
}
|
||||
@ -528,6 +529,34 @@ void VideoStreamEncoder::ReconfigureEncoder() {
|
||||
max_framerate_ = codec.maxFramerate;
|
||||
RTC_DCHECK_LE(max_framerate_, kMaxFramerateFps);
|
||||
|
||||
// Keep the same encoder, as long as the video_format is unchanged.
|
||||
if (pending_encoder_creation_) {
|
||||
pending_encoder_creation_ = false;
|
||||
if (encoder_) {
|
||||
video_sender_.RegisterExternalEncoder(nullptr, false);
|
||||
}
|
||||
|
||||
encoder_ = settings_.encoder_factory->CreateVideoEncoder(
|
||||
encoder_config_.video_format);
|
||||
// TODO(nisse): What to do if creating the encoder fails? Crash,
|
||||
// or just discard incoming frames?
|
||||
RTC_CHECK(encoder_);
|
||||
|
||||
ConfigureQualityScaler();
|
||||
|
||||
const webrtc::VideoEncoderFactory::CodecInfo info =
|
||||
settings_.encoder_factory->QueryVideoEncoder(
|
||||
encoder_config_.video_format);
|
||||
|
||||
overuse_detector_->StopCheckForOveruse();
|
||||
overuse_detector_->StartCheckForOveruse(
|
||||
GetCpuOveruseOptions(settings_, info.is_hardware_accelerated), this);
|
||||
|
||||
video_sender_.RegisterExternalEncoder(encoder_.get(),
|
||||
info.has_internal_source);
|
||||
}
|
||||
// RegisterSendCodec implies an unconditional call to
|
||||
// encoder_->InitEncode().
|
||||
bool success = video_sender_.RegisterSendCodec(
|
||||
&codec, number_of_cores_,
|
||||
static_cast<uint32_t>(max_data_payload_length_)) == VCM_OK;
|
||||
@ -563,13 +592,11 @@ void VideoStreamEncoder::ReconfigureEncoder() {
|
||||
int target_framerate = std::min(
|
||||
max_framerate_, source_proxy_->GetActiveSinkWants().max_framerate_fps);
|
||||
overuse_detector_->OnTargetFramerateUpdated(target_framerate);
|
||||
|
||||
ConfigureQualityScaler();
|
||||
}
|
||||
|
||||
void VideoStreamEncoder::ConfigureQualityScaler() {
|
||||
RTC_DCHECK_RUN_ON(&encoder_queue_);
|
||||
const auto scaling_settings = settings_.encoder->GetScalingSettings();
|
||||
const auto scaling_settings = encoder_->GetScalingSettings();
|
||||
const bool quality_scaling_allowed =
|
||||
IsResolutionScalingEnabled(degradation_preference_) &&
|
||||
scaling_settings.thresholds;
|
||||
@ -589,6 +616,8 @@ void VideoStreamEncoder::ConfigureQualityScaler() {
|
||||
initial_rampup_ = kMaxInitialFramedrop;
|
||||
}
|
||||
|
||||
// TODO(nisse): Is this still the right place to do this? This is
|
||||
// now called when the encoder is created.
|
||||
stats_proxy_->SetAdaptationStats(GetActiveCounts(kCpu),
|
||||
GetActiveCounts(kQuality));
|
||||
}
|
||||
@ -723,6 +752,24 @@ void VideoStreamEncoder::MaybeEncodeVideoFrame(const VideoFrame& video_frame,
|
||||
<< ", texture=" << last_frame_info_->is_texture << ".";
|
||||
}
|
||||
|
||||
// We have to create then encoder before the frame drop logic,
|
||||
// because the latter depends on encoder_->GetScalingSettings.
|
||||
// According to the testcase
|
||||
// InitialFrameDropOffWhenEncoderDisabledScaling, the return value
|
||||
// from GetScalingSettings should enable or disable the frame drop.
|
||||
|
||||
int64_t now_ms = clock_->TimeInMilliseconds();
|
||||
if (pending_encoder_reconfiguration_) {
|
||||
ReconfigureEncoder();
|
||||
last_parameters_update_ms_.emplace(now_ms);
|
||||
} else if (!last_parameters_update_ms_ ||
|
||||
now_ms - *last_parameters_update_ms_ >=
|
||||
vcm::VCMProcessTimer::kDefaultProcessIntervalMs) {
|
||||
video_sender_.UpdateChannelParameters(rate_allocator_.get(),
|
||||
bitrate_observer_);
|
||||
last_parameters_update_ms_.emplace(now_ms);
|
||||
}
|
||||
|
||||
if (DropDueToSize(video_frame.size())) {
|
||||
RTC_LOG(LS_INFO) << "Dropping frame. Too large for target bitrate.";
|
||||
int count = GetConstAdaptCounter().ResolutionCount(kQuality);
|
||||
@ -744,17 +791,6 @@ void VideoStreamEncoder::MaybeEncodeVideoFrame(const VideoFrame& video_frame,
|
||||
}
|
||||
initial_rampup_ = kMaxInitialFramedrop;
|
||||
|
||||
int64_t now_ms = clock_->TimeInMilliseconds();
|
||||
if (pending_encoder_reconfiguration_) {
|
||||
ReconfigureEncoder();
|
||||
last_parameters_update_ms_.emplace(now_ms);
|
||||
} else if (!last_parameters_update_ms_ ||
|
||||
now_ms - *last_parameters_update_ms_ >=
|
||||
vcm::VCMProcessTimer::kDefaultProcessIntervalMs) {
|
||||
video_sender_.UpdateChannelParameters(rate_allocator_.get(),
|
||||
bitrate_observer_);
|
||||
last_parameters_update_ms_.emplace(now_ms);
|
||||
}
|
||||
|
||||
if (EncoderPaused()) {
|
||||
// Storing references to a native buffer risks blocking frame capture.
|
||||
@ -986,7 +1022,7 @@ void VideoStreamEncoder::AdaptDown(AdaptReason reason) {
|
||||
bool min_pixels_reached = false;
|
||||
if (!source_proxy_->RequestResolutionLowerThan(
|
||||
adaptation_request.input_pixel_count_,
|
||||
settings_.encoder->GetScalingSettings().min_pixels_per_frame,
|
||||
encoder_->GetScalingSettings().min_pixels_per_frame,
|
||||
&min_pixels_reached)) {
|
||||
if (min_pixels_reached)
|
||||
stats_proxy_->OnMinPixelLimitReached();
|
||||
|
||||
@ -231,6 +231,8 @@ class VideoStreamEncoder : public rtc::VideoSinkInterface<VideoFrame>,
|
||||
rtc::ThreadChecker thread_checker_;
|
||||
|
||||
VideoEncoderConfig encoder_config_ RTC_GUARDED_BY(&encoder_queue_);
|
||||
std::unique_ptr<VideoEncoder> encoder_ RTC_GUARDED_BY(&encoder_queue_)
|
||||
RTC_PT_GUARDED_BY(&encoder_queue_);
|
||||
std::unique_ptr<VideoBitrateAllocator> rate_allocator_
|
||||
RTC_GUARDED_BY(&encoder_queue_)
|
||||
RTC_PT_GUARDED_BY(&encoder_queue_);
|
||||
@ -241,6 +243,9 @@ class VideoStreamEncoder : public rtc::VideoSinkInterface<VideoFrame>,
|
||||
// Set when ConfigureEncoder has been called in order to lazy reconfigure the
|
||||
// encoder on the next frame.
|
||||
bool pending_encoder_reconfiguration_ RTC_GUARDED_BY(&encoder_queue_);
|
||||
// Set when configuration must create a new encoder object, e.g.,
|
||||
// because of a codec change.
|
||||
bool pending_encoder_creation_ RTC_GUARDED_BY(&encoder_queue_);
|
||||
rtc::Optional<VideoFrameInfo> last_frame_info_
|
||||
RTC_GUARDED_BY(&encoder_queue_);
|
||||
int crop_width_ RTC_GUARDED_BY(&encoder_queue_);
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include "rtc_base/logging.h"
|
||||
#include "system_wrappers/include/metrics_default.h"
|
||||
#include "system_wrappers/include/sleep.h"
|
||||
#include "test/encoder_proxy_factory.h"
|
||||
#include "test/encoder_settings.h"
|
||||
#include "test/fake_encoder.h"
|
||||
#include "test/frame_generator.h"
|
||||
@ -83,6 +84,8 @@ class CpuOveruseDetectorProxy : public OveruseFrameDetector {
|
||||
return last_target_framerate_fps_;
|
||||
}
|
||||
|
||||
CpuOveruseOptions GetOptions() { return options_; }
|
||||
|
||||
private:
|
||||
rtc::CriticalSection lock_;
|
||||
int last_target_framerate_fps_ RTC_GUARDED_BY(lock_);
|
||||
@ -272,6 +275,7 @@ class VideoStreamEncoderTest : public ::testing::Test {
|
||||
codec_height_(240),
|
||||
max_framerate_(30),
|
||||
fake_encoder_(),
|
||||
encoder_factory_(&fake_encoder_),
|
||||
stats_proxy_(new MockableSendStatisticsProxy(
|
||||
Clock::GetRealTimeClock(),
|
||||
video_send_config_,
|
||||
@ -281,7 +285,7 @@ class VideoStreamEncoderTest : public ::testing::Test {
|
||||
void SetUp() override {
|
||||
metrics::Reset();
|
||||
video_send_config_ = VideoSendStream::Config(nullptr);
|
||||
video_send_config_.encoder_settings.encoder = &fake_encoder_;
|
||||
video_send_config_.encoder_settings.encoder_factory = &encoder_factory_;
|
||||
video_send_config_.rtp.payload_name = "FAKE";
|
||||
video_send_config_.rtp.payload_type = 125;
|
||||
|
||||
@ -683,6 +687,7 @@ class VideoStreamEncoderTest : public ::testing::Test {
|
||||
int codec_height_;
|
||||
int max_framerate_;
|
||||
TestEncoder fake_encoder_;
|
||||
test::EncoderProxyFactory encoder_factory_;
|
||||
std::unique_ptr<MockableSendStatisticsProxy> stats_proxy_;
|
||||
TestSink sink_;
|
||||
AdaptingFrameForwarder video_source_;
|
||||
@ -1437,11 +1442,16 @@ TEST_F(VideoStreamEncoderTest,
|
||||
EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
|
||||
EXPECT_EQ(1, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
|
||||
|
||||
// Set source with adaptation still enabled but quality scaler is off.
|
||||
// Leave source unchanged, but disable quality scaler.
|
||||
fake_encoder_.SetQualityScaling(false);
|
||||
video_stream_encoder_->SetSource(
|
||||
&video_source_,
|
||||
VideoSendStream::DegradationPreference::kMaintainFramerate);
|
||||
|
||||
VideoEncoderConfig video_encoder_config;
|
||||
test::FillEncoderConfiguration(kVideoCodecVP8, 1, &video_encoder_config);
|
||||
// Make format different, to force recreation of encoder.
|
||||
video_encoder_config.video_format.parameters["foo"] = "foo";
|
||||
video_stream_encoder_->ConfigureEncoder(std::move(video_encoder_config),
|
||||
kMaxPayloadLength,
|
||||
true /* nack_enabled */);
|
||||
|
||||
video_source_.IncomingCapturedFrame(CreateFrame(4, kWidth, kHeight));
|
||||
WaitForEncodedFrame(4);
|
||||
@ -2516,6 +2526,14 @@ TEST_F(VideoStreamEncoderTest, InitialFrameDropOffWhenEncoderDisabledScaling) {
|
||||
const int kWidth = 640;
|
||||
const int kHeight = 360;
|
||||
fake_encoder_.SetQualityScaling(false);
|
||||
|
||||
VideoEncoderConfig video_encoder_config;
|
||||
test::FillEncoderConfiguration(kVideoCodecVP8, 1, &video_encoder_config);
|
||||
// Make format different, to force recreation of encoder.
|
||||
video_encoder_config.video_format.parameters["foo"] = "foo";
|
||||
video_stream_encoder_->ConfigureEncoder(std::move(video_encoder_config),
|
||||
kMaxPayloadLength,
|
||||
true /* nack_enabled */);
|
||||
video_stream_encoder_->OnBitrateUpdated(kLowTargetBitrateBps, 0, 0);
|
||||
|
||||
// Force quality scaler reconfiguration by resetting the source.
|
||||
@ -3314,4 +3332,44 @@ TEST_F(VideoStreamEncoderTest, DoesNotUpdateBitrateAllocationWhenSuspended) {
|
||||
video_stream_encoder_->Stop();
|
||||
}
|
||||
|
||||
TEST_F(VideoStreamEncoderTest,
|
||||
DefaultCpuAdaptationThresholdsForSoftwareEncoder) {
|
||||
const int kFrameWidth = 1280;
|
||||
const int kFrameHeight = 720;
|
||||
const CpuOveruseOptions default_options;
|
||||
video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
|
||||
video_source_.IncomingCapturedFrame(
|
||||
CreateFrame(1, kFrameWidth, kFrameHeight));
|
||||
WaitForEncodedFrame(1);
|
||||
EXPECT_EQ(video_stream_encoder_->overuse_detector_proxy_->GetOptions()
|
||||
.low_encode_usage_threshold_percent,
|
||||
default_options.low_encode_usage_threshold_percent);
|
||||
EXPECT_EQ(video_stream_encoder_->overuse_detector_proxy_->GetOptions()
|
||||
.high_encode_usage_threshold_percent,
|
||||
default_options.high_encode_usage_threshold_percent);
|
||||
video_stream_encoder_->Stop();
|
||||
}
|
||||
|
||||
TEST_F(VideoStreamEncoderTest,
|
||||
HigherCpuAdaptationThresholdsForHardwareEncoder) {
|
||||
const int kFrameWidth = 1280;
|
||||
const int kFrameHeight = 720;
|
||||
CpuOveruseOptions hardware_options;
|
||||
hardware_options.low_encode_usage_threshold_percent = 150;
|
||||
hardware_options.high_encode_usage_threshold_percent = 200;
|
||||
encoder_factory_.SetIsHardwareAccelerated(true);
|
||||
|
||||
video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
|
||||
video_source_.IncomingCapturedFrame(
|
||||
CreateFrame(1, kFrameWidth, kFrameHeight));
|
||||
WaitForEncodedFrame(1);
|
||||
EXPECT_EQ(video_stream_encoder_->overuse_detector_proxy_->GetOptions()
|
||||
.low_encode_usage_threshold_percent,
|
||||
hardware_options.low_encode_usage_threshold_percent);
|
||||
EXPECT_EQ(video_stream_encoder_->overuse_detector_proxy_->GetOptions()
|
||||
.high_encode_usage_threshold_percent,
|
||||
hardware_options.high_encode_usage_threshold_percent);
|
||||
video_stream_encoder_->Stop();
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user