2013-08-20 13:14:07 +00:00
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2013 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.
|
|
|
|
|
*/
|
2013-10-28 10:16:14 +00:00
|
|
|
#include <algorithm> // max
|
2016-03-01 11:52:33 -08:00
|
|
|
#include <memory>
|
2015-03-24 12:37:36 +00:00
|
|
|
#include <vector>
|
2013-10-28 10:16:14 +00:00
|
|
|
|
2018-08-17 14:26:54 +02:00
|
|
|
#include "api/test/simulated_network.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "call/call.h"
|
2018-08-20 13:30:39 +02:00
|
|
|
#include "call/fake_network_pipe.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "call/rtp_transport_controller_send.h"
|
2018-08-20 13:30:39 +02:00
|
|
|
#include "call/simulated_network.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "common_video/include/frame_callback.h"
|
|
|
|
|
#include "common_video/include/video_frame.h"
|
|
|
|
|
#include "modules/rtp_rtcp/include/rtp_header_parser.h"
|
|
|
|
|
#include "modules/rtp_rtcp/include/rtp_rtcp.h"
|
|
|
|
|
#include "modules/rtp_rtcp/source/rtcp_sender.h"
|
|
|
|
|
#include "modules/rtp_rtcp/source/rtp_format_vp9.h"
|
|
|
|
|
#include "modules/video_coding/codecs/vp8/include/vp8.h"
|
|
|
|
|
#include "modules/video_coding/codecs/vp9/include/vp9.h"
|
|
|
|
|
#include "rtc_base/bind.h"
|
|
|
|
|
#include "rtc_base/checks.h"
|
|
|
|
|
#include "rtc_base/criticalsection.h"
|
|
|
|
|
#include "rtc_base/event.h"
|
2018-01-12 10:54:18 +01:00
|
|
|
#include "rtc_base/experiments/alr_experiment.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "rtc_base/logging.h"
|
|
|
|
|
#include "rtc_base/platform_thread.h"
|
|
|
|
|
#include "rtc_base/rate_limiter.h"
|
|
|
|
|
#include "rtc_base/timeutils.h"
|
|
|
|
|
#include "system_wrappers/include/sleep.h"
|
|
|
|
|
#include "test/call_test.h"
|
|
|
|
|
#include "test/configurable_frame_size_encoder.h"
|
2018-04-19 09:04:13 +02:00
|
|
|
#include "test/encoder_proxy_factory.h"
|
|
|
|
|
#include "test/fake_encoder.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "test/fake_texture_frame.h"
|
|
|
|
|
#include "test/field_trial.h"
|
|
|
|
|
#include "test/frame_generator.h"
|
|
|
|
|
#include "test/frame_generator_capturer.h"
|
|
|
|
|
#include "test/frame_utils.h"
|
2018-02-19 19:09:53 +01:00
|
|
|
#include "test/gmock.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "test/gtest.h"
|
|
|
|
|
#include "test/null_transport.h"
|
|
|
|
|
#include "test/rtcp_packet_parser.h"
|
|
|
|
|
#include "test/testsupport/perf_test.h"
|
2016-10-02 23:45:26 -07:00
|
|
|
|
2018-01-16 10:55:29 +01:00
|
|
|
#include "call/video_send_stream.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "video/send_statistics_proxy.h"
|
|
|
|
|
#include "video/transport_adapter.h"
|
2018-01-16 10:55:29 +01:00
|
|
|
#include "video/video_send_stream.h"
|
2013-08-20 13:14:07 +00:00
|
|
|
|
|
|
|
|
namespace webrtc {
|
2018-01-16 10:55:29 +01:00
|
|
|
namespace test {
|
|
|
|
|
class VideoSendStreamPeer {
|
|
|
|
|
public:
|
|
|
|
|
explicit VideoSendStreamPeer(webrtc::VideoSendStream* base_class_stream)
|
|
|
|
|
: internal_stream_(
|
|
|
|
|
static_cast<internal::VideoSendStream*>(base_class_stream)) {}
|
2018-06-15 12:28:07 +02:00
|
|
|
absl::optional<float> GetPacingFactorOverride() const {
|
2018-01-16 10:55:29 +01:00
|
|
|
return internal_stream_->GetPacingFactorOverride();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
internal::VideoSendStream const* const internal_stream_;
|
|
|
|
|
};
|
|
|
|
|
} // namespace test
|
2013-08-20 13:14:07 +00:00
|
|
|
|
2014-02-18 08:40:33 +00:00
|
|
|
enum VideoFormat {
|
|
|
|
|
kGeneric,
|
|
|
|
|
kVP8,
|
|
|
|
|
};
|
|
|
|
|
|
2015-05-29 17:21:40 -07:00
|
|
|
void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
|
|
|
|
|
const std::vector<VideoFrame>& frames2);
|
|
|
|
|
VideoFrame CreateVideoFrame(int width, int height, uint8_t data);
|
2014-06-20 12:04:05 +00:00
|
|
|
|
2014-06-27 08:47:52 +00:00
|
|
|
class VideoSendStreamTest : public test::CallTest {
|
2013-08-22 09:42:17 +00:00
|
|
|
protected:
|
2013-11-15 12:32:15 +00:00
|
|
|
void TestNackRetransmission(uint32_t retransmit_ssrc,
|
2014-06-12 15:12:25 +00:00
|
|
|
uint8_t retransmit_payload_type);
|
2014-02-18 08:40:33 +00:00
|
|
|
void TestPacketFragmentationSize(VideoFormat format, bool with_fec);
|
2015-12-04 10:58:08 +01:00
|
|
|
|
|
|
|
|
void TestVp9NonFlexMode(uint8_t num_temporal_layers,
|
|
|
|
|
uint8_t num_spatial_layers);
|
2016-11-01 11:45:46 -07:00
|
|
|
|
|
|
|
|
void TestRequestSourceRotateVideo(bool support_orientation_ext);
|
2013-08-22 09:42:17 +00:00
|
|
|
};
|
|
|
|
|
|
2014-01-10 18:47:32 +00:00
|
|
|
TEST_F(VideoSendStreamTest, CanStartStartedStream) {
|
2017-08-22 04:02:52 -07:00
|
|
|
task_queue_.SendTask([this]() {
|
2018-07-13 10:43:20 +02:00
|
|
|
CreateSenderCall();
|
2014-06-27 08:47:52 +00:00
|
|
|
|
2017-08-22 04:02:52 -07:00
|
|
|
test::NullTransport transport;
|
|
|
|
|
CreateSendConfig(1, 0, 0, &transport);
|
|
|
|
|
CreateVideoStreams();
|
2018-07-13 09:49:00 +02:00
|
|
|
GetVideoSendStream()->Start();
|
|
|
|
|
GetVideoSendStream()->Start();
|
2017-08-22 04:02:52 -07:00
|
|
|
DestroyStreams();
|
|
|
|
|
DestroyCalls();
|
|
|
|
|
});
|
2014-01-10 18:47:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(VideoSendStreamTest, CanStopStoppedStream) {
|
2017-08-22 04:02:52 -07:00
|
|
|
task_queue_.SendTask([this]() {
|
2018-07-13 10:43:20 +02:00
|
|
|
CreateSenderCall();
|
2014-06-27 08:47:52 +00:00
|
|
|
|
2017-08-22 04:02:52 -07:00
|
|
|
test::NullTransport transport;
|
|
|
|
|
CreateSendConfig(1, 0, 0, &transport);
|
|
|
|
|
CreateVideoStreams();
|
2018-07-13 09:49:00 +02:00
|
|
|
GetVideoSendStream()->Stop();
|
|
|
|
|
GetVideoSendStream()->Stop();
|
2017-08-22 04:02:52 -07:00
|
|
|
DestroyStreams();
|
|
|
|
|
DestroyCalls();
|
|
|
|
|
});
|
2014-01-10 18:47:32 +00:00
|
|
|
}
|
|
|
|
|
|
2013-08-22 09:42:17 +00:00
|
|
|
TEST_F(VideoSendStreamTest, SupportsCName) {
|
|
|
|
|
static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
|
2014-06-27 08:47:52 +00:00
|
|
|
class CNameObserver : public test::SendTest {
|
2013-08-22 09:42:17 +00:00
|
|
|
public:
|
2014-06-27 08:47:52 +00:00
|
|
|
CNameObserver() : SendTest(kDefaultTimeoutMs) {}
|
2013-08-22 09:42:17 +00:00
|
|
|
|
2014-06-27 08:47:52 +00:00
|
|
|
private:
|
2015-03-04 12:58:35 +00:00
|
|
|
Action OnSendRtcp(const uint8_t* packet, size_t length) override {
|
2016-11-02 08:21:59 -07:00
|
|
|
test::RtcpPacketParser parser;
|
|
|
|
|
EXPECT_TRUE(parser.Parse(packet, length));
|
|
|
|
|
if (parser.sdes()->num_packets() > 0) {
|
|
|
|
|
EXPECT_EQ(1u, parser.sdes()->chunks().size());
|
|
|
|
|
EXPECT_EQ(kCName, parser.sdes()->chunks()[0].cname);
|
2013-08-22 09:42:17 +00:00
|
|
|
|
2016-11-02 08:21:59 -07:00
|
|
|
observation_complete_.Set();
|
2013-08-22 09:42:17 +00:00
|
|
|
}
|
|
|
|
|
|
2013-11-15 12:32:15 +00:00
|
|
|
return SEND_PACKET;
|
2013-08-22 09:42:17 +00:00
|
|
|
}
|
|
|
|
|
|
2015-12-21 03:14:00 -08:00
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
2014-06-27 08:47:52 +00:00
|
|
|
send_config->rtp.c_name = kCName;
|
|
|
|
|
}
|
2013-08-22 09:42:17 +00:00
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
void PerformTest() override {
|
2015-12-10 13:02:50 +01:00
|
|
|
EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP with CNAME.";
|
2014-06-27 08:47:52 +00:00
|
|
|
}
|
|
|
|
|
} test;
|
2013-08-22 09:42:17 +00:00
|
|
|
|
2016-01-08 06:47:13 -08:00
|
|
|
RunBaseTest(&test);
|
2013-08-20 13:14:07 +00:00
|
|
|
}
|
|
|
|
|
|
2013-09-11 19:00:39 +00:00
|
|
|
TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
|
2014-06-27 08:47:52 +00:00
|
|
|
class AbsoluteSendTimeObserver : public test::SendTest {
|
2013-09-11 19:00:39 +00:00
|
|
|
public:
|
2014-06-27 08:47:52 +00:00
|
|
|
AbsoluteSendTimeObserver() : SendTest(kDefaultTimeoutMs) {
|
2013-11-15 12:32:15 +00:00
|
|
|
EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
|
2015-12-08 09:10:43 +01:00
|
|
|
kRtpExtensionAbsoluteSendTime, test::kAbsSendTimeExtensionId));
|
2013-09-11 19:00:39 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
Action OnSendRtp(const uint8_t* packet, size_t length) override {
|
2013-09-11 19:00:39 +00:00
|
|
|
RTPHeader header;
|
2014-07-08 12:10:51 +00:00
|
|
|
EXPECT_TRUE(parser_->Parse(packet, length, &header));
|
2013-09-11 19:00:39 +00:00
|
|
|
|
2013-12-16 12:24:44 +00:00
|
|
|
EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
|
|
|
|
|
EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
|
|
|
|
|
EXPECT_EQ(header.extension.transmissionTimeOffset, 0);
|
2016-09-02 13:23:46 -07:00
|
|
|
if (header.extension.absoluteSendTime != 0) {
|
|
|
|
|
// Wait for at least one packet with a non-zero send time. The send time
|
|
|
|
|
// is a 16-bit value derived from the system clock, and it is valid
|
|
|
|
|
// for a packet to have a zero send time. To tell that from an
|
|
|
|
|
// unpopulated value we'll wait for a packet with non-zero send time.
|
|
|
|
|
observation_complete_.Set();
|
|
|
|
|
} else {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_WARNING)
|
|
|
|
|
<< "Got a packet with zero absoluteSendTime, waiting"
|
|
|
|
|
" for another packet...";
|
2016-09-02 13:23:46 -07:00
|
|
|
}
|
2013-09-11 19:00:39 +00:00
|
|
|
|
2013-11-15 12:32:15 +00:00
|
|
|
return SEND_PACKET;
|
2013-09-11 19:00:39 +00:00
|
|
|
}
|
|
|
|
|
|
2015-12-21 03:14:00 -08:00
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
2015-04-10 11:58:49 +02:00
|
|
|
send_config->rtp.extensions.clear();
|
2015-12-08 09:10:43 +01:00
|
|
|
send_config->rtp.extensions.push_back(RtpExtension(
|
2016-05-26 11:24:55 -07:00
|
|
|
RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
|
2014-06-27 08:47:52 +00:00
|
|
|
}
|
2014-08-05 23:35:43 +00:00
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
void PerformTest() override {
|
2015-12-10 13:02:50 +01:00
|
|
|
EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
|
2014-06-27 08:47:52 +00:00
|
|
|
}
|
|
|
|
|
} test;
|
2013-09-11 19:00:39 +00:00
|
|
|
|
2016-01-08 06:47:13 -08:00
|
|
|
RunBaseTest(&test);
|
2013-09-11 19:00:39 +00:00
|
|
|
}
|
|
|
|
|
|
2013-09-11 10:14:56 +00:00
|
|
|
TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
|
2014-11-20 10:19:46 +00:00
|
|
|
static const int kEncodeDelayMs = 5;
|
2014-06-27 08:47:52 +00:00
|
|
|
class TransmissionTimeOffsetObserver : public test::SendTest {
|
2013-09-11 10:14:56 +00:00
|
|
|
public:
|
2014-06-27 08:47:52 +00:00
|
|
|
TransmissionTimeOffsetObserver()
|
2018-04-19 09:04:13 +02:00
|
|
|
: SendTest(kDefaultTimeoutMs), encoder_factory_([]() {
|
Use absl::make_unique and absl::WrapUnique directly
Instead of going through our wrappers in ptr_util.h.
This CL was generated by the following script:
git grep -l ptr_util | xargs perl -pi -e 's,#include "rtc_base/ptr_util.h",#include "absl/memory/memory.h",'
git grep -l MakeUnique | xargs perl -pi -e 's,\b(rtc::)?MakeUnique\b,absl::make_unique,g'
git grep -l WrapUnique | xargs perl -pi -e 's,\b(rtc::)?WrapUnique\b,absl::WrapUnique,g'
git checkout -- rtc_base/ptr_util{.h,_unittest.cc}
git cl format
Followed by manually adding dependencies on
//third_party/abseil-cpp/absl/memory until `gn check` stopped
complaining.
Bug: webrtc:9473
Change-Id: I89ccd363f070479b8c431eb2c3d404a46eaacc1c
Reviewed-on: https://webrtc-review.googlesource.com/86600
Commit-Queue: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23850}
2018-07-05 11:40:33 +02:00
|
|
|
return absl::make_unique<test::DelayedEncoder>(
|
2018-04-19 09:04:13 +02:00
|
|
|
Clock::GetRealTimeClock(), kEncodeDelayMs);
|
|
|
|
|
}) {
|
2013-11-15 12:32:15 +00:00
|
|
|
EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
|
2015-10-29 15:13:24 +01:00
|
|
|
kRtpExtensionTransmissionTimeOffset, test::kTOffsetExtensionId));
|
2013-09-11 10:14:56 +00:00
|
|
|
}
|
|
|
|
|
|
2014-06-27 08:47:52 +00:00
|
|
|
private:
|
2015-03-04 12:58:35 +00:00
|
|
|
Action OnSendRtp(const uint8_t* packet, size_t length) override {
|
2013-09-11 10:14:56 +00:00
|
|
|
RTPHeader header;
|
2014-07-08 12:10:51 +00:00
|
|
|
EXPECT_TRUE(parser_->Parse(packet, length, &header));
|
2013-09-11 10:14:56 +00:00
|
|
|
|
2013-12-16 12:24:44 +00:00
|
|
|
EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
|
|
|
|
|
EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
|
2013-09-11 10:14:56 +00:00
|
|
|
EXPECT_GT(header.extension.transmissionTimeOffset, 0);
|
2013-12-16 12:24:44 +00:00
|
|
|
EXPECT_EQ(header.extension.absoluteSendTime, 0u);
|
2015-12-10 13:02:50 +01:00
|
|
|
observation_complete_.Set();
|
2013-09-11 10:14:56 +00:00
|
|
|
|
2013-11-15 12:32:15 +00:00
|
|
|
return SEND_PACKET;
|
2013-09-11 10:14:56 +00:00
|
|
|
}
|
|
|
|
|
|
2015-12-21 03:14:00 -08:00
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
2018-04-19 09:04:13 +02:00
|
|
|
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
2015-10-29 15:13:24 +01:00
|
|
|
send_config->rtp.extensions.clear();
|
2016-05-26 11:24:55 -07:00
|
|
|
send_config->rtp.extensions.push_back(RtpExtension(
|
|
|
|
|
RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
|
2014-06-27 08:47:52 +00:00
|
|
|
}
|
2013-09-11 10:14:56 +00:00
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
void PerformTest() override {
|
2015-12-10 13:02:50 +01:00
|
|
|
EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
|
2014-06-27 08:47:52 +00:00
|
|
|
}
|
2013-09-11 10:14:56 +00:00
|
|
|
|
2018-04-19 09:04:13 +02:00
|
|
|
test::FunctionVideoEncoderFactory encoder_factory_;
|
2014-06-27 08:47:52 +00:00
|
|
|
} test;
|
|
|
|
|
|
2016-01-08 06:47:13 -08:00
|
|
|
RunBaseTest(&test);
|
2013-09-11 10:14:56 +00:00
|
|
|
}
|
|
|
|
|
|
2015-08-03 04:38:41 -07:00
|
|
|
TEST_F(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) {
|
2016-10-31 03:34:40 -07:00
|
|
|
static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
|
2015-08-03 04:38:41 -07:00
|
|
|
class TransportWideSequenceNumberObserver : public test::SendTest {
|
|
|
|
|
public:
|
|
|
|
|
TransportWideSequenceNumberObserver()
|
2018-04-19 09:04:13 +02:00
|
|
|
: SendTest(kDefaultTimeoutMs), encoder_factory_([]() {
|
Use absl::make_unique and absl::WrapUnique directly
Instead of going through our wrappers in ptr_util.h.
This CL was generated by the following script:
git grep -l ptr_util | xargs perl -pi -e 's,#include "rtc_base/ptr_util.h",#include "absl/memory/memory.h",'
git grep -l MakeUnique | xargs perl -pi -e 's,\b(rtc::)?MakeUnique\b,absl::make_unique,g'
git grep -l WrapUnique | xargs perl -pi -e 's,\b(rtc::)?WrapUnique\b,absl::WrapUnique,g'
git checkout -- rtc_base/ptr_util{.h,_unittest.cc}
git cl format
Followed by manually adding dependencies on
//third_party/abseil-cpp/absl/memory until `gn check` stopped
complaining.
Bug: webrtc:9473
Change-Id: I89ccd363f070479b8c431eb2c3d404a46eaacc1c
Reviewed-on: https://webrtc-review.googlesource.com/86600
Commit-Queue: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23850}
2018-07-05 11:40:33 +02:00
|
|
|
return absl::make_unique<test::FakeEncoder>(
|
2018-04-19 09:04:13 +02:00
|
|
|
Clock::GetRealTimeClock());
|
|
|
|
|
}) {
|
2015-08-03 04:38:41 -07:00
|
|
|
EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
|
|
|
|
|
kRtpExtensionTransportSequenceNumber, kExtensionId));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
Action OnSendRtp(const uint8_t* packet, size_t length) override {
|
|
|
|
|
RTPHeader header;
|
|
|
|
|
EXPECT_TRUE(parser_->Parse(packet, length, &header));
|
|
|
|
|
|
|
|
|
|
EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
|
|
|
|
|
EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
|
|
|
|
|
EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
|
|
|
|
|
|
2015-12-10 13:02:50 +01:00
|
|
|
observation_complete_.Set();
|
2015-08-03 04:38:41 -07:00
|
|
|
|
|
|
|
|
return SEND_PACKET;
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-21 03:14:00 -08:00
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
2018-04-19 09:04:13 +02:00
|
|
|
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
2015-08-03 04:38:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PerformTest() override {
|
2015-12-10 13:02:50 +01:00
|
|
|
EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
|
2015-08-03 04:38:41 -07:00
|
|
|
}
|
|
|
|
|
|
2018-04-19 09:04:13 +02:00
|
|
|
test::FunctionVideoEncoderFactory encoder_factory_;
|
2015-08-03 04:38:41 -07:00
|
|
|
} test;
|
|
|
|
|
|
2016-01-08 06:47:13 -08:00
|
|
|
RunBaseTest(&test);
|
2015-08-03 04:38:41 -07:00
|
|
|
}
|
|
|
|
|
|
2016-11-01 11:45:46 -07:00
|
|
|
TEST_F(VideoSendStreamTest, SupportsVideoRotation) {
|
|
|
|
|
class VideoRotationObserver : public test::SendTest {
|
|
|
|
|
public:
|
|
|
|
|
VideoRotationObserver() : SendTest(kDefaultTimeoutMs) {
|
|
|
|
|
EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
|
|
|
|
|
kRtpExtensionVideoRotation, test::kVideoRotationExtensionId));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Action OnSendRtp(const uint8_t* packet, size_t length) override {
|
|
|
|
|
RTPHeader header;
|
|
|
|
|
EXPECT_TRUE(parser_->Parse(packet, length, &header));
|
2017-05-23 09:34:21 -07:00
|
|
|
// Only the last packet of the frame is required to have the extension.
|
|
|
|
|
if (!header.markerBit)
|
|
|
|
|
return SEND_PACKET;
|
2016-11-01 11:45:46 -07:00
|
|
|
EXPECT_TRUE(header.extension.hasVideoRotation);
|
|
|
|
|
EXPECT_EQ(kVideoRotation_90, header.extension.videoRotation);
|
|
|
|
|
observation_complete_.Set();
|
|
|
|
|
return SEND_PACKET;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
|
|
|
|
send_config->rtp.extensions.clear();
|
|
|
|
|
send_config->rtp.extensions.push_back(RtpExtension(
|
|
|
|
|
RtpExtension::kVideoRotationUri, test::kVideoRotationExtensionId));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OnFrameGeneratorCapturerCreated(
|
|
|
|
|
test::FrameGeneratorCapturer* frame_generator_capturer) override {
|
|
|
|
|
frame_generator_capturer->SetFakeRotation(kVideoRotation_90);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PerformTest() override {
|
|
|
|
|
EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
|
|
|
|
|
}
|
|
|
|
|
} test;
|
|
|
|
|
|
|
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-11 10:34:31 -07:00
|
|
|
TEST_F(VideoSendStreamTest, SupportsVideoContentType) {
|
2017-06-21 08:23:19 -07:00
|
|
|
class VideoContentTypeObserver : public test::SendTest {
|
2017-04-11 10:34:31 -07:00
|
|
|
public:
|
2018-03-12 10:42:08 +01:00
|
|
|
VideoContentTypeObserver()
|
|
|
|
|
: SendTest(kDefaultTimeoutMs), first_frame_sent_(false) {
|
2017-04-11 10:34:31 -07:00
|
|
|
EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
|
|
|
|
|
kRtpExtensionVideoContentType, test::kVideoContentTypeExtensionId));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Action OnSendRtp(const uint8_t* packet, size_t length) override {
|
|
|
|
|
RTPHeader header;
|
|
|
|
|
EXPECT_TRUE(parser_->Parse(packet, length, &header));
|
2018-03-12 10:42:08 +01:00
|
|
|
// Only the last packet of the key-frame must have extension.
|
|
|
|
|
if (!header.markerBit || first_frame_sent_)
|
2017-05-23 09:34:21 -07:00
|
|
|
return SEND_PACKET;
|
2018-03-12 10:42:08 +01:00
|
|
|
// First marker bit seen means that the first frame is sent.
|
|
|
|
|
first_frame_sent_ = true;
|
2017-04-11 10:34:31 -07:00
|
|
|
EXPECT_TRUE(header.extension.hasVideoContentType);
|
2017-08-30 03:32:14 -07:00
|
|
|
EXPECT_TRUE(videocontenttypehelpers::IsScreenshare(
|
|
|
|
|
header.extension.videoContentType));
|
2017-04-11 10:34:31 -07:00
|
|
|
observation_complete_.Set();
|
|
|
|
|
return SEND_PACKET;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
|
|
|
|
send_config->rtp.extensions.clear();
|
|
|
|
|
send_config->rtp.extensions.push_back(
|
|
|
|
|
RtpExtension(RtpExtension::kVideoContentTypeUri,
|
|
|
|
|
test::kVideoContentTypeExtensionId));
|
|
|
|
|
encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PerformTest() override {
|
|
|
|
|
EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
|
|
|
|
|
}
|
2018-03-12 10:42:08 +01:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
bool first_frame_sent_;
|
2017-04-11 10:34:31 -07:00
|
|
|
} test;
|
|
|
|
|
|
|
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-19 07:18:55 -07:00
|
|
|
TEST_F(VideoSendStreamTest, SupportsVideoTimingFrames) {
|
2017-06-21 08:23:19 -07:00
|
|
|
class VideoTimingObserver : public test::SendTest {
|
2017-06-19 07:18:55 -07:00
|
|
|
public:
|
2017-06-21 08:23:19 -07:00
|
|
|
VideoTimingObserver() : SendTest(kDefaultTimeoutMs) {
|
2017-06-19 07:18:55 -07:00
|
|
|
EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
|
|
|
|
|
kRtpExtensionVideoTiming, test::kVideoTimingExtensionId));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Action OnSendRtp(const uint8_t* packet, size_t length) override {
|
|
|
|
|
RTPHeader header;
|
|
|
|
|
EXPECT_TRUE(parser_->Parse(packet, length, &header));
|
2017-06-21 08:23:19 -07:00
|
|
|
// Only the last packet of the frame must have extension.
|
|
|
|
|
if (!header.markerBit)
|
|
|
|
|
return SEND_PACKET;
|
|
|
|
|
EXPECT_TRUE(header.extension.has_video_timing);
|
|
|
|
|
observation_complete_.Set();
|
2017-06-19 07:18:55 -07:00
|
|
|
return SEND_PACKET;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
|
|
|
|
send_config->rtp.extensions.clear();
|
|
|
|
|
send_config->rtp.extensions.push_back(RtpExtension(
|
|
|
|
|
RtpExtension::kVideoTimingUri, test::kVideoTimingExtensionId));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PerformTest() override {
|
|
|
|
|
EXPECT_TRUE(Wait()) << "Timed out while waiting for timing frames.";
|
|
|
|
|
}
|
|
|
|
|
} test;
|
|
|
|
|
|
|
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-28 08:56:04 -07:00
|
|
|
class FakeReceiveStatistics : public ReceiveStatisticsProvider {
|
2013-09-20 11:56:26 +00:00
|
|
|
public:
|
2013-10-23 11:04:57 +00:00
|
|
|
FakeReceiveStatistics(uint32_t send_ssrc,
|
|
|
|
|
uint32_t last_sequence_number,
|
|
|
|
|
uint32_t cumulative_lost,
|
2017-07-28 08:56:04 -07:00
|
|
|
uint8_t fraction_lost) {
|
|
|
|
|
stat_.SetMediaSsrc(send_ssrc);
|
|
|
|
|
stat_.SetExtHighestSeqNum(last_sequence_number);
|
|
|
|
|
stat_.SetCumulativeLost(cumulative_lost);
|
|
|
|
|
stat_.SetFractionLost(fraction_lost);
|
2013-09-20 11:56:26 +00:00
|
|
|
}
|
|
|
|
|
|
2017-07-28 08:56:04 -07:00
|
|
|
std::vector<rtcp::ReportBlock> RtcpReportBlocks(size_t max_blocks) override {
|
|
|
|
|
EXPECT_GE(max_blocks, 1u);
|
|
|
|
|
return {stat_};
|
2013-09-20 11:56:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
2017-07-28 08:56:04 -07:00
|
|
|
rtcp::ReportBlock stat_;
|
2013-09-20 11:56:26 +00:00
|
|
|
};
|
|
|
|
|
|
2016-10-31 03:40:49 -07:00
|
|
|
class UlpfecObserver : public test::EndToEndTest {
|
2015-12-08 09:10:43 +01:00
|
|
|
public:
|
2016-10-31 03:40:49 -07:00
|
|
|
UlpfecObserver(bool header_extensions_enabled,
|
2016-12-12 01:54:58 -08:00
|
|
|
bool use_nack,
|
|
|
|
|
bool expect_red,
|
|
|
|
|
bool expect_ulpfec,
|
2016-12-19 05:47:28 -08:00
|
|
|
const std::string& codec,
|
2018-04-19 09:04:13 +02:00
|
|
|
VideoEncoderFactory* encoder_factory)
|
2017-01-02 00:34:27 -08:00
|
|
|
: EndToEndTest(kTimeoutMs),
|
2018-04-19 09:04:13 +02:00
|
|
|
encoder_factory_(encoder_factory),
|
2016-02-15 11:27:15 +01:00
|
|
|
payload_name_(codec),
|
|
|
|
|
use_nack_(use_nack),
|
|
|
|
|
expect_red_(expect_red),
|
2016-10-31 03:40:49 -07:00
|
|
|
expect_ulpfec_(expect_ulpfec),
|
2016-12-12 01:54:58 -08:00
|
|
|
sent_media_(false),
|
|
|
|
|
sent_ulpfec_(false),
|
2016-12-19 05:47:28 -08:00
|
|
|
header_extensions_enabled_(header_extensions_enabled) {}
|
2013-09-10 14:56:33 +00:00
|
|
|
|
2017-01-02 00:34:27 -08:00
|
|
|
// Some of the test cases are expected to time out and thus we are using
|
|
|
|
|
// a shorter timeout window than the default here.
|
|
|
|
|
static constexpr size_t kTimeoutMs = 10000;
|
|
|
|
|
|
2015-12-08 09:10:43 +01:00
|
|
|
private:
|
|
|
|
|
Action OnSendRtp(const uint8_t* packet, size_t length) override {
|
|
|
|
|
RTPHeader header;
|
|
|
|
|
EXPECT_TRUE(parser_->Parse(packet, length, &header));
|
|
|
|
|
|
|
|
|
|
int encapsulated_payload_type = -1;
|
|
|
|
|
if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
|
2016-02-15 11:27:15 +01:00
|
|
|
EXPECT_TRUE(expect_red_);
|
2015-12-08 09:10:43 +01:00
|
|
|
encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
|
|
|
|
|
if (encapsulated_payload_type !=
|
2016-02-15 11:27:15 +01:00
|
|
|
VideoSendStreamTest::kFakeVideoSendPayloadType) {
|
2015-12-08 09:10:43 +01:00
|
|
|
EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
|
|
|
|
|
encapsulated_payload_type);
|
2016-02-15 11:27:15 +01:00
|
|
|
}
|
2015-12-08 09:10:43 +01:00
|
|
|
} else {
|
2016-01-07 17:43:18 +01:00
|
|
|
EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
|
|
|
|
|
header.payloadType);
|
2016-02-15 11:27:15 +01:00
|
|
|
if (static_cast<size_t>(header.headerLength + header.paddingLength) <
|
|
|
|
|
length) {
|
|
|
|
|
// Not padding-only, media received outside of RED.
|
|
|
|
|
EXPECT_FALSE(expect_red_);
|
2016-12-12 01:54:58 -08:00
|
|
|
sent_media_ = true;
|
2016-02-15 11:27:15 +01:00
|
|
|
}
|
2015-12-08 09:10:43 +01:00
|
|
|
}
|
2013-09-10 14:56:33 +00:00
|
|
|
|
2015-12-08 09:10:43 +01:00
|
|
|
if (header_extensions_enabled_) {
|
|
|
|
|
EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
|
|
|
|
|
uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
|
|
|
|
|
if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
|
|
|
|
|
prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
|
|
|
|
|
// 24 bits wrap.
|
|
|
|
|
EXPECT_GT(prev_header_.extension.absoluteSendTime,
|
|
|
|
|
header.extension.absoluteSendTime);
|
|
|
|
|
} else {
|
|
|
|
|
EXPECT_GE(header.extension.absoluteSendTime,
|
|
|
|
|
prev_header_.extension.absoluteSendTime);
|
2013-09-20 11:56:26 +00:00
|
|
|
}
|
2015-12-08 09:10:43 +01:00
|
|
|
EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
|
|
|
|
|
uint16_t seq_num_diff = header.extension.transportSequenceNumber -
|
|
|
|
|
prev_header_.extension.transportSequenceNumber;
|
|
|
|
|
EXPECT_EQ(1, seq_num_diff);
|
|
|
|
|
}
|
2013-09-10 14:56:33 +00:00
|
|
|
|
2015-12-08 09:10:43 +01:00
|
|
|
if (encapsulated_payload_type != -1) {
|
|
|
|
|
if (encapsulated_payload_type ==
|
|
|
|
|
VideoSendStreamTest::kUlpfecPayloadType) {
|
2016-10-31 03:40:49 -07:00
|
|
|
EXPECT_TRUE(expect_ulpfec_);
|
2016-12-12 01:54:58 -08:00
|
|
|
sent_ulpfec_ = true;
|
2013-09-20 11:56:26 +00:00
|
|
|
} else {
|
2016-12-12 01:54:58 -08:00
|
|
|
sent_media_ = true;
|
2015-05-05 10:21:24 +02:00
|
|
|
}
|
2015-12-08 09:10:43 +01:00
|
|
|
}
|
2015-05-05 10:21:24 +02:00
|
|
|
|
2017-01-02 00:34:27 -08:00
|
|
|
if (sent_media_ && sent_ulpfec_) {
|
|
|
|
|
observation_complete_.Set();
|
2016-02-15 11:27:15 +01:00
|
|
|
}
|
2013-09-20 11:56:26 +00:00
|
|
|
|
2015-12-08 09:10:43 +01:00
|
|
|
prev_header_ = header;
|
2013-09-20 11:56:26 +00:00
|
|
|
|
2015-12-08 09:10:43 +01:00
|
|
|
return SEND_PACKET;
|
|
|
|
|
}
|
2013-09-10 14:56:33 +00:00
|
|
|
|
2017-08-22 04:02:52 -07:00
|
|
|
test::PacketTransport* CreateSendTransport(
|
|
|
|
|
test::SingleThreadedTaskQueueForTesting* task_queue,
|
|
|
|
|
Call* sender_call) override {
|
2016-02-15 11:27:15 +01:00
|
|
|
// At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
|
|
|
|
|
// Configure some network delay.
|
|
|
|
|
const int kNetworkDelayMs = 100;
|
2018-08-17 14:26:54 +02:00
|
|
|
DefaultNetworkSimulationConfig config;
|
2016-12-12 01:54:58 -08:00
|
|
|
config.loss_percent = 5;
|
2016-02-15 11:27:15 +01:00
|
|
|
config.queue_delay_ms = kNetworkDelayMs;
|
2017-04-10 16:57:57 -07:00
|
|
|
return new test::PacketTransport(
|
2017-08-22 04:02:52 -07:00
|
|
|
task_queue, sender_call, this, test::PacketTransport::kSender,
|
2018-08-20 13:30:39 +02:00
|
|
|
VideoSendStreamTest::payload_type_map_,
|
|
|
|
|
absl::make_unique<FakeNetworkPipe>(
|
|
|
|
|
Clock::GetRealTimeClock(),
|
|
|
|
|
absl::make_unique<SimulatedNetwork>(config)));
|
2016-02-15 11:27:15 +01:00
|
|
|
}
|
|
|
|
|
|
2015-12-21 03:14:00 -08:00
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
2016-02-15 11:27:15 +01:00
|
|
|
if (use_nack_) {
|
|
|
|
|
send_config->rtp.nack.rtp_history_ms =
|
|
|
|
|
(*receive_configs)[0].rtp.nack.rtp_history_ms =
|
|
|
|
|
VideoSendStreamTest::kNackRtpHistoryMs;
|
|
|
|
|
}
|
2018-04-19 09:04:13 +02:00
|
|
|
send_config->encoder_settings.encoder_factory = encoder_factory_;
|
Reland "Reland "Move rtp-specific config out of EncoderSettings.""
This reverts commit 6c2c13af06b32778b86950681758a7970d1c5d9e.
Reason for revert: Intend to investigate and fix perf problems.
Original change's description:
> Revert "Reland "Move rtp-specific config out of EncoderSettings.""
>
> This reverts commit 04dd1768625eb2241d1fb97fd0137897e703e266.
>
> Reason for revert: Regression in ramp up perf tests.
>
> Original change's description:
> > Reland "Move rtp-specific config out of EncoderSettings."
> >
> > This is a reland of bc900cb1d1810fcf678fe41cf1e3966daa39c88c
> >
> > Original change's description:
> > > Move rtp-specific config out of EncoderSettings.
> > >
> > > In VideoSendStream::Config, move payload_name and payload_type from
> > > EncoderSettings to Rtp.
> > >
> > > EncoderSettings now contains configuration for VideoStreamEncoder only,
> > > and should perhaps be renamed in a follow up cl. It's no longer
> > > passed as an argument to VideoCodecInitializer::SetupCodec.
> > >
> > > The latter then needs a different way to know the codec type,
> > > which is provided by a new codec_type member in VideoEncoderConfig.
> > >
> > > Bug: webrtc:8830
> > > Change-Id: Ifcc691aef1ee6a95e43c0452c5e630d92a511cd6
> > > Reviewed-on: https://webrtc-review.googlesource.com/62062
> > > Commit-Queue: Niels Moller <nisse@webrtc.org>
> > > Reviewed-by: Magnus Jedvert <magjed@webrtc.org>
> > > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> > > Cr-Commit-Position: refs/heads/master@{#22532}
> >
> > Bug: webrtc:8830
> > Change-Id: If88ef7d57cdaa4fae3c7b2a97ea5a6e1b833e019
> > Reviewed-on: https://webrtc-review.googlesource.com/63721
> > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Commit-Queue: Niels Moller <nisse@webrtc.org>
> > Cr-Commit-Position: refs/heads/master@{#22595}
>
> TBR=brandtr@webrtc.org,magjed@webrtc.org,nisse@webrtc.org,stefan@webrtc.org
>
> Bug: webrtc:8830,chromium:827080
> Change-Id: Iaaf146de91ec5c0d741b8efdf143f7e173084fef
> Reviewed-on: https://webrtc-review.googlesource.com/65520
> Commit-Queue: Niels Moller <nisse@webrtc.org>
> Reviewed-by: Niels Moller <nisse@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#22677}
TBR=brandtr@webrtc.org,magjed@webrtc.org,nisse@webrtc.org,stefan@webrtc.org
# Not skipping CQ checks because original CL landed > 1 day ago.
Bug: webrtc:8830, chromium:827080
Change-Id: I9b62987bf5daced90dfeb3ebb6739c80117c487f
Reviewed-on: https://webrtc-review.googlesource.com/66862
Commit-Queue: Niels Moller <nisse@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22751}
2018-04-05 15:36:51 +02:00
|
|
|
send_config->rtp.payload_name = payload_name_;
|
2016-10-04 23:28:39 -07:00
|
|
|
send_config->rtp.ulpfec.red_payload_type =
|
|
|
|
|
VideoSendStreamTest::kRedPayloadType;
|
|
|
|
|
send_config->rtp.ulpfec.ulpfec_payload_type =
|
|
|
|
|
VideoSendStreamTest::kUlpfecPayloadType;
|
2017-02-06 06:29:38 -08:00
|
|
|
EXPECT_FALSE(send_config->rtp.extensions.empty());
|
|
|
|
|
if (!header_extensions_enabled_) {
|
|
|
|
|
send_config->rtp.extensions.clear();
|
|
|
|
|
} else {
|
2015-12-08 09:10:43 +01:00
|
|
|
send_config->rtp.extensions.push_back(RtpExtension(
|
2016-05-26 11:24:55 -07:00
|
|
|
RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
|
2014-06-27 08:47:52 +00:00
|
|
|
}
|
Reland "Reland "Move rtp-specific config out of EncoderSettings.""
This reverts commit 6c2c13af06b32778b86950681758a7970d1c5d9e.
Reason for revert: Intend to investigate and fix perf problems.
Original change's description:
> Revert "Reland "Move rtp-specific config out of EncoderSettings.""
>
> This reverts commit 04dd1768625eb2241d1fb97fd0137897e703e266.
>
> Reason for revert: Regression in ramp up perf tests.
>
> Original change's description:
> > Reland "Move rtp-specific config out of EncoderSettings."
> >
> > This is a reland of bc900cb1d1810fcf678fe41cf1e3966daa39c88c
> >
> > Original change's description:
> > > Move rtp-specific config out of EncoderSettings.
> > >
> > > In VideoSendStream::Config, move payload_name and payload_type from
> > > EncoderSettings to Rtp.
> > >
> > > EncoderSettings now contains configuration for VideoStreamEncoder only,
> > > and should perhaps be renamed in a follow up cl. It's no longer
> > > passed as an argument to VideoCodecInitializer::SetupCodec.
> > >
> > > The latter then needs a different way to know the codec type,
> > > which is provided by a new codec_type member in VideoEncoderConfig.
> > >
> > > Bug: webrtc:8830
> > > Change-Id: Ifcc691aef1ee6a95e43c0452c5e630d92a511cd6
> > > Reviewed-on: https://webrtc-review.googlesource.com/62062
> > > Commit-Queue: Niels Moller <nisse@webrtc.org>
> > > Reviewed-by: Magnus Jedvert <magjed@webrtc.org>
> > > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> > > Cr-Commit-Position: refs/heads/master@{#22532}
> >
> > Bug: webrtc:8830
> > Change-Id: If88ef7d57cdaa4fae3c7b2a97ea5a6e1b833e019
> > Reviewed-on: https://webrtc-review.googlesource.com/63721
> > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Commit-Queue: Niels Moller <nisse@webrtc.org>
> > Cr-Commit-Position: refs/heads/master@{#22595}
>
> TBR=brandtr@webrtc.org,magjed@webrtc.org,nisse@webrtc.org,stefan@webrtc.org
>
> Bug: webrtc:8830,chromium:827080
> Change-Id: Iaaf146de91ec5c0d741b8efdf143f7e173084fef
> Reviewed-on: https://webrtc-review.googlesource.com/65520
> Commit-Queue: Niels Moller <nisse@webrtc.org>
> Reviewed-by: Niels Moller <nisse@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#22677}
TBR=brandtr@webrtc.org,magjed@webrtc.org,nisse@webrtc.org,stefan@webrtc.org
# Not skipping CQ checks because original CL landed > 1 day ago.
Bug: webrtc:8830, chromium:827080
Change-Id: I9b62987bf5daced90dfeb3ebb6739c80117c487f
Reviewed-on: https://webrtc-review.googlesource.com/66862
Commit-Queue: Niels Moller <nisse@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22751}
2018-04-05 15:36:51 +02:00
|
|
|
encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
|
2017-09-26 02:49:21 -07:00
|
|
|
(*receive_configs)[0].rtp.red_payload_type =
|
2016-10-04 23:28:39 -07:00
|
|
|
send_config->rtp.ulpfec.red_payload_type;
|
2017-09-26 02:49:21 -07:00
|
|
|
(*receive_configs)[0].rtp.ulpfec_payload_type =
|
2016-10-04 23:28:39 -07:00
|
|
|
send_config->rtp.ulpfec.ulpfec_payload_type;
|
2015-12-08 09:10:43 +01:00
|
|
|
}
|
2014-06-27 08:47:52 +00:00
|
|
|
|
2015-12-08 09:10:43 +01:00
|
|
|
void PerformTest() override {
|
2017-01-02 00:34:27 -08:00
|
|
|
EXPECT_EQ(expect_ulpfec_, Wait())
|
|
|
|
|
<< "Timed out waiting for ULPFEC and/or media packets.";
|
2015-12-08 09:10:43 +01:00
|
|
|
}
|
2014-06-27 08:47:52 +00:00
|
|
|
|
2018-04-19 09:04:13 +02:00
|
|
|
VideoEncoderFactory* encoder_factory_;
|
2016-12-19 05:47:28 -08:00
|
|
|
std::string payload_name_;
|
2016-02-15 11:27:15 +01:00
|
|
|
const bool use_nack_;
|
|
|
|
|
const bool expect_red_;
|
2016-10-31 03:40:49 -07:00
|
|
|
const bool expect_ulpfec_;
|
2016-12-12 01:54:58 -08:00
|
|
|
bool sent_media_;
|
|
|
|
|
bool sent_ulpfec_;
|
2015-12-08 09:10:43 +01:00
|
|
|
bool header_extensions_enabled_;
|
|
|
|
|
RTPHeader prev_header_;
|
|
|
|
|
};
|
|
|
|
|
|
2016-10-31 03:40:49 -07:00
|
|
|
TEST_F(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
|
2018-04-19 09:04:13 +02:00
|
|
|
test::FunctionVideoEncoderFactory encoder_factory(
|
|
|
|
|
[]() { return VP8Encoder::Create(); });
|
|
|
|
|
UlpfecObserver test(true, false, true, true, "VP8", &encoder_factory);
|
2016-02-12 15:08:31 +01:00
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-31 03:40:49 -07:00
|
|
|
TEST_F(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
|
2018-04-19 09:04:13 +02:00
|
|
|
test::FunctionVideoEncoderFactory encoder_factory(
|
|
|
|
|
[]() { return VP8Encoder::Create(); });
|
|
|
|
|
UlpfecObserver test(false, false, true, true, "VP8", &encoder_factory);
|
2016-02-15 11:27:15 +01:00
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-23 10:40:00 -07:00
|
|
|
class VideoSendStreamWithoutUlpfecTest : public VideoSendStreamTest {
|
|
|
|
|
protected:
|
|
|
|
|
VideoSendStreamWithoutUlpfecTest()
|
|
|
|
|
: field_trial_("WebRTC-DisableUlpFecExperiment/Enabled/") {}
|
|
|
|
|
|
|
|
|
|
test::ScopedFieldTrials field_trial_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
TEST_F(VideoSendStreamWithoutUlpfecTest, NoUlpfecIfDisabledThroughFieldTrial) {
|
2018-04-19 09:04:13 +02:00
|
|
|
test::FunctionVideoEncoderFactory encoder_factory(
|
|
|
|
|
[]() { return VP8Encoder::Create(); });
|
2018-07-11 16:04:57 +02:00
|
|
|
UlpfecObserver test(false, false, false, false, "VP8", &encoder_factory);
|
2017-08-23 10:40:00 -07:00
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-15 11:27:15 +01:00
|
|
|
// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
|
|
|
|
|
// since we'll still have to re-request FEC packets, effectively wasting
|
|
|
|
|
// bandwidth since the receiver has to wait for FEC retransmissions to determine
|
|
|
|
|
// that the received state is actually decodable.
|
2016-10-31 03:40:49 -07:00
|
|
|
TEST_F(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
|
2018-04-19 09:04:13 +02:00
|
|
|
test::FunctionVideoEncoderFactory encoder_factory([]() {
|
Use absl::make_unique and absl::WrapUnique directly
Instead of going through our wrappers in ptr_util.h.
This CL was generated by the following script:
git grep -l ptr_util | xargs perl -pi -e 's,#include "rtc_base/ptr_util.h",#include "absl/memory/memory.h",'
git grep -l MakeUnique | xargs perl -pi -e 's,\b(rtc::)?MakeUnique\b,absl::make_unique,g'
git grep -l WrapUnique | xargs perl -pi -e 's,\b(rtc::)?WrapUnique\b,absl::WrapUnique,g'
git checkout -- rtc_base/ptr_util{.h,_unittest.cc}
git cl format
Followed by manually adding dependencies on
//third_party/abseil-cpp/absl/memory until `gn check` stopped
complaining.
Bug: webrtc:9473
Change-Id: I89ccd363f070479b8c431eb2c3d404a46eaacc1c
Reviewed-on: https://webrtc-review.googlesource.com/86600
Commit-Queue: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23850}
2018-07-05 11:40:33 +02:00
|
|
|
return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
|
2018-04-19 09:04:13 +02:00
|
|
|
});
|
2018-07-11 16:04:57 +02:00
|
|
|
UlpfecObserver test(false, true, false, false, "H264", &encoder_factory);
|
2016-02-15 11:27:15 +01:00
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Without retransmissions FEC for H264 is fine.
|
Remove RED/RTX workaround from sender/receiver and VideoEngine2.
In older Chrome versions, the associated payload type in the RTX header
of retransmitted packets was always set to be the original media payload type,
regardless of the actual payload type of the packet. This meant that packets
encapsulated with RED headers had incorrect payload type information in the
RTX header. Due to an assumption in the receiver, this incorrect payload type
information would effectively be undone, leading to a working system.
Albeit working, this behaviour was undesired, and thus removed. In the interim,
several workarounds were introduced to not destroy interop between old and
new Chrome versions:
(1) https://codereview.webrtc.org/1649493004
- If no payload type mapping existed for RED over RTX, the payload type
of the underlying media would be used.
- If RED had been negotiated, received RTX packets would always be
assumed to contain RED.
(2) https://codereview.webrtc.org/1964473002
- If RED was removed from the remote description answer, it would be
disabled in the local receiver as well.
(3) https://codereview.webrtc.org/2033763002
- If RED was negotiated in the SDP, it would always be used, regardless
if ULPFEC was negotiated and used, or not.
Since the Chrome versions that exhibited the original bug now are very old,
this CL removes the workarounds from (1) and (2). In particular, after this
change, we will have the following behaviour:
- We assume that a payload type mapping for RED over RTX always is set.
If this is not the case, the RTX packet is not sent.
- The associated payload type of received RTX packets will always be obeyed.
- The (non)-existence of RED in the remote description does not affect the
local receiver.
The workaround in (3) still needs to exist, in order to interop with receivers
that did not have the workarounds in (1) and (2) removed. The change in (3)
can be removed in a couple of Chrome versions.
TESTED=Using AppRTC between patched Chrome (connected to ethernet) and standard Chrome M54 (connected to lossy internal Google WiFi), with and without FEC turned off using AppRTC flag. Also using "Munge SDP" sample on patched Chrome over loopback interface, with 100ms delay and 5% packet loss simulated using tc.
BUG=webrtc:6650
Review-Url: https://codereview.webrtc.org/2469093003
Cr-Commit-Position: refs/heads/master@{#15038}
2016-11-11 03:28:30 -08:00
|
|
|
TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForH264WithoutNackEnabled) {
|
2018-04-19 09:04:13 +02:00
|
|
|
test::FunctionVideoEncoderFactory encoder_factory([]() {
|
Use absl::make_unique and absl::WrapUnique directly
Instead of going through our wrappers in ptr_util.h.
This CL was generated by the following script:
git grep -l ptr_util | xargs perl -pi -e 's,#include "rtc_base/ptr_util.h",#include "absl/memory/memory.h",'
git grep -l MakeUnique | xargs perl -pi -e 's,\b(rtc::)?MakeUnique\b,absl::make_unique,g'
git grep -l WrapUnique | xargs perl -pi -e 's,\b(rtc::)?WrapUnique\b,absl::WrapUnique,g'
git checkout -- rtc_base/ptr_util{.h,_unittest.cc}
git cl format
Followed by manually adding dependencies on
//third_party/abseil-cpp/absl/memory until `gn check` stopped
complaining.
Bug: webrtc:9473
Change-Id: I89ccd363f070479b8c431eb2c3d404a46eaacc1c
Reviewed-on: https://webrtc-review.googlesource.com/86600
Commit-Queue: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23850}
2018-07-05 11:40:33 +02:00
|
|
|
return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
|
2018-04-19 09:04:13 +02:00
|
|
|
});
|
|
|
|
|
UlpfecObserver test(false, false, true, true, "H264", &encoder_factory);
|
2016-02-15 11:27:15 +01:00
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-02 06:22:21 -08:00
|
|
|
// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
|
|
|
|
|
TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp8WithNackEnabled) {
|
2018-04-19 09:04:13 +02:00
|
|
|
test::FunctionVideoEncoderFactory encoder_factory(
|
|
|
|
|
[]() { return VP8Encoder::Create(); });
|
|
|
|
|
UlpfecObserver test(false, true, true, true, "VP8", &encoder_factory);
|
2016-02-15 11:27:15 +01:00
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
2013-09-20 11:56:26 +00:00
|
|
|
|
2016-05-14 02:03:18 +02:00
|
|
|
#if !defined(RTC_DISABLE_VP9)
|
2017-03-02 06:22:21 -08:00
|
|
|
// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
|
|
|
|
|
TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp9WithNackEnabled) {
|
2018-04-19 09:04:13 +02:00
|
|
|
test::FunctionVideoEncoderFactory encoder_factory(
|
|
|
|
|
[]() { return VP9Encoder::Create(); });
|
|
|
|
|
UlpfecObserver test(false, true, true, true, "VP9", &encoder_factory);
|
2016-01-08 06:47:13 -08:00
|
|
|
RunBaseTest(&test);
|
2013-09-20 11:56:26 +00:00
|
|
|
}
|
2016-05-14 02:03:18 +02:00
|
|
|
#endif // !defined(RTC_DISABLE_VP9)
|
2013-09-20 11:56:26 +00:00
|
|
|
|
2017-01-16 05:57:16 -08:00
|
|
|
TEST_F(VideoSendStreamTest, SupportsUlpfecWithMultithreadedH264) {
|
2018-04-19 09:04:13 +02:00
|
|
|
test::FunctionVideoEncoderFactory encoder_factory([]() {
|
Use absl::make_unique and absl::WrapUnique directly
Instead of going through our wrappers in ptr_util.h.
This CL was generated by the following script:
git grep -l ptr_util | xargs perl -pi -e 's,#include "rtc_base/ptr_util.h",#include "absl/memory/memory.h",'
git grep -l MakeUnique | xargs perl -pi -e 's,\b(rtc::)?MakeUnique\b,absl::make_unique,g'
git grep -l WrapUnique | xargs perl -pi -e 's,\b(rtc::)?WrapUnique\b,absl::WrapUnique,g'
git checkout -- rtc_base/ptr_util{.h,_unittest.cc}
git cl format
Followed by manually adding dependencies on
//third_party/abseil-cpp/absl/memory until `gn check` stopped
complaining.
Bug: webrtc:9473
Change-Id: I89ccd363f070479b8c431eb2c3d404a46eaacc1c
Reviewed-on: https://webrtc-review.googlesource.com/86600
Commit-Queue: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23850}
2018-07-05 11:40:33 +02:00
|
|
|
return absl::make_unique<test::MultithreadedFakeH264Encoder>(
|
2018-04-19 09:04:13 +02:00
|
|
|
Clock::GetRealTimeClock());
|
|
|
|
|
});
|
|
|
|
|
UlpfecObserver test(false, false, true, true, "H264", &encoder_factory);
|
2016-12-19 05:47:28 -08:00
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-16 22:57:50 -08:00
|
|
|
// TODO(brandtr): Move these FlexFEC tests when we have created
|
|
|
|
|
// FlexfecSendStream.
|
|
|
|
|
class FlexfecObserver : public test::EndToEndTest {
|
|
|
|
|
public:
|
|
|
|
|
FlexfecObserver(bool header_extensions_enabled,
|
|
|
|
|
bool use_nack,
|
2016-12-19 05:47:28 -08:00
|
|
|
const std::string& codec,
|
2018-04-19 09:04:13 +02:00
|
|
|
VideoEncoderFactory* encoder_factory,
|
2018-02-19 19:09:53 +01:00
|
|
|
size_t num_video_streams)
|
2016-11-16 22:57:50 -08:00
|
|
|
: EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
|
2018-04-19 09:04:13 +02:00
|
|
|
encoder_factory_(encoder_factory),
|
2016-11-16 22:57:50 -08:00
|
|
|
payload_name_(codec),
|
|
|
|
|
use_nack_(use_nack),
|
|
|
|
|
sent_media_(false),
|
|
|
|
|
sent_flexfec_(false),
|
2018-02-19 19:09:53 +01:00
|
|
|
header_extensions_enabled_(header_extensions_enabled),
|
|
|
|
|
num_video_streams_(num_video_streams) {}
|
2016-11-16 22:57:50 -08:00
|
|
|
|
|
|
|
|
size_t GetNumFlexfecStreams() const override { return 1; }
|
2018-02-19 19:09:53 +01:00
|
|
|
size_t GetNumVideoStreams() const override { return num_video_streams_; }
|
2016-11-16 22:57:50 -08:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
Action OnSendRtp(const uint8_t* packet, size_t length) override {
|
|
|
|
|
RTPHeader header;
|
|
|
|
|
EXPECT_TRUE(parser_->Parse(packet, length, &header));
|
|
|
|
|
|
|
|
|
|
if (header.payloadType == VideoSendStreamTest::kFlexfecPayloadType) {
|
|
|
|
|
EXPECT_EQ(VideoSendStreamTest::kFlexfecSendSsrc, header.ssrc);
|
|
|
|
|
sent_flexfec_ = true;
|
|
|
|
|
} else {
|
|
|
|
|
EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
|
|
|
|
|
header.payloadType);
|
2018-02-19 19:09:53 +01:00
|
|
|
EXPECT_THAT(testing::make_tuple(VideoSendStreamTest::kVideoSendSsrcs,
|
|
|
|
|
num_video_streams_),
|
|
|
|
|
testing::Contains(header.ssrc));
|
2016-11-16 22:57:50 -08:00
|
|
|
sent_media_ = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (header_extensions_enabled_) {
|
|
|
|
|
EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
|
|
|
|
|
EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
|
|
|
|
|
EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-23 04:42:26 -08:00
|
|
|
if (sent_media_ && sent_flexfec_) {
|
2016-11-16 22:57:50 -08:00
|
|
|
observation_complete_.Set();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return SEND_PACKET;
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-22 04:02:52 -07:00
|
|
|
test::PacketTransport* CreateSendTransport(
|
|
|
|
|
test::SingleThreadedTaskQueueForTesting* task_queue,
|
|
|
|
|
Call* sender_call) override {
|
2016-11-16 22:57:50 -08:00
|
|
|
// At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
|
|
|
|
|
// Therefore we need some network delay.
|
|
|
|
|
const int kNetworkDelayMs = 100;
|
2018-08-17 14:26:54 +02:00
|
|
|
DefaultNetworkSimulationConfig config;
|
2016-12-05 05:38:19 -08:00
|
|
|
config.loss_percent = 5;
|
2016-11-16 22:57:50 -08:00
|
|
|
config.queue_delay_ms = kNetworkDelayMs;
|
2017-04-10 16:57:57 -07:00
|
|
|
return new test::PacketTransport(
|
2017-08-22 04:02:52 -07:00
|
|
|
task_queue, sender_call, this, test::PacketTransport::kSender,
|
2018-08-20 13:30:39 +02:00
|
|
|
VideoSendStreamTest::payload_type_map_,
|
|
|
|
|
absl::make_unique<FakeNetworkPipe>(
|
|
|
|
|
Clock::GetRealTimeClock(),
|
|
|
|
|
absl::make_unique<SimulatedNetwork>(config)));
|
2016-11-16 22:57:50 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
|
|
|
|
if (use_nack_) {
|
|
|
|
|
send_config->rtp.nack.rtp_history_ms =
|
|
|
|
|
(*receive_configs)[0].rtp.nack.rtp_history_ms =
|
|
|
|
|
VideoSendStreamTest::kNackRtpHistoryMs;
|
|
|
|
|
}
|
2018-04-19 09:04:13 +02:00
|
|
|
send_config->encoder_settings.encoder_factory = encoder_factory_;
|
Reland "Reland "Move rtp-specific config out of EncoderSettings.""
This reverts commit 6c2c13af06b32778b86950681758a7970d1c5d9e.
Reason for revert: Intend to investigate and fix perf problems.
Original change's description:
> Revert "Reland "Move rtp-specific config out of EncoderSettings.""
>
> This reverts commit 04dd1768625eb2241d1fb97fd0137897e703e266.
>
> Reason for revert: Regression in ramp up perf tests.
>
> Original change's description:
> > Reland "Move rtp-specific config out of EncoderSettings."
> >
> > This is a reland of bc900cb1d1810fcf678fe41cf1e3966daa39c88c
> >
> > Original change's description:
> > > Move rtp-specific config out of EncoderSettings.
> > >
> > > In VideoSendStream::Config, move payload_name and payload_type from
> > > EncoderSettings to Rtp.
> > >
> > > EncoderSettings now contains configuration for VideoStreamEncoder only,
> > > and should perhaps be renamed in a follow up cl. It's no longer
> > > passed as an argument to VideoCodecInitializer::SetupCodec.
> > >
> > > The latter then needs a different way to know the codec type,
> > > which is provided by a new codec_type member in VideoEncoderConfig.
> > >
> > > Bug: webrtc:8830
> > > Change-Id: Ifcc691aef1ee6a95e43c0452c5e630d92a511cd6
> > > Reviewed-on: https://webrtc-review.googlesource.com/62062
> > > Commit-Queue: Niels Moller <nisse@webrtc.org>
> > > Reviewed-by: Magnus Jedvert <magjed@webrtc.org>
> > > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> > > Cr-Commit-Position: refs/heads/master@{#22532}
> >
> > Bug: webrtc:8830
> > Change-Id: If88ef7d57cdaa4fae3c7b2a97ea5a6e1b833e019
> > Reviewed-on: https://webrtc-review.googlesource.com/63721
> > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Commit-Queue: Niels Moller <nisse@webrtc.org>
> > Cr-Commit-Position: refs/heads/master@{#22595}
>
> TBR=brandtr@webrtc.org,magjed@webrtc.org,nisse@webrtc.org,stefan@webrtc.org
>
> Bug: webrtc:8830,chromium:827080
> Change-Id: Iaaf146de91ec5c0d741b8efdf143f7e173084fef
> Reviewed-on: https://webrtc-review.googlesource.com/65520
> Commit-Queue: Niels Moller <nisse@webrtc.org>
> Reviewed-by: Niels Moller <nisse@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#22677}
TBR=brandtr@webrtc.org,magjed@webrtc.org,nisse@webrtc.org,stefan@webrtc.org
# Not skipping CQ checks because original CL landed > 1 day ago.
Bug: webrtc:8830, chromium:827080
Change-Id: I9b62987bf5daced90dfeb3ebb6739c80117c487f
Reviewed-on: https://webrtc-review.googlesource.com/66862
Commit-Queue: Niels Moller <nisse@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22751}
2018-04-05 15:36:51 +02:00
|
|
|
send_config->rtp.payload_name = payload_name_;
|
2016-11-16 22:57:50 -08:00
|
|
|
if (header_extensions_enabled_) {
|
|
|
|
|
send_config->rtp.extensions.push_back(RtpExtension(
|
|
|
|
|
RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
|
|
|
|
|
send_config->rtp.extensions.push_back(RtpExtension(
|
|
|
|
|
RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
|
2017-02-06 06:29:38 -08:00
|
|
|
} else {
|
|
|
|
|
send_config->rtp.extensions.clear();
|
2016-11-16 22:57:50 -08:00
|
|
|
}
|
Reland "Reland "Move rtp-specific config out of EncoderSettings.""
This reverts commit 6c2c13af06b32778b86950681758a7970d1c5d9e.
Reason for revert: Intend to investigate and fix perf problems.
Original change's description:
> Revert "Reland "Move rtp-specific config out of EncoderSettings.""
>
> This reverts commit 04dd1768625eb2241d1fb97fd0137897e703e266.
>
> Reason for revert: Regression in ramp up perf tests.
>
> Original change's description:
> > Reland "Move rtp-specific config out of EncoderSettings."
> >
> > This is a reland of bc900cb1d1810fcf678fe41cf1e3966daa39c88c
> >
> > Original change's description:
> > > Move rtp-specific config out of EncoderSettings.
> > >
> > > In VideoSendStream::Config, move payload_name and payload_type from
> > > EncoderSettings to Rtp.
> > >
> > > EncoderSettings now contains configuration for VideoStreamEncoder only,
> > > and should perhaps be renamed in a follow up cl. It's no longer
> > > passed as an argument to VideoCodecInitializer::SetupCodec.
> > >
> > > The latter then needs a different way to know the codec type,
> > > which is provided by a new codec_type member in VideoEncoderConfig.
> > >
> > > Bug: webrtc:8830
> > > Change-Id: Ifcc691aef1ee6a95e43c0452c5e630d92a511cd6
> > > Reviewed-on: https://webrtc-review.googlesource.com/62062
> > > Commit-Queue: Niels Moller <nisse@webrtc.org>
> > > Reviewed-by: Magnus Jedvert <magjed@webrtc.org>
> > > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> > > Cr-Commit-Position: refs/heads/master@{#22532}
> >
> > Bug: webrtc:8830
> > Change-Id: If88ef7d57cdaa4fae3c7b2a97ea5a6e1b833e019
> > Reviewed-on: https://webrtc-review.googlesource.com/63721
> > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Commit-Queue: Niels Moller <nisse@webrtc.org>
> > Cr-Commit-Position: refs/heads/master@{#22595}
>
> TBR=brandtr@webrtc.org,magjed@webrtc.org,nisse@webrtc.org,stefan@webrtc.org
>
> Bug: webrtc:8830,chromium:827080
> Change-Id: Iaaf146de91ec5c0d741b8efdf143f7e173084fef
> Reviewed-on: https://webrtc-review.googlesource.com/65520
> Commit-Queue: Niels Moller <nisse@webrtc.org>
> Reviewed-by: Niels Moller <nisse@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#22677}
TBR=brandtr@webrtc.org,magjed@webrtc.org,nisse@webrtc.org,stefan@webrtc.org
# Not skipping CQ checks because original CL landed > 1 day ago.
Bug: webrtc:8830, chromium:827080
Change-Id: I9b62987bf5daced90dfeb3ebb6739c80117c487f
Reviewed-on: https://webrtc-review.googlesource.com/66862
Commit-Queue: Niels Moller <nisse@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22751}
2018-04-05 15:36:51 +02:00
|
|
|
encoder_config->codec_type = PayloadStringToCodecType(payload_name_);
|
2016-11-16 22:57:50 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PerformTest() override {
|
|
|
|
|
EXPECT_TRUE(Wait())
|
|
|
|
|
<< "Timed out waiting for FlexFEC and/or media packets.";
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-19 09:04:13 +02:00
|
|
|
VideoEncoderFactory* encoder_factory_;
|
2016-12-19 05:47:28 -08:00
|
|
|
std::string payload_name_;
|
2016-11-16 22:57:50 -08:00
|
|
|
const bool use_nack_;
|
|
|
|
|
bool sent_media_;
|
|
|
|
|
bool sent_flexfec_;
|
2018-02-19 19:09:53 +01:00
|
|
|
const bool header_extensions_enabled_;
|
|
|
|
|
const size_t num_video_streams_;
|
2016-11-16 22:57:50 -08:00
|
|
|
};
|
|
|
|
|
|
2016-12-05 05:38:19 -08:00
|
|
|
TEST_F(VideoSendStreamTest, SupportsFlexfecVp8) {
|
2018-04-19 09:04:13 +02:00
|
|
|
test::FunctionVideoEncoderFactory encoder_factory(
|
|
|
|
|
[]() { return VP8Encoder::Create(); });
|
|
|
|
|
FlexfecObserver test(false, false, "VP8", &encoder_factory, 1);
|
2018-02-19 19:09:53 +01:00
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(VideoSendStreamTest, SupportsFlexfecSimulcastVp8) {
|
2018-04-19 09:04:13 +02:00
|
|
|
test::FunctionVideoEncoderFactory encoder_factory(
|
|
|
|
|
[]() { return VP8Encoder::Create(); });
|
|
|
|
|
FlexfecObserver test(false, false, "VP8", &encoder_factory, 2);
|
2016-11-16 22:57:50 -08:00
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-05 05:38:19 -08:00
|
|
|
TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp8) {
|
2018-04-19 09:04:13 +02:00
|
|
|
test::FunctionVideoEncoderFactory encoder_factory(
|
|
|
|
|
[]() { return VP8Encoder::Create(); });
|
|
|
|
|
FlexfecObserver test(false, true, "VP8", &encoder_factory, 1);
|
2016-11-16 22:57:50 -08:00
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-05 05:38:19 -08:00
|
|
|
TEST_F(VideoSendStreamTest, SupportsFlexfecWithRtpExtensionsVp8) {
|
2018-04-19 09:04:13 +02:00
|
|
|
test::FunctionVideoEncoderFactory encoder_factory(
|
|
|
|
|
[]() { return VP8Encoder::Create(); });
|
|
|
|
|
FlexfecObserver test(true, false, "VP8", &encoder_factory, 1);
|
2016-11-16 22:57:50 -08:00
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-05 05:38:19 -08:00
|
|
|
#if !defined(RTC_DISABLE_VP9)
|
|
|
|
|
TEST_F(VideoSendStreamTest, SupportsFlexfecVp9) {
|
2018-04-19 09:04:13 +02:00
|
|
|
test::FunctionVideoEncoderFactory encoder_factory(
|
|
|
|
|
[]() { return VP9Encoder::Create(); });
|
|
|
|
|
FlexfecObserver test(false, false, "VP9", &encoder_factory, 1);
|
2016-11-16 22:57:50 -08:00
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-05 05:38:19 -08:00
|
|
|
TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp9) {
|
2018-04-19 09:04:13 +02:00
|
|
|
test::FunctionVideoEncoderFactory encoder_factory(
|
|
|
|
|
[]() { return VP9Encoder::Create(); });
|
|
|
|
|
FlexfecObserver test(false, true, "VP9", &encoder_factory, 1);
|
2016-11-16 22:57:50 -08:00
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
#endif // defined(RTC_DISABLE_VP9)
|
|
|
|
|
|
2016-12-05 05:38:19 -08:00
|
|
|
TEST_F(VideoSendStreamTest, SupportsFlexfecH264) {
|
2018-04-19 09:04:13 +02:00
|
|
|
test::FunctionVideoEncoderFactory encoder_factory([]() {
|
Use absl::make_unique and absl::WrapUnique directly
Instead of going through our wrappers in ptr_util.h.
This CL was generated by the following script:
git grep -l ptr_util | xargs perl -pi -e 's,#include "rtc_base/ptr_util.h",#include "absl/memory/memory.h",'
git grep -l MakeUnique | xargs perl -pi -e 's,\b(rtc::)?MakeUnique\b,absl::make_unique,g'
git grep -l WrapUnique | xargs perl -pi -e 's,\b(rtc::)?WrapUnique\b,absl::WrapUnique,g'
git checkout -- rtc_base/ptr_util{.h,_unittest.cc}
git cl format
Followed by manually adding dependencies on
//third_party/abseil-cpp/absl/memory until `gn check` stopped
complaining.
Bug: webrtc:9473
Change-Id: I89ccd363f070479b8c431eb2c3d404a46eaacc1c
Reviewed-on: https://webrtc-review.googlesource.com/86600
Commit-Queue: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23850}
2018-07-05 11:40:33 +02:00
|
|
|
return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
|
2018-04-19 09:04:13 +02:00
|
|
|
});
|
|
|
|
|
FlexfecObserver test(false, false, "H264", &encoder_factory, 1);
|
2016-11-16 22:57:50 -08:00
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-05 05:38:19 -08:00
|
|
|
TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackH264) {
|
2018-04-19 09:04:13 +02:00
|
|
|
test::FunctionVideoEncoderFactory encoder_factory([]() {
|
Use absl::make_unique and absl::WrapUnique directly
Instead of going through our wrappers in ptr_util.h.
This CL was generated by the following script:
git grep -l ptr_util | xargs perl -pi -e 's,#include "rtc_base/ptr_util.h",#include "absl/memory/memory.h",'
git grep -l MakeUnique | xargs perl -pi -e 's,\b(rtc::)?MakeUnique\b,absl::make_unique,g'
git grep -l WrapUnique | xargs perl -pi -e 's,\b(rtc::)?WrapUnique\b,absl::WrapUnique,g'
git checkout -- rtc_base/ptr_util{.h,_unittest.cc}
git cl format
Followed by manually adding dependencies on
//third_party/abseil-cpp/absl/memory until `gn check` stopped
complaining.
Bug: webrtc:9473
Change-Id: I89ccd363f070479b8c431eb2c3d404a46eaacc1c
Reviewed-on: https://webrtc-review.googlesource.com/86600
Commit-Queue: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23850}
2018-07-05 11:40:33 +02:00
|
|
|
return absl::make_unique<test::FakeH264Encoder>(Clock::GetRealTimeClock());
|
2018-04-19 09:04:13 +02:00
|
|
|
});
|
|
|
|
|
FlexfecObserver test(false, true, "H264", &encoder_factory, 1);
|
2016-12-19 05:47:28 -08:00
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-16 05:57:16 -08:00
|
|
|
TEST_F(VideoSendStreamTest, SupportsFlexfecWithMultithreadedH264) {
|
2018-04-19 09:04:13 +02:00
|
|
|
test::FunctionVideoEncoderFactory encoder_factory([]() {
|
Use absl::make_unique and absl::WrapUnique directly
Instead of going through our wrappers in ptr_util.h.
This CL was generated by the following script:
git grep -l ptr_util | xargs perl -pi -e 's,#include "rtc_base/ptr_util.h",#include "absl/memory/memory.h",'
git grep -l MakeUnique | xargs perl -pi -e 's,\b(rtc::)?MakeUnique\b,absl::make_unique,g'
git grep -l WrapUnique | xargs perl -pi -e 's,\b(rtc::)?WrapUnique\b,absl::WrapUnique,g'
git checkout -- rtc_base/ptr_util{.h,_unittest.cc}
git cl format
Followed by manually adding dependencies on
//third_party/abseil-cpp/absl/memory until `gn check` stopped
complaining.
Bug: webrtc:9473
Change-Id: I89ccd363f070479b8c431eb2c3d404a46eaacc1c
Reviewed-on: https://webrtc-review.googlesource.com/86600
Commit-Queue: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23850}
2018-07-05 11:40:33 +02:00
|
|
|
return absl::make_unique<test::MultithreadedFakeH264Encoder>(
|
2018-04-19 09:04:13 +02:00
|
|
|
Clock::GetRealTimeClock());
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
FlexfecObserver test(false, false, "H264", &encoder_factory, 1);
|
2016-11-16 22:57:50 -08:00
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-15 12:32:15 +00:00
|
|
|
void VideoSendStreamTest::TestNackRetransmission(
|
|
|
|
|
uint32_t retransmit_ssrc,
|
2014-06-12 15:12:25 +00:00
|
|
|
uint8_t retransmit_payload_type) {
|
2014-06-27 08:47:52 +00:00
|
|
|
class NackObserver : public test::SendTest {
|
2013-09-20 11:56:26 +00:00
|
|
|
public:
|
2013-11-15 12:32:15 +00:00
|
|
|
explicit NackObserver(uint32_t retransmit_ssrc,
|
|
|
|
|
uint8_t retransmit_payload_type)
|
2014-06-27 08:47:52 +00:00
|
|
|
: SendTest(kDefaultTimeoutMs),
|
2013-09-20 11:56:26 +00:00
|
|
|
send_count_(0),
|
2018-02-28 16:14:44 +01:00
|
|
|
retransmit_count_(0),
|
2013-09-20 11:56:26 +00:00
|
|
|
retransmit_ssrc_(retransmit_ssrc),
|
2018-02-28 16:14:44 +01:00
|
|
|
retransmit_payload_type_(retransmit_payload_type) {}
|
2013-09-20 11:56:26 +00:00
|
|
|
|
2014-06-27 08:47:52 +00:00
|
|
|
private:
|
2015-03-04 12:58:35 +00:00
|
|
|
Action OnSendRtp(const uint8_t* packet, size_t length) override {
|
2013-09-10 14:56:33 +00:00
|
|
|
RTPHeader header;
|
2014-07-08 12:10:51 +00:00
|
|
|
EXPECT_TRUE(parser_->Parse(packet, length, &header));
|
2013-09-10 14:56:33 +00:00
|
|
|
|
2018-02-28 16:14:44 +01:00
|
|
|
int kRetransmitTarget = 6;
|
|
|
|
|
++send_count_;
|
|
|
|
|
if (send_count_ == 5 || send_count_ == 25) {
|
|
|
|
|
nacked_sequence_numbers_.push_back(
|
|
|
|
|
static_cast<uint16_t>(header.sequenceNumber - 3));
|
|
|
|
|
nacked_sequence_numbers_.push_back(
|
|
|
|
|
static_cast<uint16_t>(header.sequenceNumber - 2));
|
|
|
|
|
nacked_sequence_numbers_.push_back(
|
|
|
|
|
static_cast<uint16_t>(header.sequenceNumber - 1));
|
|
|
|
|
|
2017-08-01 03:21:37 -07:00
|
|
|
RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(), nullptr,
|
2018-01-31 22:08:26 -08:00
|
|
|
nullptr, nullptr, transport_adapter_.get(),
|
|
|
|
|
RtcpIntervalConfig{});
|
2013-09-20 11:56:26 +00:00
|
|
|
|
2015-10-02 02:36:56 -07:00
|
|
|
rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
|
2016-01-07 17:43:18 +01:00
|
|
|
rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
|
2013-09-20 11:56:26 +00:00
|
|
|
|
|
|
|
|
RTCPSender::FeedbackState feedback_state;
|
|
|
|
|
|
2018-02-28 16:14:44 +01:00
|
|
|
EXPECT_EQ(0, rtcp_sender.SendRTCP(
|
|
|
|
|
feedback_state, kRtcpNack,
|
|
|
|
|
static_cast<int>(nacked_sequence_numbers_.size()),
|
|
|
|
|
&nacked_sequence_numbers_.front()));
|
2013-09-10 14:56:33 +00:00
|
|
|
}
|
|
|
|
|
|
2013-09-16 13:01:47 +00:00
|
|
|
uint16_t sequence_number = header.sequenceNumber;
|
|
|
|
|
|
2014-06-27 08:47:52 +00:00
|
|
|
if (header.ssrc == retransmit_ssrc_ &&
|
2016-01-07 17:43:18 +01:00
|
|
|
retransmit_ssrc_ != kVideoSendSsrcs[0]) {
|
|
|
|
|
// Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
|
2014-06-27 08:47:52 +00:00
|
|
|
// number.
|
2013-09-16 13:01:47 +00:00
|
|
|
const uint8_t* rtx_header = packet + header.headerLength;
|
|
|
|
|
sequence_number = (rtx_header[0] << 8) + rtx_header[1];
|
|
|
|
|
}
|
2018-02-28 16:14:44 +01:00
|
|
|
auto found = std::find(nacked_sequence_numbers_.begin(),
|
|
|
|
|
nacked_sequence_numbers_.end(), sequence_number);
|
|
|
|
|
if (found != nacked_sequence_numbers_.end()) {
|
|
|
|
|
nacked_sequence_numbers_.erase(found);
|
|
|
|
|
|
|
|
|
|
if (++retransmit_count_ == kRetransmitTarget) {
|
|
|
|
|
EXPECT_EQ(retransmit_ssrc_, header.ssrc);
|
|
|
|
|
EXPECT_EQ(retransmit_payload_type_, header.payloadType);
|
|
|
|
|
observation_complete_.Set();
|
|
|
|
|
}
|
2013-09-16 13:01:47 +00:00
|
|
|
}
|
2013-09-10 14:56:33 +00:00
|
|
|
|
2013-11-15 12:32:15 +00:00
|
|
|
return SEND_PACKET;
|
2013-09-10 14:56:33 +00:00
|
|
|
}
|
2013-10-23 11:04:57 +00:00
|
|
|
|
2015-12-21 03:14:00 -08:00
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
2015-10-27 08:29:42 -07:00
|
|
|
transport_adapter_.reset(
|
|
|
|
|
new internal::TransportAdapter(send_config->send_transport));
|
|
|
|
|
transport_adapter_->Enable();
|
2014-06-30 13:19:09 +00:00
|
|
|
send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
|
2014-06-27 08:47:52 +00:00
|
|
|
send_config->rtp.rtx.payload_type = retransmit_payload_type_;
|
2016-01-07 17:43:18 +01:00
|
|
|
if (retransmit_ssrc_ != kVideoSendSsrcs[0])
|
2014-06-27 08:47:52 +00:00
|
|
|
send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
void PerformTest() override {
|
2015-12-10 13:02:50 +01:00
|
|
|
EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
|
2014-06-27 08:47:52 +00:00
|
|
|
}
|
|
|
|
|
|
2016-03-01 11:52:33 -08:00
|
|
|
std::unique_ptr<internal::TransportAdapter> transport_adapter_;
|
2013-09-10 14:56:33 +00:00
|
|
|
int send_count_;
|
2018-02-28 16:14:44 +01:00
|
|
|
int retransmit_count_;
|
2013-09-16 13:01:47 +00:00
|
|
|
uint32_t retransmit_ssrc_;
|
2013-11-15 12:32:15 +00:00
|
|
|
uint8_t retransmit_payload_type_;
|
2018-02-28 16:14:44 +01:00
|
|
|
std::vector<uint16_t> nacked_sequence_numbers_;
|
2014-06-27 08:47:52 +00:00
|
|
|
} test(retransmit_ssrc, retransmit_payload_type);
|
2013-09-10 14:56:33 +00:00
|
|
|
|
2016-01-08 06:47:13 -08:00
|
|
|
RunBaseTest(&test);
|
2013-09-10 14:56:33 +00:00
|
|
|
}
|
|
|
|
|
|
2013-09-16 13:01:47 +00:00
|
|
|
TEST_F(VideoSendStreamTest, RetransmitsNack) {
|
|
|
|
|
// Normal NACKs should use the send SSRC.
|
2016-01-07 17:43:18 +01:00
|
|
|
TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType);
|
2013-09-16 13:01:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
|
|
|
|
|
// NACKs over RTX should use a separate SSRC.
|
2014-07-07 13:06:48 +00:00
|
|
|
TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
|
2013-09-16 13:01:47 +00:00
|
|
|
}
|
|
|
|
|
|
2014-02-18 08:40:33 +00:00
|
|
|
void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
|
|
|
|
|
bool with_fec) {
|
2014-06-27 08:47:52 +00:00
|
|
|
// Use a fake encoder to output a frame of every size in the range [90, 290],
|
|
|
|
|
// for each size making sure that the exact number of payload bytes received
|
|
|
|
|
// is correct and that packets are fragmented to respect max packet size.
|
Use size_t more consistently for packet/payload lengths.
See design doc at https://docs.google.com/a/chromium.org/document/d/1I6nmE9D_BmCY-IoV6MDPY2V6WYpEI-dg2apWXTfZyUI/edit?usp=sharing for more information.
This CL was reviewed and approved in pieces in the following CLs:
https://webrtc-codereview.appspot.com/24209004/
https://webrtc-codereview.appspot.com/24229004/
https://webrtc-codereview.appspot.com/24259004/
https://webrtc-codereview.appspot.com/25109004/
https://webrtc-codereview.appspot.com/26099004/
https://webrtc-codereview.appspot.com/27069004/
https://webrtc-codereview.appspot.com/27969004/
https://webrtc-codereview.appspot.com/27989004/
https://webrtc-codereview.appspot.com/29009004/
https://webrtc-codereview.appspot.com/30929004/
https://webrtc-codereview.appspot.com/30939004/
https://webrtc-codereview.appspot.com/31999004/
Committing as TBR to the original reviewers.
BUG=chromium:81439
TEST=none
TBR=pthatcher,henrik.lundin,tina.legrand,stefan,tkchin,glaznev,kjellander,perkj,mflodman,henrika,asapersson,niklas.enbom
Review URL: https://webrtc-codereview.appspot.com/23129004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@7726 4adac7df-926f-26a2-2b94-8c16560cd09d
2014-11-20 22:28:14 +00:00
|
|
|
static const size_t kMaxPacketSize = 128;
|
|
|
|
|
static const size_t start = 90;
|
|
|
|
|
static const size_t stop = 290;
|
2014-06-27 08:47:52 +00:00
|
|
|
|
2013-12-10 10:05:17 +00:00
|
|
|
// Observer that verifies that the expected number of packets and bytes
|
|
|
|
|
// arrive for each frame size, from start_size to stop_size.
|
2014-06-27 08:47:52 +00:00
|
|
|
class FrameFragmentationTest : public test::SendTest,
|
|
|
|
|
public EncodedFrameObserver {
|
2013-10-16 11:37:54 +00:00
|
|
|
public:
|
Use size_t more consistently for packet/payload lengths.
See design doc at https://docs.google.com/a/chromium.org/document/d/1I6nmE9D_BmCY-IoV6MDPY2V6WYpEI-dg2apWXTfZyUI/edit?usp=sharing for more information.
This CL was reviewed and approved in pieces in the following CLs:
https://webrtc-codereview.appspot.com/24209004/
https://webrtc-codereview.appspot.com/24229004/
https://webrtc-codereview.appspot.com/24259004/
https://webrtc-codereview.appspot.com/25109004/
https://webrtc-codereview.appspot.com/26099004/
https://webrtc-codereview.appspot.com/27069004/
https://webrtc-codereview.appspot.com/27969004/
https://webrtc-codereview.appspot.com/27989004/
https://webrtc-codereview.appspot.com/29009004/
https://webrtc-codereview.appspot.com/30929004/
https://webrtc-codereview.appspot.com/30939004/
https://webrtc-codereview.appspot.com/31999004/
Committing as TBR to the original reviewers.
BUG=chromium:81439
TEST=none
TBR=pthatcher,henrik.lundin,tina.legrand,stefan,tkchin,glaznev,kjellander,perkj,mflodman,henrika,asapersson,niklas.enbom
Review URL: https://webrtc-codereview.appspot.com/23129004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@7726 4adac7df-926f-26a2-2b94-8c16560cd09d
2014-11-20 22:28:14 +00:00
|
|
|
FrameFragmentationTest(size_t max_packet_size,
|
|
|
|
|
size_t start_size,
|
|
|
|
|
size_t stop_size,
|
2014-06-27 08:47:52 +00:00
|
|
|
bool test_generic_packetization,
|
|
|
|
|
bool use_fec)
|
|
|
|
|
: SendTest(kLongTimeoutMs),
|
|
|
|
|
encoder_(stop),
|
2018-04-19 09:04:13 +02:00
|
|
|
encoder_factory_(&encoder_),
|
2013-12-10 10:05:17 +00:00
|
|
|
max_packet_size_(max_packet_size),
|
2014-02-18 08:40:33 +00:00
|
|
|
stop_size_(stop_size),
|
|
|
|
|
test_generic_packetization_(test_generic_packetization),
|
|
|
|
|
use_fec_(use_fec),
|
|
|
|
|
packet_count_(0),
|
2018-02-01 13:00:57 +01:00
|
|
|
packets_lost_(0),
|
|
|
|
|
last_packet_count_(0),
|
|
|
|
|
last_packets_lost_(0),
|
2013-12-10 10:05:17 +00:00
|
|
|
accumulated_size_(0),
|
|
|
|
|
accumulated_payload_(0),
|
2014-02-18 08:40:33 +00:00
|
|
|
fec_packet_received_(false),
|
2013-12-10 10:05:17 +00:00
|
|
|
current_size_rtp_(start_size),
|
2017-10-24 15:40:52 -07:00
|
|
|
current_size_frame_(static_cast<int>(start_size)) {
|
2013-12-10 10:05:17 +00:00
|
|
|
// Fragmentation required, this test doesn't make sense without it.
|
Use size_t more consistently for packet/payload lengths.
See design doc at https://docs.google.com/a/chromium.org/document/d/1I6nmE9D_BmCY-IoV6MDPY2V6WYpEI-dg2apWXTfZyUI/edit?usp=sharing for more information.
This CL was reviewed and approved in pieces in the following CLs:
https://webrtc-codereview.appspot.com/24209004/
https://webrtc-codereview.appspot.com/24229004/
https://webrtc-codereview.appspot.com/24259004/
https://webrtc-codereview.appspot.com/25109004/
https://webrtc-codereview.appspot.com/26099004/
https://webrtc-codereview.appspot.com/27069004/
https://webrtc-codereview.appspot.com/27969004/
https://webrtc-codereview.appspot.com/27989004/
https://webrtc-codereview.appspot.com/29009004/
https://webrtc-codereview.appspot.com/30929004/
https://webrtc-codereview.appspot.com/30939004/
https://webrtc-codereview.appspot.com/31999004/
Committing as TBR to the original reviewers.
BUG=chromium:81439
TEST=none
TBR=pthatcher,henrik.lundin,tina.legrand,stefan,tkchin,glaznev,kjellander,perkj,mflodman,henrika,asapersson,niklas.enbom
Review URL: https://webrtc-codereview.appspot.com/23129004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@7726 4adac7df-926f-26a2-2b94-8c16560cd09d
2014-11-20 22:28:14 +00:00
|
|
|
encoder_.SetFrameSize(start_size);
|
2015-09-17 00:24:34 -07:00
|
|
|
RTC_DCHECK_GT(stop_size, max_packet_size);
|
2013-12-10 10:05:17 +00:00
|
|
|
}
|
2013-10-16 11:37:54 +00:00
|
|
|
|
2014-06-27 08:47:52 +00:00
|
|
|
private:
|
2015-03-04 12:58:35 +00:00
|
|
|
Action OnSendRtp(const uint8_t* packet, size_t size) override {
|
Use size_t more consistently for packet/payload lengths.
See design doc at https://docs.google.com/a/chromium.org/document/d/1I6nmE9D_BmCY-IoV6MDPY2V6WYpEI-dg2apWXTfZyUI/edit?usp=sharing for more information.
This CL was reviewed and approved in pieces in the following CLs:
https://webrtc-codereview.appspot.com/24209004/
https://webrtc-codereview.appspot.com/24229004/
https://webrtc-codereview.appspot.com/24259004/
https://webrtc-codereview.appspot.com/25109004/
https://webrtc-codereview.appspot.com/26099004/
https://webrtc-codereview.appspot.com/27069004/
https://webrtc-codereview.appspot.com/27969004/
https://webrtc-codereview.appspot.com/27989004/
https://webrtc-codereview.appspot.com/29009004/
https://webrtc-codereview.appspot.com/30929004/
https://webrtc-codereview.appspot.com/30939004/
https://webrtc-codereview.appspot.com/31999004/
Committing as TBR to the original reviewers.
BUG=chromium:81439
TEST=none
TBR=pthatcher,henrik.lundin,tina.legrand,stefan,tkchin,glaznev,kjellander,perkj,mflodman,henrika,asapersson,niklas.enbom
Review URL: https://webrtc-codereview.appspot.com/23129004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@7726 4adac7df-926f-26a2-2b94-8c16560cd09d
2014-11-20 22:28:14 +00:00
|
|
|
size_t length = size;
|
2013-10-16 11:37:54 +00:00
|
|
|
RTPHeader header;
|
2014-02-18 08:40:33 +00:00
|
|
|
EXPECT_TRUE(parser_->Parse(packet, length, &header));
|
2013-10-16 11:37:54 +00:00
|
|
|
|
2013-12-10 10:05:17 +00:00
|
|
|
EXPECT_LE(length, max_packet_size_);
|
2013-10-16 11:37:54 +00:00
|
|
|
|
2014-02-18 08:40:33 +00:00
|
|
|
if (use_fec_) {
|
|
|
|
|
uint8_t payload_type = packet[header.headerLength];
|
|
|
|
|
bool is_fec = header.payloadType == kRedPayloadType &&
|
|
|
|
|
payload_type == kUlpfecPayloadType;
|
|
|
|
|
if (is_fec) {
|
|
|
|
|
fec_packet_received_ = true;
|
|
|
|
|
return SEND_PACKET;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-16 11:37:54 +00:00
|
|
|
accumulated_size_ += length;
|
2014-02-18 08:40:33 +00:00
|
|
|
|
|
|
|
|
if (use_fec_)
|
|
|
|
|
TriggerLossReport(header);
|
|
|
|
|
|
|
|
|
|
if (test_generic_packetization_) {
|
2015-09-18 11:14:31 +02:00
|
|
|
size_t overhead = header.headerLength + header.paddingLength;
|
|
|
|
|
// Only remove payload header and RED header if the packet actually
|
|
|
|
|
// contains payload.
|
|
|
|
|
if (length > overhead) {
|
|
|
|
|
overhead += (1 /* Generic header */);
|
|
|
|
|
if (use_fec_)
|
|
|
|
|
overhead += 1; // RED for FEC header.
|
|
|
|
|
}
|
|
|
|
|
EXPECT_GE(length, overhead);
|
2014-02-18 08:40:33 +00:00
|
|
|
accumulated_payload_ += length - overhead;
|
|
|
|
|
}
|
2013-10-16 11:37:54 +00:00
|
|
|
|
2013-12-10 10:05:17 +00:00
|
|
|
// Marker bit set indicates last packet of a frame.
|
2013-10-16 11:37:54 +00:00
|
|
|
if (header.markerBit) {
|
2014-02-18 08:40:33 +00:00
|
|
|
if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
|
|
|
|
|
// With FEC enabled, frame size is incremented asynchronously, so
|
|
|
|
|
// "old" frames one byte too small may arrive. Accept, but don't
|
|
|
|
|
// increase expected frame size.
|
|
|
|
|
accumulated_size_ = 0;
|
|
|
|
|
accumulated_payload_ = 0;
|
|
|
|
|
return SEND_PACKET;
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-10 10:05:17 +00:00
|
|
|
EXPECT_GE(accumulated_size_, current_size_rtp_);
|
2014-02-18 08:40:33 +00:00
|
|
|
if (test_generic_packetization_) {
|
|
|
|
|
EXPECT_EQ(current_size_rtp_, accumulated_payload_);
|
|
|
|
|
}
|
2013-12-10 10:05:17 +00:00
|
|
|
|
|
|
|
|
// Last packet of frame; reset counters.
|
|
|
|
|
accumulated_size_ = 0;
|
|
|
|
|
accumulated_payload_ = 0;
|
|
|
|
|
if (current_size_rtp_ == stop_size_) {
|
|
|
|
|
// Done! (Don't increase size again, might arrive more @ stop_size).
|
2015-12-10 13:02:50 +01:00
|
|
|
observation_complete_.Set();
|
2013-12-10 10:05:17 +00:00
|
|
|
} else {
|
2014-02-18 08:40:33 +00:00
|
|
|
// Increase next expected frame size. If testing with FEC, make sure
|
|
|
|
|
// a FEC packet has been received for this frame size before
|
|
|
|
|
// proceeding, to make sure that redundancy packets don't exceed
|
|
|
|
|
// size limit.
|
|
|
|
|
if (!use_fec_) {
|
|
|
|
|
++current_size_rtp_;
|
|
|
|
|
} else if (fec_packet_received_) {
|
|
|
|
|
fec_packet_received_ = false;
|
|
|
|
|
++current_size_rtp_;
|
2017-10-24 15:40:52 -07:00
|
|
|
|
|
|
|
|
rtc::CritScope lock(&mutex_);
|
2014-02-18 08:40:33 +00:00
|
|
|
++current_size_frame_;
|
|
|
|
|
}
|
2013-10-16 11:37:54 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-15 12:32:15 +00:00
|
|
|
return SEND_PACKET;
|
2013-10-16 11:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
2014-02-18 08:40:33 +00:00
|
|
|
void TriggerLossReport(const RTPHeader& header) {
|
|
|
|
|
// Send lossy receive reports to trigger FEC enabling.
|
2017-06-27 07:06:52 -07:00
|
|
|
const int kLossPercent = 5;
|
2018-02-01 13:00:57 +01:00
|
|
|
if (++packet_count_ % (100 / kLossPercent) == 0) {
|
|
|
|
|
packets_lost_++;
|
|
|
|
|
int loss_delta = packets_lost_ - last_packets_lost_;
|
|
|
|
|
int packets_delta = packet_count_ - last_packet_count_;
|
|
|
|
|
last_packet_count_ = packet_count_;
|
|
|
|
|
last_packets_lost_ = packets_lost_;
|
|
|
|
|
uint8_t loss_ratio =
|
|
|
|
|
static_cast<uint8_t>(loss_delta * 255 / packets_delta);
|
2014-02-18 08:40:33 +00:00
|
|
|
FakeReceiveStatistics lossy_receive_stats(
|
2017-06-27 07:06:52 -07:00
|
|
|
kVideoSendSsrcs[0], header.sequenceNumber,
|
2018-02-01 13:00:57 +01:00
|
|
|
packets_lost_, // Cumulative lost.
|
|
|
|
|
loss_ratio); // Loss percent.
|
2015-09-17 23:03:57 +02:00
|
|
|
RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(),
|
2016-01-21 05:42:04 -08:00
|
|
|
&lossy_receive_stats, nullptr, nullptr,
|
2018-01-31 22:08:26 -08:00
|
|
|
transport_adapter_.get(), RtcpIntervalConfig{});
|
2014-02-18 08:40:33 +00:00
|
|
|
|
2015-10-02 02:36:56 -07:00
|
|
|
rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
|
2016-01-07 17:43:18 +01:00
|
|
|
rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
|
2014-02-18 08:40:33 +00:00
|
|
|
|
|
|
|
|
RTCPSender::FeedbackState feedback_state;
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-29 06:09:15 -07:00
|
|
|
void EncodedFrameCallback(const EncodedFrame& encoded_frame) override {
|
2017-10-24 15:40:52 -07:00
|
|
|
rtc::CritScope lock(&mutex_);
|
2013-12-10 10:05:17 +00:00
|
|
|
// Increase frame size for next encoded frame, in the context of the
|
|
|
|
|
// encoder thread.
|
2017-10-24 15:40:52 -07:00
|
|
|
if (!use_fec_ && current_size_frame_ < static_cast<int32_t>(stop_size_)) {
|
2013-12-10 10:05:17 +00:00
|
|
|
++current_size_frame_;
|
|
|
|
|
}
|
2017-10-24 15:40:52 -07:00
|
|
|
encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_));
|
2014-06-27 08:47:52 +00:00
|
|
|
}
|
2018-07-13 13:19:42 +02:00
|
|
|
void ModifySenderCallConfig(Call::Config* config) override {
|
2015-03-26 11:11:06 +01:00
|
|
|
const int kMinBitrateBps = 30000;
|
2018-07-13 13:19:42 +02:00
|
|
|
config->bitrate_config.min_bitrate_bps = kMinBitrateBps;
|
2015-03-26 11:11:06 +01:00
|
|
|
}
|
|
|
|
|
|
2015-12-21 03:14:00 -08:00
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
2015-10-27 08:29:42 -07:00
|
|
|
transport_adapter_.reset(
|
|
|
|
|
new internal::TransportAdapter(send_config->send_transport));
|
|
|
|
|
transport_adapter_->Enable();
|
2014-06-27 08:47:52 +00:00
|
|
|
if (use_fec_) {
|
2016-10-04 23:28:39 -07:00
|
|
|
send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
|
|
|
|
|
send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
|
2014-06-27 08:47:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!test_generic_packetization_)
|
Reland "Reland "Move rtp-specific config out of EncoderSettings.""
This reverts commit 6c2c13af06b32778b86950681758a7970d1c5d9e.
Reason for revert: Intend to investigate and fix perf problems.
Original change's description:
> Revert "Reland "Move rtp-specific config out of EncoderSettings.""
>
> This reverts commit 04dd1768625eb2241d1fb97fd0137897e703e266.
>
> Reason for revert: Regression in ramp up perf tests.
>
> Original change's description:
> > Reland "Move rtp-specific config out of EncoderSettings."
> >
> > This is a reland of bc900cb1d1810fcf678fe41cf1e3966daa39c88c
> >
> > Original change's description:
> > > Move rtp-specific config out of EncoderSettings.
> > >
> > > In VideoSendStream::Config, move payload_name and payload_type from
> > > EncoderSettings to Rtp.
> > >
> > > EncoderSettings now contains configuration for VideoStreamEncoder only,
> > > and should perhaps be renamed in a follow up cl. It's no longer
> > > passed as an argument to VideoCodecInitializer::SetupCodec.
> > >
> > > The latter then needs a different way to know the codec type,
> > > which is provided by a new codec_type member in VideoEncoderConfig.
> > >
> > > Bug: webrtc:8830
> > > Change-Id: Ifcc691aef1ee6a95e43c0452c5e630d92a511cd6
> > > Reviewed-on: https://webrtc-review.googlesource.com/62062
> > > Commit-Queue: Niels Moller <nisse@webrtc.org>
> > > Reviewed-by: Magnus Jedvert <magjed@webrtc.org>
> > > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> > > Cr-Commit-Position: refs/heads/master@{#22532}
> >
> > Bug: webrtc:8830
> > Change-Id: If88ef7d57cdaa4fae3c7b2a97ea5a6e1b833e019
> > Reviewed-on: https://webrtc-review.googlesource.com/63721
> > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Commit-Queue: Niels Moller <nisse@webrtc.org>
> > Cr-Commit-Position: refs/heads/master@{#22595}
>
> TBR=brandtr@webrtc.org,magjed@webrtc.org,nisse@webrtc.org,stefan@webrtc.org
>
> Bug: webrtc:8830,chromium:827080
> Change-Id: Iaaf146de91ec5c0d741b8efdf143f7e173084fef
> Reviewed-on: https://webrtc-review.googlesource.com/65520
> Commit-Queue: Niels Moller <nisse@webrtc.org>
> Reviewed-by: Niels Moller <nisse@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#22677}
TBR=brandtr@webrtc.org,magjed@webrtc.org,nisse@webrtc.org,stefan@webrtc.org
# Not skipping CQ checks because original CL landed > 1 day ago.
Bug: webrtc:8830, chromium:827080
Change-Id: I9b62987bf5daced90dfeb3ebb6739c80117c487f
Reviewed-on: https://webrtc-review.googlesource.com/66862
Commit-Queue: Niels Moller <nisse@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22751}
2018-04-05 15:36:51 +02:00
|
|
|
send_config->rtp.payload_name = "VP8";
|
2018-04-19 09:04:13 +02:00
|
|
|
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
2014-06-27 08:47:52 +00:00
|
|
|
send_config->rtp.max_packet_size = kMaxPacketSize;
|
|
|
|
|
send_config->post_encode_callback = this;
|
|
|
|
|
|
2015-04-10 11:58:49 +02:00
|
|
|
// Make sure there is at least one extension header, to make the RTP
|
|
|
|
|
// header larger than the base length of 12 bytes.
|
|
|
|
|
EXPECT_FALSE(send_config->rtp.extensions.empty());
|
2017-06-27 07:06:52 -07:00
|
|
|
|
|
|
|
|
// Setup screen content disables frame dropping which makes this easier.
|
|
|
|
|
class VideoStreamFactory
|
|
|
|
|
: public VideoEncoderConfig::VideoStreamFactoryInterface {
|
|
|
|
|
public:
|
|
|
|
|
explicit VideoStreamFactory(size_t num_temporal_layers)
|
|
|
|
|
: num_temporal_layers_(num_temporal_layers) {
|
|
|
|
|
EXPECT_GT(num_temporal_layers, 0u);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
std::vector<VideoStream> CreateEncoderStreams(
|
|
|
|
|
int width,
|
|
|
|
|
int height,
|
|
|
|
|
const VideoEncoderConfig& encoder_config) override {
|
|
|
|
|
std::vector<VideoStream> streams =
|
|
|
|
|
test::CreateVideoStreams(width, height, encoder_config);
|
|
|
|
|
for (VideoStream& stream : streams) {
|
2018-03-01 15:11:29 +01:00
|
|
|
stream.num_temporal_layers = num_temporal_layers_;
|
2017-06-27 07:06:52 -07:00
|
|
|
}
|
|
|
|
|
return streams;
|
|
|
|
|
}
|
|
|
|
|
const size_t num_temporal_layers_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
encoder_config->video_stream_factory =
|
|
|
|
|
new rtc::RefCountedObject<VideoStreamFactory>(2);
|
|
|
|
|
encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
|
2014-06-27 08:47:52 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
void PerformTest() override {
|
2015-12-10 13:02:50 +01:00
|
|
|
EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
|
2013-12-10 10:05:17 +00:00
|
|
|
}
|
|
|
|
|
|
2016-03-01 11:52:33 -08:00
|
|
|
std::unique_ptr<internal::TransportAdapter> transport_adapter_;
|
2014-06-27 08:47:52 +00:00
|
|
|
test::ConfigurableFrameSizeEncoder encoder_;
|
2018-04-19 09:04:13 +02:00
|
|
|
test::EncoderProxyFactory encoder_factory_;
|
2014-02-18 08:40:33 +00:00
|
|
|
|
Use size_t more consistently for packet/payload lengths.
See design doc at https://docs.google.com/a/chromium.org/document/d/1I6nmE9D_BmCY-IoV6MDPY2V6WYpEI-dg2apWXTfZyUI/edit?usp=sharing for more information.
This CL was reviewed and approved in pieces in the following CLs:
https://webrtc-codereview.appspot.com/24209004/
https://webrtc-codereview.appspot.com/24229004/
https://webrtc-codereview.appspot.com/24259004/
https://webrtc-codereview.appspot.com/25109004/
https://webrtc-codereview.appspot.com/26099004/
https://webrtc-codereview.appspot.com/27069004/
https://webrtc-codereview.appspot.com/27969004/
https://webrtc-codereview.appspot.com/27989004/
https://webrtc-codereview.appspot.com/29009004/
https://webrtc-codereview.appspot.com/30929004/
https://webrtc-codereview.appspot.com/30939004/
https://webrtc-codereview.appspot.com/31999004/
Committing as TBR to the original reviewers.
BUG=chromium:81439
TEST=none
TBR=pthatcher,henrik.lundin,tina.legrand,stefan,tkchin,glaznev,kjellander,perkj,mflodman,henrika,asapersson,niklas.enbom
Review URL: https://webrtc-codereview.appspot.com/23129004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@7726 4adac7df-926f-26a2-2b94-8c16560cd09d
2014-11-20 22:28:14 +00:00
|
|
|
const size_t max_packet_size_;
|
|
|
|
|
const size_t stop_size_;
|
2014-02-18 08:40:33 +00:00
|
|
|
const bool test_generic_packetization_;
|
|
|
|
|
const bool use_fec_;
|
|
|
|
|
|
|
|
|
|
uint32_t packet_count_;
|
2018-02-01 13:00:57 +01:00
|
|
|
uint32_t packets_lost_;
|
|
|
|
|
uint32_t last_packet_count_;
|
|
|
|
|
uint32_t last_packets_lost_;
|
Use size_t more consistently for packet/payload lengths.
See design doc at https://docs.google.com/a/chromium.org/document/d/1I6nmE9D_BmCY-IoV6MDPY2V6WYpEI-dg2apWXTfZyUI/edit?usp=sharing for more information.
This CL was reviewed and approved in pieces in the following CLs:
https://webrtc-codereview.appspot.com/24209004/
https://webrtc-codereview.appspot.com/24229004/
https://webrtc-codereview.appspot.com/24259004/
https://webrtc-codereview.appspot.com/25109004/
https://webrtc-codereview.appspot.com/26099004/
https://webrtc-codereview.appspot.com/27069004/
https://webrtc-codereview.appspot.com/27969004/
https://webrtc-codereview.appspot.com/27989004/
https://webrtc-codereview.appspot.com/29009004/
https://webrtc-codereview.appspot.com/30929004/
https://webrtc-codereview.appspot.com/30939004/
https://webrtc-codereview.appspot.com/31999004/
Committing as TBR to the original reviewers.
BUG=chromium:81439
TEST=none
TBR=pthatcher,henrik.lundin,tina.legrand,stefan,tkchin,glaznev,kjellander,perkj,mflodman,henrika,asapersson,niklas.enbom
Review URL: https://webrtc-codereview.appspot.com/23129004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@7726 4adac7df-926f-26a2-2b94-8c16560cd09d
2014-11-20 22:28:14 +00:00
|
|
|
size_t accumulated_size_;
|
|
|
|
|
size_t accumulated_payload_;
|
2014-02-18 08:40:33 +00:00
|
|
|
bool fec_packet_received_;
|
2013-12-10 10:05:17 +00:00
|
|
|
|
Use size_t more consistently for packet/payload lengths.
See design doc at https://docs.google.com/a/chromium.org/document/d/1I6nmE9D_BmCY-IoV6MDPY2V6WYpEI-dg2apWXTfZyUI/edit?usp=sharing for more information.
This CL was reviewed and approved in pieces in the following CLs:
https://webrtc-codereview.appspot.com/24209004/
https://webrtc-codereview.appspot.com/24229004/
https://webrtc-codereview.appspot.com/24259004/
https://webrtc-codereview.appspot.com/25109004/
https://webrtc-codereview.appspot.com/26099004/
https://webrtc-codereview.appspot.com/27069004/
https://webrtc-codereview.appspot.com/27969004/
https://webrtc-codereview.appspot.com/27989004/
https://webrtc-codereview.appspot.com/29009004/
https://webrtc-codereview.appspot.com/30929004/
https://webrtc-codereview.appspot.com/30939004/
https://webrtc-codereview.appspot.com/31999004/
Committing as TBR to the original reviewers.
BUG=chromium:81439
TEST=none
TBR=pthatcher,henrik.lundin,tina.legrand,stefan,tkchin,glaznev,kjellander,perkj,mflodman,henrika,asapersson,niklas.enbom
Review URL: https://webrtc-codereview.appspot.com/23129004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@7726 4adac7df-926f-26a2-2b94-8c16560cd09d
2014-11-20 22:28:14 +00:00
|
|
|
size_t current_size_rtp_;
|
2017-10-24 15:40:52 -07:00
|
|
|
rtc::CriticalSection mutex_;
|
|
|
|
|
int current_size_frame_ RTC_GUARDED_BY(mutex_);
|
2013-10-16 11:37:54 +00:00
|
|
|
};
|
|
|
|
|
|
2014-02-18 08:40:33 +00:00
|
|
|
// Don't auto increment if FEC is used; continue sending frame size until
|
|
|
|
|
// a FEC packet has been received.
|
2014-06-27 08:47:52 +00:00
|
|
|
FrameFragmentationTest test(kMaxPacketSize, start, stop, format == kGeneric,
|
|
|
|
|
with_fec);
|
2013-12-10 10:05:17 +00:00
|
|
|
|
2016-01-08 06:47:13 -08:00
|
|
|
RunBaseTest(&test);
|
2013-10-16 11:37:54 +00:00
|
|
|
}
|
|
|
|
|
|
2014-02-18 08:40:33 +00:00
|
|
|
// TODO(sprang): Is there any way of speeding up these tests?
|
|
|
|
|
TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
|
|
|
|
|
TestPacketFragmentationSize(kGeneric, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
|
|
|
|
|
TestPacketFragmentationSize(kGeneric, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
|
|
|
|
|
TestPacketFragmentationSize(kVP8, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
|
|
|
|
|
TestPacketFragmentationSize(kVP8, true);
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-23 11:04:57 +00:00
|
|
|
// The test will go through a number of phases.
|
|
|
|
|
// 1. Start sending packets.
|
|
|
|
|
// 2. As soon as the RTP stream has been detected, signal a low REMB value to
|
2013-11-18 12:18:43 +00:00
|
|
|
// suspend the stream.
|
|
|
|
|
// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
|
2013-10-23 11:04:57 +00:00
|
|
|
// packets.
|
2013-11-18 12:18:43 +00:00
|
|
|
// 4. Signal a high REMB and then wait for the RTP stream to start again.
|
2014-03-18 08:43:29 +00:00
|
|
|
// When the stream is detected again, and the stats show that the stream
|
|
|
|
|
// is no longer suspended, the test ends.
|
2013-11-18 12:18:43 +00:00
|
|
|
TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
|
|
|
|
|
static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
|
2013-10-23 11:04:57 +00:00
|
|
|
|
2016-04-18 05:15:22 -07:00
|
|
|
class RembObserver : public test::SendTest,
|
|
|
|
|
public rtc::VideoSinkInterface<VideoFrame> {
|
2013-10-23 11:04:57 +00:00
|
|
|
public:
|
2014-06-27 08:47:52 +00:00
|
|
|
RembObserver()
|
|
|
|
|
: SendTest(kDefaultTimeoutMs),
|
2013-10-23 11:04:57 +00:00
|
|
|
clock_(Clock::GetRealTimeClock()),
|
2016-07-29 12:59:36 +02:00
|
|
|
stream_(nullptr),
|
2013-11-18 12:18:43 +00:00
|
|
|
test_state_(kBeforeSuspend),
|
2013-10-23 11:04:57 +00:00
|
|
|
rtp_count_(0),
|
|
|
|
|
last_sequence_number_(0),
|
2013-11-18 12:18:43 +00:00
|
|
|
suspended_frame_count_(0),
|
2013-10-28 10:16:14 +00:00
|
|
|
low_remb_bps_(0),
|
2016-07-29 12:59:36 +02:00
|
|
|
high_remb_bps_(0) {}
|
2013-10-23 11:04:57 +00:00
|
|
|
|
2014-06-27 08:47:52 +00:00
|
|
|
private:
|
2015-03-04 12:58:35 +00:00
|
|
|
Action OnSendRtp(const uint8_t* packet, size_t length) override {
|
2015-05-01 13:00:41 +02:00
|
|
|
rtc::CritScope lock(&crit_);
|
2013-10-23 11:04:57 +00:00
|
|
|
++rtp_count_;
|
|
|
|
|
RTPHeader header;
|
2014-07-08 12:10:51 +00:00
|
|
|
EXPECT_TRUE(parser_->Parse(packet, length, &header));
|
2013-10-23 11:04:57 +00:00
|
|
|
last_sequence_number_ = header.sequenceNumber;
|
|
|
|
|
|
2013-11-18 12:18:43 +00:00
|
|
|
if (test_state_ == kBeforeSuspend) {
|
|
|
|
|
// The stream has started. Try to suspend it.
|
2013-10-28 10:16:14 +00:00
|
|
|
SendRtcpFeedback(low_remb_bps_);
|
2013-11-18 12:18:43 +00:00
|
|
|
test_state_ = kDuringSuspend;
|
|
|
|
|
} else if (test_state_ == kDuringSuspend) {
|
2013-11-21 14:05:40 +00:00
|
|
|
if (header.paddingLength == 0) {
|
|
|
|
|
// Received non-padding packet during suspension period. Reset the
|
|
|
|
|
// counter.
|
|
|
|
|
suspended_frame_count_ = 0;
|
|
|
|
|
}
|
2015-10-27 08:29:42 -07:00
|
|
|
SendRtcpFeedback(0); // REMB is only sent if value is > 0.
|
2013-10-23 11:04:57 +00:00
|
|
|
} else if (test_state_ == kWaitingForPacket) {
|
2013-11-21 14:05:40 +00:00
|
|
|
if (header.paddingLength == 0) {
|
2014-03-18 08:43:29 +00:00
|
|
|
// Non-padding packet observed. Test is almost complete. Will just
|
|
|
|
|
// have to wait for the stats to change.
|
|
|
|
|
test_state_ = kWaitingForStats;
|
|
|
|
|
}
|
2015-10-27 08:29:42 -07:00
|
|
|
SendRtcpFeedback(0); // REMB is only sent if value is > 0.
|
2014-03-18 08:43:29 +00:00
|
|
|
} else if (test_state_ == kWaitingForStats) {
|
2014-06-27 08:47:52 +00:00
|
|
|
VideoSendStream::Stats stats = stream_->GetStats();
|
2014-03-18 08:43:29 +00:00
|
|
|
if (stats.suspended == false) {
|
|
|
|
|
// Stats flipped to false. Test is complete.
|
2015-12-10 13:02:50 +01:00
|
|
|
observation_complete_.Set();
|
2013-11-21 14:05:40 +00:00
|
|
|
}
|
2015-10-27 08:29:42 -07:00
|
|
|
SendRtcpFeedback(0); // REMB is only sent if value is > 0.
|
2013-10-23 11:04:57 +00:00
|
|
|
}
|
|
|
|
|
|
2013-11-15 12:32:15 +00:00
|
|
|
return SEND_PACKET;
|
2013-10-23 11:04:57 +00:00
|
|
|
}
|
|
|
|
|
|
2016-09-01 01:17:40 -07:00
|
|
|
// This method implements the rtc::VideoSinkInterface. This is called when
|
|
|
|
|
// a frame is provided to the VideoSendStream.
|
2016-04-18 05:15:22 -07:00
|
|
|
void OnFrame(const VideoFrame& video_frame) override {
|
2015-05-01 13:00:41 +02:00
|
|
|
rtc::CritScope lock(&crit_);
|
2013-11-18 12:18:43 +00:00
|
|
|
if (test_state_ == kDuringSuspend &&
|
|
|
|
|
++suspended_frame_count_ > kSuspendTimeFrames) {
|
2014-06-27 08:47:52 +00:00
|
|
|
VideoSendStream::Stats stats = stream_->GetStats();
|
2014-03-13 13:31:21 +00:00
|
|
|
EXPECT_TRUE(stats.suspended);
|
2013-10-28 10:16:14 +00:00
|
|
|
SendRtcpFeedback(high_remb_bps_);
|
2013-10-23 11:04:57 +00:00
|
|
|
test_state_ = kWaitingForPacket;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-28 13:00:21 +00:00
|
|
|
void set_low_remb_bps(int value) {
|
2015-05-01 13:00:41 +02:00
|
|
|
rtc::CritScope lock(&crit_);
|
2014-04-28 13:00:21 +00:00
|
|
|
low_remb_bps_ = value;
|
|
|
|
|
}
|
2013-10-28 10:16:14 +00:00
|
|
|
|
2014-04-28 13:00:21 +00:00
|
|
|
void set_high_remb_bps(int value) {
|
2015-05-01 13:00:41 +02:00
|
|
|
rtc::CritScope lock(&crit_);
|
2014-04-28 13:00:21 +00:00
|
|
|
high_remb_bps_ = value;
|
|
|
|
|
}
|
2013-10-28 10:16:14 +00:00
|
|
|
|
2015-12-21 03:14:00 -08:00
|
|
|
void OnVideoStreamsCreated(
|
2014-06-30 13:19:09 +00:00
|
|
|
VideoSendStream* send_stream,
|
2015-03-04 12:58:35 +00:00
|
|
|
const std::vector<VideoReceiveStream*>& receive_streams) override {
|
2014-06-27 08:47:52 +00:00
|
|
|
stream_ = send_stream;
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-21 03:14:00 -08:00
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
2016-11-28 15:21:39 -08:00
|
|
|
RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
|
2015-10-27 08:29:42 -07:00
|
|
|
transport_adapter_.reset(
|
|
|
|
|
new internal::TransportAdapter(send_config->send_transport));
|
|
|
|
|
transport_adapter_->Enable();
|
2014-06-30 13:19:09 +00:00
|
|
|
send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
|
2014-06-27 08:47:52 +00:00
|
|
|
send_config->pre_encode_callback = this;
|
|
|
|
|
send_config->suspend_below_min_bitrate = true;
|
2016-10-02 23:45:26 -07:00
|
|
|
int min_bitrate_bps =
|
|
|
|
|
test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0];
|
2014-06-27 08:47:52 +00:00
|
|
|
set_low_remb_bps(min_bitrate_bps - 10000);
|
2016-06-09 17:21:19 +02:00
|
|
|
int threshold_window = std::max(min_bitrate_bps / 10, 20000);
|
2016-10-02 23:45:26 -07:00
|
|
|
ASSERT_GT(encoder_config->max_bitrate_bps,
|
2014-06-27 08:47:52 +00:00
|
|
|
min_bitrate_bps + threshold_window + 5000);
|
|
|
|
|
set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
void PerformTest() override {
|
2015-12-10 13:02:50 +01:00
|
|
|
EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test.";
|
2014-06-27 08:47:52 +00:00
|
|
|
}
|
2013-10-29 10:12:10 +00:00
|
|
|
|
2013-10-23 11:04:57 +00:00
|
|
|
enum TestState {
|
2013-11-18 12:18:43 +00:00
|
|
|
kBeforeSuspend,
|
|
|
|
|
kDuringSuspend,
|
2013-10-23 11:04:57 +00:00
|
|
|
kWaitingForPacket,
|
2014-03-18 08:43:29 +00:00
|
|
|
kWaitingForStats
|
2013-10-23 11:04:57 +00:00
|
|
|
};
|
|
|
|
|
|
2014-04-28 13:00:21 +00:00
|
|
|
virtual void SendRtcpFeedback(int remb_value)
|
2017-09-09 04:17:22 -07:00
|
|
|
RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_) {
|
2016-01-07 17:43:18 +01:00
|
|
|
FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0],
|
|
|
|
|
last_sequence_number_, rtp_count_, 0);
|
2016-01-21 05:42:04 -08:00
|
|
|
RTCPSender rtcp_sender(false, clock_, &receive_stats, nullptr, nullptr,
|
2018-01-31 22:08:26 -08:00
|
|
|
transport_adapter_.get(), RtcpIntervalConfig{});
|
2013-10-23 11:04:57 +00:00
|
|
|
|
2015-10-02 02:36:56 -07:00
|
|
|
rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
|
2016-01-07 17:43:18 +01:00
|
|
|
rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
|
2013-10-23 11:04:57 +00:00
|
|
|
if (remb_value > 0) {
|
2017-10-18 13:32:57 +02:00
|
|
|
rtcp_sender.SetRemb(remb_value, std::vector<uint32_t>());
|
2013-10-23 11:04:57 +00:00
|
|
|
}
|
|
|
|
|
RTCPSender::FeedbackState feedback_state;
|
|
|
|
|
EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-01 11:52:33 -08:00
|
|
|
std::unique_ptr<internal::TransportAdapter> transport_adapter_;
|
2014-04-28 13:00:21 +00:00
|
|
|
Clock* const clock_;
|
2014-06-27 08:47:52 +00:00
|
|
|
VideoSendStream* stream_;
|
2014-04-28 13:00:21 +00:00
|
|
|
|
2015-05-01 13:00:41 +02:00
|
|
|
rtc::CriticalSection crit_;
|
2017-09-09 04:17:22 -07:00
|
|
|
TestState test_state_ RTC_GUARDED_BY(crit_);
|
|
|
|
|
int rtp_count_ RTC_GUARDED_BY(crit_);
|
|
|
|
|
int last_sequence_number_ RTC_GUARDED_BY(crit_);
|
|
|
|
|
int suspended_frame_count_ RTC_GUARDED_BY(crit_);
|
|
|
|
|
int low_remb_bps_ RTC_GUARDED_BY(crit_);
|
|
|
|
|
int high_remb_bps_ RTC_GUARDED_BY(crit_);
|
2014-06-27 08:47:52 +00:00
|
|
|
} test;
|
2013-10-23 11:04:57 +00:00
|
|
|
|
2016-01-08 06:47:13 -08:00
|
|
|
RunBaseTest(&test);
|
2013-10-23 11:04:57 +00:00
|
|
|
}
|
|
|
|
|
|
2016-06-15 00:47:53 -07:00
|
|
|
// This test that padding stops being send after a while if the Camera stops
|
|
|
|
|
// producing video frames and that padding resumes if the camera restarts.
|
2013-11-25 11:54:24 +00:00
|
|
|
TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
|
2014-06-27 08:47:52 +00:00
|
|
|
class NoPaddingWhenVideoIsMuted : public test::SendTest {
|
2013-11-25 11:54:24 +00:00
|
|
|
public:
|
2014-06-27 08:47:52 +00:00
|
|
|
NoPaddingWhenVideoIsMuted()
|
|
|
|
|
: SendTest(kDefaultTimeoutMs),
|
2013-11-25 11:54:24 +00:00
|
|
|
clock_(Clock::GetRealTimeClock()),
|
2014-04-28 13:00:21 +00:00
|
|
|
last_packet_time_ms_(-1),
|
2015-03-23 13:12:24 +00:00
|
|
|
capturer_(nullptr) {}
|
2013-11-25 11:54:24 +00:00
|
|
|
|
2014-06-27 08:47:52 +00:00
|
|
|
private:
|
2015-03-04 12:58:35 +00:00
|
|
|
Action OnSendRtp(const uint8_t* packet, size_t length) override {
|
2015-05-01 13:00:41 +02:00
|
|
|
rtc::CritScope lock(&crit_);
|
2013-11-25 11:54:24 +00:00
|
|
|
last_packet_time_ms_ = clock_->TimeInMilliseconds();
|
2016-06-15 00:47:53 -07:00
|
|
|
|
|
|
|
|
RTPHeader header;
|
|
|
|
|
parser_->Parse(packet, length, &header);
|
|
|
|
|
const bool only_padding =
|
|
|
|
|
header.headerLength + header.paddingLength == length;
|
|
|
|
|
|
|
|
|
|
if (test_state_ == kBeforeStopCapture) {
|
|
|
|
|
capturer_->Stop();
|
|
|
|
|
test_state_ = kWaitingForPadding;
|
|
|
|
|
} else if (test_state_ == kWaitingForPadding && only_padding) {
|
|
|
|
|
test_state_ = kWaitingForNoPackets;
|
|
|
|
|
} else if (test_state_ == kWaitingForPaddingAfterCameraRestart &&
|
|
|
|
|
only_padding) {
|
|
|
|
|
observation_complete_.Set();
|
|
|
|
|
}
|
2013-11-25 11:54:24 +00:00
|
|
|
return SEND_PACKET;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
Action OnSendRtcp(const uint8_t* packet, size_t length) override {
|
2015-05-01 13:00:41 +02:00
|
|
|
rtc::CritScope lock(&crit_);
|
2016-06-15 00:47:53 -07:00
|
|
|
const int kNoPacketsThresholdMs = 2000;
|
|
|
|
|
if (test_state_ == kWaitingForNoPackets &&
|
|
|
|
|
(last_packet_time_ms_ > 0 &&
|
|
|
|
|
clock_->TimeInMilliseconds() - last_packet_time_ms_ >
|
|
|
|
|
kNoPacketsThresholdMs)) {
|
|
|
|
|
capturer_->Start();
|
|
|
|
|
test_state_ = kWaitingForPaddingAfterCameraRestart;
|
|
|
|
|
}
|
2013-11-25 11:54:24 +00:00
|
|
|
return SEND_PACKET;
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-07 17:43:18 +01:00
|
|
|
size_t GetNumVideoStreams() const override { return 3; }
|
2014-06-27 08:47:52 +00:00
|
|
|
|
2016-04-29 06:09:15 -07:00
|
|
|
void OnFrameGeneratorCapturerCreated(
|
|
|
|
|
test::FrameGeneratorCapturer* frame_generator_capturer) override {
|
2015-05-01 13:00:41 +02:00
|
|
|
rtc::CritScope lock(&crit_);
|
2014-06-27 08:47:52 +00:00
|
|
|
capturer_ = frame_generator_capturer;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
void PerformTest() override {
|
2015-12-10 13:02:50 +01:00
|
|
|
EXPECT_TRUE(Wait())
|
2014-06-27 08:47:52 +00:00
|
|
|
<< "Timed out while waiting for RTP packets to stop being sent.";
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-15 00:47:53 -07:00
|
|
|
enum TestState {
|
|
|
|
|
kBeforeStopCapture,
|
|
|
|
|
kWaitingForPadding,
|
|
|
|
|
kWaitingForNoPackets,
|
|
|
|
|
kWaitingForPaddingAfterCameraRestart
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
TestState test_state_ = kBeforeStopCapture;
|
2014-04-28 13:00:21 +00:00
|
|
|
Clock* const clock_;
|
2016-03-01 11:52:33 -08:00
|
|
|
std::unique_ptr<internal::TransportAdapter> transport_adapter_;
|
2015-05-01 13:00:41 +02:00
|
|
|
rtc::CriticalSection crit_;
|
2017-09-09 04:17:22 -07:00
|
|
|
int64_t last_packet_time_ms_ RTC_GUARDED_BY(crit_);
|
|
|
|
|
test::FrameGeneratorCapturer* capturer_ RTC_GUARDED_BY(crit_);
|
2014-06-27 08:47:52 +00:00
|
|
|
} test;
|
2013-11-25 11:54:24 +00:00
|
|
|
|
2016-01-08 06:47:13 -08:00
|
|
|
RunBaseTest(&test);
|
2013-11-25 11:54:24 +00:00
|
|
|
}
|
|
|
|
|
|
2016-10-04 08:29:38 -07:00
|
|
|
TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
|
|
|
|
|
const int kCapacityKbps = 10000; // 10 Mbps
|
|
|
|
|
class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest {
|
|
|
|
|
public:
|
|
|
|
|
PaddingIsPrimarilyRetransmissions()
|
|
|
|
|
: EndToEndTest(kDefaultTimeoutMs),
|
|
|
|
|
clock_(Clock::GetRealTimeClock()),
|
|
|
|
|
padding_length_(0),
|
|
|
|
|
total_length_(0),
|
|
|
|
|
call_(nullptr) {}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
|
|
|
|
|
call_ = sender_call;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Action OnSendRtp(const uint8_t* packet, size_t length) override {
|
|
|
|
|
rtc::CritScope lock(&crit_);
|
|
|
|
|
|
|
|
|
|
RTPHeader header;
|
|
|
|
|
parser_->Parse(packet, length, &header);
|
|
|
|
|
padding_length_ += header.paddingLength;
|
|
|
|
|
total_length_ += length;
|
|
|
|
|
return SEND_PACKET;
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-22 04:02:52 -07:00
|
|
|
test::PacketTransport* CreateSendTransport(
|
|
|
|
|
test::SingleThreadedTaskQueueForTesting* task_queue,
|
|
|
|
|
Call* sender_call) override {
|
2016-10-04 08:29:38 -07:00
|
|
|
const int kNetworkDelayMs = 50;
|
2018-08-17 14:26:54 +02:00
|
|
|
DefaultNetworkSimulationConfig config;
|
2016-10-04 08:29:38 -07:00
|
|
|
config.loss_percent = 10;
|
|
|
|
|
config.link_capacity_kbps = kCapacityKbps;
|
|
|
|
|
config.queue_delay_ms = kNetworkDelayMs;
|
2018-08-20 13:30:39 +02:00
|
|
|
return new test::PacketTransport(
|
|
|
|
|
task_queue, sender_call, this, test::PacketTransport::kSender,
|
|
|
|
|
payload_type_map_,
|
|
|
|
|
absl::make_unique<FakeNetworkPipe>(
|
|
|
|
|
Clock::GetRealTimeClock(),
|
|
|
|
|
absl::make_unique<SimulatedNetwork>(config)));
|
2016-10-04 08:29:38 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
|
|
|
|
// Turn on RTX.
|
|
|
|
|
send_config->rtp.rtx.payload_type = kFakeVideoSendPayloadType;
|
|
|
|
|
send_config->rtp.rtx.ssrcs.push_back(kVideoSendSsrcs[0]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PerformTest() override {
|
|
|
|
|
// TODO(isheriff): Some platforms do not ramp up as expected to full
|
|
|
|
|
// capacity due to packet scheduling delays. Fix that before getting
|
|
|
|
|
// rid of this.
|
|
|
|
|
SleepMs(5000);
|
|
|
|
|
{
|
|
|
|
|
rtc::CritScope lock(&crit_);
|
|
|
|
|
// Expect padding to be a small percentage of total bytes sent.
|
|
|
|
|
EXPECT_LT(padding_length_, .1 * total_length_);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rtc::CriticalSection crit_;
|
|
|
|
|
Clock* const clock_;
|
2017-09-09 04:17:22 -07:00
|
|
|
size_t padding_length_ RTC_GUARDED_BY(crit_);
|
|
|
|
|
size_t total_length_ RTC_GUARDED_BY(crit_);
|
2016-10-04 08:29:38 -07:00
|
|
|
Call* call_;
|
|
|
|
|
} test;
|
|
|
|
|
|
|
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-19 10:59:52 +00:00
|
|
|
// This test first observes "high" bitrate use at which point it sends a REMB to
|
|
|
|
|
// indicate that it should be lowered significantly. The test then observes that
|
|
|
|
|
// the bitrate observed is sinking well below the min-transmit-bitrate threshold
|
|
|
|
|
// to verify that the min-transmit bitrate respects incoming REMB.
|
2014-03-26 21:00:21 +00:00
|
|
|
//
|
|
|
|
|
// Note that the test starts at "high" bitrate and does not ramp up to "higher"
|
|
|
|
|
// bitrate since no receiver block or remb is sent in the initial phase.
|
2014-03-19 10:59:52 +00:00
|
|
|
TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
|
|
|
|
|
static const int kMinTransmitBitrateBps = 400000;
|
2014-03-26 21:00:21 +00:00
|
|
|
static const int kHighBitrateBps = 150000;
|
2014-03-19 10:59:52 +00:00
|
|
|
static const int kRembBitrateBps = 80000;
|
|
|
|
|
static const int kRembRespectedBitrateBps = 100000;
|
2015-10-27 08:29:42 -07:00
|
|
|
class BitrateObserver : public test::SendTest {
|
2014-03-19 10:59:52 +00:00
|
|
|
public:
|
|
|
|
|
BitrateObserver()
|
2014-06-27 08:47:52 +00:00
|
|
|
: SendTest(kDefaultTimeoutMs),
|
2016-07-29 12:59:36 +02:00
|
|
|
retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
|
|
|
|
|
stream_(nullptr),
|
|
|
|
|
bitrate_capped_(false) {}
|
2014-03-19 10:59:52 +00:00
|
|
|
|
|
|
|
|
private:
|
2016-04-29 06:09:15 -07:00
|
|
|
Action OnSendRtp(const uint8_t* packet, size_t length) override {
|
2014-07-08 12:10:51 +00:00
|
|
|
if (RtpHeaderParser::IsRtcp(packet, length))
|
2015-10-27 08:29:42 -07:00
|
|
|
return DROP_PACKET;
|
2014-03-19 10:59:52 +00:00
|
|
|
|
|
|
|
|
RTPHeader header;
|
2014-07-08 12:10:51 +00:00
|
|
|
if (!parser_->Parse(packet, length, &header))
|
2015-10-27 08:29:42 -07:00
|
|
|
return DROP_PACKET;
|
2016-04-04 17:56:10 +02:00
|
|
|
RTC_DCHECK(stream_);
|
2014-06-27 08:47:52 +00:00
|
|
|
VideoSendStream::Stats stats = stream_->GetStats();
|
2014-03-19 10:59:52 +00:00
|
|
|
if (!stats.substreams.empty()) {
|
|
|
|
|
EXPECT_EQ(1u, stats.substreams.size());
|
2014-11-05 14:05:29 +00:00
|
|
|
int total_bitrate_bps =
|
|
|
|
|
stats.substreams.begin()->second.total_bitrate_bps;
|
|
|
|
|
test::PrintResult("bitrate_stats_", "min_transmit_bitrate_low_remb",
|
|
|
|
|
"bitrate_bps", static_cast<size_t>(total_bitrate_bps),
|
|
|
|
|
"bps", false);
|
|
|
|
|
if (total_bitrate_bps > kHighBitrateBps) {
|
2017-10-10 17:46:26 +02:00
|
|
|
rtp_rtcp_->SetRemb(kRembBitrateBps,
|
|
|
|
|
std::vector<uint32_t>(1, header.ssrc));
|
2014-03-19 10:59:52 +00:00
|
|
|
rtp_rtcp_->Process();
|
|
|
|
|
bitrate_capped_ = true;
|
|
|
|
|
} else if (bitrate_capped_ &&
|
2014-11-05 14:05:29 +00:00
|
|
|
total_bitrate_bps < kRembRespectedBitrateBps) {
|
2015-12-10 13:02:50 +01:00
|
|
|
observation_complete_.Set();
|
2014-03-19 10:59:52 +00:00
|
|
|
}
|
|
|
|
|
}
|
2015-10-27 08:29:42 -07:00
|
|
|
// Packets don't have to be delivered since the test is the receiver.
|
|
|
|
|
return DROP_PACKET;
|
2014-03-19 10:59:52 +00:00
|
|
|
}
|
|
|
|
|
|
2015-12-21 03:14:00 -08:00
|
|
|
void OnVideoStreamsCreated(
|
2015-10-27 08:29:42 -07:00
|
|
|
VideoSendStream* send_stream,
|
|
|
|
|
const std::vector<VideoReceiveStream*>& receive_streams) override {
|
|
|
|
|
stream_ = send_stream;
|
|
|
|
|
RtpRtcp::Configuration config;
|
|
|
|
|
config.outgoing_transport = feedback_transport_.get();
|
2016-07-29 12:59:36 +02:00
|
|
|
config.retransmission_rate_limiter = &retranmission_rate_limiter_;
|
2015-10-27 08:29:42 -07:00
|
|
|
rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
|
|
|
|
|
rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
|
2014-06-27 08:47:52 +00:00
|
|
|
}
|
2014-03-19 10:59:52 +00:00
|
|
|
|
2015-12-21 03:14:00 -08:00
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
2015-10-27 08:29:42 -07:00
|
|
|
feedback_transport_.reset(
|
|
|
|
|
new internal::TransportAdapter(send_config->send_transport));
|
|
|
|
|
feedback_transport_->Enable();
|
2014-10-24 09:23:21 +00:00
|
|
|
encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
|
2014-06-27 08:47:52 +00:00
|
|
|
}
|
2014-03-19 10:59:52 +00:00
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
void PerformTest() override {
|
2015-12-10 13:02:50 +01:00
|
|
|
EXPECT_TRUE(Wait())
|
2014-06-27 08:47:52 +00:00
|
|
|
<< "Timeout while waiting for low bitrate stats after REMB.";
|
|
|
|
|
}
|
2014-03-19 10:59:52 +00:00
|
|
|
|
2016-03-01 11:52:33 -08:00
|
|
|
std::unique_ptr<RtpRtcp> rtp_rtcp_;
|
|
|
|
|
std::unique_ptr<internal::TransportAdapter> feedback_transport_;
|
2016-07-29 12:59:36 +02:00
|
|
|
RateLimiter retranmission_rate_limiter_;
|
2014-06-27 08:47:52 +00:00
|
|
|
VideoSendStream* stream_;
|
|
|
|
|
bool bitrate_capped_;
|
|
|
|
|
} test;
|
2014-03-19 10:59:52 +00:00
|
|
|
|
2016-01-08 06:47:13 -08:00
|
|
|
RunBaseTest(&test);
|
2014-03-19 10:59:52 +00:00
|
|
|
}
|
|
|
|
|
|
2016-09-30 10:06:51 +02:00
|
|
|
TEST_F(VideoSendStreamTest, ChangingNetworkRoute) {
|
|
|
|
|
static const int kStartBitrateBps = 300000;
|
|
|
|
|
static const int kNewMaxBitrateBps = 1234567;
|
2016-10-31 03:34:40 -07:00
|
|
|
static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
|
2016-07-08 16:16:41 +02:00
|
|
|
class ChangingNetworkRouteTest : public test::EndToEndTest {
|
|
|
|
|
public:
|
2017-08-22 04:02:52 -07:00
|
|
|
explicit ChangingNetworkRouteTest(
|
|
|
|
|
test::SingleThreadedTaskQueueForTesting* task_queue)
|
|
|
|
|
: EndToEndTest(test::CallTest::kDefaultTimeoutMs),
|
|
|
|
|
task_queue_(task_queue),
|
|
|
|
|
call_(nullptr) {
|
2016-09-30 10:06:51 +02:00
|
|
|
EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
|
|
|
|
|
kRtpExtensionTransportSequenceNumber, kExtensionId));
|
|
|
|
|
}
|
2016-07-08 16:16:41 +02:00
|
|
|
|
|
|
|
|
void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
|
|
|
|
|
call_ = sender_call;
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-30 10:06:51 +02:00
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
|
|
|
|
send_config->rtp.extensions.clear();
|
|
|
|
|
send_config->rtp.extensions.push_back(RtpExtension(
|
|
|
|
|
RtpExtension::kTransportSequenceNumberUri, kExtensionId));
|
|
|
|
|
(*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
|
|
|
|
|
(*receive_configs)[0].rtp.transport_cc = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModifyAudioConfigs(
|
|
|
|
|
AudioSendStream::Config* send_config,
|
|
|
|
|
std::vector<AudioReceiveStream::Config>* receive_configs) override {
|
|
|
|
|
send_config->rtp.extensions.clear();
|
|
|
|
|
send_config->rtp.extensions.push_back(RtpExtension(
|
|
|
|
|
RtpExtension::kTransportSequenceNumberUri, kExtensionId));
|
|
|
|
|
(*receive_configs)[0].rtp.extensions.clear();
|
|
|
|
|
(*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
|
|
|
|
|
(*receive_configs)[0].rtp.transport_cc = true;
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-08 16:16:41 +02:00
|
|
|
Action OnSendRtp(const uint8_t* packet, size_t length) override {
|
|
|
|
|
if (call_->GetStats().send_bandwidth_bps > kStartBitrateBps) {
|
|
|
|
|
observation_complete_.Set();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return SEND_PACKET;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PerformTest() override {
|
2018-07-23 10:12:37 -07:00
|
|
|
rtc::NetworkRoute new_route;
|
|
|
|
|
new_route.connected = true;
|
|
|
|
|
new_route.local_network_id = 10;
|
|
|
|
|
new_route.remote_network_id = 20;
|
2018-02-21 09:52:06 +01:00
|
|
|
BitrateConstraints bitrate_config;
|
2017-08-22 04:02:52 -07:00
|
|
|
|
|
|
|
|
task_queue_->SendTask([this, &new_route, &bitrate_config]() {
|
2018-02-21 13:07:13 +01:00
|
|
|
call_->GetTransportControllerSend()->OnNetworkRouteChanged("transport",
|
|
|
|
|
new_route);
|
2017-08-22 04:02:52 -07:00
|
|
|
bitrate_config.start_bitrate_bps = kStartBitrateBps;
|
2018-02-21 13:07:13 +01:00
|
|
|
call_->GetTransportControllerSend()->SetSdpBitrateParameters(
|
|
|
|
|
bitrate_config);
|
2017-08-22 04:02:52 -07:00
|
|
|
});
|
|
|
|
|
|
2016-07-08 16:16:41 +02:00
|
|
|
EXPECT_TRUE(Wait())
|
|
|
|
|
<< "Timed out while waiting for start bitrate to be exceeded.";
|
|
|
|
|
|
2017-08-22 04:02:52 -07:00
|
|
|
task_queue_->SendTask([this, &new_route, &bitrate_config]() {
|
|
|
|
|
bitrate_config.start_bitrate_bps = -1;
|
|
|
|
|
bitrate_config.max_bitrate_bps = kNewMaxBitrateBps;
|
2018-02-21 13:07:13 +01:00
|
|
|
call_->GetTransportControllerSend()->SetSdpBitrateParameters(
|
|
|
|
|
bitrate_config);
|
2017-08-22 04:02:52 -07:00
|
|
|
// TODO(holmer): We should set the last sent packet id here and verify
|
|
|
|
|
// that we correctly ignore any packet loss reported prior to that id.
|
|
|
|
|
++new_route.local_network_id;
|
2018-02-21 13:07:13 +01:00
|
|
|
call_->GetTransportControllerSend()->OnNetworkRouteChanged("transport",
|
|
|
|
|
new_route);
|
2017-08-22 04:02:52 -07:00
|
|
|
EXPECT_GE(call_->GetStats().send_bandwidth_bps, kStartBitrateBps);
|
|
|
|
|
});
|
2016-07-08 16:16:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
2017-08-22 04:02:52 -07:00
|
|
|
test::SingleThreadedTaskQueueForTesting* const task_queue_;
|
2016-07-08 16:16:41 +02:00
|
|
|
Call* call_;
|
2017-08-22 04:02:52 -07:00
|
|
|
} test(&task_queue_);
|
2016-07-08 16:16:41 +02:00
|
|
|
|
|
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-08 02:50:09 -08:00
|
|
|
TEST_F(VideoSendStreamTest, ChangingTransportOverhead) {
|
|
|
|
|
class ChangingTransportOverheadTest : public test::EndToEndTest {
|
|
|
|
|
public:
|
2017-08-22 04:02:52 -07:00
|
|
|
explicit ChangingTransportOverheadTest(
|
|
|
|
|
test::SingleThreadedTaskQueueForTesting* task_queue)
|
2016-11-08 02:50:09 -08:00
|
|
|
: EndToEndTest(test::CallTest::kDefaultTimeoutMs),
|
2017-08-22 04:02:52 -07:00
|
|
|
task_queue_(task_queue),
|
2016-11-08 02:50:09 -08:00
|
|
|
call_(nullptr),
|
2016-11-16 16:41:30 +01:00
|
|
|
packets_sent_(0),
|
|
|
|
|
transport_overhead_(0) {}
|
2016-11-08 02:50:09 -08:00
|
|
|
|
|
|
|
|
void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
|
|
|
|
|
call_ = sender_call;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Action OnSendRtp(const uint8_t* packet, size_t length) override {
|
2016-11-29 09:25:03 -08:00
|
|
|
EXPECT_LE(length, kMaxRtpPacketSize);
|
2017-02-27 03:35:47 -08:00
|
|
|
rtc::CritScope cs(&lock_);
|
2016-11-08 02:50:09 -08:00
|
|
|
if (++packets_sent_ < 100)
|
|
|
|
|
return SEND_PACKET;
|
|
|
|
|
observation_complete_.Set();
|
|
|
|
|
return SEND_PACKET;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-29 09:25:03 -08:00
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
|
|
|
|
send_config->rtp.max_packet_size = kMaxRtpPacketSize;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-08 02:50:09 -08:00
|
|
|
void PerformTest() override {
|
2017-08-22 04:02:52 -07:00
|
|
|
task_queue_->SendTask([this]() {
|
|
|
|
|
transport_overhead_ = 100;
|
|
|
|
|
call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
|
|
|
|
|
transport_overhead_);
|
|
|
|
|
});
|
|
|
|
|
|
2016-11-08 02:50:09 -08:00
|
|
|
EXPECT_TRUE(Wait());
|
2017-08-22 04:02:52 -07:00
|
|
|
|
2017-02-27 03:35:47 -08:00
|
|
|
{
|
|
|
|
|
rtc::CritScope cs(&lock_);
|
|
|
|
|
packets_sent_ = 0;
|
|
|
|
|
}
|
2017-08-22 04:02:52 -07:00
|
|
|
|
|
|
|
|
task_queue_->SendTask([this]() {
|
|
|
|
|
transport_overhead_ = 500;
|
|
|
|
|
call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
|
|
|
|
|
transport_overhead_);
|
|
|
|
|
});
|
|
|
|
|
|
2016-11-08 02:50:09 -08:00
|
|
|
EXPECT_TRUE(Wait());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
2017-08-22 04:02:52 -07:00
|
|
|
test::SingleThreadedTaskQueueForTesting* const task_queue_;
|
2016-11-08 02:50:09 -08:00
|
|
|
Call* call_;
|
2017-02-27 03:35:47 -08:00
|
|
|
rtc::CriticalSection lock_;
|
2017-09-09 04:17:22 -07:00
|
|
|
int packets_sent_ RTC_GUARDED_BY(lock_);
|
2016-11-08 02:50:09 -08:00
|
|
|
int transport_overhead_;
|
2016-11-29 09:25:03 -08:00
|
|
|
const size_t kMaxRtpPacketSize = 1000;
|
2017-08-22 04:02:52 -07:00
|
|
|
} test(&task_queue_);
|
2016-11-08 02:50:09 -08:00
|
|
|
|
|
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-28 13:23:26 -08:00
|
|
|
// Test class takes takes as argument a switch selecting if type switch should
|
|
|
|
|
// occur and a function pointer to reset the send stream. This is necessary
|
|
|
|
|
// since you cannot change the content type of a VideoSendStream, you need to
|
|
|
|
|
// recreate it. Stopping and recreating the stream can only be done on the main
|
|
|
|
|
// thread and in the context of VideoSendStreamTest (not BaseTest).
|
|
|
|
|
template <typename T>
|
2016-07-06 00:54:28 -07:00
|
|
|
class MaxPaddingSetTest : public test::SendTest {
|
|
|
|
|
public:
|
|
|
|
|
static const uint32_t kMinTransmitBitrateBps = 400000;
|
|
|
|
|
static const uint32_t kActualEncodeBitrateBps = 40000;
|
|
|
|
|
static const uint32_t kMinPacketsToSend = 50;
|
|
|
|
|
|
2017-02-28 13:23:26 -08:00
|
|
|
explicit MaxPaddingSetTest(bool test_switch_content_type, T* stream_reset_fun)
|
2016-07-06 00:54:28 -07:00
|
|
|
: SendTest(test::CallTest::kDefaultTimeoutMs),
|
2017-02-28 13:23:26 -08:00
|
|
|
content_switch_event_(false, false),
|
2016-07-06 00:54:28 -07:00
|
|
|
call_(nullptr),
|
|
|
|
|
send_stream_(nullptr),
|
2017-02-28 13:23:26 -08:00
|
|
|
send_stream_config_(nullptr),
|
2016-07-06 00:54:28 -07:00
|
|
|
packets_sent_(0),
|
2017-02-28 13:23:26 -08:00
|
|
|
running_without_padding_(test_switch_content_type),
|
2017-03-13 05:15:14 -07:00
|
|
|
stream_resetter_(stream_reset_fun) {
|
|
|
|
|
RTC_DCHECK(stream_resetter_);
|
|
|
|
|
}
|
2016-07-06 00:54:28 -07:00
|
|
|
|
|
|
|
|
void OnVideoStreamsCreated(
|
|
|
|
|
VideoSendStream* send_stream,
|
|
|
|
|
const std::vector<VideoReceiveStream*>& receive_streams) override {
|
2017-02-28 13:23:26 -08:00
|
|
|
rtc::CritScope lock(&crit_);
|
2016-07-06 00:54:28 -07:00
|
|
|
send_stream_ = send_stream;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
2016-11-28 15:21:39 -08:00
|
|
|
RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
|
2017-02-28 13:23:26 -08:00
|
|
|
if (RunningWithoutPadding()) {
|
2016-07-06 00:54:28 -07:00
|
|
|
encoder_config->min_transmit_bitrate_bps = 0;
|
|
|
|
|
encoder_config->content_type =
|
|
|
|
|
VideoEncoderConfig::ContentType::kRealtimeVideo;
|
|
|
|
|
} else {
|
|
|
|
|
encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
|
|
|
|
|
encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
|
|
|
|
|
}
|
2017-02-28 13:23:26 -08:00
|
|
|
send_stream_config_ = send_config->Copy();
|
2016-09-01 01:17:40 -07:00
|
|
|
encoder_config_ = encoder_config->Copy();
|
2016-07-06 00:54:28 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
|
|
|
|
|
call_ = sender_call;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Action OnSendRtp(const uint8_t* packet, size_t length) override {
|
|
|
|
|
rtc::CritScope lock(&crit_);
|
|
|
|
|
if (running_without_padding_)
|
|
|
|
|
EXPECT_EQ(0, call_->GetStats().max_padding_bitrate_bps);
|
|
|
|
|
|
|
|
|
|
// Wait until at least kMinPacketsToSend frames have been encoded, so that
|
|
|
|
|
// we have reliable data.
|
|
|
|
|
if (++packets_sent_ < kMinPacketsToSend)
|
|
|
|
|
return SEND_PACKET;
|
|
|
|
|
|
|
|
|
|
if (running_without_padding_) {
|
|
|
|
|
// We've sent kMinPacketsToSend packets with default configuration, switch
|
|
|
|
|
// to enabling screen content and setting min transmit bitrate.
|
2017-02-28 13:23:26 -08:00
|
|
|
// Note that we need to recreate the stream if changing content type.
|
2016-07-06 00:54:28 -07:00
|
|
|
packets_sent_ = 0;
|
|
|
|
|
encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
|
|
|
|
|
encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
|
|
|
|
|
running_without_padding_ = false;
|
2017-02-28 13:23:26 -08:00
|
|
|
content_switch_event_.Set();
|
2016-07-06 00:54:28 -07:00
|
|
|
return SEND_PACKET;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Make sure the pacer has been configured with a min transmit bitrate.
|
|
|
|
|
if (call_->GetStats().max_padding_bitrate_bps > 0)
|
|
|
|
|
observation_complete_.Set();
|
|
|
|
|
|
|
|
|
|
return SEND_PACKET;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PerformTest() override {
|
2017-02-28 13:23:26 -08:00
|
|
|
if (RunningWithoutPadding()) {
|
|
|
|
|
ASSERT_TRUE(
|
|
|
|
|
content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
|
|
|
|
|
(*stream_resetter_)(send_stream_config_, encoder_config_);
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-06 00:54:28 -07:00
|
|
|
ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate.";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
2017-02-28 13:23:26 -08:00
|
|
|
bool RunningWithoutPadding() const {
|
|
|
|
|
rtc::CritScope lock(&crit_);
|
|
|
|
|
return running_without_padding_;
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-06 00:54:28 -07:00
|
|
|
rtc::CriticalSection crit_;
|
2017-02-28 13:23:26 -08:00
|
|
|
rtc::Event content_switch_event_;
|
2016-07-06 00:54:28 -07:00
|
|
|
Call* call_;
|
2017-09-09 04:17:22 -07:00
|
|
|
VideoSendStream* send_stream_ RTC_GUARDED_BY(crit_);
|
2017-02-28 13:23:26 -08:00
|
|
|
VideoSendStream::Config send_stream_config_;
|
2016-07-06 00:54:28 -07:00
|
|
|
VideoEncoderConfig encoder_config_;
|
2017-09-09 04:17:22 -07:00
|
|
|
uint32_t packets_sent_ RTC_GUARDED_BY(crit_);
|
2016-07-06 00:54:28 -07:00
|
|
|
bool running_without_padding_;
|
2017-02-28 13:23:26 -08:00
|
|
|
T* const stream_resetter_;
|
2016-07-06 00:54:28 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrate) {
|
2017-02-28 13:23:26 -08:00
|
|
|
auto reset_fun = [](const VideoSendStream::Config& send_stream_config,
|
|
|
|
|
const VideoEncoderConfig& encoder_config) {};
|
|
|
|
|
MaxPaddingSetTest<decltype(reset_fun)> test(false, &reset_fun);
|
2016-07-06 00:54:28 -07:00
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrateAfterContentSwitch) {
|
2017-02-28 13:23:26 -08:00
|
|
|
// Function for removing and recreating the send stream with a new config.
|
|
|
|
|
auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
|
|
|
|
|
const VideoEncoderConfig& encoder_config) {
|
2017-08-22 04:02:52 -07:00
|
|
|
task_queue_.SendTask([this, &send_stream_config, &encoder_config]() {
|
|
|
|
|
Stop();
|
2018-07-13 09:49:00 +02:00
|
|
|
DestroyVideoSendStreams();
|
|
|
|
|
SetVideoSendConfig(send_stream_config);
|
|
|
|
|
SetVideoEncoderConfig(encoder_config);
|
|
|
|
|
CreateVideoSendStreams();
|
|
|
|
|
SetVideoDegradation(DegradationPreference::MAINTAIN_RESOLUTION);
|
2017-08-22 04:02:52 -07:00
|
|
|
Start();
|
|
|
|
|
});
|
2017-02-28 13:23:26 -08:00
|
|
|
};
|
|
|
|
|
MaxPaddingSetTest<decltype(reset_fun)> test(true, &reset_fun);
|
2016-07-06 00:54:28 -07:00
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-02 23:45:26 -07:00
|
|
|
// This test verifies that new frame sizes reconfigures encoders even though not
|
|
|
|
|
// (yet) sending. The purpose of this is to permit encoding as quickly as
|
|
|
|
|
// possible once we start sending. Likely the frames being input are from the
|
|
|
|
|
// same source that will be sent later, which just means that we're ready
|
|
|
|
|
// earlier.
|
|
|
|
|
TEST_F(VideoSendStreamTest,
|
|
|
|
|
EncoderReconfigureOnResolutionChangeWhenNotSending) {
|
|
|
|
|
class EncoderObserver : public test::FakeEncoder {
|
|
|
|
|
public:
|
|
|
|
|
EncoderObserver()
|
|
|
|
|
: FakeEncoder(Clock::GetRealTimeClock()),
|
|
|
|
|
init_encode_called_(false, false),
|
|
|
|
|
number_of_initializations_(0),
|
|
|
|
|
last_initialized_frame_width_(0),
|
|
|
|
|
last_initialized_frame_height_(0) {}
|
|
|
|
|
|
|
|
|
|
void WaitForResolution(int width, int height) {
|
|
|
|
|
{
|
|
|
|
|
rtc::CritScope lock(&crit_);
|
|
|
|
|
if (last_initialized_frame_width_ == width &&
|
|
|
|
|
last_initialized_frame_height_ == height) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-11-16 16:41:30 +01:00
|
|
|
EXPECT_TRUE(
|
|
|
|
|
init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
|
2016-10-02 23:45:26 -07:00
|
|
|
{
|
|
|
|
|
rtc::CritScope lock(&crit_);
|
|
|
|
|
EXPECT_EQ(width, last_initialized_frame_width_);
|
|
|
|
|
EXPECT_EQ(height, last_initialized_frame_height_);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
int32_t InitEncode(const VideoCodec* config,
|
|
|
|
|
int32_t number_of_cores,
|
|
|
|
|
size_t max_payload_size) override {
|
|
|
|
|
rtc::CritScope lock(&crit_);
|
|
|
|
|
last_initialized_frame_width_ = config->width;
|
|
|
|
|
last_initialized_frame_height_ = config->height;
|
|
|
|
|
++number_of_initializations_;
|
2016-11-16 16:41:30 +01:00
|
|
|
init_encode_called_.Set();
|
2016-10-02 23:45:26 -07:00
|
|
|
return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int32_t Encode(const VideoFrame& input_image,
|
|
|
|
|
const CodecSpecificInfo* codec_specific_info,
|
|
|
|
|
const std::vector<FrameType>* frame_types) override {
|
|
|
|
|
ADD_FAILURE()
|
|
|
|
|
<< "Unexpected Encode call since the send stream is not started";
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rtc::CriticalSection crit_;
|
|
|
|
|
rtc::Event init_encode_called_;
|
2017-09-09 04:17:22 -07:00
|
|
|
size_t number_of_initializations_ RTC_GUARDED_BY(&crit_);
|
|
|
|
|
int last_initialized_frame_width_ RTC_GUARDED_BY(&crit_);
|
|
|
|
|
int last_initialized_frame_height_ RTC_GUARDED_BY(&crit_);
|
2016-10-02 23:45:26 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
test::NullTransport transport;
|
|
|
|
|
EncoderObserver encoder;
|
2018-04-19 09:04:13 +02:00
|
|
|
test::EncoderProxyFactory encoder_factory(&encoder);
|
2017-08-22 04:02:52 -07:00
|
|
|
|
2018-04-19 09:04:13 +02:00
|
|
|
task_queue_.SendTask([this, &transport, &encoder_factory]() {
|
2018-07-13 10:43:20 +02:00
|
|
|
CreateSenderCall();
|
2017-08-22 04:02:52 -07:00
|
|
|
CreateSendConfig(1, 0, 0, &transport);
|
2018-07-13 09:49:00 +02:00
|
|
|
GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
|
2017-08-22 04:02:52 -07:00
|
|
|
CreateVideoStreams();
|
|
|
|
|
CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
|
|
|
|
|
kDefaultHeight);
|
|
|
|
|
frame_generator_capturer_->Start();
|
|
|
|
|
});
|
2016-10-02 23:45:26 -07:00
|
|
|
|
|
|
|
|
encoder.WaitForResolution(kDefaultWidth, kDefaultHeight);
|
2017-08-22 04:02:52 -07:00
|
|
|
|
|
|
|
|
task_queue_.SendTask([this]() {
|
|
|
|
|
frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2,
|
|
|
|
|
kDefaultHeight * 2);
|
|
|
|
|
});
|
|
|
|
|
|
2016-10-02 23:45:26 -07:00
|
|
|
encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2);
|
2017-08-22 04:02:52 -07:00
|
|
|
|
|
|
|
|
task_queue_.SendTask([this]() {
|
|
|
|
|
DestroyStreams();
|
|
|
|
|
DestroyCalls();
|
|
|
|
|
});
|
2016-10-02 23:45:26 -07:00
|
|
|
}
|
|
|
|
|
|
2015-03-18 14:40:03 +00:00
|
|
|
TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
|
|
|
|
|
class StartBitrateObserver : public test::FakeEncoder {
|
|
|
|
|
public:
|
|
|
|
|
StartBitrateObserver()
|
2016-04-20 06:35:56 -07:00
|
|
|
: FakeEncoder(Clock::GetRealTimeClock()),
|
|
|
|
|
start_bitrate_changed_(false, false),
|
|
|
|
|
start_bitrate_kbps_(0) {}
|
2015-03-18 14:40:03 +00:00
|
|
|
int32_t InitEncode(const VideoCodec* config,
|
|
|
|
|
int32_t number_of_cores,
|
|
|
|
|
size_t max_payload_size) override {
|
|
|
|
|
rtc::CritScope lock(&crit_);
|
|
|
|
|
start_bitrate_kbps_ = config->startBitrate;
|
2016-04-20 06:35:56 -07:00
|
|
|
start_bitrate_changed_.Set();
|
2015-03-18 14:40:03 +00:00
|
|
|
return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
|
|
|
|
|
rtc::CritScope lock(&crit_);
|
|
|
|
|
start_bitrate_kbps_ = new_target_bitrate;
|
2016-04-20 06:35:56 -07:00
|
|
|
start_bitrate_changed_.Set();
|
2015-03-18 14:40:03 +00:00
|
|
|
return FakeEncoder::SetRates(new_target_bitrate, framerate);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int GetStartBitrateKbps() const {
|
|
|
|
|
rtc::CritScope lock(&crit_);
|
|
|
|
|
return start_bitrate_kbps_;
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-20 06:35:56 -07:00
|
|
|
bool WaitForStartBitrate() {
|
|
|
|
|
return start_bitrate_changed_.Wait(
|
|
|
|
|
VideoSendStreamTest::kDefaultTimeoutMs);
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-18 14:40:03 +00:00
|
|
|
private:
|
2016-01-25 03:52:44 -08:00
|
|
|
rtc::CriticalSection crit_;
|
2016-04-20 06:35:56 -07:00
|
|
|
rtc::Event start_bitrate_changed_;
|
2017-09-09 04:17:22 -07:00
|
|
|
int start_bitrate_kbps_ RTC_GUARDED_BY(crit_);
|
2015-03-18 14:40:03 +00:00
|
|
|
};
|
|
|
|
|
|
2018-07-13 10:43:20 +02:00
|
|
|
CreateSenderCall();
|
2015-03-18 14:40:03 +00:00
|
|
|
|
2015-08-28 04:07:10 -07:00
|
|
|
test::NullTransport transport;
|
2016-11-15 07:10:52 -08:00
|
|
|
CreateSendConfig(1, 0, 0, &transport);
|
2015-03-18 14:40:03 +00:00
|
|
|
|
2018-02-21 09:52:06 +01:00
|
|
|
BitrateConstraints bitrate_config;
|
2018-07-13 09:49:00 +02:00
|
|
|
bitrate_config.start_bitrate_bps =
|
|
|
|
|
2 * GetVideoEncoderConfig()->max_bitrate_bps;
|
2018-02-21 13:07:13 +01:00
|
|
|
sender_call_->GetTransportControllerSend()->SetSdpBitrateParameters(
|
|
|
|
|
bitrate_config);
|
2015-03-18 14:40:03 +00:00
|
|
|
|
|
|
|
|
StartBitrateObserver encoder;
|
2018-04-19 09:04:13 +02:00
|
|
|
test::EncoderProxyFactory encoder_factory(&encoder);
|
2016-10-02 23:45:26 -07:00
|
|
|
// Since this test does not use a capturer, set |internal_source| = true.
|
|
|
|
|
// Encoder configuration is otherwise updated on the next video frame.
|
2018-04-19 09:04:13 +02:00
|
|
|
encoder_factory.SetHasInternalSource(true);
|
2018-07-13 09:49:00 +02:00
|
|
|
GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
|
2015-03-18 14:40:03 +00:00
|
|
|
|
2016-01-07 17:43:18 +01:00
|
|
|
CreateVideoStreams();
|
2015-03-18 14:40:03 +00:00
|
|
|
|
2016-04-20 06:35:56 -07:00
|
|
|
EXPECT_TRUE(encoder.WaitForStartBitrate());
|
2018-07-13 09:49:00 +02:00
|
|
|
EXPECT_EQ(GetVideoEncoderConfig()->max_bitrate_bps / 1000,
|
2015-03-18 14:40:03 +00:00
|
|
|
encoder.GetStartBitrateKbps());
|
|
|
|
|
|
2018-07-13 09:49:00 +02:00
|
|
|
GetVideoEncoderConfig()->max_bitrate_bps =
|
|
|
|
|
2 * bitrate_config.start_bitrate_bps;
|
|
|
|
|
GetVideoSendStream()->ReconfigureVideoEncoder(
|
|
|
|
|
GetVideoEncoderConfig()->Copy());
|
2015-03-18 14:40:03 +00:00
|
|
|
|
|
|
|
|
// New bitrate should be reconfigured above the previous max. As there's no
|
|
|
|
|
// network connection this shouldn't be flaky, as no bitrate should've been
|
|
|
|
|
// reported in between.
|
2016-04-20 06:35:56 -07:00
|
|
|
EXPECT_TRUE(encoder.WaitForStartBitrate());
|
2015-03-18 14:40:03 +00:00
|
|
|
EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
|
|
|
|
|
encoder.GetStartBitrateKbps());
|
|
|
|
|
|
|
|
|
|
DestroyStreams();
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-02 08:46:16 -08:00
|
|
|
class StartStopBitrateObserver : public test::FakeEncoder {
|
|
|
|
|
public:
|
|
|
|
|
StartStopBitrateObserver()
|
|
|
|
|
: FakeEncoder(Clock::GetRealTimeClock()),
|
|
|
|
|
encoder_init_(false, false),
|
|
|
|
|
bitrate_changed_(false, false) {}
|
|
|
|
|
int32_t InitEncode(const VideoCodec* config,
|
|
|
|
|
int32_t number_of_cores,
|
|
|
|
|
size_t max_payload_size) override {
|
|
|
|
|
rtc::CritScope lock(&crit_);
|
|
|
|
|
encoder_init_.Set();
|
|
|
|
|
return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
|
|
|
|
|
}
|
2016-06-17 07:27:16 -07:00
|
|
|
|
2018-04-23 12:32:22 +02:00
|
|
|
int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
|
2018-02-02 08:46:16 -08:00
|
|
|
uint32_t framerate) override {
|
|
|
|
|
rtc::CritScope lock(&crit_);
|
|
|
|
|
bitrate_kbps_ = bitrate.get_sum_kbps();
|
|
|
|
|
bitrate_changed_.Set();
|
|
|
|
|
return FakeEncoder::SetRateAllocation(bitrate, framerate);
|
|
|
|
|
}
|
2016-06-17 07:27:16 -07:00
|
|
|
|
2018-02-02 08:46:16 -08:00
|
|
|
bool WaitForEncoderInit() {
|
|
|
|
|
return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
|
|
|
|
|
}
|
2016-11-16 16:41:30 +01:00
|
|
|
|
2018-02-02 08:46:16 -08:00
|
|
|
bool WaitBitrateChanged(bool non_zero) {
|
|
|
|
|
do {
|
2018-06-15 12:28:07 +02:00
|
|
|
absl::optional<int> bitrate_kbps;
|
2018-02-02 08:46:16 -08:00
|
|
|
{
|
|
|
|
|
rtc::CritScope lock(&crit_);
|
|
|
|
|
bitrate_kbps = bitrate_kbps_;
|
|
|
|
|
}
|
|
|
|
|
if (!bitrate_kbps)
|
|
|
|
|
continue;
|
2016-11-16 16:41:30 +01:00
|
|
|
|
2018-02-02 08:46:16 -08:00
|
|
|
if ((non_zero && *bitrate_kbps > 0) ||
|
|
|
|
|
(!non_zero && *bitrate_kbps == 0)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
} while (bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2016-06-17 07:27:16 -07:00
|
|
|
|
2018-02-02 08:46:16 -08:00
|
|
|
private:
|
|
|
|
|
rtc::CriticalSection crit_;
|
|
|
|
|
rtc::Event encoder_init_;
|
|
|
|
|
rtc::Event bitrate_changed_;
|
2018-06-15 12:28:07 +02:00
|
|
|
absl::optional<int> bitrate_kbps_ RTC_GUARDED_BY(crit_);
|
2018-02-02 08:46:16 -08:00
|
|
|
};
|
2016-06-17 07:27:16 -07:00
|
|
|
|
2018-02-02 08:46:16 -08:00
|
|
|
// This test that if the encoder use an internal source, VideoEncoder::SetRates
|
|
|
|
|
// will be called with zero bitrate during initialization and that
|
|
|
|
|
// VideoSendStream::Stop also triggers VideoEncoder::SetRates Start to be called
|
|
|
|
|
// with zero bitrate.
|
|
|
|
|
TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
|
2016-06-17 07:27:16 -07:00
|
|
|
test::NullTransport transport;
|
2017-08-22 04:02:52 -07:00
|
|
|
StartStopBitrateObserver encoder;
|
2018-04-19 09:04:13 +02:00
|
|
|
test::EncoderProxyFactory encoder_factory(&encoder);
|
|
|
|
|
encoder_factory.SetHasInternalSource(true);
|
|
|
|
|
test::FrameForwarder forwarder;
|
2016-06-17 07:27:16 -07:00
|
|
|
|
2018-04-19 09:04:13 +02:00
|
|
|
task_queue_.SendTask([this, &transport, &encoder_factory, &forwarder]() {
|
2018-07-13 10:43:20 +02:00
|
|
|
CreateSenderCall();
|
2017-08-22 04:02:52 -07:00
|
|
|
CreateSendConfig(1, 0, 0, &transport);
|
2016-11-22 16:08:30 -08:00
|
|
|
|
2017-08-22 04:02:52 -07:00
|
|
|
sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
|
2018-07-13 09:49:00 +02:00
|
|
|
GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
|
2017-08-22 04:02:52 -07:00
|
|
|
|
|
|
|
|
CreateVideoStreams();
|
2018-04-19 09:04:13 +02:00
|
|
|
// Inject a frame, to force encoder creation.
|
2018-07-13 09:49:00 +02:00
|
|
|
GetVideoSendStream()->Start();
|
|
|
|
|
GetVideoSendStream()->SetSource(&forwarder,
|
|
|
|
|
DegradationPreference::DISABLED);
|
2018-04-19 09:04:13 +02:00
|
|
|
forwarder.IncomingCapturedFrame(CreateVideoFrame(640, 480, 4));
|
2017-08-22 04:02:52 -07:00
|
|
|
});
|
2016-06-17 07:27:16 -07:00
|
|
|
|
|
|
|
|
EXPECT_TRUE(encoder.WaitForEncoderInit());
|
2016-11-16 16:41:30 +01:00
|
|
|
|
2018-07-13 09:49:00 +02:00
|
|
|
task_queue_.SendTask([this]() { GetVideoSendStream()->Start(); });
|
2016-11-16 16:41:30 +01:00
|
|
|
EXPECT_TRUE(encoder.WaitBitrateChanged(true));
|
|
|
|
|
|
2018-07-13 09:49:00 +02:00
|
|
|
task_queue_.SendTask([this]() { GetVideoSendStream()->Stop(); });
|
2016-11-16 16:41:30 +01:00
|
|
|
EXPECT_TRUE(encoder.WaitBitrateChanged(false));
|
|
|
|
|
|
2018-07-13 09:49:00 +02:00
|
|
|
task_queue_.SendTask([this]() { GetVideoSendStream()->Start(); });
|
2016-11-16 16:41:30 +01:00
|
|
|
EXPECT_TRUE(encoder.WaitBitrateChanged(true));
|
2016-06-17 07:27:16 -07:00
|
|
|
|
2017-08-22 04:02:52 -07:00
|
|
|
task_queue_.SendTask([this]() {
|
|
|
|
|
DestroyStreams();
|
|
|
|
|
DestroyCalls();
|
|
|
|
|
});
|
2016-06-17 07:27:16 -07:00
|
|
|
}
|
|
|
|
|
|
2018-02-02 08:46:16 -08:00
|
|
|
// Tests that when the encoder uses an internal source, the VideoEncoder will
|
|
|
|
|
// be updated with a new bitrate when turning the VideoSendStream on/off with
|
|
|
|
|
// VideoSendStream::UpdateActiveSimulcastLayers, and when the VideoStreamEncoder
|
|
|
|
|
// is reconfigured with new active layers.
|
|
|
|
|
TEST_F(VideoSendStreamTest, VideoSendStreamUpdateActiveSimulcastLayers) {
|
|
|
|
|
test::NullTransport transport;
|
|
|
|
|
StartStopBitrateObserver encoder;
|
2018-04-19 09:04:13 +02:00
|
|
|
test::EncoderProxyFactory encoder_factory(&encoder);
|
|
|
|
|
encoder_factory.SetHasInternalSource(true);
|
|
|
|
|
test::FrameForwarder forwarder;
|
2018-02-02 08:46:16 -08:00
|
|
|
|
2018-04-19 09:04:13 +02:00
|
|
|
task_queue_.SendTask([this, &transport, &encoder_factory, &forwarder]() {
|
2018-07-13 10:43:20 +02:00
|
|
|
CreateSenderCall();
|
2018-02-02 08:46:16 -08:00
|
|
|
// Create two simulcast streams.
|
|
|
|
|
CreateSendConfig(2, 0, 0, &transport);
|
|
|
|
|
|
|
|
|
|
sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
|
2018-07-13 09:49:00 +02:00
|
|
|
GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory;
|
2018-02-02 08:46:16 -08:00
|
|
|
|
2018-07-13 09:49:00 +02:00
|
|
|
GetVideoSendConfig()->rtp.payload_name = "VP8";
|
2018-02-02 08:46:16 -08:00
|
|
|
|
|
|
|
|
CreateVideoStreams();
|
2018-04-19 09:04:13 +02:00
|
|
|
|
|
|
|
|
// Inject a frame, to force encoder creation.
|
2018-07-13 09:49:00 +02:00
|
|
|
GetVideoSendStream()->Start();
|
|
|
|
|
GetVideoSendStream()->SetSource(&forwarder,
|
|
|
|
|
DegradationPreference::DISABLED);
|
2018-04-19 09:04:13 +02:00
|
|
|
forwarder.IncomingCapturedFrame(CreateVideoFrame(640, 480, 4));
|
2018-02-02 08:46:16 -08:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
EXPECT_TRUE(encoder.WaitForEncoderInit());
|
|
|
|
|
|
|
|
|
|
// When we turn on the simulcast layers it will update the BitrateAllocator,
|
|
|
|
|
// which in turn updates the VideoEncoder's bitrate.
|
|
|
|
|
task_queue_.SendTask([this]() {
|
2018-07-13 09:49:00 +02:00
|
|
|
GetVideoSendStream()->UpdateActiveSimulcastLayers({true, true});
|
2018-02-02 08:46:16 -08:00
|
|
|
});
|
|
|
|
|
EXPECT_TRUE(encoder.WaitBitrateChanged(true));
|
|
|
|
|
|
2018-07-13 09:49:00 +02:00
|
|
|
GetVideoEncoderConfig()->simulcast_layers[0].active = true;
|
|
|
|
|
GetVideoEncoderConfig()->simulcast_layers[1].active = false;
|
2018-02-02 08:46:16 -08:00
|
|
|
task_queue_.SendTask([this]() {
|
2018-07-13 09:49:00 +02:00
|
|
|
GetVideoSendStream()->ReconfigureVideoEncoder(
|
|
|
|
|
GetVideoEncoderConfig()->Copy());
|
2018-02-02 08:46:16 -08:00
|
|
|
});
|
|
|
|
|
// TODO(bugs.webrtc.org/8807): Currently we require a hard reconfiguration to
|
|
|
|
|
// update the VideoBitrateAllocator and BitrateAllocator of which layers are
|
|
|
|
|
// active. Once the change is made for a "soft" reconfiguration we can remove
|
|
|
|
|
// the expecation for an encoder init. We can also test that bitrate changes
|
|
|
|
|
// when just updating individual active layers, which should change the
|
|
|
|
|
// bitrate set to the video encoder.
|
|
|
|
|
EXPECT_TRUE(encoder.WaitForEncoderInit());
|
|
|
|
|
EXPECT_TRUE(encoder.WaitBitrateChanged(true));
|
|
|
|
|
|
|
|
|
|
// Turning off both simulcast layers should trigger a bitrate change of 0.
|
2018-07-13 09:49:00 +02:00
|
|
|
GetVideoEncoderConfig()->simulcast_layers[0].active = false;
|
|
|
|
|
GetVideoEncoderConfig()->simulcast_layers[1].active = false;
|
2018-02-02 08:46:16 -08:00
|
|
|
task_queue_.SendTask([this]() {
|
2018-07-13 09:49:00 +02:00
|
|
|
GetVideoSendStream()->UpdateActiveSimulcastLayers({false, false});
|
2018-02-02 08:46:16 -08:00
|
|
|
});
|
|
|
|
|
EXPECT_TRUE(encoder.WaitBitrateChanged(false));
|
|
|
|
|
|
|
|
|
|
task_queue_.SendTask([this]() {
|
|
|
|
|
DestroyStreams();
|
|
|
|
|
DestroyCalls();
|
|
|
|
|
});
|
|
|
|
|
}
|
2015-05-29 17:21:40 -07:00
|
|
|
TEST_F(VideoSendStreamTest, CapturesTextureAndVideoFrames) {
|
2016-04-18 05:15:22 -07:00
|
|
|
class FrameObserver : public rtc::VideoSinkInterface<VideoFrame> {
|
2014-06-20 12:04:05 +00:00
|
|
|
public:
|
2015-12-10 13:02:50 +01:00
|
|
|
FrameObserver() : output_frame_event_(false, false) {}
|
2014-06-20 12:04:05 +00:00
|
|
|
|
2016-04-18 05:15:22 -07:00
|
|
|
void OnFrame(const VideoFrame& video_frame) override {
|
|
|
|
|
output_frames_.push_back(video_frame);
|
2015-12-10 13:02:50 +01:00
|
|
|
output_frame_event_.Set();
|
2014-06-20 12:04:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WaitOutputFrame() {
|
2015-12-10 13:02:50 +01:00
|
|
|
const int kWaitFrameTimeoutMs = 3000;
|
|
|
|
|
EXPECT_TRUE(output_frame_event_.Wait(kWaitFrameTimeoutMs))
|
2014-06-20 12:04:05 +00:00
|
|
|
<< "Timeout while waiting for output frames.";
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-29 17:21:40 -07:00
|
|
|
const std::vector<VideoFrame>& output_frames() const {
|
2015-03-24 12:37:36 +00:00
|
|
|
return output_frames_;
|
2014-06-20 12:04:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
// Delivered output frames.
|
2015-05-29 17:21:40 -07:00
|
|
|
std::vector<VideoFrame> output_frames_;
|
2014-06-20 12:04:05 +00:00
|
|
|
|
|
|
|
|
// Indicate an output frame has arrived.
|
2015-12-10 13:02:50 +01:00
|
|
|
rtc::Event output_frame_event_;
|
2014-06-20 12:04:05 +00:00
|
|
|
};
|
|
|
|
|
|
2015-08-28 04:07:10 -07:00
|
|
|
test::NullTransport transport;
|
2014-06-20 12:04:05 +00:00
|
|
|
FrameObserver observer;
|
2015-05-29 17:21:40 -07:00
|
|
|
std::vector<VideoFrame> input_frames;
|
2017-08-22 04:02:52 -07:00
|
|
|
|
|
|
|
|
task_queue_.SendTask([this, &transport, &observer, &input_frames]() {
|
|
|
|
|
// Initialize send stream.
|
2018-07-13 10:43:20 +02:00
|
|
|
CreateSenderCall();
|
2017-08-22 04:02:52 -07:00
|
|
|
|
|
|
|
|
CreateSendConfig(1, 0, 0, &transport);
|
2018-07-13 09:49:00 +02:00
|
|
|
GetVideoSendConfig()->pre_encode_callback = &observer;
|
2017-08-22 04:02:52 -07:00
|
|
|
CreateVideoStreams();
|
|
|
|
|
|
|
|
|
|
// Prepare five input frames. Send ordinary VideoFrame and texture frames
|
|
|
|
|
// alternatively.
|
|
|
|
|
int width = 168;
|
|
|
|
|
int height = 132;
|
|
|
|
|
|
|
|
|
|
input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
|
|
|
|
|
width, height, 1, 1, kVideoRotation_0));
|
|
|
|
|
input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
|
|
|
|
|
width, height, 2, 2, kVideoRotation_0));
|
|
|
|
|
input_frames.push_back(CreateVideoFrame(width, height, 3));
|
|
|
|
|
input_frames.push_back(CreateVideoFrame(width, height, 4));
|
|
|
|
|
input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
|
|
|
|
|
width, height, 5, 5, kVideoRotation_0));
|
|
|
|
|
|
2018-07-13 09:49:00 +02:00
|
|
|
GetVideoSendStream()->Start();
|
2017-08-22 04:02:52 -07:00
|
|
|
test::FrameForwarder forwarder;
|
2018-07-13 09:49:00 +02:00
|
|
|
GetVideoSendStream()->SetSource(&forwarder,
|
|
|
|
|
DegradationPreference::MAINTAIN_FRAMERATE);
|
2017-08-22 04:02:52 -07:00
|
|
|
for (size_t i = 0; i < input_frames.size(); i++) {
|
|
|
|
|
forwarder.IncomingCapturedFrame(input_frames[i]);
|
|
|
|
|
// Wait until the output frame is received before sending the next input
|
|
|
|
|
// frame. Or the previous input frame may be replaced without delivering.
|
|
|
|
|
observer.WaitOutputFrame();
|
|
|
|
|
}
|
2018-07-13 09:49:00 +02:00
|
|
|
GetVideoSendStream()->Stop();
|
|
|
|
|
GetVideoSendStream()->SetSource(nullptr,
|
|
|
|
|
DegradationPreference::MAINTAIN_FRAMERATE);
|
2017-08-22 04:02:52 -07:00
|
|
|
});
|
2014-06-20 12:04:05 +00:00
|
|
|
|
|
|
|
|
// Test if the input and output frames are the same. render_time_ms and
|
|
|
|
|
// timestamp are not compared because capturer sets those values.
|
2015-03-24 12:37:36 +00:00
|
|
|
ExpectEqualFramesVector(input_frames, observer.output_frames());
|
2014-06-20 12:04:05 +00:00
|
|
|
|
2017-08-22 04:02:52 -07:00
|
|
|
task_queue_.SendTask([this]() {
|
|
|
|
|
DestroyStreams();
|
|
|
|
|
DestroyCalls();
|
|
|
|
|
});
|
2014-06-20 12:04:05 +00:00
|
|
|
}
|
|
|
|
|
|
2015-05-29 17:21:40 -07:00
|
|
|
void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
|
|
|
|
|
const std::vector<VideoFrame>& frames2) {
|
2014-06-20 12:04:05 +00:00
|
|
|
EXPECT_EQ(frames1.size(), frames2.size());
|
|
|
|
|
for (size_t i = 0; i < std::min(frames1.size(), frames2.size()); ++i)
|
2016-04-15 03:43:39 -07:00
|
|
|
// Compare frame buffers, since we don't care about differing timestamps.
|
|
|
|
|
EXPECT_TRUE(test::FrameBufsEqual(frames1[i].video_frame_buffer(),
|
|
|
|
|
frames2[i].video_frame_buffer()));
|
2014-06-20 12:04:05 +00:00
|
|
|
}
|
|
|
|
|
|
2015-05-29 17:21:40 -07:00
|
|
|
VideoFrame CreateVideoFrame(int width, int height, uint8_t data) {
|
2014-06-20 12:04:05 +00:00
|
|
|
const int kSizeY = width * height * 2;
|
2016-03-01 11:52:33 -08:00
|
|
|
std::unique_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
|
2014-06-20 12:04:05 +00:00
|
|
|
memset(buffer.get(), data, kSizeY);
|
2017-06-07 11:32:50 +02:00
|
|
|
VideoFrame frame(I420Buffer::Create(width, height), kVideoRotation_0, data);
|
2015-03-24 12:37:36 +00:00
|
|
|
frame.set_timestamp(data);
|
2017-01-30 02:43:18 -08:00
|
|
|
// Use data as a ms timestamp.
|
|
|
|
|
frame.set_timestamp_us(data * rtc::kNumMicrosecsPerMillisec);
|
2014-06-20 12:04:05 +00:00
|
|
|
return frame;
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-07 14:22:35 +00:00
|
|
|
TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
|
|
|
|
|
class EncoderStateObserver : public test::SendTest, public VideoEncoder {
|
|
|
|
|
public:
|
2017-08-22 04:02:52 -07:00
|
|
|
explicit EncoderStateObserver(
|
|
|
|
|
test::SingleThreadedTaskQueueForTesting* task_queue)
|
2014-07-07 14:22:35 +00:00
|
|
|
: SendTest(kDefaultTimeoutMs),
|
2017-08-22 04:02:52 -07:00
|
|
|
task_queue_(task_queue),
|
2016-07-29 12:59:36 +02:00
|
|
|
stream_(nullptr),
|
2014-07-07 14:22:35 +00:00
|
|
|
initialized_(false),
|
|
|
|
|
callback_registered_(false),
|
|
|
|
|
num_releases_(0),
|
2018-04-19 09:04:13 +02:00
|
|
|
released_(false),
|
|
|
|
|
encoder_factory_(this) {}
|
2014-07-07 14:22:35 +00:00
|
|
|
|
|
|
|
|
bool IsReleased() {
|
2015-05-01 13:00:41 +02:00
|
|
|
rtc::CritScope lock(&crit_);
|
2014-07-07 14:22:35 +00:00
|
|
|
return released_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool IsReadyForEncode() {
|
2015-05-01 13:00:41 +02:00
|
|
|
rtc::CritScope lock(&crit_);
|
2014-07-07 14:22:35 +00:00
|
|
|
return initialized_ && callback_registered_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t num_releases() {
|
2015-05-01 13:00:41 +02:00
|
|
|
rtc::CritScope lock(&crit_);
|
2014-07-07 14:22:35 +00:00
|
|
|
return num_releases_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
2015-03-04 12:58:35 +00:00
|
|
|
int32_t InitEncode(const VideoCodec* codecSettings,
|
|
|
|
|
int32_t numberOfCores,
|
|
|
|
|
size_t maxPayloadSize) override {
|
2015-05-01 13:00:41 +02:00
|
|
|
rtc::CritScope lock(&crit_);
|
2014-07-07 14:22:35 +00:00
|
|
|
EXPECT_FALSE(initialized_);
|
|
|
|
|
initialized_ = true;
|
|
|
|
|
released_ = false;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-29 17:21:40 -07:00
|
|
|
int32_t Encode(const VideoFrame& inputImage,
|
2015-03-04 12:58:35 +00:00
|
|
|
const CodecSpecificInfo* codecSpecificInfo,
|
2015-10-19 02:39:06 -07:00
|
|
|
const std::vector<FrameType>* frame_types) override {
|
2014-07-07 14:22:35 +00:00
|
|
|
EXPECT_TRUE(IsReadyForEncode());
|
|
|
|
|
|
2015-12-10 13:02:50 +01:00
|
|
|
observation_complete_.Set();
|
2014-07-07 14:22:35 +00:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
int32_t RegisterEncodeCompleteCallback(
|
|
|
|
|
EncodedImageCallback* callback) override {
|
2015-05-01 13:00:41 +02:00
|
|
|
rtc::CritScope lock(&crit_);
|
2014-07-07 14:22:35 +00:00
|
|
|
EXPECT_TRUE(initialized_);
|
|
|
|
|
callback_registered_ = true;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
int32_t Release() override {
|
2015-05-01 13:00:41 +02:00
|
|
|
rtc::CritScope lock(&crit_);
|
2014-07-07 14:22:35 +00:00
|
|
|
EXPECT_TRUE(IsReadyForEncode());
|
|
|
|
|
EXPECT_FALSE(released_);
|
|
|
|
|
initialized_ = false;
|
|
|
|
|
callback_registered_ = false;
|
|
|
|
|
released_ = true;
|
|
|
|
|
++num_releases_;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
int32_t SetChannelParameters(uint32_t packetLoss, int64_t rtt) override {
|
2014-07-07 14:22:35 +00:00
|
|
|
EXPECT_TRUE(IsReadyForEncode());
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override {
|
2014-07-07 14:22:35 +00:00
|
|
|
EXPECT_TRUE(IsReadyForEncode());
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-21 03:14:00 -08:00
|
|
|
void OnVideoStreamsCreated(
|
2014-07-07 14:22:35 +00:00
|
|
|
VideoSendStream* send_stream,
|
2015-03-04 12:58:35 +00:00
|
|
|
const std::vector<VideoReceiveStream*>& receive_streams) override {
|
2014-07-07 14:22:35 +00:00
|
|
|
stream_ = send_stream;
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-21 03:14:00 -08:00
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
2018-04-19 09:04:13 +02:00
|
|
|
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
2016-09-01 01:17:40 -07:00
|
|
|
encoder_config_ = encoder_config->Copy();
|
2014-07-07 14:22:35 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
void PerformTest() override {
|
2015-12-10 13:02:50 +01:00
|
|
|
EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
|
2017-08-22 04:02:52 -07:00
|
|
|
|
|
|
|
|
task_queue_->SendTask([this]() {
|
|
|
|
|
EXPECT_EQ(0u, num_releases());
|
|
|
|
|
stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
|
|
|
|
|
EXPECT_EQ(0u, num_releases());
|
|
|
|
|
stream_->Stop();
|
|
|
|
|
// Encoder should not be released before destroying the VideoSendStream.
|
|
|
|
|
EXPECT_FALSE(IsReleased());
|
|
|
|
|
EXPECT_TRUE(IsReadyForEncode());
|
|
|
|
|
stream_->Start();
|
|
|
|
|
});
|
|
|
|
|
|
2014-07-07 14:22:35 +00:00
|
|
|
// Sanity check, make sure we still encode frames with this encoder.
|
2015-12-10 13:02:50 +01:00
|
|
|
EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
|
2014-07-07 14:22:35 +00:00
|
|
|
}
|
|
|
|
|
|
2017-08-22 04:02:52 -07:00
|
|
|
test::SingleThreadedTaskQueueForTesting* const task_queue_;
|
2015-05-01 13:00:41 +02:00
|
|
|
rtc::CriticalSection crit_;
|
2014-07-07 14:22:35 +00:00
|
|
|
VideoSendStream* stream_;
|
2017-09-09 04:17:22 -07:00
|
|
|
bool initialized_ RTC_GUARDED_BY(crit_);
|
|
|
|
|
bool callback_registered_ RTC_GUARDED_BY(crit_);
|
|
|
|
|
size_t num_releases_ RTC_GUARDED_BY(crit_);
|
|
|
|
|
bool released_ RTC_GUARDED_BY(crit_);
|
2018-04-19 09:04:13 +02:00
|
|
|
test::EncoderProxyFactory encoder_factory_;
|
2014-09-19 12:30:25 +00:00
|
|
|
VideoEncoderConfig encoder_config_;
|
2017-08-22 04:02:52 -07:00
|
|
|
} test_encoder(&task_queue_);
|
2014-07-07 14:22:35 +00:00
|
|
|
|
2016-01-08 06:47:13 -08:00
|
|
|
RunBaseTest(&test_encoder);
|
2014-07-07 14:22:35 +00:00
|
|
|
|
|
|
|
|
EXPECT_TRUE(test_encoder.IsReleased());
|
2016-10-30 21:37:57 +01:00
|
|
|
EXPECT_EQ(1u, test_encoder.num_releases());
|
2014-07-07 14:22:35 +00:00
|
|
|
}
|
|
|
|
|
|
2014-09-19 12:30:25 +00:00
|
|
|
TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
|
|
|
|
|
class VideoCodecConfigObserver : public test::SendTest,
|
|
|
|
|
public test::FakeEncoder {
|
|
|
|
|
public:
|
|
|
|
|
VideoCodecConfigObserver()
|
|
|
|
|
: SendTest(kDefaultTimeoutMs),
|
|
|
|
|
FakeEncoder(Clock::GetRealTimeClock()),
|
2016-04-20 06:35:56 -07:00
|
|
|
init_encode_event_(false, false),
|
2016-07-29 12:59:36 +02:00
|
|
|
num_initializations_(0),
|
2018-04-19 09:04:13 +02:00
|
|
|
stream_(nullptr),
|
|
|
|
|
encoder_factory_(this) {}
|
2014-09-19 12:30:25 +00:00
|
|
|
|
|
|
|
|
private:
|
2015-12-21 03:14:00 -08:00
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
2018-04-19 09:04:13 +02:00
|
|
|
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
2017-02-28 13:23:26 -08:00
|
|
|
encoder_config->max_bitrate_bps = kFirstMaxBitrateBps;
|
2016-09-01 01:17:40 -07:00
|
|
|
encoder_config_ = encoder_config->Copy();
|
2014-09-19 12:30:25 +00:00
|
|
|
}
|
|
|
|
|
|
2015-12-21 03:14:00 -08:00
|
|
|
void OnVideoStreamsCreated(
|
2014-09-19 12:30:25 +00:00
|
|
|
VideoSendStream* send_stream,
|
2015-03-04 12:58:35 +00:00
|
|
|
const std::vector<VideoReceiveStream*>& receive_streams) override {
|
2014-09-19 12:30:25 +00:00
|
|
|
stream_ = send_stream;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
int32_t InitEncode(const VideoCodec* config,
|
|
|
|
|
int32_t number_of_cores,
|
|
|
|
|
size_t max_payload_size) override {
|
2016-10-30 21:37:57 +01:00
|
|
|
if (num_initializations_ == 0) {
|
2014-09-19 12:30:25 +00:00
|
|
|
// Verify default values.
|
2017-02-28 13:23:26 -08:00
|
|
|
EXPECT_EQ(kFirstMaxBitrateBps / 1000, config->maxBitrate);
|
2014-09-19 12:30:25 +00:00
|
|
|
} else {
|
|
|
|
|
// Verify that changed values are propagated.
|
2017-02-28 13:23:26 -08:00
|
|
|
EXPECT_EQ(kSecondMaxBitrateBps / 1000, config->maxBitrate);
|
2014-09-19 12:30:25 +00:00
|
|
|
}
|
|
|
|
|
++num_initializations_;
|
2016-10-30 21:37:57 +01:00
|
|
|
init_encode_event_.Set();
|
2014-09-19 12:30:25 +00:00
|
|
|
return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
void PerformTest() override {
|
2016-04-20 06:35:56 -07:00
|
|
|
EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
|
2016-10-30 21:37:57 +01:00
|
|
|
EXPECT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
|
2014-09-19 12:30:25 +00:00
|
|
|
|
2017-02-28 13:23:26 -08:00
|
|
|
encoder_config_.max_bitrate_bps = kSecondMaxBitrateBps;
|
2016-09-01 01:17:40 -07:00
|
|
|
stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
|
2016-04-20 06:35:56 -07:00
|
|
|
EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
|
2016-10-30 21:37:57 +01:00
|
|
|
EXPECT_EQ(2u, num_initializations_)
|
2014-09-19 12:30:25 +00:00
|
|
|
<< "ReconfigureVideoEncoder did not reinitialize the encoder with "
|
|
|
|
|
"new encoder settings.";
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-28 13:23:26 -08:00
|
|
|
const uint32_t kFirstMaxBitrateBps = 1000000;
|
|
|
|
|
const uint32_t kSecondMaxBitrateBps = 2000000;
|
|
|
|
|
|
2016-04-20 06:35:56 -07:00
|
|
|
rtc::Event init_encode_event_;
|
2014-09-19 12:30:25 +00:00
|
|
|
size_t num_initializations_;
|
|
|
|
|
VideoSendStream* stream_;
|
2018-04-19 09:04:13 +02:00
|
|
|
test::EncoderProxyFactory encoder_factory_;
|
2014-09-19 12:30:25 +00:00
|
|
|
VideoEncoderConfig encoder_config_;
|
|
|
|
|
} test;
|
|
|
|
|
|
2016-01-08 06:47:13 -08:00
|
|
|
RunBaseTest(&test);
|
2014-09-19 12:30:25 +00:00
|
|
|
}
|
|
|
|
|
|
2018-04-03 10:03:31 +02:00
|
|
|
static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 3;
|
2015-03-27 15:53:18 +01:00
|
|
|
template <typename T>
|
|
|
|
|
class VideoCodecConfigObserver : public test::SendTest,
|
|
|
|
|
public test::FakeEncoder {
|
|
|
|
|
public:
|
|
|
|
|
VideoCodecConfigObserver(VideoCodecType video_codec_type,
|
|
|
|
|
const char* codec_name)
|
|
|
|
|
: SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
|
|
|
|
|
FakeEncoder(Clock::GetRealTimeClock()),
|
|
|
|
|
video_codec_type_(video_codec_type),
|
|
|
|
|
codec_name_(codec_name),
|
2016-04-20 06:35:56 -07:00
|
|
|
init_encode_event_(false, false),
|
2016-07-29 12:59:36 +02:00
|
|
|
num_initializations_(0),
|
2018-04-19 09:04:13 +02:00
|
|
|
stream_(nullptr),
|
|
|
|
|
encoder_factory_(this) {
|
2018-03-28 19:32:37 +02:00
|
|
|
InitCodecSpecifics();
|
2015-03-27 15:53:18 +01:00
|
|
|
}
|
2014-07-10 10:13:37 +00:00
|
|
|
|
2015-03-27 15:53:18 +01:00
|
|
|
private:
|
2016-10-02 23:45:26 -07:00
|
|
|
class VideoStreamFactory
|
|
|
|
|
: public VideoEncoderConfig::VideoStreamFactoryInterface {
|
|
|
|
|
public:
|
|
|
|
|
VideoStreamFactory() {}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
std::vector<VideoStream> CreateEncoderStreams(
|
|
|
|
|
int width,
|
|
|
|
|
int height,
|
|
|
|
|
const VideoEncoderConfig& encoder_config) override {
|
|
|
|
|
std::vector<VideoStream> streams =
|
|
|
|
|
test::CreateVideoStreams(width, height, encoder_config);
|
|
|
|
|
for (size_t i = 0; i < streams.size(); ++i) {
|
2018-03-01 15:11:29 +01:00
|
|
|
streams[i].num_temporal_layers =
|
|
|
|
|
kVideoCodecConfigObserverNumberOfTemporalLayers;
|
2016-10-02 23:45:26 -07:00
|
|
|
}
|
|
|
|
|
return streams;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2015-12-21 03:14:00 -08:00
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
2018-04-19 09:04:13 +02:00
|
|
|
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
Reland "Reland "Move rtp-specific config out of EncoderSettings.""
This reverts commit 6c2c13af06b32778b86950681758a7970d1c5d9e.
Reason for revert: Intend to investigate and fix perf problems.
Original change's description:
> Revert "Reland "Move rtp-specific config out of EncoderSettings.""
>
> This reverts commit 04dd1768625eb2241d1fb97fd0137897e703e266.
>
> Reason for revert: Regression in ramp up perf tests.
>
> Original change's description:
> > Reland "Move rtp-specific config out of EncoderSettings."
> >
> > This is a reland of bc900cb1d1810fcf678fe41cf1e3966daa39c88c
> >
> > Original change's description:
> > > Move rtp-specific config out of EncoderSettings.
> > >
> > > In VideoSendStream::Config, move payload_name and payload_type from
> > > EncoderSettings to Rtp.
> > >
> > > EncoderSettings now contains configuration for VideoStreamEncoder only,
> > > and should perhaps be renamed in a follow up cl. It's no longer
> > > passed as an argument to VideoCodecInitializer::SetupCodec.
> > >
> > > The latter then needs a different way to know the codec type,
> > > which is provided by a new codec_type member in VideoEncoderConfig.
> > >
> > > Bug: webrtc:8830
> > > Change-Id: Ifcc691aef1ee6a95e43c0452c5e630d92a511cd6
> > > Reviewed-on: https://webrtc-review.googlesource.com/62062
> > > Commit-Queue: Niels Moller <nisse@webrtc.org>
> > > Reviewed-by: Magnus Jedvert <magjed@webrtc.org>
> > > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> > > Cr-Commit-Position: refs/heads/master@{#22532}
> >
> > Bug: webrtc:8830
> > Change-Id: If88ef7d57cdaa4fae3c7b2a97ea5a6e1b833e019
> > Reviewed-on: https://webrtc-review.googlesource.com/63721
> > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Commit-Queue: Niels Moller <nisse@webrtc.org>
> > Cr-Commit-Position: refs/heads/master@{#22595}
>
> TBR=brandtr@webrtc.org,magjed@webrtc.org,nisse@webrtc.org,stefan@webrtc.org
>
> Bug: webrtc:8830,chromium:827080
> Change-Id: Iaaf146de91ec5c0d741b8efdf143f7e173084fef
> Reviewed-on: https://webrtc-review.googlesource.com/65520
> Commit-Queue: Niels Moller <nisse@webrtc.org>
> Reviewed-by: Niels Moller <nisse@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#22677}
TBR=brandtr@webrtc.org,magjed@webrtc.org,nisse@webrtc.org,stefan@webrtc.org
# Not skipping CQ checks because original CL landed > 1 day ago.
Bug: webrtc:8830, chromium:827080
Change-Id: I9b62987bf5daced90dfeb3ebb6739c80117c487f
Reviewed-on: https://webrtc-review.googlesource.com/66862
Commit-Queue: Niels Moller <nisse@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22751}
2018-04-05 15:36:51 +02:00
|
|
|
send_config->rtp.payload_name = codec_name_;
|
2014-09-22 09:32:46 +00:00
|
|
|
|
Reland "Reland "Move rtp-specific config out of EncoderSettings.""
This reverts commit 6c2c13af06b32778b86950681758a7970d1c5d9e.
Reason for revert: Intend to investigate and fix perf problems.
Original change's description:
> Revert "Reland "Move rtp-specific config out of EncoderSettings.""
>
> This reverts commit 04dd1768625eb2241d1fb97fd0137897e703e266.
>
> Reason for revert: Regression in ramp up perf tests.
>
> Original change's description:
> > Reland "Move rtp-specific config out of EncoderSettings."
> >
> > This is a reland of bc900cb1d1810fcf678fe41cf1e3966daa39c88c
> >
> > Original change's description:
> > > Move rtp-specific config out of EncoderSettings.
> > >
> > > In VideoSendStream::Config, move payload_name and payload_type from
> > > EncoderSettings to Rtp.
> > >
> > > EncoderSettings now contains configuration for VideoStreamEncoder only,
> > > and should perhaps be renamed in a follow up cl. It's no longer
> > > passed as an argument to VideoCodecInitializer::SetupCodec.
> > >
> > > The latter then needs a different way to know the codec type,
> > > which is provided by a new codec_type member in VideoEncoderConfig.
> > >
> > > Bug: webrtc:8830
> > > Change-Id: Ifcc691aef1ee6a95e43c0452c5e630d92a511cd6
> > > Reviewed-on: https://webrtc-review.googlesource.com/62062
> > > Commit-Queue: Niels Moller <nisse@webrtc.org>
> > > Reviewed-by: Magnus Jedvert <magjed@webrtc.org>
> > > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> > > Cr-Commit-Position: refs/heads/master@{#22532}
> >
> > Bug: webrtc:8830
> > Change-Id: If88ef7d57cdaa4fae3c7b2a97ea5a6e1b833e019
> > Reviewed-on: https://webrtc-review.googlesource.com/63721
> > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Commit-Queue: Niels Moller <nisse@webrtc.org>
> > Cr-Commit-Position: refs/heads/master@{#22595}
>
> TBR=brandtr@webrtc.org,magjed@webrtc.org,nisse@webrtc.org,stefan@webrtc.org
>
> Bug: webrtc:8830,chromium:827080
> Change-Id: Iaaf146de91ec5c0d741b8efdf143f7e173084fef
> Reviewed-on: https://webrtc-review.googlesource.com/65520
> Commit-Queue: Niels Moller <nisse@webrtc.org>
> Reviewed-by: Niels Moller <nisse@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#22677}
TBR=brandtr@webrtc.org,magjed@webrtc.org,nisse@webrtc.org,stefan@webrtc.org
# Not skipping CQ checks because original CL landed > 1 day ago.
Bug: webrtc:8830, chromium:827080
Change-Id: I9b62987bf5daced90dfeb3ebb6739c80117c487f
Reviewed-on: https://webrtc-review.googlesource.com/66862
Commit-Queue: Niels Moller <nisse@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22751}
2018-04-05 15:36:51 +02:00
|
|
|
encoder_config->codec_type = video_codec_type_;
|
2016-09-27 03:52:02 -07:00
|
|
|
encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
|
2016-10-02 23:45:26 -07:00
|
|
|
encoder_config->video_stream_factory =
|
|
|
|
|
new rtc::RefCountedObject<VideoStreamFactory>();
|
2016-09-01 01:17:40 -07:00
|
|
|
encoder_config_ = encoder_config->Copy();
|
2015-03-27 15:53:18 +01:00
|
|
|
}
|
2014-07-10 10:13:37 +00:00
|
|
|
|
2015-12-21 03:14:00 -08:00
|
|
|
void OnVideoStreamsCreated(
|
2015-03-27 15:53:18 +01:00
|
|
|
VideoSendStream* send_stream,
|
|
|
|
|
const std::vector<VideoReceiveStream*>& receive_streams) override {
|
|
|
|
|
stream_ = send_stream;
|
|
|
|
|
}
|
2014-09-22 09:32:46 +00:00
|
|
|
|
2015-03-27 15:53:18 +01:00
|
|
|
int32_t InitEncode(const VideoCodec* config,
|
|
|
|
|
int32_t number_of_cores,
|
|
|
|
|
size_t max_payload_size) override {
|
|
|
|
|
EXPECT_EQ(video_codec_type_, config->codecType);
|
|
|
|
|
VerifyCodecSpecifics(*config);
|
|
|
|
|
++num_initializations_;
|
2016-10-30 21:37:57 +01:00
|
|
|
init_encode_event_.Set();
|
2015-03-27 15:53:18 +01:00
|
|
|
return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
|
|
|
|
|
}
|
2014-09-22 09:32:46 +00:00
|
|
|
|
2018-03-28 19:32:37 +02:00
|
|
|
void InitCodecSpecifics();
|
2015-03-27 15:53:18 +01:00
|
|
|
void VerifyCodecSpecifics(const VideoCodec& config) const;
|
2016-09-27 03:52:02 -07:00
|
|
|
rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
|
|
|
|
|
GetEncoderSpecificSettings() const;
|
2014-09-22 09:32:46 +00:00
|
|
|
|
2015-03-27 15:53:18 +01:00
|
|
|
void PerformTest() override {
|
2016-04-20 06:35:56 -07:00
|
|
|
EXPECT_TRUE(
|
|
|
|
|
init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
|
2016-10-30 21:37:57 +01:00
|
|
|
ASSERT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
|
2014-07-10 10:13:37 +00:00
|
|
|
|
2018-03-28 19:32:37 +02:00
|
|
|
// Change encoder settings to actually trigger reconfiguration.
|
|
|
|
|
encoder_settings_.frameDroppingOn = !encoder_settings_.frameDroppingOn;
|
2016-09-27 03:52:02 -07:00
|
|
|
encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
|
2016-09-01 01:17:40 -07:00
|
|
|
stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
|
2016-04-20 06:35:56 -07:00
|
|
|
ASSERT_TRUE(
|
|
|
|
|
init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
|
2016-10-30 21:37:57 +01:00
|
|
|
EXPECT_EQ(2u, num_initializations_)
|
2015-03-27 15:53:18 +01:00
|
|
|
<< "ReconfigureVideoEncoder did not reinitialize the encoder with "
|
|
|
|
|
"new encoder settings.";
|
|
|
|
|
}
|
2014-07-10 10:13:37 +00:00
|
|
|
|
2015-05-29 17:21:40 -07:00
|
|
|
int32_t Encode(const VideoFrame& input_image,
|
2015-03-27 15:53:18 +01:00
|
|
|
const CodecSpecificInfo* codec_specific_info,
|
2015-10-19 02:39:06 -07:00
|
|
|
const std::vector<FrameType>* frame_types) override {
|
2015-03-27 15:53:18 +01:00
|
|
|
// Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2014-07-10 10:13:37 +00:00
|
|
|
|
2015-03-27 15:53:18 +01:00
|
|
|
T encoder_settings_;
|
|
|
|
|
const VideoCodecType video_codec_type_;
|
|
|
|
|
const char* const codec_name_;
|
2016-04-20 06:35:56 -07:00
|
|
|
rtc::Event init_encode_event_;
|
2015-03-27 15:53:18 +01:00
|
|
|
size_t num_initializations_;
|
|
|
|
|
VideoSendStream* stream_;
|
2018-04-19 09:04:13 +02:00
|
|
|
test::EncoderProxyFactory encoder_factory_;
|
2015-03-27 15:53:18 +01:00
|
|
|
VideoEncoderConfig encoder_config_;
|
|
|
|
|
};
|
2014-07-10 13:21:40 +00:00
|
|
|
|
2018-03-28 19:32:37 +02:00
|
|
|
template <>
|
|
|
|
|
void VideoCodecConfigObserver<VideoCodecH264>::InitCodecSpecifics() {
|
|
|
|
|
encoder_settings_ = VideoEncoder::GetDefaultH264Settings();
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-27 15:53:18 +01:00
|
|
|
template <>
|
|
|
|
|
void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
|
|
|
|
|
const VideoCodec& config) const {
|
2016-10-25 09:05:06 -07:00
|
|
|
EXPECT_EQ(
|
|
|
|
|
0, memcmp(&config.H264(), &encoder_settings_, sizeof(encoder_settings_)));
|
2015-03-27 15:53:18 +01:00
|
|
|
}
|
2016-09-27 03:52:02 -07:00
|
|
|
|
|
|
|
|
template <>
|
|
|
|
|
rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
|
|
|
|
|
VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
|
|
|
|
|
return new rtc::RefCountedObject<
|
|
|
|
|
VideoEncoderConfig::H264EncoderSpecificSettings>(encoder_settings_);
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-28 19:32:37 +02:00
|
|
|
template <>
|
|
|
|
|
void VideoCodecConfigObserver<VideoCodecVP8>::InitCodecSpecifics() {
|
|
|
|
|
encoder_settings_ = VideoEncoder::GetDefaultVp8Settings();
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-27 15:53:18 +01:00
|
|
|
template <>
|
|
|
|
|
void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
|
|
|
|
|
const VideoCodec& config) const {
|
|
|
|
|
// Check that the number of temporal layers has propagated properly to
|
|
|
|
|
// VideoCodec.
|
|
|
|
|
EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
|
2016-10-25 09:05:06 -07:00
|
|
|
config.VP8().numberOfTemporalLayers);
|
2015-03-27 15:53:18 +01:00
|
|
|
|
|
|
|
|
for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
|
|
|
|
|
EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
|
|
|
|
|
config.simulcastStream[i].numberOfTemporalLayers);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set expected temporal layers as they should have been set when
|
2018-03-21 09:57:23 +01:00
|
|
|
// reconfiguring the encoder and not match the set config.
|
2015-03-27 15:53:18 +01:00
|
|
|
VideoCodecVP8 encoder_settings = encoder_settings_;
|
|
|
|
|
encoder_settings.numberOfTemporalLayers =
|
|
|
|
|
kVideoCodecConfigObserverNumberOfTemporalLayers;
|
2016-10-25 09:05:06 -07:00
|
|
|
EXPECT_EQ(
|
|
|
|
|
0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
|
2015-03-27 15:53:18 +01:00
|
|
|
}
|
2016-09-27 03:52:02 -07:00
|
|
|
|
|
|
|
|
template <>
|
|
|
|
|
rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
|
|
|
|
|
VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
|
|
|
|
|
return new rtc::RefCountedObject<
|
|
|
|
|
VideoEncoderConfig::Vp8EncoderSpecificSettings>(encoder_settings_);
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-28 19:32:37 +02:00
|
|
|
template <>
|
|
|
|
|
void VideoCodecConfigObserver<VideoCodecVP9>::InitCodecSpecifics() {
|
|
|
|
|
encoder_settings_ = VideoEncoder::GetDefaultVp9Settings();
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-27 15:53:18 +01:00
|
|
|
template <>
|
|
|
|
|
void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
|
|
|
|
|
const VideoCodec& config) const {
|
|
|
|
|
// Check that the number of temporal layers has propagated properly to
|
|
|
|
|
// VideoCodec.
|
|
|
|
|
EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
|
2016-10-25 09:05:06 -07:00
|
|
|
config.VP9().numberOfTemporalLayers);
|
2015-03-27 15:53:18 +01:00
|
|
|
|
|
|
|
|
for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
|
|
|
|
|
EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
|
|
|
|
|
config.simulcastStream[i].numberOfTemporalLayers);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set expected temporal layers as they should have been set when
|
|
|
|
|
// reconfiguring the encoder and not match the set config.
|
|
|
|
|
VideoCodecVP9 encoder_settings = encoder_settings_;
|
|
|
|
|
encoder_settings.numberOfTemporalLayers =
|
|
|
|
|
kVideoCodecConfigObserverNumberOfTemporalLayers;
|
2016-10-25 09:05:06 -07:00
|
|
|
EXPECT_EQ(
|
|
|
|
|
0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
|
2015-03-27 15:53:18 +01:00
|
|
|
}
|
|
|
|
|
|
2016-09-27 03:52:02 -07:00
|
|
|
template <>
|
|
|
|
|
rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
|
|
|
|
|
VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
|
|
|
|
|
return new rtc::RefCountedObject<
|
|
|
|
|
VideoEncoderConfig::Vp9EncoderSpecificSettings>(encoder_settings_);
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-27 15:53:18 +01:00
|
|
|
TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
|
|
|
|
|
VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8");
|
2016-01-08 06:47:13 -08:00
|
|
|
RunBaseTest(&test);
|
2015-03-27 15:53:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
|
|
|
|
|
VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9");
|
2016-01-08 06:47:13 -08:00
|
|
|
RunBaseTest(&test);
|
2015-03-27 15:53:18 +01:00
|
|
|
}
|
2014-07-10 10:13:37 +00:00
|
|
|
|
2015-03-27 15:53:18 +01:00
|
|
|
TEST_F(VideoSendStreamTest, EncoderSetupPropagatesH264Config) {
|
|
|
|
|
VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264");
|
2016-01-08 06:47:13 -08:00
|
|
|
RunBaseTest(&test);
|
2014-07-10 10:13:37 +00:00
|
|
|
}
|
|
|
|
|
|
2014-07-15 15:25:39 +00:00
|
|
|
TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
|
2015-02-23 08:14:07 +00:00
|
|
|
class RtcpSenderReportTest : public test::SendTest {
|
2014-07-15 15:25:39 +00:00
|
|
|
public:
|
2015-02-23 08:14:07 +00:00
|
|
|
RtcpSenderReportTest()
|
|
|
|
|
: SendTest(kDefaultTimeoutMs),
|
|
|
|
|
rtp_packets_sent_(0),
|
|
|
|
|
media_bytes_sent_(0) {}
|
2014-07-15 15:25:39 +00:00
|
|
|
|
|
|
|
|
private:
|
2015-03-04 12:58:35 +00:00
|
|
|
Action OnSendRtp(const uint8_t* packet, size_t length) override {
|
2015-11-11 06:39:57 -08:00
|
|
|
rtc::CritScope lock(&crit_);
|
2014-07-15 15:25:39 +00:00
|
|
|
RTPHeader header;
|
|
|
|
|
EXPECT_TRUE(parser_->Parse(packet, length, &header));
|
2015-02-23 08:14:07 +00:00
|
|
|
++rtp_packets_sent_;
|
2014-07-15 15:25:39 +00:00
|
|
|
media_bytes_sent_ += length - header.headerLength - header.paddingLength;
|
|
|
|
|
return SEND_PACKET;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
Action OnSendRtcp(const uint8_t* packet, size_t length) override {
|
2015-11-11 06:39:57 -08:00
|
|
|
rtc::CritScope lock(&crit_);
|
2016-11-02 08:21:59 -07:00
|
|
|
test::RtcpPacketParser parser;
|
|
|
|
|
EXPECT_TRUE(parser.Parse(packet, length));
|
|
|
|
|
|
|
|
|
|
if (parser.sender_report()->num_packets() > 0) {
|
|
|
|
|
// Only compare sent media bytes if SenderPacketCount matches the
|
|
|
|
|
// number of sent rtp packets (a new rtp packet could be sent before
|
|
|
|
|
// the rtcp packet).
|
|
|
|
|
if (parser.sender_report()->sender_octet_count() > 0 &&
|
|
|
|
|
parser.sender_report()->sender_packet_count() ==
|
|
|
|
|
rtp_packets_sent_) {
|
|
|
|
|
EXPECT_EQ(media_bytes_sent_,
|
|
|
|
|
parser.sender_report()->sender_octet_count());
|
|
|
|
|
observation_complete_.Set();
|
2014-07-15 15:25:39 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return SEND_PACKET;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
void PerformTest() override {
|
2015-12-10 13:02:50 +01:00
|
|
|
EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
|
2014-07-15 15:25:39 +00:00
|
|
|
}
|
|
|
|
|
|
2015-11-11 06:39:57 -08:00
|
|
|
rtc::CriticalSection crit_;
|
2017-09-09 04:17:22 -07:00
|
|
|
size_t rtp_packets_sent_ RTC_GUARDED_BY(&crit_);
|
|
|
|
|
size_t media_bytes_sent_ RTC_GUARDED_BY(&crit_);
|
2014-07-15 15:25:39 +00:00
|
|
|
} test;
|
|
|
|
|
|
2016-01-08 06:47:13 -08:00
|
|
|
RunBaseTest(&test);
|
2014-07-15 15:25:39 +00:00
|
|
|
}
|
|
|
|
|
|
2014-10-31 13:08:10 +00:00
|
|
|
TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
|
2018-03-01 15:11:29 +01:00
|
|
|
static const int kScreencastMaxTargetBitrateDeltaKbps = 1;
|
2016-10-02 23:45:26 -07:00
|
|
|
|
|
|
|
|
class VideoStreamFactory
|
|
|
|
|
: public VideoEncoderConfig::VideoStreamFactoryInterface {
|
|
|
|
|
public:
|
|
|
|
|
VideoStreamFactory() {}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
std::vector<VideoStream> CreateEncoderStreams(
|
|
|
|
|
int width,
|
|
|
|
|
int height,
|
|
|
|
|
const VideoEncoderConfig& encoder_config) override {
|
|
|
|
|
std::vector<VideoStream> streams =
|
|
|
|
|
test::CreateVideoStreams(width, height, encoder_config);
|
2018-03-01 15:11:29 +01:00
|
|
|
EXPECT_FALSE(streams[0].num_temporal_layers.has_value());
|
|
|
|
|
streams[0].num_temporal_layers = 2;
|
|
|
|
|
RTC_CHECK_GT(streams[0].max_bitrate_bps,
|
|
|
|
|
kScreencastMaxTargetBitrateDeltaKbps);
|
|
|
|
|
streams[0].target_bitrate_bps =
|
|
|
|
|
streams[0].max_bitrate_bps -
|
|
|
|
|
kScreencastMaxTargetBitrateDeltaKbps * 1000;
|
2016-10-02 23:45:26 -07:00
|
|
|
return streams;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2014-10-31 13:08:10 +00:00
|
|
|
class ScreencastTargetBitrateTest : public test::SendTest,
|
|
|
|
|
public test::FakeEncoder {
|
|
|
|
|
public:
|
|
|
|
|
ScreencastTargetBitrateTest()
|
|
|
|
|
: SendTest(kDefaultTimeoutMs),
|
2018-04-19 09:04:13 +02:00
|
|
|
test::FakeEncoder(Clock::GetRealTimeClock()),
|
|
|
|
|
encoder_factory_(this) {}
|
2014-10-31 13:08:10 +00:00
|
|
|
|
|
|
|
|
private:
|
2015-03-04 12:58:35 +00:00
|
|
|
int32_t InitEncode(const VideoCodec* config,
|
|
|
|
|
int32_t number_of_cores,
|
|
|
|
|
size_t max_payload_size) override {
|
2018-07-06 16:32:20 +02:00
|
|
|
EXPECT_EQ(config->numberOfSimulcastStreams, 1);
|
2018-03-01 15:11:29 +01:00
|
|
|
EXPECT_EQ(static_cast<unsigned int>(kScreencastMaxTargetBitrateDeltaKbps),
|
2018-07-06 16:32:20 +02:00
|
|
|
config->simulcastStream[0].maxBitrate -
|
|
|
|
|
config->simulcastStream[0].targetBitrate);
|
2015-12-10 13:02:50 +01:00
|
|
|
observation_complete_.Set();
|
2014-10-31 13:08:10 +00:00
|
|
|
return test::FakeEncoder::InitEncode(config, number_of_cores,
|
|
|
|
|
max_payload_size);
|
|
|
|
|
}
|
2015-12-21 03:14:00 -08:00
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
2018-04-19 09:04:13 +02:00
|
|
|
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
2016-10-02 23:45:26 -07:00
|
|
|
EXPECT_EQ(1u, encoder_config->number_of_streams);
|
|
|
|
|
encoder_config->video_stream_factory =
|
|
|
|
|
new rtc::RefCountedObject<VideoStreamFactory>();
|
2015-04-28 10:01:41 +02:00
|
|
|
encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
|
2014-10-31 13:08:10 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
void PerformTest() override {
|
2015-12-10 13:02:50 +01:00
|
|
|
EXPECT_TRUE(Wait())
|
2014-10-31 13:08:10 +00:00
|
|
|
<< "Timed out while waiting for the encoder to be initialized.";
|
|
|
|
|
}
|
2018-04-19 09:04:13 +02:00
|
|
|
test::EncoderProxyFactory encoder_factory_;
|
2014-10-31 13:08:10 +00:00
|
|
|
} test;
|
|
|
|
|
|
2016-01-08 06:47:13 -08:00
|
|
|
RunBaseTest(&test);
|
2014-10-31 13:08:10 +00:00
|
|
|
}
|
2014-11-25 14:03:34 +00:00
|
|
|
|
2016-04-28 15:52:49 +02:00
|
|
|
TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
|
2014-11-25 14:03:34 +00:00
|
|
|
// These are chosen to be "kind of odd" to not be accidentally checked against
|
|
|
|
|
// default values.
|
|
|
|
|
static const int kMinBitrateKbps = 137;
|
|
|
|
|
static const int kStartBitrateKbps = 345;
|
|
|
|
|
static const int kLowerMaxBitrateKbps = 312;
|
|
|
|
|
static const int kMaxBitrateKbps = 413;
|
|
|
|
|
static const int kIncreasedStartBitrateKbps = 451;
|
|
|
|
|
static const int kIncreasedMaxBitrateKbps = 597;
|
|
|
|
|
class EncoderBitrateThresholdObserver : public test::SendTest,
|
|
|
|
|
public test::FakeEncoder {
|
|
|
|
|
public:
|
2017-08-22 04:02:52 -07:00
|
|
|
explicit EncoderBitrateThresholdObserver(
|
|
|
|
|
test::SingleThreadedTaskQueueForTesting* task_queue)
|
2014-11-25 14:03:34 +00:00
|
|
|
: SendTest(kDefaultTimeoutMs),
|
|
|
|
|
FakeEncoder(Clock::GetRealTimeClock()),
|
2017-08-22 04:02:52 -07:00
|
|
|
task_queue_(task_queue),
|
2016-04-20 06:35:56 -07:00
|
|
|
init_encode_event_(false, false),
|
2016-09-01 01:17:40 -07:00
|
|
|
bitrate_changed_event_(false, false),
|
|
|
|
|
target_bitrate_(0),
|
2016-07-29 12:59:36 +02:00
|
|
|
num_initializations_(0),
|
|
|
|
|
call_(nullptr),
|
2018-04-19 09:04:13 +02:00
|
|
|
send_stream_(nullptr),
|
|
|
|
|
encoder_factory_(this) {}
|
2014-11-25 14:03:34 +00:00
|
|
|
|
|
|
|
|
private:
|
2015-03-04 12:58:35 +00:00
|
|
|
int32_t InitEncode(const VideoCodec* codecSettings,
|
|
|
|
|
int32_t numberOfCores,
|
|
|
|
|
size_t maxPayloadSize) override {
|
2016-09-01 01:17:40 -07:00
|
|
|
EXPECT_GE(codecSettings->startBitrate, codecSettings->minBitrate);
|
|
|
|
|
EXPECT_LE(codecSettings->startBitrate, codecSettings->maxBitrate);
|
2016-10-30 21:37:57 +01:00
|
|
|
if (num_initializations_ == 0) {
|
2014-11-25 14:03:34 +00:00
|
|
|
EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
|
|
|
|
|
codecSettings->minBitrate);
|
|
|
|
|
EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
|
|
|
|
|
codecSettings->startBitrate);
|
|
|
|
|
EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
|
|
|
|
|
codecSettings->maxBitrate);
|
2015-12-10 13:02:50 +01:00
|
|
|
observation_complete_.Set();
|
2016-10-30 21:37:57 +01:00
|
|
|
} else if (num_initializations_ == 1) {
|
2014-11-25 14:03:34 +00:00
|
|
|
EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
|
|
|
|
|
codecSettings->maxBitrate);
|
|
|
|
|
// The start bitrate should be kept (-1) and capped to the max bitrate.
|
|
|
|
|
// Since this is not an end-to-end call no receiver should have been
|
|
|
|
|
// returning a REMB that could lower this estimate.
|
|
|
|
|
EXPECT_EQ(codecSettings->startBitrate, codecSettings->maxBitrate);
|
2016-10-30 21:37:57 +01:00
|
|
|
} else if (num_initializations_ == 2) {
|
2014-11-25 14:03:34 +00:00
|
|
|
EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
|
|
|
|
|
codecSettings->maxBitrate);
|
2016-09-01 01:17:40 -07:00
|
|
|
// The start bitrate will be whatever the rate BitRateController
|
|
|
|
|
// has currently configured but in the span of the set max and min
|
|
|
|
|
// bitrate.
|
2014-11-25 14:03:34 +00:00
|
|
|
}
|
|
|
|
|
++num_initializations_;
|
2016-10-30 21:37:57 +01:00
|
|
|
init_encode_event_.Set();
|
|
|
|
|
|
2014-11-25 14:03:34 +00:00
|
|
|
return FakeEncoder::InitEncode(codecSettings, numberOfCores,
|
|
|
|
|
maxPayloadSize);
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-23 12:32:22 +02:00
|
|
|
int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
|
2016-11-16 16:41:30 +01:00
|
|
|
uint32_t frameRate) override {
|
2016-09-01 01:17:40 -07:00
|
|
|
{
|
|
|
|
|
rtc::CritScope lock(&crit_);
|
2016-11-16 16:41:30 +01:00
|
|
|
if (target_bitrate_ == bitrate.get_sum_kbps()) {
|
|
|
|
|
return FakeEncoder::SetRateAllocation(bitrate, frameRate);
|
2016-10-02 23:45:26 -07:00
|
|
|
}
|
2016-11-16 16:41:30 +01:00
|
|
|
target_bitrate_ = bitrate.get_sum_kbps();
|
2016-09-01 01:17:40 -07:00
|
|
|
}
|
|
|
|
|
bitrate_changed_event_.Set();
|
2016-11-16 16:41:30 +01:00
|
|
|
return FakeEncoder::SetRateAllocation(bitrate, frameRate);
|
2016-09-01 01:17:40 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WaitForSetRates(uint32_t expected_bitrate) {
|
|
|
|
|
EXPECT_TRUE(
|
|
|
|
|
bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
|
|
|
|
|
<< "Timed out while waiting encoder rate to be set.";
|
|
|
|
|
rtc::CritScope lock(&crit_);
|
|
|
|
|
EXPECT_EQ(expected_bitrate, target_bitrate_);
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-13 13:19:42 +02:00
|
|
|
void ModifySenderCallConfig(Call::Config* config) override {
|
|
|
|
|
config->bitrate_config.min_bitrate_bps = kMinBitrateKbps * 1000;
|
|
|
|
|
config->bitrate_config.start_bitrate_bps = kStartBitrateKbps * 1000;
|
|
|
|
|
config->bitrate_config.max_bitrate_bps = kMaxBitrateKbps * 1000;
|
2014-11-25 14:03:34 +00:00
|
|
|
}
|
|
|
|
|
|
2016-10-02 23:45:26 -07:00
|
|
|
class VideoStreamFactory
|
|
|
|
|
: public VideoEncoderConfig::VideoStreamFactoryInterface {
|
|
|
|
|
public:
|
|
|
|
|
explicit VideoStreamFactory(int min_bitrate_bps)
|
|
|
|
|
: min_bitrate_bps_(min_bitrate_bps) {}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
std::vector<VideoStream> CreateEncoderStreams(
|
|
|
|
|
int width,
|
|
|
|
|
int height,
|
|
|
|
|
const VideoEncoderConfig& encoder_config) override {
|
|
|
|
|
std::vector<VideoStream> streams =
|
|
|
|
|
test::CreateVideoStreams(width, height, encoder_config);
|
|
|
|
|
streams[0].min_bitrate_bps = min_bitrate_bps_;
|
|
|
|
|
return streams;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const int min_bitrate_bps_;
|
|
|
|
|
};
|
|
|
|
|
|
2015-12-21 03:14:00 -08:00
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
2018-04-19 09:04:13 +02:00
|
|
|
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
2014-11-25 14:03:34 +00:00
|
|
|
// Set bitrates lower/higher than min/max to make sure they are properly
|
|
|
|
|
// capped.
|
2016-10-02 23:45:26 -07:00
|
|
|
encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
|
|
|
|
|
// Create a new StreamFactory to be able to set
|
|
|
|
|
// |VideoStream.min_bitrate_bps|.
|
|
|
|
|
encoder_config->video_stream_factory =
|
|
|
|
|
new rtc::RefCountedObject<VideoStreamFactory>(kMinBitrateKbps * 1000);
|
2016-09-01 01:17:40 -07:00
|
|
|
encoder_config_ = encoder_config->Copy();
|
2014-11-25 14:03:34 +00:00
|
|
|
}
|
|
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
|
2014-11-25 14:03:34 +00:00
|
|
|
call_ = sender_call;
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-21 03:14:00 -08:00
|
|
|
void OnVideoStreamsCreated(
|
2015-03-26 11:11:06 +01:00
|
|
|
VideoSendStream* send_stream,
|
|
|
|
|
const std::vector<VideoReceiveStream*>& receive_streams) override {
|
|
|
|
|
send_stream_ = send_stream;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
void PerformTest() override {
|
2016-04-20 06:35:56 -07:00
|
|
|
ASSERT_TRUE(
|
|
|
|
|
init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
|
2016-09-01 01:17:40 -07:00
|
|
|
<< "Timed out while waiting for encoder to be configured.";
|
|
|
|
|
WaitForSetRates(kStartBitrateKbps);
|
2018-02-21 09:52:06 +01:00
|
|
|
BitrateConstraints bitrate_config;
|
2014-11-25 14:03:34 +00:00
|
|
|
bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
|
|
|
|
|
bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
|
2017-08-22 04:02:52 -07:00
|
|
|
task_queue_->SendTask([this, &bitrate_config]() {
|
2018-02-21 13:07:13 +01:00
|
|
|
call_->GetTransportControllerSend()->SetSdpBitrateParameters(
|
|
|
|
|
bitrate_config);
|
2017-08-22 04:02:52 -07:00
|
|
|
});
|
2016-09-01 01:17:40 -07:00
|
|
|
// Encoder rate is capped by EncoderConfig max_bitrate_bps.
|
|
|
|
|
WaitForSetRates(kMaxBitrateKbps);
|
2016-10-02 23:45:26 -07:00
|
|
|
encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
|
2016-09-01 01:17:40 -07:00
|
|
|
send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
|
2016-04-20 06:35:56 -07:00
|
|
|
ASSERT_TRUE(
|
|
|
|
|
init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
|
2016-10-30 21:37:57 +01:00
|
|
|
EXPECT_EQ(2, num_initializations_)
|
2015-03-26 11:11:06 +01:00
|
|
|
<< "Encoder should have been reconfigured with the new value.";
|
2016-09-01 01:17:40 -07:00
|
|
|
WaitForSetRates(kLowerMaxBitrateKbps);
|
|
|
|
|
|
2016-10-02 23:45:26 -07:00
|
|
|
encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
|
2016-09-01 01:17:40 -07:00
|
|
|
send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
|
2016-04-20 06:35:56 -07:00
|
|
|
ASSERT_TRUE(
|
|
|
|
|
init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
|
2016-10-30 21:37:57 +01:00
|
|
|
EXPECT_EQ(3, num_initializations_)
|
2014-11-25 14:03:34 +00:00
|
|
|
<< "Encoder should have been reconfigured with the new value.";
|
2016-09-01 01:17:40 -07:00
|
|
|
// Expected target bitrate is the start bitrate set in the call to
|
2018-02-21 13:07:13 +01:00
|
|
|
// call_->GetTransportControllerSend()->SetSdpBitrateParameters.
|
2016-09-01 01:17:40 -07:00
|
|
|
WaitForSetRates(kIncreasedStartBitrateKbps);
|
2014-11-25 14:03:34 +00:00
|
|
|
}
|
|
|
|
|
|
2017-08-22 04:02:52 -07:00
|
|
|
test::SingleThreadedTaskQueueForTesting* const task_queue_;
|
2016-04-20 06:35:56 -07:00
|
|
|
rtc::Event init_encode_event_;
|
2016-09-01 01:17:40 -07:00
|
|
|
rtc::Event bitrate_changed_event_;
|
|
|
|
|
rtc::CriticalSection crit_;
|
2017-09-09 04:17:22 -07:00
|
|
|
uint32_t target_bitrate_ RTC_GUARDED_BY(&crit_);
|
2016-10-02 23:45:26 -07:00
|
|
|
|
2014-11-25 14:03:34 +00:00
|
|
|
int num_initializations_;
|
|
|
|
|
webrtc::Call* call_;
|
2015-03-26 11:11:06 +01:00
|
|
|
webrtc::VideoSendStream* send_stream_;
|
2018-04-19 09:04:13 +02:00
|
|
|
test::EncoderProxyFactory encoder_factory_;
|
2015-03-26 11:11:06 +01:00
|
|
|
webrtc::VideoEncoderConfig encoder_config_;
|
2017-08-22 04:02:52 -07:00
|
|
|
} test(&task_queue_);
|
2014-11-25 14:03:34 +00:00
|
|
|
|
2016-01-08 06:47:13 -08:00
|
|
|
RunBaseTest(&test);
|
2014-11-25 14:03:34 +00:00
|
|
|
}
|
2014-12-01 15:23:21 +00:00
|
|
|
|
|
|
|
|
TEST_F(VideoSendStreamTest, ReportsSentResolution) {
|
|
|
|
|
static const size_t kNumStreams = 3;
|
|
|
|
|
// Unusual resolutions to make sure that they are the ones being reported.
|
|
|
|
|
static const struct {
|
|
|
|
|
int width;
|
|
|
|
|
int height;
|
|
|
|
|
} kEncodedResolution[kNumStreams] = {{241, 181}, {300, 121}, {121, 221}};
|
|
|
|
|
class ScreencastTargetBitrateTest : public test::SendTest,
|
|
|
|
|
public test::FakeEncoder {
|
|
|
|
|
public:
|
|
|
|
|
ScreencastTargetBitrateTest()
|
|
|
|
|
: SendTest(kDefaultTimeoutMs),
|
2016-07-29 12:59:36 +02:00
|
|
|
test::FakeEncoder(Clock::GetRealTimeClock()),
|
2018-04-19 09:04:13 +02:00
|
|
|
send_stream_(nullptr),
|
|
|
|
|
encoder_factory_(this) {}
|
2014-12-01 15:23:21 +00:00
|
|
|
|
|
|
|
|
private:
|
2015-05-29 17:21:40 -07:00
|
|
|
int32_t Encode(const VideoFrame& input_image,
|
2015-03-04 12:58:35 +00:00
|
|
|
const CodecSpecificInfo* codecSpecificInfo,
|
2015-10-19 02:39:06 -07:00
|
|
|
const std::vector<FrameType>* frame_types) override {
|
2014-12-01 15:23:21 +00:00
|
|
|
CodecSpecificInfo specifics;
|
|
|
|
|
specifics.codecType = kVideoCodecGeneric;
|
|
|
|
|
|
|
|
|
|
uint8_t buffer[16] = {0};
|
|
|
|
|
EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer));
|
2018-08-16 10:24:12 +02:00
|
|
|
encoded.SetTimestamp(input_image.timestamp());
|
2014-12-01 15:23:21 +00:00
|
|
|
encoded.capture_time_ms_ = input_image.render_time_ms();
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < kNumStreams; ++i) {
|
2018-08-29 14:35:58 +00:00
|
|
|
specifics.codecSpecific.generic.simulcast_idx = static_cast<uint8_t>(i);
|
2014-12-01 15:23:21 +00:00
|
|
|
encoded._frameType = (*frame_types)[i];
|
|
|
|
|
encoded._encodedWidth = kEncodedResolution[i].width;
|
|
|
|
|
encoded._encodedHeight = kEncodedResolution[i].height;
|
2017-01-16 05:57:16 -08:00
|
|
|
EncodedImageCallback* callback;
|
|
|
|
|
{
|
|
|
|
|
rtc::CritScope cs(&crit_sect_);
|
|
|
|
|
callback = callback_;
|
|
|
|
|
}
|
|
|
|
|
RTC_DCHECK(callback);
|
|
|
|
|
if (callback->OnEncodedImage(encoded, &specifics, nullptr).error !=
|
2016-11-04 11:39:29 -07:00
|
|
|
EncodedImageCallback::Result::OK) {
|
2014-12-01 15:23:21 +00:00
|
|
|
return -1;
|
2016-11-04 11:39:29 -07:00
|
|
|
}
|
2014-12-01 15:23:21 +00:00
|
|
|
}
|
|
|
|
|
|
2015-12-10 13:02:50 +01:00
|
|
|
observation_complete_.Set();
|
2014-12-01 15:23:21 +00:00
|
|
|
return 0;
|
|
|
|
|
}
|
2015-12-21 03:14:00 -08:00
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
2018-04-19 09:04:13 +02:00
|
|
|
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
2016-10-02 23:45:26 -07:00
|
|
|
EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
|
2014-12-01 15:23:21 +00:00
|
|
|
}
|
|
|
|
|
|
2016-01-07 17:43:18 +01:00
|
|
|
size_t GetNumVideoStreams() const override { return kNumStreams; }
|
2014-12-01 15:23:21 +00:00
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
void PerformTest() override {
|
2015-12-10 13:02:50 +01:00
|
|
|
EXPECT_TRUE(Wait())
|
2014-12-01 15:23:21 +00:00
|
|
|
<< "Timed out while waiting for the encoder to send one frame.";
|
|
|
|
|
VideoSendStream::Stats stats = send_stream_->GetStats();
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < kNumStreams; ++i) {
|
2016-01-07 17:43:18 +01:00
|
|
|
ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) !=
|
2014-12-01 15:23:21 +00:00
|
|
|
stats.substreams.end())
|
2016-01-07 17:43:18 +01:00
|
|
|
<< "No stats for SSRC: " << kVideoSendSsrcs[i]
|
2014-12-01 15:23:21 +00:00
|
|
|
<< ", stats should exist as soon as frames have been encoded.";
|
2015-02-25 10:42:16 +00:00
|
|
|
VideoSendStream::StreamStats ssrc_stats =
|
2016-01-07 17:43:18 +01:00
|
|
|
stats.substreams[kVideoSendSsrcs[i]];
|
2015-02-25 10:42:16 +00:00
|
|
|
EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
|
|
|
|
|
EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
|
2014-12-01 15:23:21 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-21 03:14:00 -08:00
|
|
|
void OnVideoStreamsCreated(
|
2014-12-01 15:23:21 +00:00
|
|
|
VideoSendStream* send_stream,
|
2015-03-04 12:58:35 +00:00
|
|
|
const std::vector<VideoReceiveStream*>& receive_streams) override {
|
2014-12-01 15:23:21 +00:00
|
|
|
send_stream_ = send_stream;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VideoSendStream* send_stream_;
|
2018-04-19 09:04:13 +02:00
|
|
|
test::EncoderProxyFactory encoder_factory_;
|
2014-12-01 15:23:21 +00:00
|
|
|
} test;
|
|
|
|
|
|
2016-01-08 06:47:13 -08:00
|
|
|
RunBaseTest(&test);
|
2014-12-01 15:23:21 +00:00
|
|
|
}
|
2015-09-01 07:01:51 -07:00
|
|
|
|
2016-05-14 02:03:18 +02:00
|
|
|
#if !defined(RTC_DISABLE_VP9)
|
2015-12-04 10:58:08 +01:00
|
|
|
class Vp9HeaderObserver : public test::SendTest {
|
2015-09-01 07:01:51 -07:00
|
|
|
public:
|
2015-12-04 10:58:08 +01:00
|
|
|
Vp9HeaderObserver()
|
|
|
|
|
: SendTest(VideoSendStreamTest::kLongTimeoutMs),
|
2018-04-19 09:04:13 +02:00
|
|
|
encoder_factory_([]() { return VP9Encoder::Create(); }),
|
2015-12-04 10:58:08 +01:00
|
|
|
vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
|
|
|
|
|
packets_sent_(0),
|
2016-10-02 23:45:26 -07:00
|
|
|
frames_sent_(0),
|
|
|
|
|
expected_width_(0),
|
|
|
|
|
expected_height_(0) {}
|
2015-09-03 04:42:32 -07:00
|
|
|
|
2015-12-21 03:14:00 -08:00
|
|
|
virtual void ModifyVideoConfigsHook(
|
2015-09-01 07:01:51 -07:00
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) {}
|
|
|
|
|
|
2015-12-04 10:58:08 +01:00
|
|
|
virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
|
2015-09-01 07:01:51 -07:00
|
|
|
|
|
|
|
|
private:
|
2017-04-10 16:57:57 -07:00
|
|
|
const int kVp9PayloadType = test::CallTest::kVideoSendPayloadType;
|
2015-09-01 07:01:51 -07:00
|
|
|
|
2016-10-02 23:45:26 -07:00
|
|
|
class VideoStreamFactory
|
|
|
|
|
: public VideoEncoderConfig::VideoStreamFactoryInterface {
|
|
|
|
|
public:
|
|
|
|
|
explicit VideoStreamFactory(size_t number_of_temporal_layers)
|
|
|
|
|
: number_of_temporal_layers_(number_of_temporal_layers) {}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
std::vector<VideoStream> CreateEncoderStreams(
|
|
|
|
|
int width,
|
|
|
|
|
int height,
|
|
|
|
|
const VideoEncoderConfig& encoder_config) override {
|
|
|
|
|
std::vector<VideoStream> streams =
|
|
|
|
|
test::CreateVideoStreams(width, height, encoder_config);
|
2018-03-01 15:11:29 +01:00
|
|
|
streams.back().num_temporal_layers = number_of_temporal_layers_;
|
2016-10-02 23:45:26 -07:00
|
|
|
return streams;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const size_t number_of_temporal_layers_;
|
|
|
|
|
};
|
|
|
|
|
|
2015-12-21 03:14:00 -08:00
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
2018-04-19 09:04:13 +02:00
|
|
|
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
Reland "Reland "Move rtp-specific config out of EncoderSettings.""
This reverts commit 6c2c13af06b32778b86950681758a7970d1c5d9e.
Reason for revert: Intend to investigate and fix perf problems.
Original change's description:
> Revert "Reland "Move rtp-specific config out of EncoderSettings.""
>
> This reverts commit 04dd1768625eb2241d1fb97fd0137897e703e266.
>
> Reason for revert: Regression in ramp up perf tests.
>
> Original change's description:
> > Reland "Move rtp-specific config out of EncoderSettings."
> >
> > This is a reland of bc900cb1d1810fcf678fe41cf1e3966daa39c88c
> >
> > Original change's description:
> > > Move rtp-specific config out of EncoderSettings.
> > >
> > > In VideoSendStream::Config, move payload_name and payload_type from
> > > EncoderSettings to Rtp.
> > >
> > > EncoderSettings now contains configuration for VideoStreamEncoder only,
> > > and should perhaps be renamed in a follow up cl. It's no longer
> > > passed as an argument to VideoCodecInitializer::SetupCodec.
> > >
> > > The latter then needs a different way to know the codec type,
> > > which is provided by a new codec_type member in VideoEncoderConfig.
> > >
> > > Bug: webrtc:8830
> > > Change-Id: Ifcc691aef1ee6a95e43c0452c5e630d92a511cd6
> > > Reviewed-on: https://webrtc-review.googlesource.com/62062
> > > Commit-Queue: Niels Moller <nisse@webrtc.org>
> > > Reviewed-by: Magnus Jedvert <magjed@webrtc.org>
> > > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> > > Cr-Commit-Position: refs/heads/master@{#22532}
> >
> > Bug: webrtc:8830
> > Change-Id: If88ef7d57cdaa4fae3c7b2a97ea5a6e1b833e019
> > Reviewed-on: https://webrtc-review.googlesource.com/63721
> > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Commit-Queue: Niels Moller <nisse@webrtc.org>
> > Cr-Commit-Position: refs/heads/master@{#22595}
>
> TBR=brandtr@webrtc.org,magjed@webrtc.org,nisse@webrtc.org,stefan@webrtc.org
>
> Bug: webrtc:8830,chromium:827080
> Change-Id: Iaaf146de91ec5c0d741b8efdf143f7e173084fef
> Reviewed-on: https://webrtc-review.googlesource.com/65520
> Commit-Queue: Niels Moller <nisse@webrtc.org>
> Reviewed-by: Niels Moller <nisse@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#22677}
TBR=brandtr@webrtc.org,magjed@webrtc.org,nisse@webrtc.org,stefan@webrtc.org
# Not skipping CQ checks because original CL landed > 1 day ago.
Bug: webrtc:8830, chromium:827080
Change-Id: I9b62987bf5daced90dfeb3ebb6739c80117c487f
Reviewed-on: https://webrtc-review.googlesource.com/66862
Commit-Queue: Niels Moller <nisse@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22751}
2018-04-05 15:36:51 +02:00
|
|
|
send_config->rtp.payload_name = "VP9";
|
|
|
|
|
send_config->rtp.payload_type = kVp9PayloadType;
|
2015-12-21 03:14:00 -08:00
|
|
|
ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
|
2016-09-27 03:52:02 -07:00
|
|
|
encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
|
|
|
|
|
VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings_);
|
2016-10-02 23:45:26 -07:00
|
|
|
EXPECT_EQ(1u, encoder_config->number_of_streams);
|
|
|
|
|
encoder_config->video_stream_factory =
|
|
|
|
|
new rtc::RefCountedObject<VideoStreamFactory>(
|
|
|
|
|
vp9_settings_.numberOfTemporalLayers);
|
2016-09-01 01:17:40 -07:00
|
|
|
encoder_config_ = encoder_config->Copy();
|
2015-09-01 07:01:51 -07:00
|
|
|
}
|
|
|
|
|
|
2016-10-02 23:45:26 -07:00
|
|
|
void ModifyVideoCaptureStartResolution(int* width,
|
|
|
|
|
int* height,
|
|
|
|
|
int* frame_rate) override {
|
|
|
|
|
expected_width_ = *width;
|
|
|
|
|
expected_height_ = *height;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-01 07:01:51 -07:00
|
|
|
void PerformTest() override {
|
2015-12-10 13:02:50 +01:00
|
|
|
EXPECT_TRUE(Wait()) << "Test timed out waiting for VP9 packet, num frames "
|
|
|
|
|
<< frames_sent_;
|
2015-09-01 07:01:51 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Action OnSendRtp(const uint8_t* packet, size_t length) override {
|
|
|
|
|
RTPHeader header;
|
|
|
|
|
EXPECT_TRUE(parser_->Parse(packet, length, &header));
|
|
|
|
|
|
2015-12-04 10:58:08 +01:00
|
|
|
EXPECT_EQ(kVp9PayloadType, header.payloadType);
|
|
|
|
|
const uint8_t* payload = packet + header.headerLength;
|
|
|
|
|
size_t payload_length = length - header.headerLength - header.paddingLength;
|
|
|
|
|
|
|
|
|
|
bool new_packet = packets_sent_ == 0 ||
|
|
|
|
|
IsNewerSequenceNumber(header.sequenceNumber,
|
|
|
|
|
last_header_.sequenceNumber);
|
|
|
|
|
if (payload_length > 0 && new_packet) {
|
|
|
|
|
RtpDepacketizer::ParsedPayload parsed;
|
|
|
|
|
RtpDepacketizerVp9 depacketizer;
|
|
|
|
|
EXPECT_TRUE(depacketizer.Parse(&parsed, payload, payload_length));
|
2018-07-02 14:41:58 +02:00
|
|
|
EXPECT_EQ(VideoCodecType::kVideoCodecVP9, parsed.video_header().codec);
|
2015-12-04 10:58:08 +01:00
|
|
|
// Verify common fields for all configurations.
|
2018-08-08 14:26:00 +02:00
|
|
|
const auto& vp9_header =
|
|
|
|
|
absl::get<RTPVideoHeaderVP9>(parsed.video_header().video_type_header);
|
|
|
|
|
VerifyCommonHeader(vp9_header);
|
2018-07-02 14:41:58 +02:00
|
|
|
CompareConsecutiveFrames(header, parsed.video_header());
|
2015-12-04 10:58:08 +01:00
|
|
|
// Verify configuration specific settings.
|
2018-08-08 14:26:00 +02:00
|
|
|
InspectHeader(vp9_header);
|
2015-12-04 10:58:08 +01:00
|
|
|
|
|
|
|
|
++packets_sent_;
|
|
|
|
|
if (header.markerBit) {
|
|
|
|
|
++frames_sent_;
|
2015-09-01 07:01:51 -07:00
|
|
|
}
|
2015-12-04 10:58:08 +01:00
|
|
|
last_header_ = header;
|
2018-08-08 14:26:00 +02:00
|
|
|
last_vp9_ = vp9_header;
|
2015-09-01 07:01:51 -07:00
|
|
|
}
|
|
|
|
|
return SEND_PACKET;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-03 04:42:32 -07:00
|
|
|
protected:
|
2015-12-04 10:58:08 +01:00
|
|
|
bool ContinuousPictureId(const RTPVideoHeaderVP9& vp9) const {
|
|
|
|
|
if (last_vp9_.picture_id > vp9.picture_id) {
|
|
|
|
|
return vp9.picture_id == 0; // Wrap.
|
|
|
|
|
} else {
|
|
|
|
|
return vp9.picture_id == last_vp9_.picture_id + 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-12-01 23:52:14 -08:00
|
|
|
|
2015-12-04 10:58:08 +01:00
|
|
|
void VerifySpatialIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
|
|
|
|
|
bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
|
|
|
|
|
EXPECT_EQ(new_layer, vp9.beginning_of_frame);
|
|
|
|
|
EXPECT_EQ(new_layer, last_vp9_.end_of_frame);
|
|
|
|
|
EXPECT_EQ(new_layer ? last_vp9_.spatial_idx + 1 : last_vp9_.spatial_idx,
|
|
|
|
|
vp9.spatial_idx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VerifyFixedTemporalLayerStructure(const RTPVideoHeaderVP9& vp9,
|
|
|
|
|
uint8_t num_layers) const {
|
|
|
|
|
switch (num_layers) {
|
|
|
|
|
case 0:
|
|
|
|
|
VerifyTemporalLayerStructure0(vp9);
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
VerifyTemporalLayerStructure1(vp9);
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
VerifyTemporalLayerStructure2(vp9);
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
VerifyTemporalLayerStructure3(vp9);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
RTC_NOTREACHED();
|
2015-12-02 01:05:11 -08:00
|
|
|
}
|
2015-12-04 10:58:08 +01:00
|
|
|
}
|
Reland of Work on flexible mode and screen sharing. (patchset #1 id:1 of https://codereview.webrtc.org/1438543002/ )
Reason for revert:
Failed test not related to this CL (test fails on
master at an earlier date), re-landing original CL..
(This time from my @webrtc account.)
Original issue's description:
> Revert of Work on flexible mode and screen sharing. (patchset #28 id:520001 of https://codereview.webrtc.org/1328113004/ )
>
> Reason for revert:
> Seems to break VideoSendStreamTest.ReconfigureBitratesSetsEncoderBitratesCorrectly on Linux Memcheck buildbot.
>
> Original issue's description:
> > Work on flexible mode and screen sharing.
> >
> > Implement VP8 style screensharing but with spatial layers.
> > Implement flexible mode.
> >
> > Files from other patches:
> > generic_encoder.cc
> > layer_filtering_transport.cc
> >
> > BUG=webrtc:4914
> >
> > Committed: https://crrev.com/77ccfb4d16c148e61a316746bb5d9705e8b39f4a
> > Cr-Commit-Position: refs/heads/master@{#10572}
>
> TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,philipel@webrtc.org
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:4914
>
> Committed: https://crrev.com/0be8f1d347bdb171462df89c2a4c69b3f3eb7519
> Cr-Commit-Position: refs/heads/master@{#10578}
TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,terelius@webrtc.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:4914
Review URL: https://codereview.webrtc.org/1431283002
Cr-Commit-Position: refs/heads/master@{#10581}
2015-11-10 07:17:23 -08:00
|
|
|
|
2015-12-04 10:58:08 +01:00
|
|
|
void VerifyTemporalLayerStructure0(const RTPVideoHeaderVP9& vp9) const {
|
|
|
|
|
EXPECT_EQ(kNoTl0PicIdx, vp9.tl0_pic_idx);
|
|
|
|
|
EXPECT_EQ(kNoTemporalIdx, vp9.temporal_idx); // no tid
|
|
|
|
|
EXPECT_FALSE(vp9.temporal_up_switch);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VerifyTemporalLayerStructure1(const RTPVideoHeaderVP9& vp9) const {
|
|
|
|
|
EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
|
|
|
|
|
EXPECT_EQ(0, vp9.temporal_idx); // 0,0,0,...
|
|
|
|
|
EXPECT_FALSE(vp9.temporal_up_switch);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VerifyTemporalLayerStructure2(const RTPVideoHeaderVP9& vp9) const {
|
|
|
|
|
EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
|
|
|
|
|
EXPECT_GE(vp9.temporal_idx, 0); // 0,1,0,1,... (tid reset on I-frames).
|
|
|
|
|
EXPECT_LE(vp9.temporal_idx, 1);
|
|
|
|
|
EXPECT_EQ(vp9.temporal_idx > 0, vp9.temporal_up_switch);
|
|
|
|
|
if (IsNewPictureId(vp9)) {
|
|
|
|
|
uint8_t expected_tid =
|
|
|
|
|
(!vp9.inter_pic_predicted || last_vp9_.temporal_idx == 1) ? 0 : 1;
|
|
|
|
|
EXPECT_EQ(expected_tid, vp9.temporal_idx);
|
2015-12-02 01:05:11 -08:00
|
|
|
}
|
2015-12-04 10:58:08 +01:00
|
|
|
}
|
2015-12-01 23:52:14 -08:00
|
|
|
|
2015-12-04 10:58:08 +01:00
|
|
|
void VerifyTemporalLayerStructure3(const RTPVideoHeaderVP9& vp9) const {
|
|
|
|
|
EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
|
|
|
|
|
EXPECT_GE(vp9.temporal_idx, 0); // 0,2,1,2,... (tid reset on I-frames).
|
|
|
|
|
EXPECT_LE(vp9.temporal_idx, 2);
|
|
|
|
|
if (IsNewPictureId(vp9) && vp9.inter_pic_predicted) {
|
|
|
|
|
EXPECT_NE(vp9.temporal_idx, last_vp9_.temporal_idx);
|
|
|
|
|
switch (vp9.temporal_idx) {
|
|
|
|
|
case 0:
|
|
|
|
|
EXPECT_EQ(2, last_vp9_.temporal_idx);
|
|
|
|
|
EXPECT_FALSE(vp9.temporal_up_switch);
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
EXPECT_EQ(2, last_vp9_.temporal_idx);
|
|
|
|
|
EXPECT_TRUE(vp9.temporal_up_switch);
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
2018-05-07 09:17:12 +02:00
|
|
|
EXPECT_LT(last_vp9_.temporal_idx, 2);
|
|
|
|
|
EXPECT_TRUE(vp9.temporal_up_switch);
|
2015-12-04 10:58:08 +01:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-12-01 23:52:14 -08:00
|
|
|
|
2015-12-04 10:58:08 +01:00
|
|
|
void VerifyTl0Idx(const RTPVideoHeaderVP9& vp9) const {
|
|
|
|
|
if (vp9.tl0_pic_idx == kNoTl0PicIdx)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
uint8_t expected_tl0_idx = last_vp9_.tl0_pic_idx;
|
|
|
|
|
if (vp9.temporal_idx == 0)
|
|
|
|
|
++expected_tl0_idx;
|
|
|
|
|
EXPECT_EQ(expected_tl0_idx, vp9.tl0_pic_idx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool IsNewPictureId(const RTPVideoHeaderVP9& vp9) const {
|
|
|
|
|
return frames_sent_ > 0 && (vp9.picture_id != last_vp9_.picture_id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Flexible mode (F=1): Non-flexible mode (F=0):
|
|
|
|
|
//
|
|
|
|
|
// +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|
|
|
|
|
// |I|P|L|F|B|E|V|-| |I|P|L|F|B|E|V|-|
|
|
|
|
|
// +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|
|
|
|
|
// I: |M| PICTURE ID | I: |M| PICTURE ID |
|
|
|
|
|
// +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|
|
|
|
|
// M: | EXTENDED PID | M: | EXTENDED PID |
|
|
|
|
|
// +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|
|
|
|
|
// L: | T |U| S |D| L: | T |U| S |D|
|
|
|
|
|
// +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|
|
|
|
|
// P,F: | P_DIFF |X|N| | TL0PICIDX |
|
|
|
|
|
// +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|
|
|
|
|
// X: |EXTENDED P_DIFF| V: | SS .. |
|
|
|
|
|
// +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|
|
|
|
|
// V: | SS .. |
|
|
|
|
|
// +-+-+-+-+-+-+-+-+
|
|
|
|
|
void VerifyCommonHeader(const RTPVideoHeaderVP9& vp9) const {
|
|
|
|
|
EXPECT_EQ(kMaxTwoBytePictureId, vp9.max_picture_id); // M:1
|
|
|
|
|
EXPECT_NE(kNoPictureId, vp9.picture_id); // I:1
|
|
|
|
|
EXPECT_EQ(vp9_settings_.flexibleMode, vp9.flexible_mode); // F
|
2017-11-06 11:49:19 +01:00
|
|
|
|
|
|
|
|
if (vp9_settings_.numberOfSpatialLayers > 1) {
|
|
|
|
|
EXPECT_LT(vp9.spatial_idx, vp9_settings_.numberOfSpatialLayers);
|
|
|
|
|
} else if (vp9_settings_.numberOfTemporalLayers > 1) {
|
|
|
|
|
EXPECT_EQ(vp9.spatial_idx, 0);
|
|
|
|
|
} else {
|
|
|
|
|
EXPECT_EQ(vp9.spatial_idx, kNoSpatialIdx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (vp9_settings_.numberOfTemporalLayers > 1) {
|
|
|
|
|
EXPECT_LT(vp9.temporal_idx, vp9_settings_.numberOfTemporalLayers);
|
|
|
|
|
} else if (vp9_settings_.numberOfSpatialLayers > 1) {
|
|
|
|
|
EXPECT_EQ(vp9.temporal_idx, 0);
|
|
|
|
|
} else {
|
|
|
|
|
EXPECT_EQ(vp9.temporal_idx, kNoTemporalIdx);
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-04 10:58:08 +01:00
|
|
|
if (vp9.ss_data_available) // V
|
|
|
|
|
VerifySsData(vp9);
|
|
|
|
|
|
|
|
|
|
if (frames_sent_ == 0)
|
|
|
|
|
EXPECT_FALSE(vp9.inter_pic_predicted); // P
|
|
|
|
|
|
|
|
|
|
if (!vp9.inter_pic_predicted) {
|
|
|
|
|
EXPECT_TRUE(vp9.temporal_idx == 0 || vp9.temporal_idx == kNoTemporalIdx);
|
|
|
|
|
EXPECT_FALSE(vp9.temporal_up_switch);
|
2015-12-02 01:05:11 -08:00
|
|
|
}
|
2015-12-04 10:58:08 +01:00
|
|
|
}
|
2015-12-01 23:52:14 -08:00
|
|
|
|
2015-12-04 10:58:08 +01:00
|
|
|
// Scalability structure (SS).
|
|
|
|
|
//
|
|
|
|
|
// +-+-+-+-+-+-+-+-+
|
|
|
|
|
// V: | N_S |Y|G|-|-|-|
|
|
|
|
|
// +-+-+-+-+-+-+-+-+
|
|
|
|
|
// Y: | WIDTH | N_S + 1 times
|
|
|
|
|
// +-+-+-+-+-+-+-+-+
|
|
|
|
|
// | HEIGHT |
|
|
|
|
|
// +-+-+-+-+-+-+-+-+
|
|
|
|
|
// G: | N_G |
|
|
|
|
|
// +-+-+-+-+-+-+-+-+
|
|
|
|
|
// N_G: | T |U| R |-|-| N_G times
|
|
|
|
|
// +-+-+-+-+-+-+-+-+
|
|
|
|
|
// | P_DIFF | R times
|
|
|
|
|
// +-+-+-+-+-+-+-+-+
|
|
|
|
|
void VerifySsData(const RTPVideoHeaderVP9& vp9) const {
|
|
|
|
|
EXPECT_TRUE(vp9.ss_data_available); // V
|
|
|
|
|
EXPECT_EQ(vp9_settings_.numberOfSpatialLayers, // N_S + 1
|
|
|
|
|
vp9.num_spatial_layers);
|
|
|
|
|
EXPECT_TRUE(vp9.spatial_layer_resolution_present); // Y:1
|
2016-10-02 23:45:26 -07:00
|
|
|
int expected_width = expected_width_;
|
|
|
|
|
int expected_height = expected_height_;
|
2016-06-14 12:52:54 +02:00
|
|
|
for (int i = static_cast<int>(vp9.num_spatial_layers) - 1; i >= 0; --i) {
|
2015-12-04 10:58:08 +01:00
|
|
|
EXPECT_EQ(expected_width, vp9.width[i]); // WIDTH
|
|
|
|
|
EXPECT_EQ(expected_height, vp9.height[i]); // HEIGHT
|
|
|
|
|
expected_width /= 2;
|
|
|
|
|
expected_height /= 2;
|
2015-12-02 01:05:11 -08:00
|
|
|
}
|
2015-12-04 10:58:08 +01:00
|
|
|
}
|
2015-12-01 23:52:14 -08:00
|
|
|
|
2015-12-04 10:58:08 +01:00
|
|
|
void CompareConsecutiveFrames(const RTPHeader& header,
|
|
|
|
|
const RTPVideoHeader& video) const {
|
2018-08-08 14:26:00 +02:00
|
|
|
const auto& vp9_header =
|
|
|
|
|
absl::get<RTPVideoHeaderVP9>(video.video_type_header);
|
2015-12-04 10:58:08 +01:00
|
|
|
|
|
|
|
|
bool new_frame = packets_sent_ == 0 ||
|
|
|
|
|
IsNewerTimestamp(header.timestamp, last_header_.timestamp);
|
2017-01-10 04:21:35 -08:00
|
|
|
EXPECT_EQ(new_frame, video.is_first_packet_in_frame);
|
2015-12-04 10:58:08 +01:00
|
|
|
if (!new_frame) {
|
|
|
|
|
EXPECT_FALSE(last_header_.markerBit);
|
|
|
|
|
EXPECT_EQ(last_header_.timestamp, header.timestamp);
|
2018-08-08 14:26:00 +02:00
|
|
|
EXPECT_EQ(last_vp9_.picture_id, vp9_header.picture_id);
|
|
|
|
|
EXPECT_EQ(last_vp9_.temporal_idx, vp9_header.temporal_idx);
|
|
|
|
|
EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9_header.tl0_pic_idx);
|
|
|
|
|
VerifySpatialIdxWithinFrame(vp9_header);
|
2015-12-04 10:58:08 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// New frame.
|
2018-08-08 14:26:00 +02:00
|
|
|
EXPECT_TRUE(vp9_header.beginning_of_frame);
|
2015-12-04 10:58:08 +01:00
|
|
|
|
|
|
|
|
// Compare with last packet in previous frame.
|
|
|
|
|
if (frames_sent_ == 0)
|
|
|
|
|
return;
|
|
|
|
|
EXPECT_TRUE(last_vp9_.end_of_frame);
|
|
|
|
|
EXPECT_TRUE(last_header_.markerBit);
|
2018-08-08 14:26:00 +02:00
|
|
|
EXPECT_TRUE(ContinuousPictureId(vp9_header));
|
|
|
|
|
VerifyTl0Idx(vp9_header);
|
2015-12-04 10:58:08 +01:00
|
|
|
}
|
|
|
|
|
|
2018-04-19 09:04:13 +02:00
|
|
|
test::FunctionVideoEncoderFactory encoder_factory_;
|
2015-12-04 10:58:08 +01:00
|
|
|
VideoCodecVP9 vp9_settings_;
|
|
|
|
|
webrtc::VideoEncoderConfig encoder_config_;
|
|
|
|
|
RTPHeader last_header_;
|
|
|
|
|
RTPVideoHeaderVP9 last_vp9_;
|
|
|
|
|
size_t packets_sent_;
|
|
|
|
|
size_t frames_sent_;
|
2016-10-02 23:45:26 -07:00
|
|
|
int expected_width_;
|
|
|
|
|
int expected_height_;
|
2015-12-04 10:58:08 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl1SLayers) {
|
|
|
|
|
const uint8_t kNumTemporalLayers = 1;
|
|
|
|
|
const uint8_t kNumSpatialLayers = 1;
|
|
|
|
|
TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
|
2015-12-01 23:52:14 -08:00
|
|
|
}
|
|
|
|
|
|
2015-12-04 10:58:08 +01:00
|
|
|
TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl1SLayers) {
|
|
|
|
|
const uint8_t kNumTemporalLayers = 2;
|
|
|
|
|
const uint8_t kNumSpatialLayers = 1;
|
|
|
|
|
TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl1SLayers) {
|
|
|
|
|
const uint8_t kNumTemporalLayers = 3;
|
|
|
|
|
const uint8_t kNumSpatialLayers = 1;
|
|
|
|
|
TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl2SLayers) {
|
|
|
|
|
const uint8_t kNumTemporalLayers = 1;
|
|
|
|
|
const uint8_t kNumSpatialLayers = 2;
|
|
|
|
|
TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl2SLayers) {
|
|
|
|
|
const uint8_t kNumTemporalLayers = 2;
|
|
|
|
|
const uint8_t kNumSpatialLayers = 2;
|
|
|
|
|
TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl2SLayers) {
|
|
|
|
|
const uint8_t kNumTemporalLayers = 3;
|
|
|
|
|
const uint8_t kNumSpatialLayers = 2;
|
|
|
|
|
TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VideoSendStreamTest::TestVp9NonFlexMode(uint8_t num_temporal_layers,
|
|
|
|
|
uint8_t num_spatial_layers) {
|
|
|
|
|
static const size_t kNumFramesToSend = 100;
|
|
|
|
|
// Set to < kNumFramesToSend and coprime to length of temporal layer
|
|
|
|
|
// structures to verify temporal id reset on key frame.
|
|
|
|
|
static const int kKeyFrameInterval = 31;
|
2018-03-28 19:32:37 +02:00
|
|
|
|
|
|
|
|
static const int kWidth = kMinVp9SpatialLayerWidth;
|
|
|
|
|
static const int kHeight = kMinVp9SpatialLayerHeight;
|
|
|
|
|
static const float kGoodBitsPerPixel = 0.1f;
|
2015-12-04 10:58:08 +01:00
|
|
|
class NonFlexibleMode : public Vp9HeaderObserver {
|
|
|
|
|
public:
|
|
|
|
|
NonFlexibleMode(uint8_t num_temporal_layers, uint8_t num_spatial_layers)
|
|
|
|
|
: num_temporal_layers_(num_temporal_layers),
|
|
|
|
|
num_spatial_layers_(num_spatial_layers),
|
|
|
|
|
l_field_(num_temporal_layers > 1 || num_spatial_layers > 1) {}
|
2018-03-28 19:32:37 +02:00
|
|
|
|
2015-12-21 03:14:00 -08:00
|
|
|
void ModifyVideoConfigsHook(
|
Reland of Work on flexible mode and screen sharing. (patchset #1 id:1 of https://codereview.webrtc.org/1438543002/ )
Reason for revert:
Failed test not related to this CL (test fails on
master at an earlier date), re-landing original CL..
(This time from my @webrtc account.)
Original issue's description:
> Revert of Work on flexible mode and screen sharing. (patchset #28 id:520001 of https://codereview.webrtc.org/1328113004/ )
>
> Reason for revert:
> Seems to break VideoSendStreamTest.ReconfigureBitratesSetsEncoderBitratesCorrectly on Linux Memcheck buildbot.
>
> Original issue's description:
> > Work on flexible mode and screen sharing.
> >
> > Implement VP8 style screensharing but with spatial layers.
> > Implement flexible mode.
> >
> > Files from other patches:
> > generic_encoder.cc
> > layer_filtering_transport.cc
> >
> > BUG=webrtc:4914
> >
> > Committed: https://crrev.com/77ccfb4d16c148e61a316746bb5d9705e8b39f4a
> > Cr-Commit-Position: refs/heads/master@{#10572}
>
> TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,philipel@webrtc.org
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:4914
>
> Committed: https://crrev.com/0be8f1d347bdb171462df89c2a4c69b3f3eb7519
> Cr-Commit-Position: refs/heads/master@{#10578}
TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,terelius@webrtc.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:4914
Review URL: https://codereview.webrtc.org/1431283002
Cr-Commit-Position: refs/heads/master@{#10581}
2015-11-10 07:17:23 -08:00
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
2018-03-23 16:05:22 +01:00
|
|
|
encoder_config->codec_type = kVideoCodecVP9;
|
2018-03-28 19:32:37 +02:00
|
|
|
int bitrate_bps = 0;
|
|
|
|
|
for (int sl_idx = 0; sl_idx < num_spatial_layers_; ++sl_idx) {
|
|
|
|
|
const int width = kWidth << sl_idx;
|
|
|
|
|
const int height = kHeight << sl_idx;
|
|
|
|
|
const float bpp = kGoodBitsPerPixel / (1 << sl_idx);
|
|
|
|
|
bitrate_bps += static_cast<int>(width * height * bpp * 30);
|
|
|
|
|
}
|
|
|
|
|
encoder_config->max_bitrate_bps = bitrate_bps * 2;
|
|
|
|
|
|
2015-12-04 10:58:08 +01:00
|
|
|
vp9_settings_.flexibleMode = false;
|
|
|
|
|
vp9_settings_.frameDroppingOn = false;
|
|
|
|
|
vp9_settings_.keyFrameInterval = kKeyFrameInterval;
|
|
|
|
|
vp9_settings_.numberOfTemporalLayers = num_temporal_layers_;
|
|
|
|
|
vp9_settings_.numberOfSpatialLayers = num_spatial_layers_;
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-28 19:32:37 +02:00
|
|
|
void ModifyVideoCaptureStartResolution(int* width,
|
|
|
|
|
int* height,
|
|
|
|
|
int* frame_rate) override {
|
|
|
|
|
expected_width_ = kWidth << (num_spatial_layers_ - 1);
|
|
|
|
|
expected_height_ = kHeight << (num_spatial_layers_ - 1);
|
|
|
|
|
*width = expected_width_;
|
|
|
|
|
*height = expected_height_;
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-04 10:58:08 +01:00
|
|
|
void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
|
2017-11-06 11:49:19 +01:00
|
|
|
bool ss_data_expected =
|
|
|
|
|
!vp9.inter_pic_predicted && vp9.beginning_of_frame &&
|
|
|
|
|
(vp9.spatial_idx == 0 || vp9.spatial_idx == kNoSpatialIdx);
|
2015-12-04 10:58:08 +01:00
|
|
|
EXPECT_EQ(ss_data_expected, vp9.ss_data_available);
|
2017-11-06 11:49:19 +01:00
|
|
|
if (num_spatial_layers_ > 1) {
|
|
|
|
|
EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted);
|
|
|
|
|
} else {
|
|
|
|
|
EXPECT_FALSE(vp9.inter_layer_predicted);
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-14 01:41:19 -08:00
|
|
|
EXPECT_EQ(!vp9.inter_pic_predicted,
|
|
|
|
|
frames_sent_ % kKeyFrameInterval == 0);
|
2015-12-04 10:58:08 +01:00
|
|
|
|
|
|
|
|
if (IsNewPictureId(vp9)) {
|
2017-11-06 11:49:19 +01:00
|
|
|
if (num_temporal_layers_ == 1 && num_spatial_layers_ == 1) {
|
|
|
|
|
EXPECT_EQ(kNoSpatialIdx, vp9.spatial_idx);
|
|
|
|
|
} else {
|
|
|
|
|
EXPECT_EQ(0, vp9.spatial_idx);
|
|
|
|
|
}
|
|
|
|
|
if (num_spatial_layers_ > 1)
|
|
|
|
|
EXPECT_EQ(num_spatial_layers_ - 1, last_vp9_.spatial_idx);
|
2015-12-04 10:58:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VerifyFixedTemporalLayerStructure(vp9,
|
|
|
|
|
l_field_ ? num_temporal_layers_ : 0);
|
Reland of Work on flexible mode and screen sharing. (patchset #1 id:1 of https://codereview.webrtc.org/1438543002/ )
Reason for revert:
Failed test not related to this CL (test fails on
master at an earlier date), re-landing original CL..
(This time from my @webrtc account.)
Original issue's description:
> Revert of Work on flexible mode and screen sharing. (patchset #28 id:520001 of https://codereview.webrtc.org/1328113004/ )
>
> Reason for revert:
> Seems to break VideoSendStreamTest.ReconfigureBitratesSetsEncoderBitratesCorrectly on Linux Memcheck buildbot.
>
> Original issue's description:
> > Work on flexible mode and screen sharing.
> >
> > Implement VP8 style screensharing but with spatial layers.
> > Implement flexible mode.
> >
> > Files from other patches:
> > generic_encoder.cc
> > layer_filtering_transport.cc
> >
> > BUG=webrtc:4914
> >
> > Committed: https://crrev.com/77ccfb4d16c148e61a316746bb5d9705e8b39f4a
> > Cr-Commit-Position: refs/heads/master@{#10572}
>
> TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,philipel@webrtc.org
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:4914
>
> Committed: https://crrev.com/0be8f1d347bdb171462df89c2a4c69b3f3eb7519
> Cr-Commit-Position: refs/heads/master@{#10578}
TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,terelius@webrtc.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:4914
Review URL: https://codereview.webrtc.org/1431283002
Cr-Commit-Position: refs/heads/master@{#10581}
2015-11-10 07:17:23 -08:00
|
|
|
|
2015-12-04 10:58:08 +01:00
|
|
|
if (frames_sent_ > kNumFramesToSend)
|
2015-12-10 13:02:50 +01:00
|
|
|
observation_complete_.Set();
|
Reland of Work on flexible mode and screen sharing. (patchset #1 id:1 of https://codereview.webrtc.org/1438543002/ )
Reason for revert:
Failed test not related to this CL (test fails on
master at an earlier date), re-landing original CL..
(This time from my @webrtc account.)
Original issue's description:
> Revert of Work on flexible mode and screen sharing. (patchset #28 id:520001 of https://codereview.webrtc.org/1328113004/ )
>
> Reason for revert:
> Seems to break VideoSendStreamTest.ReconfigureBitratesSetsEncoderBitratesCorrectly on Linux Memcheck buildbot.
>
> Original issue's description:
> > Work on flexible mode and screen sharing.
> >
> > Implement VP8 style screensharing but with spatial layers.
> > Implement flexible mode.
> >
> > Files from other patches:
> > generic_encoder.cc
> > layer_filtering_transport.cc
> >
> > BUG=webrtc:4914
> >
> > Committed: https://crrev.com/77ccfb4d16c148e61a316746bb5d9705e8b39f4a
> > Cr-Commit-Position: refs/heads/master@{#10572}
>
> TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,philipel@webrtc.org
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:4914
>
> Committed: https://crrev.com/0be8f1d347bdb171462df89c2a4c69b3f3eb7519
> Cr-Commit-Position: refs/heads/master@{#10578}
TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,terelius@webrtc.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:4914
Review URL: https://codereview.webrtc.org/1431283002
Cr-Commit-Position: refs/heads/master@{#10581}
2015-11-10 07:17:23 -08:00
|
|
|
}
|
2015-12-04 10:58:08 +01:00
|
|
|
const uint8_t num_temporal_layers_;
|
|
|
|
|
const uint8_t num_spatial_layers_;
|
|
|
|
|
const bool l_field_;
|
|
|
|
|
} test(num_temporal_layers, num_spatial_layers);
|
Reland of Work on flexible mode and screen sharing. (patchset #1 id:1 of https://codereview.webrtc.org/1438543002/ )
Reason for revert:
Failed test not related to this CL (test fails on
master at an earlier date), re-landing original CL..
(This time from my @webrtc account.)
Original issue's description:
> Revert of Work on flexible mode and screen sharing. (patchset #28 id:520001 of https://codereview.webrtc.org/1328113004/ )
>
> Reason for revert:
> Seems to break VideoSendStreamTest.ReconfigureBitratesSetsEncoderBitratesCorrectly on Linux Memcheck buildbot.
>
> Original issue's description:
> > Work on flexible mode and screen sharing.
> >
> > Implement VP8 style screensharing but with spatial layers.
> > Implement flexible mode.
> >
> > Files from other patches:
> > generic_encoder.cc
> > layer_filtering_transport.cc
> >
> > BUG=webrtc:4914
> >
> > Committed: https://crrev.com/77ccfb4d16c148e61a316746bb5d9705e8b39f4a
> > Cr-Commit-Position: refs/heads/master@{#10572}
>
> TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,philipel@webrtc.org
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:4914
>
> Committed: https://crrev.com/0be8f1d347bdb171462df89c2a4c69b3f3eb7519
> Cr-Commit-Position: refs/heads/master@{#10578}
TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,terelius@webrtc.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:4914
Review URL: https://codereview.webrtc.org/1431283002
Cr-Commit-Position: refs/heads/master@{#10581}
2015-11-10 07:17:23 -08:00
|
|
|
|
2016-01-08 06:47:13 -08:00
|
|
|
RunBaseTest(&test);
|
Reland of Work on flexible mode and screen sharing. (patchset #1 id:1 of https://codereview.webrtc.org/1438543002/ )
Reason for revert:
Failed test not related to this CL (test fails on
master at an earlier date), re-landing original CL..
(This time from my @webrtc account.)
Original issue's description:
> Revert of Work on flexible mode and screen sharing. (patchset #28 id:520001 of https://codereview.webrtc.org/1328113004/ )
>
> Reason for revert:
> Seems to break VideoSendStreamTest.ReconfigureBitratesSetsEncoderBitratesCorrectly on Linux Memcheck buildbot.
>
> Original issue's description:
> > Work on flexible mode and screen sharing.
> >
> > Implement VP8 style screensharing but with spatial layers.
> > Implement flexible mode.
> >
> > Files from other patches:
> > generic_encoder.cc
> > layer_filtering_transport.cc
> >
> > BUG=webrtc:4914
> >
> > Committed: https://crrev.com/77ccfb4d16c148e61a316746bb5d9705e8b39f4a
> > Cr-Commit-Position: refs/heads/master@{#10572}
>
> TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,philipel@webrtc.org
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:4914
>
> Committed: https://crrev.com/0be8f1d347bdb171462df89c2a4c69b3f3eb7519
> Cr-Commit-Position: refs/heads/master@{#10578}
TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,terelius@webrtc.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:4914
Review URL: https://codereview.webrtc.org/1431283002
Cr-Commit-Position: refs/heads/master@{#10581}
2015-11-10 07:17:23 -08:00
|
|
|
}
|
|
|
|
|
|
2016-01-21 01:11:35 -08:00
|
|
|
TEST_F(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
|
|
|
|
|
static const size_t kNumFramesToSend = 50;
|
|
|
|
|
static const int kWidth = 4;
|
|
|
|
|
static const int kHeight = 4;
|
|
|
|
|
class NonFlexibleModeResolution : public Vp9HeaderObserver {
|
|
|
|
|
void ModifyVideoConfigsHook(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
Reland "Reland "Move rtp-specific config out of EncoderSettings.""
This reverts commit 6c2c13af06b32778b86950681758a7970d1c5d9e.
Reason for revert: Intend to investigate and fix perf problems.
Original change's description:
> Revert "Reland "Move rtp-specific config out of EncoderSettings.""
>
> This reverts commit 04dd1768625eb2241d1fb97fd0137897e703e266.
>
> Reason for revert: Regression in ramp up perf tests.
>
> Original change's description:
> > Reland "Move rtp-specific config out of EncoderSettings."
> >
> > This is a reland of bc900cb1d1810fcf678fe41cf1e3966daa39c88c
> >
> > Original change's description:
> > > Move rtp-specific config out of EncoderSettings.
> > >
> > > In VideoSendStream::Config, move payload_name and payload_type from
> > > EncoderSettings to Rtp.
> > >
> > > EncoderSettings now contains configuration for VideoStreamEncoder only,
> > > and should perhaps be renamed in a follow up cl. It's no longer
> > > passed as an argument to VideoCodecInitializer::SetupCodec.
> > >
> > > The latter then needs a different way to know the codec type,
> > > which is provided by a new codec_type member in VideoEncoderConfig.
> > >
> > > Bug: webrtc:8830
> > > Change-Id: Ifcc691aef1ee6a95e43c0452c5e630d92a511cd6
> > > Reviewed-on: https://webrtc-review.googlesource.com/62062
> > > Commit-Queue: Niels Moller <nisse@webrtc.org>
> > > Reviewed-by: Magnus Jedvert <magjed@webrtc.org>
> > > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> > > Cr-Commit-Position: refs/heads/master@{#22532}
> >
> > Bug: webrtc:8830
> > Change-Id: If88ef7d57cdaa4fae3c7b2a97ea5a6e1b833e019
> > Reviewed-on: https://webrtc-review.googlesource.com/63721
> > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Commit-Queue: Niels Moller <nisse@webrtc.org>
> > Cr-Commit-Position: refs/heads/master@{#22595}
>
> TBR=brandtr@webrtc.org,magjed@webrtc.org,nisse@webrtc.org,stefan@webrtc.org
>
> Bug: webrtc:8830,chromium:827080
> Change-Id: Iaaf146de91ec5c0d741b8efdf143f7e173084fef
> Reviewed-on: https://webrtc-review.googlesource.com/65520
> Commit-Queue: Niels Moller <nisse@webrtc.org>
> Reviewed-by: Niels Moller <nisse@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#22677}
TBR=brandtr@webrtc.org,magjed@webrtc.org,nisse@webrtc.org,stefan@webrtc.org
# Not skipping CQ checks because original CL landed > 1 day ago.
Bug: webrtc:8830, chromium:827080
Change-Id: I9b62987bf5daced90dfeb3ebb6739c80117c487f
Reviewed-on: https://webrtc-review.googlesource.com/66862
Commit-Queue: Niels Moller <nisse@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22751}
2018-04-05 15:36:51 +02:00
|
|
|
encoder_config->codec_type = kVideoCodecVP9;
|
2016-01-21 01:11:35 -08:00
|
|
|
vp9_settings_.flexibleMode = false;
|
|
|
|
|
vp9_settings_.numberOfTemporalLayers = 1;
|
|
|
|
|
vp9_settings_.numberOfSpatialLayers = 1;
|
|
|
|
|
|
2016-10-02 23:45:26 -07:00
|
|
|
EXPECT_EQ(1u, encoder_config->number_of_streams);
|
2016-01-21 01:11:35 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
|
|
|
|
|
if (frames_sent_ > kNumFramesToSend)
|
|
|
|
|
observation_complete_.Set();
|
|
|
|
|
}
|
2016-10-02 23:45:26 -07:00
|
|
|
|
|
|
|
|
void ModifyVideoCaptureStartResolution(int* width,
|
|
|
|
|
int* height,
|
|
|
|
|
int* frame_rate) override {
|
|
|
|
|
expected_width_ = kWidth;
|
|
|
|
|
expected_height_ = kHeight;
|
|
|
|
|
*width = kWidth;
|
|
|
|
|
*height = kHeight;
|
|
|
|
|
}
|
2016-01-21 01:11:35 -08:00
|
|
|
} test;
|
|
|
|
|
|
|
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-24 12:17:33 -07:00
|
|
|
#if defined(WEBRTC_ANDROID)
|
|
|
|
|
// Crashes on Android; bugs.webrtc.org/7401
|
|
|
|
|
#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
|
|
|
|
|
#else
|
2018-05-17 16:46:43 +02:00
|
|
|
// TODO(webrtc:9270): Support of flexible mode is temporarily disabled. Enable
|
|
|
|
|
// the test after webrtc:9270 is implemented.
|
|
|
|
|
#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
|
|
|
|
|
// #define MAYBE_Vp9FlexModeRefCount Vp9FlexModeRefCount
|
2017-03-24 12:17:33 -07:00
|
|
|
#endif
|
|
|
|
|
TEST_F(VideoSendStreamTest, MAYBE_Vp9FlexModeRefCount) {
|
2015-12-04 10:58:08 +01:00
|
|
|
class FlexibleMode : public Vp9HeaderObserver {
|
2015-12-21 03:14:00 -08:00
|
|
|
void ModifyVideoConfigsHook(
|
Reland of Work on flexible mode and screen sharing. (patchset #1 id:1 of https://codereview.webrtc.org/1438543002/ )
Reason for revert:
Failed test not related to this CL (test fails on
master at an earlier date), re-landing original CL..
(This time from my @webrtc account.)
Original issue's description:
> Revert of Work on flexible mode and screen sharing. (patchset #28 id:520001 of https://codereview.webrtc.org/1328113004/ )
>
> Reason for revert:
> Seems to break VideoSendStreamTest.ReconfigureBitratesSetsEncoderBitratesCorrectly on Linux Memcheck buildbot.
>
> Original issue's description:
> > Work on flexible mode and screen sharing.
> >
> > Implement VP8 style screensharing but with spatial layers.
> > Implement flexible mode.
> >
> > Files from other patches:
> > generic_encoder.cc
> > layer_filtering_transport.cc
> >
> > BUG=webrtc:4914
> >
> > Committed: https://crrev.com/77ccfb4d16c148e61a316746bb5d9705e8b39f4a
> > Cr-Commit-Position: refs/heads/master@{#10572}
>
> TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,philipel@webrtc.org
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:4914
>
> Committed: https://crrev.com/0be8f1d347bdb171462df89c2a4c69b3f3eb7519
> Cr-Commit-Position: refs/heads/master@{#10578}
TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,terelius@webrtc.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:4914
Review URL: https://codereview.webrtc.org/1431283002
Cr-Commit-Position: refs/heads/master@{#10581}
2015-11-10 07:17:23 -08:00
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
Reland "Reland "Move rtp-specific config out of EncoderSettings.""
This reverts commit 6c2c13af06b32778b86950681758a7970d1c5d9e.
Reason for revert: Intend to investigate and fix perf problems.
Original change's description:
> Revert "Reland "Move rtp-specific config out of EncoderSettings.""
>
> This reverts commit 04dd1768625eb2241d1fb97fd0137897e703e266.
>
> Reason for revert: Regression in ramp up perf tests.
>
> Original change's description:
> > Reland "Move rtp-specific config out of EncoderSettings."
> >
> > This is a reland of bc900cb1d1810fcf678fe41cf1e3966daa39c88c
> >
> > Original change's description:
> > > Move rtp-specific config out of EncoderSettings.
> > >
> > > In VideoSendStream::Config, move payload_name and payload_type from
> > > EncoderSettings to Rtp.
> > >
> > > EncoderSettings now contains configuration for VideoStreamEncoder only,
> > > and should perhaps be renamed in a follow up cl. It's no longer
> > > passed as an argument to VideoCodecInitializer::SetupCodec.
> > >
> > > The latter then needs a different way to know the codec type,
> > > which is provided by a new codec_type member in VideoEncoderConfig.
> > >
> > > Bug: webrtc:8830
> > > Change-Id: Ifcc691aef1ee6a95e43c0452c5e630d92a511cd6
> > > Reviewed-on: https://webrtc-review.googlesource.com/62062
> > > Commit-Queue: Niels Moller <nisse@webrtc.org>
> > > Reviewed-by: Magnus Jedvert <magjed@webrtc.org>
> > > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> > > Cr-Commit-Position: refs/heads/master@{#22532}
> >
> > Bug: webrtc:8830
> > Change-Id: If88ef7d57cdaa4fae3c7b2a97ea5a6e1b833e019
> > Reviewed-on: https://webrtc-review.googlesource.com/63721
> > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Commit-Queue: Niels Moller <nisse@webrtc.org>
> > Cr-Commit-Position: refs/heads/master@{#22595}
>
> TBR=brandtr@webrtc.org,magjed@webrtc.org,nisse@webrtc.org,stefan@webrtc.org
>
> Bug: webrtc:8830,chromium:827080
> Change-Id: Iaaf146de91ec5c0d741b8efdf143f7e173084fef
> Reviewed-on: https://webrtc-review.googlesource.com/65520
> Commit-Queue: Niels Moller <nisse@webrtc.org>
> Reviewed-by: Niels Moller <nisse@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#22677}
TBR=brandtr@webrtc.org,magjed@webrtc.org,nisse@webrtc.org,stefan@webrtc.org
# Not skipping CQ checks because original CL landed > 1 day ago.
Bug: webrtc:8830, chromium:827080
Change-Id: I9b62987bf5daced90dfeb3ebb6739c80117c487f
Reviewed-on: https://webrtc-review.googlesource.com/66862
Commit-Queue: Niels Moller <nisse@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22751}
2018-04-05 15:36:51 +02:00
|
|
|
encoder_config->codec_type = kVideoCodecVP9;
|
2015-12-04 10:58:08 +01:00
|
|
|
encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
|
Reland of Work on flexible mode and screen sharing. (patchset #1 id:1 of https://codereview.webrtc.org/1438543002/ )
Reason for revert:
Failed test not related to this CL (test fails on
master at an earlier date), re-landing original CL..
(This time from my @webrtc account.)
Original issue's description:
> Revert of Work on flexible mode and screen sharing. (patchset #28 id:520001 of https://codereview.webrtc.org/1328113004/ )
>
> Reason for revert:
> Seems to break VideoSendStreamTest.ReconfigureBitratesSetsEncoderBitratesCorrectly on Linux Memcheck buildbot.
>
> Original issue's description:
> > Work on flexible mode and screen sharing.
> >
> > Implement VP8 style screensharing but with spatial layers.
> > Implement flexible mode.
> >
> > Files from other patches:
> > generic_encoder.cc
> > layer_filtering_transport.cc
> >
> > BUG=webrtc:4914
> >
> > Committed: https://crrev.com/77ccfb4d16c148e61a316746bb5d9705e8b39f4a
> > Cr-Commit-Position: refs/heads/master@{#10572}
>
> TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,philipel@webrtc.org
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:4914
>
> Committed: https://crrev.com/0be8f1d347bdb171462df89c2a4c69b3f3eb7519
> Cr-Commit-Position: refs/heads/master@{#10578}
TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,terelius@webrtc.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:4914
Review URL: https://codereview.webrtc.org/1431283002
Cr-Commit-Position: refs/heads/master@{#10581}
2015-11-10 07:17:23 -08:00
|
|
|
vp9_settings_.flexibleMode = true;
|
2015-12-04 10:58:08 +01:00
|
|
|
vp9_settings_.numberOfTemporalLayers = 1;
|
|
|
|
|
vp9_settings_.numberOfSpatialLayers = 2;
|
Reland of Work on flexible mode and screen sharing. (patchset #1 id:1 of https://codereview.webrtc.org/1438543002/ )
Reason for revert:
Failed test not related to this CL (test fails on
master at an earlier date), re-landing original CL..
(This time from my @webrtc account.)
Original issue's description:
> Revert of Work on flexible mode and screen sharing. (patchset #28 id:520001 of https://codereview.webrtc.org/1328113004/ )
>
> Reason for revert:
> Seems to break VideoSendStreamTest.ReconfigureBitratesSetsEncoderBitratesCorrectly on Linux Memcheck buildbot.
>
> Original issue's description:
> > Work on flexible mode and screen sharing.
> >
> > Implement VP8 style screensharing but with spatial layers.
> > Implement flexible mode.
> >
> > Files from other patches:
> > generic_encoder.cc
> > layer_filtering_transport.cc
> >
> > BUG=webrtc:4914
> >
> > Committed: https://crrev.com/77ccfb4d16c148e61a316746bb5d9705e8b39f4a
> > Cr-Commit-Position: refs/heads/master@{#10572}
>
> TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,philipel@webrtc.org
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:4914
>
> Committed: https://crrev.com/0be8f1d347bdb171462df89c2a4c69b3f3eb7519
> Cr-Commit-Position: refs/heads/master@{#10578}
TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,terelius@webrtc.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:4914
Review URL: https://codereview.webrtc.org/1431283002
Cr-Commit-Position: refs/heads/master@{#10581}
2015-11-10 07:17:23 -08:00
|
|
|
}
|
|
|
|
|
|
2015-12-04 10:58:08 +01:00
|
|
|
void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
|
|
|
|
|
EXPECT_TRUE(vp9_header.flexible_mode);
|
|
|
|
|
EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
|
|
|
|
|
if (vp9_header.inter_pic_predicted) {
|
|
|
|
|
EXPECT_GT(vp9_header.num_ref_pics, 0u);
|
2015-12-10 13:02:50 +01:00
|
|
|
observation_complete_.Set();
|
Reland of Work on flexible mode and screen sharing. (patchset #1 id:1 of https://codereview.webrtc.org/1438543002/ )
Reason for revert:
Failed test not related to this CL (test fails on
master at an earlier date), re-landing original CL..
(This time from my @webrtc account.)
Original issue's description:
> Revert of Work on flexible mode and screen sharing. (patchset #28 id:520001 of https://codereview.webrtc.org/1328113004/ )
>
> Reason for revert:
> Seems to break VideoSendStreamTest.ReconfigureBitratesSetsEncoderBitratesCorrectly on Linux Memcheck buildbot.
>
> Original issue's description:
> > Work on flexible mode and screen sharing.
> >
> > Implement VP8 style screensharing but with spatial layers.
> > Implement flexible mode.
> >
> > Files from other patches:
> > generic_encoder.cc
> > layer_filtering_transport.cc
> >
> > BUG=webrtc:4914
> >
> > Committed: https://crrev.com/77ccfb4d16c148e61a316746bb5d9705e8b39f4a
> > Cr-Commit-Position: refs/heads/master@{#10572}
>
> TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,philipel@webrtc.org
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:4914
>
> Committed: https://crrev.com/0be8f1d347bdb171462df89c2a4c69b3f3eb7519
> Cr-Commit-Position: refs/heads/master@{#10578}
TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@google.com,asapersson@webrtc.org,mflodman@webrtc.org,terelius@webrtc.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:4914
Review URL: https://codereview.webrtc.org/1431283002
Cr-Commit-Position: refs/heads/master@{#10581}
2015-11-10 07:17:23 -08:00
|
|
|
}
|
|
|
|
|
}
|
2015-09-01 07:01:51 -07:00
|
|
|
} test;
|
|
|
|
|
|
2016-01-08 06:47:13 -08:00
|
|
|
RunBaseTest(&test);
|
2015-09-01 07:01:51 -07:00
|
|
|
}
|
2016-05-14 02:03:18 +02:00
|
|
|
#endif // !defined(RTC_DISABLE_VP9)
|
2015-09-01 07:01:51 -07:00
|
|
|
|
2016-11-01 11:45:46 -07:00
|
|
|
void VideoSendStreamTest::TestRequestSourceRotateVideo(
|
|
|
|
|
bool support_orientation_ext) {
|
2018-07-13 10:43:20 +02:00
|
|
|
CreateSenderCall();
|
2016-11-01 11:45:46 -07:00
|
|
|
|
|
|
|
|
test::NullTransport transport;
|
2016-11-15 07:10:52 -08:00
|
|
|
CreateSendConfig(1, 0, 0, &transport);
|
2018-07-13 09:49:00 +02:00
|
|
|
GetVideoSendConfig()->rtp.extensions.clear();
|
2016-11-01 11:45:46 -07:00
|
|
|
if (support_orientation_ext) {
|
2018-07-13 09:49:00 +02:00
|
|
|
GetVideoSendConfig()->rtp.extensions.push_back(
|
2016-11-01 11:45:46 -07:00
|
|
|
RtpExtension(RtpExtension::kVideoRotationUri, 1));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CreateVideoStreams();
|
|
|
|
|
test::FrameForwarder forwarder;
|
2018-07-13 09:49:00 +02:00
|
|
|
GetVideoSendStream()->SetSource(&forwarder,
|
|
|
|
|
DegradationPreference::MAINTAIN_FRAMERATE);
|
2016-11-01 11:45:46 -07:00
|
|
|
|
|
|
|
|
EXPECT_TRUE(forwarder.sink_wants().rotation_applied !=
|
|
|
|
|
support_orientation_ext);
|
|
|
|
|
|
|
|
|
|
DestroyStreams();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(VideoSendStreamTest,
|
|
|
|
|
RequestSourceRotateIfVideoOrientationExtensionNotSupported) {
|
|
|
|
|
TestRequestSourceRotateVideo(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(VideoSendStreamTest,
|
|
|
|
|
DoNotRequestsRotationIfVideoOrientationExtensionSupported) {
|
|
|
|
|
TestRequestSourceRotateVideo(true);
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-29 09:25:03 -08:00
|
|
|
// This test verifies that overhead is removed from the bandwidth estimate by
|
|
|
|
|
// testing that the maximum possible target payload rate is smaller than the
|
|
|
|
|
// maximum bandwidth estimate by the overhead rate.
|
2017-02-08 08:21:52 -08:00
|
|
|
TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
|
2016-11-29 09:25:03 -08:00
|
|
|
test::ScopedFieldTrials override_field_trials(
|
|
|
|
|
"WebRTC-SendSideBwe-WithOverhead/Enabled/");
|
|
|
|
|
class RemoveOverheadFromBandwidthTest : public test::EndToEndTest,
|
|
|
|
|
public test::FakeEncoder {
|
|
|
|
|
public:
|
2017-08-22 04:02:52 -07:00
|
|
|
explicit RemoveOverheadFromBandwidthTest(
|
|
|
|
|
test::SingleThreadedTaskQueueForTesting* task_queue)
|
2016-11-29 09:25:03 -08:00
|
|
|
: EndToEndTest(test::CallTest::kDefaultTimeoutMs),
|
|
|
|
|
FakeEncoder(Clock::GetRealTimeClock()),
|
2017-08-22 04:02:52 -07:00
|
|
|
task_queue_(task_queue),
|
2018-04-19 09:04:13 +02:00
|
|
|
encoder_factory_(this),
|
2016-11-29 09:25:03 -08:00
|
|
|
call_(nullptr),
|
2017-01-26 09:05:27 -08:00
|
|
|
max_bitrate_bps_(0),
|
|
|
|
|
first_packet_sent_(false),
|
|
|
|
|
bitrate_changed_event_(false, false) {}
|
2016-11-29 09:25:03 -08:00
|
|
|
|
2018-04-23 12:32:22 +02:00
|
|
|
int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate,
|
2016-11-29 09:25:03 -08:00
|
|
|
uint32_t frameRate) override {
|
|
|
|
|
rtc::CritScope lock(&crit_);
|
2017-01-26 09:05:27 -08:00
|
|
|
// Wait for the first sent packet so that videosendstream knows
|
|
|
|
|
// rtp_overhead.
|
|
|
|
|
if (first_packet_sent_) {
|
|
|
|
|
max_bitrate_bps_ = bitrate.get_sum_bps();
|
|
|
|
|
bitrate_changed_event_.Set();
|
|
|
|
|
}
|
2016-11-29 09:25:03 -08:00
|
|
|
return FakeEncoder::SetRateAllocation(bitrate, frameRate);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
|
|
|
|
|
call_ = sender_call;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
|
|
|
|
send_config->rtp.max_packet_size = 1200;
|
2018-04-19 09:04:13 +02:00
|
|
|
send_config->encoder_settings.encoder_factory = &encoder_factory_;
|
2016-11-29 09:25:03 -08:00
|
|
|
EXPECT_FALSE(send_config->rtp.extensions.empty());
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-26 09:05:27 -08:00
|
|
|
Action OnSendRtp(const uint8_t* packet, size_t length) override {
|
|
|
|
|
rtc::CritScope lock(&crit_);
|
|
|
|
|
first_packet_sent_ = true;
|
|
|
|
|
return SEND_PACKET;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-29 09:25:03 -08:00
|
|
|
void PerformTest() override {
|
2018-02-21 09:52:06 +01:00
|
|
|
BitrateConstraints bitrate_config;
|
2017-01-26 09:05:27 -08:00
|
|
|
constexpr int kStartBitrateBps = 60000;
|
2016-11-29 09:25:03 -08:00
|
|
|
constexpr int kMaxBitrateBps = 60000;
|
2017-01-26 09:05:27 -08:00
|
|
|
constexpr int kMinBitrateBps = 10000;
|
2016-11-29 09:25:03 -08:00
|
|
|
bitrate_config.start_bitrate_bps = kStartBitrateBps;
|
|
|
|
|
bitrate_config.max_bitrate_bps = kMaxBitrateBps;
|
2017-01-26 09:05:27 -08:00
|
|
|
bitrate_config.min_bitrate_bps = kMinBitrateBps;
|
2017-08-22 04:02:52 -07:00
|
|
|
task_queue_->SendTask([this, &bitrate_config]() {
|
2018-02-21 13:07:13 +01:00
|
|
|
call_->GetTransportControllerSend()->SetSdpBitrateParameters(
|
|
|
|
|
bitrate_config);
|
2017-08-22 04:02:52 -07:00
|
|
|
call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO, 40);
|
|
|
|
|
});
|
2016-11-29 09:25:03 -08:00
|
|
|
|
|
|
|
|
// At a bitrate of 60kbps with a packet size of 1200B video and an
|
2017-01-26 09:05:27 -08:00
|
|
|
// overhead of 40B per packet video produces 2240bps overhead.
|
|
|
|
|
// So the encoder BW should be set to 57760bps.
|
2018-04-19 09:04:13 +02:00
|
|
|
EXPECT_TRUE(
|
|
|
|
|
bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
|
2016-11-29 09:25:03 -08:00
|
|
|
{
|
|
|
|
|
rtc::CritScope lock(&crit_);
|
2017-02-08 08:21:52 -08:00
|
|
|
EXPECT_LE(max_bitrate_bps_, 57760u);
|
2016-11-29 09:25:03 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
2017-08-22 04:02:52 -07:00
|
|
|
test::SingleThreadedTaskQueueForTesting* const task_queue_;
|
2018-04-19 09:04:13 +02:00
|
|
|
test::EncoderProxyFactory encoder_factory_;
|
2016-11-29 09:25:03 -08:00
|
|
|
Call* call_;
|
|
|
|
|
rtc::CriticalSection crit_;
|
2017-09-09 04:17:22 -07:00
|
|
|
uint32_t max_bitrate_bps_ RTC_GUARDED_BY(&crit_);
|
|
|
|
|
bool first_packet_sent_ RTC_GUARDED_BY(&crit_);
|
2017-01-26 09:05:27 -08:00
|
|
|
rtc::Event bitrate_changed_event_;
|
2017-08-22 04:02:52 -07:00
|
|
|
} test(&task_queue_);
|
2016-11-29 09:25:03 -08:00
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-06 04:38:06 -07:00
|
|
|
TEST_F(VideoSendStreamTest, SendsKeepAlive) {
|
|
|
|
|
const int kTimeoutMs = 50; // Really short timeout for testing.
|
|
|
|
|
|
|
|
|
|
class KeepaliveObserver : public test::SendTest {
|
|
|
|
|
public:
|
|
|
|
|
KeepaliveObserver() : SendTest(kDefaultTimeoutMs) {}
|
|
|
|
|
|
2017-08-09 06:42:32 -07:00
|
|
|
void OnRtpTransportControllerSendCreated(
|
|
|
|
|
RtpTransportControllerSend* controller) override {
|
|
|
|
|
RtpKeepAliveConfig config;
|
|
|
|
|
config.timeout_interval_ms = kTimeoutMs;
|
|
|
|
|
config.payload_type = CallTest::kDefaultKeepalivePayloadType;
|
|
|
|
|
controller->SetKeepAliveConfig(config);
|
2017-07-11 03:44:17 -07:00
|
|
|
}
|
|
|
|
|
|
2017-07-06 04:38:06 -07:00
|
|
|
private:
|
|
|
|
|
Action OnSendRtp(const uint8_t* packet, size_t length) override {
|
|
|
|
|
RTPHeader header;
|
|
|
|
|
EXPECT_TRUE(parser_->Parse(packet, length, &header));
|
|
|
|
|
|
2017-07-10 08:41:10 -07:00
|
|
|
if (header.payloadType != CallTest::kDefaultKeepalivePayloadType) {
|
2017-07-06 04:38:06 -07:00
|
|
|
// The video stream has started. Stop it now.
|
|
|
|
|
if (capturer_)
|
|
|
|
|
capturer_->Stop();
|
|
|
|
|
} else {
|
|
|
|
|
observation_complete_.Set();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return SEND_PACKET;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PerformTest() override {
|
|
|
|
|
EXPECT_TRUE(Wait()) << "Timed out while waiting for keep-alive packet.";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OnFrameGeneratorCapturerCreated(
|
|
|
|
|
test::FrameGeneratorCapturer* frame_generator_capturer) override {
|
|
|
|
|
capturer_ = frame_generator_capturer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
test::FrameGeneratorCapturer* capturer_ = nullptr;
|
|
|
|
|
} test;
|
|
|
|
|
|
|
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-16 10:55:29 +01:00
|
|
|
class PacingFactorObserver : public test::SendTest {
|
|
|
|
|
public:
|
|
|
|
|
PacingFactorObserver(bool configure_send_side,
|
2018-06-15 12:28:07 +02:00
|
|
|
absl::optional<float> expected_pacing_factor)
|
2018-01-16 10:55:29 +01:00
|
|
|
: test::SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
|
|
|
|
|
configure_send_side_(configure_send_side),
|
|
|
|
|
expected_pacing_factor_(expected_pacing_factor) {}
|
2017-10-24 17:05:18 +02:00
|
|
|
|
2018-01-16 10:55:29 +01:00
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
|
|
|
|
// Check if send-side bwe extension is already present, and remove it if
|
|
|
|
|
// it is not desired.
|
|
|
|
|
bool has_send_side = false;
|
|
|
|
|
for (auto it = send_config->rtp.extensions.begin();
|
|
|
|
|
it != send_config->rtp.extensions.end(); ++it) {
|
|
|
|
|
if (it->uri == RtpExtension::kTransportSequenceNumberUri) {
|
|
|
|
|
if (configure_send_side_) {
|
|
|
|
|
has_send_side = true;
|
|
|
|
|
} else {
|
|
|
|
|
send_config->rtp.extensions.erase(it);
|
2017-10-24 17:05:18 +02:00
|
|
|
}
|
2018-01-16 10:55:29 +01:00
|
|
|
break;
|
2017-10-24 17:05:18 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-16 10:55:29 +01:00
|
|
|
if (configure_send_side_ && !has_send_side) {
|
|
|
|
|
// Want send side, not present by default, so add it.
|
|
|
|
|
send_config->rtp.extensions.emplace_back(
|
|
|
|
|
RtpExtension::kTransportSequenceNumberUri,
|
|
|
|
|
RtpExtension::kTransportSequenceNumberDefaultId);
|
2017-10-24 17:05:18 +02:00
|
|
|
}
|
|
|
|
|
|
2018-01-16 10:55:29 +01:00
|
|
|
// ALR only enabled for screenshare.
|
|
|
|
|
encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
|
|
|
|
|
}
|
2017-10-24 17:05:18 +02:00
|
|
|
|
2018-01-16 10:55:29 +01:00
|
|
|
void OnVideoStreamsCreated(
|
|
|
|
|
VideoSendStream* send_stream,
|
|
|
|
|
const std::vector<VideoReceiveStream*>& receive_streams) override {
|
|
|
|
|
auto internal_send_peer = test::VideoSendStreamPeer(send_stream);
|
|
|
|
|
// Video streams created, check that pacing factor is correctly configured.
|
|
|
|
|
EXPECT_EQ(expected_pacing_factor_,
|
|
|
|
|
internal_send_peer.GetPacingFactorOverride());
|
|
|
|
|
observation_complete_.Set();
|
|
|
|
|
}
|
2017-10-24 17:05:18 +02:00
|
|
|
|
2018-01-16 10:55:29 +01:00
|
|
|
void PerformTest() override {
|
|
|
|
|
EXPECT_TRUE(Wait()) << "Timed out while waiting for stream creation.";
|
|
|
|
|
}
|
2017-10-24 17:05:18 +02:00
|
|
|
|
2018-01-16 10:55:29 +01:00
|
|
|
private:
|
|
|
|
|
const bool configure_send_side_;
|
2018-06-15 12:28:07 +02:00
|
|
|
const absl::optional<float> expected_pacing_factor_;
|
2018-01-16 10:55:29 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::string GetAlrProbingExperimentString() {
|
|
|
|
|
return std::string(
|
|
|
|
|
AlrExperimentSettings::kScreenshareProbingBweExperimentName) +
|
|
|
|
|
"/1.0,2875,80,40,-60,3/";
|
|
|
|
|
}
|
|
|
|
|
const float kAlrProbingExperimentPaceMultiplier = 1.0f;
|
|
|
|
|
|
|
|
|
|
TEST_F(VideoSendStreamTest, AlrConfiguredWhenSendSideOn) {
|
|
|
|
|
test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
|
2017-10-24 17:05:18 +02:00
|
|
|
// Send-side bwe on, use pacing factor from |kAlrProbingExperiment| above.
|
2018-01-16 10:55:29 +01:00
|
|
|
PacingFactorObserver test_with_send_side(true,
|
|
|
|
|
kAlrProbingExperimentPaceMultiplier);
|
2017-10-24 17:05:18 +02:00
|
|
|
RunBaseTest(&test_with_send_side);
|
2018-01-16 10:55:29 +01:00
|
|
|
}
|
2017-10-24 17:05:18 +02:00
|
|
|
|
2018-01-16 10:55:29 +01:00
|
|
|
TEST_F(VideoSendStreamTest, AlrNotConfiguredWhenSendSideOff) {
|
|
|
|
|
test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString());
|
|
|
|
|
// Send-side bwe off, use configuration should not be overridden.
|
2018-06-15 12:28:07 +02:00
|
|
|
PacingFactorObserver test_without_send_side(false, absl::nullopt);
|
2017-10-24 17:05:18 +02:00
|
|
|
RunBaseTest(&test_without_send_side);
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-15 11:42:00 +01:00
|
|
|
// Test class takes as argument a function pointer to reset the send
|
|
|
|
|
// stream and call OnVideoStreamsCreated. This is necessary since you cannot
|
|
|
|
|
// change the content type of a VideoSendStream, you need to recreate it.
|
|
|
|
|
// Stopping and recreating the stream can only be done on the main thread and in
|
|
|
|
|
// the context of VideoSendStreamTest (not BaseTest). The test switches from
|
|
|
|
|
// realtime to screenshare and back.
|
|
|
|
|
template <typename T>
|
|
|
|
|
class ContentSwitchTest : public test::SendTest {
|
|
|
|
|
public:
|
|
|
|
|
enum class StreamState {
|
|
|
|
|
kBeforeSwitch = 0,
|
|
|
|
|
kInScreenshare = 1,
|
|
|
|
|
kAfterSwitchBack = 2,
|
|
|
|
|
};
|
|
|
|
|
static const uint32_t kMinPacketsToSend = 50;
|
|
|
|
|
|
|
|
|
|
explicit ContentSwitchTest(T* stream_reset_fun)
|
|
|
|
|
: SendTest(test::CallTest::kDefaultTimeoutMs),
|
|
|
|
|
content_switch_event_(false, false),
|
|
|
|
|
call_(nullptr),
|
|
|
|
|
state_(StreamState::kBeforeSwitch),
|
|
|
|
|
send_stream_(nullptr),
|
|
|
|
|
send_stream_config_(nullptr),
|
|
|
|
|
packets_sent_(0),
|
|
|
|
|
stream_resetter_(stream_reset_fun) {
|
|
|
|
|
RTC_DCHECK(stream_resetter_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OnVideoStreamsCreated(
|
|
|
|
|
VideoSendStream* send_stream,
|
|
|
|
|
const std::vector<VideoReceiveStream*>& receive_streams) override {
|
|
|
|
|
rtc::CritScope lock(&crit_);
|
|
|
|
|
send_stream_ = send_stream;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModifyVideoConfigs(
|
|
|
|
|
VideoSendStream::Config* send_config,
|
|
|
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
|
|
|
VideoEncoderConfig* encoder_config) override {
|
|
|
|
|
RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
|
|
|
|
|
encoder_config->min_transmit_bitrate_bps = 0;
|
|
|
|
|
encoder_config->content_type =
|
|
|
|
|
VideoEncoderConfig::ContentType::kRealtimeVideo;
|
|
|
|
|
send_stream_config_ = send_config->Copy();
|
|
|
|
|
encoder_config_ = encoder_config->Copy();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
|
|
|
|
|
call_ = sender_call;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Action OnSendRtp(const uint8_t* packet, size_t length) override {
|
|
|
|
|
rtc::CritScope lock(&crit_);
|
|
|
|
|
|
|
|
|
|
auto internal_send_peer = test::VideoSendStreamPeer(send_stream_);
|
|
|
|
|
float pacing_factor =
|
|
|
|
|
internal_send_peer.GetPacingFactorOverride().value_or(0.0f);
|
|
|
|
|
float expected_pacing_factor = PacedSender::kDefaultPaceMultiplier;
|
|
|
|
|
if (send_stream_->GetStats().content_type ==
|
|
|
|
|
webrtc::VideoContentType::SCREENSHARE) {
|
|
|
|
|
expected_pacing_factor = 1.0f; // Currently used pacing factor in ALR.
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EXPECT_NEAR(expected_pacing_factor, pacing_factor, 1e-6);
|
|
|
|
|
|
|
|
|
|
// Wait until at least kMinPacketsToSend packets to be sent, so that
|
|
|
|
|
// some frames would be encoded.
|
|
|
|
|
if (++packets_sent_ < kMinPacketsToSend)
|
|
|
|
|
return SEND_PACKET;
|
|
|
|
|
|
|
|
|
|
if (state_ != StreamState::kAfterSwitchBack) {
|
|
|
|
|
// We've sent kMinPacketsToSend packets, switch the content type and move
|
|
|
|
|
// move to the next state.
|
|
|
|
|
// Note that we need to recreate the stream if changing content type.
|
|
|
|
|
packets_sent_ = 0;
|
|
|
|
|
if (encoder_config_.content_type ==
|
|
|
|
|
VideoEncoderConfig::ContentType::kRealtimeVideo) {
|
|
|
|
|
encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
|
|
|
|
|
} else {
|
|
|
|
|
encoder_config_.content_type =
|
|
|
|
|
VideoEncoderConfig::ContentType::kRealtimeVideo;
|
|
|
|
|
}
|
|
|
|
|
switch (state_) {
|
|
|
|
|
case StreamState::kBeforeSwitch:
|
|
|
|
|
state_ = StreamState::kInScreenshare;
|
|
|
|
|
break;
|
|
|
|
|
case StreamState::kInScreenshare:
|
|
|
|
|
state_ = StreamState::kAfterSwitchBack;
|
|
|
|
|
break;
|
|
|
|
|
case StreamState::kAfterSwitchBack:
|
|
|
|
|
RTC_NOTREACHED();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
content_switch_event_.Set();
|
|
|
|
|
return SEND_PACKET;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
observation_complete_.Set();
|
|
|
|
|
return SEND_PACKET;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PerformTest() override {
|
|
|
|
|
while (GetStreamState() != StreamState::kAfterSwitchBack) {
|
|
|
|
|
ASSERT_TRUE(
|
|
|
|
|
content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
|
|
|
|
|
(*stream_resetter_)(send_stream_config_, encoder_config_, this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ASSERT_TRUE(Wait())
|
|
|
|
|
<< "Timed out waiting for a frame sent after switch back";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
StreamState GetStreamState() {
|
|
|
|
|
rtc::CritScope lock(&crit_);
|
|
|
|
|
return state_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rtc::CriticalSection crit_;
|
|
|
|
|
rtc::Event content_switch_event_;
|
|
|
|
|
Call* call_;
|
|
|
|
|
StreamState state_ RTC_GUARDED_BY(crit_);
|
|
|
|
|
VideoSendStream* send_stream_ RTC_GUARDED_BY(crit_);
|
|
|
|
|
VideoSendStream::Config send_stream_config_;
|
|
|
|
|
VideoEncoderConfig encoder_config_;
|
|
|
|
|
uint32_t packets_sent_ RTC_GUARDED_BY(crit_);
|
|
|
|
|
T* stream_resetter_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
TEST_F(VideoSendStreamTest, SwitchesToScreenshareAndBack) {
|
|
|
|
|
auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
|
|
|
|
|
const VideoEncoderConfig& encoder_config,
|
|
|
|
|
test::BaseTest* test) {
|
|
|
|
|
task_queue_.SendTask([this, &send_stream_config, &encoder_config, &test]() {
|
|
|
|
|
Stop();
|
2018-07-13 09:49:00 +02:00
|
|
|
DestroyVideoSendStreams();
|
|
|
|
|
SetVideoSendConfig(send_stream_config);
|
|
|
|
|
SetVideoEncoderConfig(encoder_config);
|
|
|
|
|
CreateVideoSendStreams();
|
|
|
|
|
SetVideoDegradation(DegradationPreference::MAINTAIN_RESOLUTION);
|
|
|
|
|
test->OnVideoStreamsCreated(GetVideoSendStream(), video_receive_streams_);
|
2018-03-15 11:42:00 +01:00
|
|
|
Start();
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
ContentSwitchTest<decltype(reset_fun)> test(&reset_fun);
|
|
|
|
|
RunBaseTest(&test);
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-20 13:14:07 +00:00
|
|
|
} // namespace webrtc
|