diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-12 05:43:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-12 05:43:14 +0000 |
commit | 8dd16259287f58f9273002717ec4d27e97127719 (patch) | |
tree | 3863e62a53829a84037444beab3abd4ed9dfc7d0 /third_party/libwebrtc/test | |
parent | Releasing progress-linux version 126.0.1-1~progress7.99u1. (diff) | |
download | firefox-8dd16259287f58f9273002717ec4d27e97127719.tar.xz firefox-8dd16259287f58f9273002717ec4d27e97127719.zip |
Merging upstream version 127.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
36 files changed, 825 insertions, 440 deletions
diff --git a/third_party/libwebrtc/test/mock_frame_transformer.h b/third_party/libwebrtc/api/test/mock_frame_transformer.h index 617cda8a43..8f438bdf9e 100644 --- a/third_party/libwebrtc/test/mock_frame_transformer.h +++ b/third_party/libwebrtc/api/test/mock_frame_transformer.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef TEST_MOCK_FRAME_TRANSFORMER_H_ -#define TEST_MOCK_FRAME_TRANSFORMER_H_ +#ifndef API_TEST_MOCK_FRAME_TRANSFORMER_H_ +#define API_TEST_MOCK_FRAME_TRANSFORMER_H_ #include <memory> #include <vector> @@ -42,4 +42,4 @@ class MockFrameTransformer : public FrameTransformerInterface { } // namespace webrtc -#endif // TEST_MOCK_FRAME_TRANSFORMER_H_ +#endif // API_TEST_MOCK_FRAME_TRANSFORMER_H_ diff --git a/third_party/libwebrtc/test/BUILD.gn b/third_party/libwebrtc/test/BUILD.gn index 75d8d9f3a8..bf98ec7d3a 100644 --- a/third_party/libwebrtc/test/BUILD.gn +++ b/third_party/libwebrtc/test/BUILD.gn @@ -735,6 +735,8 @@ if (rtc_include_tests) { "../api:mock_video_encoder", "../api:scoped_refptr", "../api:simulcast_test_fixture_api", + "../api/environment", + "../api/environment:environment_factory", "../api/task_queue", "../api/task_queue:task_queue_test", "../api/test/video:function_video_factory", @@ -867,6 +869,7 @@ rtc_library("fileutils") { ":fileutils_override_api", ":fileutils_override_impl", "../rtc_base:checks", + "../rtc_base:ssl", "../rtc_base:stringutils", ] absl_deps = [ @@ -956,6 +959,7 @@ rtc_library("fileutils_unittests") { ":fileutils", ":test_support", "../rtc_base:checks", + "../rtc_base:ssl", ] absl_deps = [ "//third_party/abseil-cpp/absl/strings:strings", @@ -1107,28 +1111,6 @@ rtc_source_set("test_renderer") { } } -rtc_library("mock_frame_transformer") { - visibility = [ "*" ] - testonly = true - sources = [ "mock_frame_transformer.h" ] - deps = [ - "../api:frame_transformer_interface", - "../test:test_support", - ] -} - -rtc_library("mock_transformable_frame") { - visibility = [ "*" ] - - testonly = true - sources = [ "mock_transformable_frame.h" ] - - deps = [ - "../api:frame_transformer_interface", - "../test:test_support", - ] -} - if (is_mac) { rtc_library("test_renderer_objc") { testonly = true diff --git a/third_party/libwebrtc/test/call_test.cc b/third_party/libwebrtc/test/call_test.cc index 6cdd8da133..f26a44a341 100644 --- a/third_party/libwebrtc/test/call_test.cc +++ b/third_party/libwebrtc/test/call_test.cc @@ -657,9 +657,7 @@ void CallTest::StartVideoSources() { void CallTest::StartVideoStreams() { StartVideoSources(); for (size_t i = 0; i < video_send_streams_.size(); ++i) { - std::vector<bool> active_rtp_streams( - video_send_configs_[i].rtp.ssrcs.size(), true); - video_send_streams_[i]->StartPerRtpStream(active_rtp_streams); + video_send_streams_[i]->Start(); } for (VideoReceiveStreamInterface* video_recv_stream : video_receive_streams_) video_recv_stream->Start(); diff --git a/third_party/libwebrtc/test/fuzzers/BUILD.gn b/third_party/libwebrtc/test/fuzzers/BUILD.gn index 083c20c6f4..642b0c8e08 100644 --- a/third_party/libwebrtc/test/fuzzers/BUILD.gn +++ b/third_party/libwebrtc/test/fuzzers/BUILD.gn @@ -132,6 +132,11 @@ if (rtc_use_h265) { "../../modules/video_coding/", ] } + + webrtc_fuzzer_test("h265_depacketizer_fuzzer") { + sources = [ "h265_depacketizer_fuzzer.cc" ] + deps = [ "../../modules/rtp_rtcp" ] + } } webrtc_fuzzer_test("forward_error_correction_fuzzer") { @@ -471,6 +476,7 @@ webrtc_fuzzer_test("stun_validator_fuzzer") { webrtc_fuzzer_test("pseudotcp_parser_fuzzer") { sources = [ "pseudotcp_parser_fuzzer.cc" ] deps = [ + "../../p2p:pseudo_tcp", "../../p2p:rtc_p2p", "../../rtc_base:threading", ] diff --git a/third_party/libwebrtc/test/fuzzers/h265_depacketizer_fuzzer.cc b/third_party/libwebrtc/test/fuzzers/h265_depacketizer_fuzzer.cc new file mode 100644 index 0000000000..00025ef887 --- /dev/null +++ b/third_party/libwebrtc/test/fuzzers/h265_depacketizer_fuzzer.cc @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024 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. + */ +#include "modules/rtp_rtcp/source/video_rtp_depacketizer_h265.h" + +namespace webrtc { +void FuzzOneInput(const uint8_t* data, size_t size) { + if (size > 200000) + return; + VideoRtpDepacketizerH265 depacketizer; + depacketizer.Parse(rtc::CopyOnWriteBuffer(data, size)); +} +} // namespace webrtc diff --git a/third_party/libwebrtc/test/fuzzers/neteq_signal_fuzzer.cc b/third_party/libwebrtc/test/fuzzers/neteq_signal_fuzzer.cc index 485c38085e..3b1f70cdb4 100644 --- a/third_party/libwebrtc/test/fuzzers/neteq_signal_fuzzer.cc +++ b/third_party/libwebrtc/test/fuzzers/neteq_signal_fuzzer.cc @@ -179,7 +179,6 @@ void FuzzOneInputTest(const uint8_t* data, size_t size) { // Configure NetEq and the NetEqTest object. NetEqTest::Callbacks callbacks; NetEq::Config config; - config.enable_post_decode_vad = true; config.enable_fast_accelerate = true; auto codecs = NetEqTest::StandardDecoderMap(); // rate_types contains the payload types that will be used for encoding. diff --git a/third_party/libwebrtc/test/fuzzers/rtp_format_h264_fuzzer.cc b/third_party/libwebrtc/test/fuzzers/rtp_format_h264_fuzzer.cc index ddf2ca9d3d..97b0ce2c03 100644 --- a/third_party/libwebrtc/test/fuzzers/rtp_format_h264_fuzzer.cc +++ b/third_party/libwebrtc/test/fuzzers/rtp_format_h264_fuzzer.cc @@ -1,75 +1,75 @@ -/*
- * Copyright (c) 2024 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.
- */
-#include <stddef.h>
-#include <stdint.h>
-
-#include "api/video/video_frame_type.h"
-#include "modules/rtp_rtcp/source/rtp_format.h"
-#include "modules/rtp_rtcp/source/rtp_format_h264.h"
-#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
-#include "rtc_base/checks.h"
-#include "test/fuzzers/fuzz_data_helper.h"
-
-namespace webrtc {
-void FuzzOneInput(const uint8_t* data, size_t size) {
- test::FuzzDataHelper fuzz_input(rtc::MakeArrayView(data, size));
-
- RtpPacketizer::PayloadSizeLimits limits;
- limits.max_payload_len = 1200;
- // Read uint8_t to be sure reduction_lens are much smaller than
- // max_payload_len and thus limits structure is valid.
- limits.first_packet_reduction_len = fuzz_input.ReadOrDefaultValue<uint8_t>(0);
- limits.last_packet_reduction_len = fuzz_input.ReadOrDefaultValue<uint8_t>(0);
- limits.single_packet_reduction_len =
- fuzz_input.ReadOrDefaultValue<uint8_t>(0);
- const H264PacketizationMode kPacketizationModes[] = {
- H264PacketizationMode::NonInterleaved,
- H264PacketizationMode::SingleNalUnit};
-
- H264PacketizationMode packetization_mode =
- fuzz_input.SelectOneOf(kPacketizationModes);
-
- // Main function under test: RtpPacketizerH264's constructor.
- RtpPacketizerH264 packetizer(fuzz_input.ReadByteArray(fuzz_input.BytesLeft()),
- limits, packetization_mode);
-
- size_t num_packets = packetizer.NumPackets();
- if (num_packets == 0) {
- return;
- }
- // When packetization was successful, validate NextPacket function too.
- // While at it, check that packets respect the payload size limits.
- RtpPacketToSend rtp_packet(nullptr);
- // Single packet.
- if (num_packets == 1) {
- RTC_CHECK(packetizer.NextPacket(&rtp_packet));
- RTC_CHECK_LE(rtp_packet.payload_size(),
- limits.max_payload_len - limits.single_packet_reduction_len);
- return;
- }
- // First packet.
- RTC_CHECK(packetizer.NextPacket(&rtp_packet));
- RTC_CHECK_LE(rtp_packet.payload_size(),
- limits.max_payload_len - limits.first_packet_reduction_len);
- // Middle packets.
- for (size_t i = 1; i < num_packets - 1; ++i) {
- rtp_packet.Clear();
- RTC_CHECK(packetizer.NextPacket(&rtp_packet))
- << "Failed to get packet#" << i;
- RTC_CHECK_LE(rtp_packet.payload_size(), limits.max_payload_len)
- << "Packet #" << i << " exceeds it's limit";
- }
- // Last packet.
- rtp_packet.Clear();
- RTC_CHECK(packetizer.NextPacket(&rtp_packet));
- RTC_CHECK_LE(rtp_packet.payload_size(),
- limits.max_payload_len - limits.last_packet_reduction_len);
-}
-} // namespace webrtc
+/* + * Copyright (c) 2024 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. + */ +#include <stddef.h> +#include <stdint.h> + +#include "api/video/video_frame_type.h" +#include "modules/rtp_rtcp/source/rtp_format.h" +#include "modules/rtp_rtcp/source/rtp_format_h264.h" +#include "modules/rtp_rtcp/source/rtp_packet_to_send.h" +#include "rtc_base/checks.h" +#include "test/fuzzers/fuzz_data_helper.h" + +namespace webrtc { +void FuzzOneInput(const uint8_t* data, size_t size) { + test::FuzzDataHelper fuzz_input(rtc::MakeArrayView(data, size)); + + RtpPacketizer::PayloadSizeLimits limits; + limits.max_payload_len = 1200; + // Read uint8_t to be sure reduction_lens are much smaller than + // max_payload_len and thus limits structure is valid. + limits.first_packet_reduction_len = fuzz_input.ReadOrDefaultValue<uint8_t>(0); + limits.last_packet_reduction_len = fuzz_input.ReadOrDefaultValue<uint8_t>(0); + limits.single_packet_reduction_len = + fuzz_input.ReadOrDefaultValue<uint8_t>(0); + const H264PacketizationMode kPacketizationModes[] = { + H264PacketizationMode::NonInterleaved, + H264PacketizationMode::SingleNalUnit}; + + H264PacketizationMode packetization_mode = + fuzz_input.SelectOneOf(kPacketizationModes); + + // Main function under test: RtpPacketizerH264's constructor. + RtpPacketizerH264 packetizer(fuzz_input.ReadByteArray(fuzz_input.BytesLeft()), + limits, packetization_mode); + + size_t num_packets = packetizer.NumPackets(); + if (num_packets == 0) { + return; + } + // When packetization was successful, validate NextPacket function too. + // While at it, check that packets respect the payload size limits. + RtpPacketToSend rtp_packet(nullptr); + // Single packet. + if (num_packets == 1) { + RTC_CHECK(packetizer.NextPacket(&rtp_packet)); + RTC_CHECK_LE(rtp_packet.payload_size(), + limits.max_payload_len - limits.single_packet_reduction_len); + return; + } + // First packet. + RTC_CHECK(packetizer.NextPacket(&rtp_packet)); + RTC_CHECK_LE(rtp_packet.payload_size(), + limits.max_payload_len - limits.first_packet_reduction_len); + // Middle packets. + for (size_t i = 1; i < num_packets - 1; ++i) { + rtp_packet.Clear(); + RTC_CHECK(packetizer.NextPacket(&rtp_packet)) + << "Failed to get packet#" << i; + RTC_CHECK_LE(rtp_packet.payload_size(), limits.max_payload_len) + << "Packet #" << i << " exceeds it's limit"; + } + // Last packet. + rtp_packet.Clear(); + RTC_CHECK(packetizer.NextPacket(&rtp_packet)); + RTC_CHECK_LE(rtp_packet.payload_size(), + limits.max_payload_len - limits.last_packet_reduction_len); +} +} // namespace webrtc diff --git a/third_party/libwebrtc/test/fuzzers/rtp_format_vp8_fuzzer.cc b/third_party/libwebrtc/test/fuzzers/rtp_format_vp8_fuzzer.cc index c3c055de0f..93706e9253 100644 --- a/third_party/libwebrtc/test/fuzzers/rtp_format_vp8_fuzzer.cc +++ b/third_party/libwebrtc/test/fuzzers/rtp_format_vp8_fuzzer.cc @@ -1,73 +1,73 @@ -/*
- * Copyright (c) 2024 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.
- */
-#include <stddef.h>
-#include <stdint.h>
-
-#include "api/video/video_frame_type.h"
-#include "modules/rtp_rtcp/source/rtp_format.h"
-#include "modules/rtp_rtcp/source/rtp_format_vp8.h"
-#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
-#include "rtc_base/checks.h"
-#include "test/fuzzers/fuzz_data_helper.h"
-
-namespace webrtc {
-void FuzzOneInput(const uint8_t* data, size_t size) {
- test::FuzzDataHelper fuzz_input(rtc::MakeArrayView(data, size));
-
- RtpPacketizer::PayloadSizeLimits limits;
- limits.max_payload_len = 1200;
- // Read uint8_t to be sure reduction_lens are much smaller than
- // max_payload_len and thus limits structure is valid.
- limits.first_packet_reduction_len = fuzz_input.ReadOrDefaultValue<uint8_t>(0);
- limits.last_packet_reduction_len = fuzz_input.ReadOrDefaultValue<uint8_t>(0);
- limits.single_packet_reduction_len =
- fuzz_input.ReadOrDefaultValue<uint8_t>(0);
-
- RTPVideoHeaderVP8 hdr_info;
- hdr_info.InitRTPVideoHeaderVP8();
- uint16_t picture_id = fuzz_input.ReadOrDefaultValue<uint16_t>(0);
- hdr_info.pictureId =
- picture_id >= 0x8000 ? kNoPictureId : picture_id & 0x7fff;
-
- // Main function under test: RtpPacketizerVp8's constructor.
- RtpPacketizerVp8 packetizer(fuzz_input.ReadByteArray(fuzz_input.BytesLeft()),
- limits, hdr_info);
-
- size_t num_packets = packetizer.NumPackets();
- if (num_packets == 0) {
- return;
- }
- // When packetization was successful, validate NextPacket function too.
- // While at it, check that packets respect the payload size limits.
- RtpPacketToSend rtp_packet(nullptr);
- // Single packet.
- if (num_packets == 1) {
- RTC_CHECK(packetizer.NextPacket(&rtp_packet));
- RTC_CHECK_LE(rtp_packet.payload_size(),
- limits.max_payload_len - limits.single_packet_reduction_len);
- return;
- }
- // First packet.
- RTC_CHECK(packetizer.NextPacket(&rtp_packet));
- RTC_CHECK_LE(rtp_packet.payload_size(),
- limits.max_payload_len - limits.first_packet_reduction_len);
- // Middle packets.
- for (size_t i = 1; i < num_packets - 1; ++i) {
- RTC_CHECK(packetizer.NextPacket(&rtp_packet))
- << "Failed to get packet#" << i;
- RTC_CHECK_LE(rtp_packet.payload_size(), limits.max_payload_len)
- << "Packet #" << i << " exceeds it's limit";
- }
- // Last packet.
- RTC_CHECK(packetizer.NextPacket(&rtp_packet));
- RTC_CHECK_LE(rtp_packet.payload_size(),
- limits.max_payload_len - limits.last_packet_reduction_len);
-}
-} // namespace webrtc
+/* + * Copyright (c) 2024 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. + */ +#include <stddef.h> +#include <stdint.h> + +#include "api/video/video_frame_type.h" +#include "modules/rtp_rtcp/source/rtp_format.h" +#include "modules/rtp_rtcp/source/rtp_format_vp8.h" +#include "modules/rtp_rtcp/source/rtp_packet_to_send.h" +#include "rtc_base/checks.h" +#include "test/fuzzers/fuzz_data_helper.h" + +namespace webrtc { +void FuzzOneInput(const uint8_t* data, size_t size) { + test::FuzzDataHelper fuzz_input(rtc::MakeArrayView(data, size)); + + RtpPacketizer::PayloadSizeLimits limits; + limits.max_payload_len = 1200; + // Read uint8_t to be sure reduction_lens are much smaller than + // max_payload_len and thus limits structure is valid. + limits.first_packet_reduction_len = fuzz_input.ReadOrDefaultValue<uint8_t>(0); + limits.last_packet_reduction_len = fuzz_input.ReadOrDefaultValue<uint8_t>(0); + limits.single_packet_reduction_len = + fuzz_input.ReadOrDefaultValue<uint8_t>(0); + + RTPVideoHeaderVP8 hdr_info; + hdr_info.InitRTPVideoHeaderVP8(); + uint16_t picture_id = fuzz_input.ReadOrDefaultValue<uint16_t>(0); + hdr_info.pictureId = + picture_id >= 0x8000 ? kNoPictureId : picture_id & 0x7fff; + + // Main function under test: RtpPacketizerVp8's constructor. + RtpPacketizerVp8 packetizer(fuzz_input.ReadByteArray(fuzz_input.BytesLeft()), + limits, hdr_info); + + size_t num_packets = packetizer.NumPackets(); + if (num_packets == 0) { + return; + } + // When packetization was successful, validate NextPacket function too. + // While at it, check that packets respect the payload size limits. + RtpPacketToSend rtp_packet(nullptr); + // Single packet. + if (num_packets == 1) { + RTC_CHECK(packetizer.NextPacket(&rtp_packet)); + RTC_CHECK_LE(rtp_packet.payload_size(), + limits.max_payload_len - limits.single_packet_reduction_len); + return; + } + // First packet. + RTC_CHECK(packetizer.NextPacket(&rtp_packet)); + RTC_CHECK_LE(rtp_packet.payload_size(), + limits.max_payload_len - limits.first_packet_reduction_len); + // Middle packets. + for (size_t i = 1; i < num_packets - 1; ++i) { + RTC_CHECK(packetizer.NextPacket(&rtp_packet)) + << "Failed to get packet#" << i; + RTC_CHECK_LE(rtp_packet.payload_size(), limits.max_payload_len) + << "Packet #" << i << " exceeds it's limit"; + } + // Last packet. + RTC_CHECK(packetizer.NextPacket(&rtp_packet)); + RTC_CHECK_LE(rtp_packet.payload_size(), + limits.max_payload_len - limits.last_packet_reduction_len); +} +} // namespace webrtc diff --git a/third_party/libwebrtc/test/fuzzers/rtp_format_vp9_fuzzer.cc b/third_party/libwebrtc/test/fuzzers/rtp_format_vp9_fuzzer.cc index 3b5e67f697..d95114eaef 100644 --- a/third_party/libwebrtc/test/fuzzers/rtp_format_vp9_fuzzer.cc +++ b/third_party/libwebrtc/test/fuzzers/rtp_format_vp9_fuzzer.cc @@ -1,73 +1,73 @@ -/*
- * Copyright (c) 2024 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.
- */
-#include <stddef.h>
-#include <stdint.h>
-
-#include "api/video/video_frame_type.h"
-#include "modules/rtp_rtcp/source/rtp_format.h"
-#include "modules/rtp_rtcp/source/rtp_format_vp9.h"
-#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
-#include "rtc_base/checks.h"
-#include "test/fuzzers/fuzz_data_helper.h"
-
-namespace webrtc {
-void FuzzOneInput(const uint8_t* data, size_t size) {
- test::FuzzDataHelper fuzz_input(rtc::MakeArrayView(data, size));
-
- RtpPacketizer::PayloadSizeLimits limits;
- limits.max_payload_len = 1200;
- // Read uint8_t to be sure reduction_lens are much smaller than
- // max_payload_len and thus limits structure is valid.
- limits.first_packet_reduction_len = fuzz_input.ReadOrDefaultValue<uint8_t>(0);
- limits.last_packet_reduction_len = fuzz_input.ReadOrDefaultValue<uint8_t>(0);
- limits.single_packet_reduction_len =
- fuzz_input.ReadOrDefaultValue<uint8_t>(0);
-
- RTPVideoHeaderVP9 hdr_info;
- hdr_info.InitRTPVideoHeaderVP9();
- uint16_t picture_id = fuzz_input.ReadOrDefaultValue<uint16_t>(0);
- hdr_info.picture_id =
- picture_id >= 0x8000 ? kNoPictureId : picture_id & 0x7fff;
-
- // Main function under test: RtpPacketizerVp9's constructor.
- RtpPacketizerVp9 packetizer(fuzz_input.ReadByteArray(fuzz_input.BytesLeft()),
- limits, hdr_info);
-
- size_t num_packets = packetizer.NumPackets();
- if (num_packets == 0) {
- return;
- }
- // When packetization was successful, validate NextPacket function too.
- // While at it, check that packets respect the payload size limits.
- RtpPacketToSend rtp_packet(nullptr);
- // Single packet.
- if (num_packets == 1) {
- RTC_CHECK(packetizer.NextPacket(&rtp_packet));
- RTC_CHECK_LE(rtp_packet.payload_size(),
- limits.max_payload_len - limits.single_packet_reduction_len);
- return;
- }
- // First packet.
- RTC_CHECK(packetizer.NextPacket(&rtp_packet));
- RTC_CHECK_LE(rtp_packet.payload_size(),
- limits.max_payload_len - limits.first_packet_reduction_len);
- // Middle packets.
- for (size_t i = 1; i < num_packets - 1; ++i) {
- RTC_CHECK(packetizer.NextPacket(&rtp_packet))
- << "Failed to get packet#" << i;
- RTC_CHECK_LE(rtp_packet.payload_size(), limits.max_payload_len)
- << "Packet #" << i << " exceeds it's limit";
- }
- // Last packet.
- RTC_CHECK(packetizer.NextPacket(&rtp_packet));
- RTC_CHECK_LE(rtp_packet.payload_size(),
- limits.max_payload_len - limits.last_packet_reduction_len);
-}
-} // namespace webrtc
+/* + * Copyright (c) 2024 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. + */ +#include <stddef.h> +#include <stdint.h> + +#include "api/video/video_frame_type.h" +#include "modules/rtp_rtcp/source/rtp_format.h" +#include "modules/rtp_rtcp/source/rtp_format_vp9.h" +#include "modules/rtp_rtcp/source/rtp_packet_to_send.h" +#include "rtc_base/checks.h" +#include "test/fuzzers/fuzz_data_helper.h" + +namespace webrtc { +void FuzzOneInput(const uint8_t* data, size_t size) { + test::FuzzDataHelper fuzz_input(rtc::MakeArrayView(data, size)); + + RtpPacketizer::PayloadSizeLimits limits; + limits.max_payload_len = 1200; + // Read uint8_t to be sure reduction_lens are much smaller than + // max_payload_len and thus limits structure is valid. + limits.first_packet_reduction_len = fuzz_input.ReadOrDefaultValue<uint8_t>(0); + limits.last_packet_reduction_len = fuzz_input.ReadOrDefaultValue<uint8_t>(0); + limits.single_packet_reduction_len = + fuzz_input.ReadOrDefaultValue<uint8_t>(0); + + RTPVideoHeaderVP9 hdr_info; + hdr_info.InitRTPVideoHeaderVP9(); + uint16_t picture_id = fuzz_input.ReadOrDefaultValue<uint16_t>(0); + hdr_info.picture_id = + picture_id >= 0x8000 ? kNoPictureId : picture_id & 0x7fff; + + // Main function under test: RtpPacketizerVp9's constructor. + RtpPacketizerVp9 packetizer(fuzz_input.ReadByteArray(fuzz_input.BytesLeft()), + limits, hdr_info); + + size_t num_packets = packetizer.NumPackets(); + if (num_packets == 0) { + return; + } + // When packetization was successful, validate NextPacket function too. + // While at it, check that packets respect the payload size limits. + RtpPacketToSend rtp_packet(nullptr); + // Single packet. + if (num_packets == 1) { + RTC_CHECK(packetizer.NextPacket(&rtp_packet)); + RTC_CHECK_LE(rtp_packet.payload_size(), + limits.max_payload_len - limits.single_packet_reduction_len); + return; + } + // First packet. + RTC_CHECK(packetizer.NextPacket(&rtp_packet)); + RTC_CHECK_LE(rtp_packet.payload_size(), + limits.max_payload_len - limits.first_packet_reduction_len); + // Middle packets. + for (size_t i = 1; i < num_packets - 1; ++i) { + RTC_CHECK(packetizer.NextPacket(&rtp_packet)) + << "Failed to get packet#" << i; + RTC_CHECK_LE(rtp_packet.payload_size(), limits.max_payload_len) + << "Packet #" << i << " exceeds it's limit"; + } + // Last packet. + RTC_CHECK(packetizer.NextPacket(&rtp_packet)); + RTC_CHECK_LE(rtp_packet.payload_size(), + limits.max_payload_len - limits.last_packet_reduction_len); +} +} // namespace webrtc diff --git a/third_party/libwebrtc/test/mock_audio_encoder.h b/third_party/libwebrtc/test/mock_audio_encoder.h index 1f4510e885..30518e8f49 100644 --- a/third_party/libwebrtc/test/mock_audio_encoder.h +++ b/third_party/libwebrtc/test/mock_audio_encoder.h @@ -33,6 +33,10 @@ class MockAudioEncoder : public AudioEncoder { GetFrameLengthRange, (), (const, override)); + MOCK_METHOD((absl::optional<std::pair<DataRate, DataRate>>), + GetBitrateRange, + (), + (const, override)); MOCK_METHOD(void, Reset, (), (override)); MOCK_METHOD(bool, SetFec, (bool enable), (override)); diff --git a/third_party/libwebrtc/test/mock_transformable_frame.h b/third_party/libwebrtc/test/mock_transformable_frame.h deleted file mode 100644 index 26eb6b7030..0000000000 --- a/third_party/libwebrtc/test/mock_transformable_frame.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef TEST_MOCK_TRANSFORMABLE_FRAME_H_ -#define TEST_MOCK_TRANSFORMABLE_FRAME_H_ - -#include "api/frame_transformer_interface.h" -#include "test/gmock.h" - -namespace webrtc { - -class MockTransformableAudioFrame : public TransformableAudioFrameInterface { - public: - MOCK_METHOD(rtc::ArrayView<const uint8_t>, GetData, (), (const, override)); - MOCK_METHOD(rtc::ArrayView<const uint32_t>, - GetContributingSources, - (), - (const, override)); - MOCK_METHOD(absl::optional<uint64_t>, - AbsoluteCaptureTimestamp, - (), - (const, override)); - MOCK_METHOD(void, SetData, (rtc::ArrayView<const uint8_t>), (override)); - MOCK_METHOD(uint8_t, GetPayloadType, (), (const, override)); - MOCK_METHOD(uint32_t, GetSsrc, (), (const, override)); - MOCK_METHOD(uint32_t, GetTimestamp, (), (const, override)); - MOCK_METHOD(void, SetRTPTimestamp, (uint32_t), (override)); - MOCK_METHOD(Direction, GetDirection, (), (const, override)); - MOCK_METHOD(std::string, GetMimeType, (), (const, override)); -}; - -} // namespace webrtc - -#endif // TEST_MOCK_TRANSFORMABLE_FRAME_H_ diff --git a/third_party/libwebrtc/test/network/BUILD.gn b/third_party/libwebrtc/test/network/BUILD.gn index 6df563d31d..e9bd263ed9 100644 --- a/third_party/libwebrtc/test/network/BUILD.gn +++ b/third_party/libwebrtc/test/network/BUILD.gn @@ -56,6 +56,7 @@ rtc_library("emulated_network") { "../../api/units:time_delta", "../../api/units:timestamp", "../../call:simulated_network", + "../../p2p:basic_packet_socket_factory", "../../p2p:p2p_server_utils", "../../p2p:rtc_p2p", "../../rtc_base:async_packet_socket", @@ -128,6 +129,8 @@ if (rtc_include_tests && !build_with_chromium) { "../../call:simulated_network", "../../media:rtc_audio_video", "../../modules/audio_device:test_audio_device_module", + "../../p2p:basic_packet_socket_factory", + "../../p2p:basic_port_allocator", "../../p2p:rtc_p2p", "../../pc:pc_test_utils", "../../pc:peerconnection_wrapper", diff --git a/third_party/libwebrtc/test/pc/e2e/BUILD.gn b/third_party/libwebrtc/test/pc/e2e/BUILD.gn index 0eb7aa2c68..22c9ee48d2 100644 --- a/third_party/libwebrtc/test/pc/e2e/BUILD.gn +++ b/third_party/libwebrtc/test/pc/e2e/BUILD.gn @@ -109,6 +109,7 @@ if (!build_with_chromium) { "../../../api/video_codecs:builtin_video_encoder_factory", "../../../modules/audio_device:test_audio_device_module", "../../../modules/audio_processing/aec_dump", + "../../../p2p:basic_port_allocator", "../../../p2p:rtc_p2p", "../../../rtc_base:threading", "analyzer/video:quality_analyzing_video_encoder", @@ -576,6 +577,7 @@ if (!build_with_chromium) { "../../../media:media_constants", "../../../media:rid_description", "../../../media:rtc_media_base", + "../../../p2p:p2p_constants", "../../../p2p:rtc_p2p", "../../../pc:sdp_utils", "../../../pc:session_description", diff --git a/third_party/libwebrtc/test/pc/e2e/analyzer/video/BUILD.gn b/third_party/libwebrtc/test/pc/e2e/analyzer/video/BUILD.gn index 17876e54be..6adfc50049 100644 --- a/third_party/libwebrtc/test/pc/e2e/analyzer/video/BUILD.gn +++ b/third_party/libwebrtc/test/pc/e2e/analyzer/video/BUILD.gn @@ -130,6 +130,7 @@ rtc_library("quality_analyzing_video_decoder") { ":encoded_image_data_injector_api", ":simulcast_dummy_buffer_helper", "../../../../../api:video_quality_analyzer_api", + "../../../../../api/environment", "../../../../../api/video:encoded_image", "../../../../../api/video:video_frame", "../../../../../api/video_codecs:video_codecs_api", diff --git a/third_party/libwebrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc b/third_party/libwebrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc index e17b5d5d83..3cd179370f 100644 --- a/third_party/libwebrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc +++ b/third_party/libwebrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc @@ -259,10 +259,10 @@ QualityAnalyzingVideoDecoderFactory::GetSupportedFormats() const { return delegate_->GetSupportedFormats(); } -std::unique_ptr<VideoDecoder> -QualityAnalyzingVideoDecoderFactory::CreateVideoDecoder( +std::unique_ptr<VideoDecoder> QualityAnalyzingVideoDecoderFactory::Create( + const Environment& env, const SdpVideoFormat& format) { - std::unique_ptr<VideoDecoder> decoder = delegate_->CreateVideoDecoder(format); + std::unique_ptr<VideoDecoder> decoder = delegate_->Create(env, format); return std::make_unique<QualityAnalyzingVideoDecoder>( peer_name_, std::move(decoder), extractor_, analyzer_); } diff --git a/third_party/libwebrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h b/third_party/libwebrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h index 2f0c2b9d5d..daa919d7e4 100644 --- a/third_party/libwebrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h +++ b/third_party/libwebrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h @@ -18,6 +18,7 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" +#include "api/environment/environment.h" #include "api/test/video_quality_analyzer_interface.h" #include "api/video/encoded_image.h" #include "api/video/video_frame.h" @@ -136,8 +137,8 @@ class QualityAnalyzingVideoDecoderFactory : public VideoDecoderFactory { // Methods of VideoDecoderFactory interface. std::vector<SdpVideoFormat> GetSupportedFormats() const override; - std::unique_ptr<VideoDecoder> CreateVideoDecoder( - const SdpVideoFormat& format) override; + std::unique_ptr<VideoDecoder> Create(const Environment& env, + const SdpVideoFormat& format) override; private: const std::string peer_name_; diff --git a/third_party/libwebrtc/test/pc/e2e/network_quality_metrics_reporter.cc b/third_party/libwebrtc/test/pc/e2e/network_quality_metrics_reporter.cc index 257fecf309..3c4f6cabe1 100644 --- a/third_party/libwebrtc/test/pc/e2e/network_quality_metrics_reporter.cc +++ b/third_party/libwebrtc/test/pc/e2e/network_quality_metrics_reporter.cc @@ -27,11 +27,6 @@ using ::webrtc::test::Unit; constexpr TimeDelta kStatsWaitTimeout = TimeDelta::Seconds(1); -// Field trial which controls whether to report standard-compliant bytes -// sent/received per stream. If enabled, padding and headers are not included -// in bytes sent or received. -constexpr char kUseStandardBytesStats[] = "WebRTC-UseStandardBytesStats"; - } // namespace NetworkQualityMetricsReporter::NetworkQualityMetricsReporter( @@ -107,11 +102,6 @@ void NetworkQualityMetricsReporter::StopAndReportResults() { ReportStats(alice_network_label_, alice_stats, alice_packets_loss); ReportStats(bob_network_label_, bob_stats, bob_packets_loss); - if (!webrtc::field_trial::IsEnabled(kUseStandardBytesStats)) { - RTC_LOG(LS_ERROR) - << "Non-standard GetStats; \"payload\" counts include RTP headers"; - } - MutexLock lock(&lock_); for (const auto& pair : pc_stats_) { ReportPCStats(pair.first, pair.second); diff --git a/third_party/libwebrtc/test/pc/e2e/network_quality_metrics_reporter.h b/third_party/libwebrtc/test/pc/e2e/network_quality_metrics_reporter.h index 1348a58943..fd523cc48d 100644 --- a/third_party/libwebrtc/test/pc/e2e/network_quality_metrics_reporter.h +++ b/third_party/libwebrtc/test/pc/e2e/network_quality_metrics_reporter.h @@ -48,8 +48,6 @@ class NetworkQualityMetricsReporter private: struct PCStats { - // TODO(nisse): Separate audio and video counters. Depends on standard stat - // counters, enabled by field trial "WebRTC-UseStandardBytesStats". DataSize payload_received = DataSize::Zero(); DataSize payload_sent = DataSize::Zero(); }; diff --git a/third_party/libwebrtc/test/pc/e2e/peer_connection_quality_test.cc b/third_party/libwebrtc/test/pc/e2e/peer_connection_quality_test.cc index 90f201facd..3a6b808167 100644 --- a/third_party/libwebrtc/test/pc/e2e/peer_connection_quality_test.cc +++ b/third_party/libwebrtc/test/pc/e2e/peer_connection_quality_test.cc @@ -73,8 +73,6 @@ constexpr TimeDelta kQuickTestModeRunDuration = TimeDelta::Millis(100); // Field trials to enable Flex FEC advertising and receiving. constexpr char kFlexFecEnabledFieldTrials[] = "WebRTC-FlexFEC-03-Advertised/Enabled/WebRTC-FlexFEC-03/Enabled/"; -constexpr char kUseStandardsBytesStats[] = - "WebRTC-UseStandardBytesStats/Enabled/"; class FixturePeerConnectionObserver : public MockPeerConnectionObserver { public: @@ -439,8 +437,7 @@ void PeerConnectionE2EQualityTest::Run(RunParams run_params) { std::string PeerConnectionE2EQualityTest::GetFieldTrials( const RunParams& run_params) { - std::vector<absl::string_view> default_field_trials = { - kUseStandardsBytesStats}; + std::vector<absl::string_view> default_field_trials = {}; if (run_params.enable_flex_fec_support) { default_field_trials.push_back(kFlexFecEnabledFieldTrials); } diff --git a/third_party/libwebrtc/test/pc/e2e/stats_based_network_quality_metrics_reporter.cc b/third_party/libwebrtc/test/pc/e2e/stats_based_network_quality_metrics_reporter.cc index b965a7acd8..706224ce08 100644 --- a/third_party/libwebrtc/test/pc/e2e/stats_based_network_quality_metrics_reporter.cc +++ b/third_party/libwebrtc/test/pc/e2e/stats_based_network_quality_metrics_reporter.cc @@ -51,11 +51,6 @@ using NetworkLayerStats = constexpr TimeDelta kStatsWaitTimeout = TimeDelta::Seconds(1); -// Field trial which controls whether to report standard-compliant bytes -// sent/received per stream. If enabled, padding and headers are not included -// in bytes sent or received. -constexpr char kUseStandardBytesStats[] = "WebRTC-UseStandardBytesStats"; - EmulatedNetworkStats PopulateStats(std::vector<EmulatedEndpoint*> endpoints, NetworkEmulationManager* network_emulation) { rtc::Event stats_loaded; @@ -325,11 +320,6 @@ void StatsBasedNetworkQualityMetricsReporter::OnStatsReports( void StatsBasedNetworkQualityMetricsReporter::StopAndReportResults() { Timestamp end_time = clock_->CurrentTime(); - if (!webrtc::field_trial::IsEnabled(kUseStandardBytesStats)) { - RTC_LOG(LS_ERROR) - << "Non-standard GetStats; \"payload\" counts include RTP headers"; - } - std::map<std::string, NetworkLayerStats> stats = collector_.GetStats(); for (const auto& entry : stats) { LogNetworkLayerStats(entry.first, entry.second); diff --git a/third_party/libwebrtc/test/pc/e2e/stats_based_network_quality_metrics_reporter.h b/third_party/libwebrtc/test/pc/e2e/stats_based_network_quality_metrics_reporter.h index 60daf40c8c..ba6bf04e18 100644 --- a/third_party/libwebrtc/test/pc/e2e/stats_based_network_quality_metrics_reporter.h +++ b/third_party/libwebrtc/test/pc/e2e/stats_based_network_quality_metrics_reporter.h @@ -70,9 +70,6 @@ class StatsBasedNetworkQualityMetricsReporter private: struct PCStats { - // TODO(bugs.webrtc.org/10525): Separate audio and video counters. Depends - // on standard stat counters, enabled by field trial - // "WebRTC-UseStandardBytesStats". DataSize payload_received = DataSize::Zero(); DataSize payload_sent = DataSize::Zero(); diff --git a/third_party/libwebrtc/test/peer_scenario/BUILD.gn b/third_party/libwebrtc/test/peer_scenario/BUILD.gn index 18f81a56e6..e1d164a47d 100644 --- a/third_party/libwebrtc/test/peer_scenario/BUILD.gn +++ b/third_party/libwebrtc/test/peer_scenario/BUILD.gn @@ -53,7 +53,9 @@ if (rtc_include_tests) { "../../media:rtp_utils", "../../modules/audio_device:test_audio_device_module", "../../modules/rtp_rtcp:rtp_rtcp_format", + "../../p2p:basic_port_allocator", "../../p2p:rtc_p2p", + "../../p2p:transport_description", "../../pc:channel", "../../pc:jsep_transport_controller", "../../pc:pc_test_utils", diff --git a/third_party/libwebrtc/test/peer_scenario/peer_scenario_client.cc b/third_party/libwebrtc/test/peer_scenario/peer_scenario_client.cc index 1397b32fe3..3ba4fdb677 100644 --- a/third_party/libwebrtc/test/peer_scenario/peer_scenario_client.cc +++ b/third_party/libwebrtc/test/peer_scenario/peer_scenario_client.cc @@ -370,10 +370,13 @@ void PeerScenarioClient::CreateAndSetSdp( void PeerScenarioClient::SetSdpOfferAndGetAnswer( std::string remote_offer, + std::function<void()> remote_description_set, std::function<void(std::string)> answer_handler) { if (!signaling_thread_->IsCurrent()) { - signaling_thread_->PostTask( - [=] { SetSdpOfferAndGetAnswer(remote_offer, answer_handler); }); + signaling_thread_->PostTask([=] { + SetSdpOfferAndGetAnswer(remote_offer, remote_description_set, + answer_handler); + }); return; } RTC_DCHECK_RUN_ON(signaling_thread_); @@ -381,6 +384,11 @@ void PeerScenarioClient::SetSdpOfferAndGetAnswer( CreateSessionDescription(SdpType::kOffer, remote_offer), rtc::make_ref_counted<LambdaSetRemoteDescriptionObserver>([=](RTCError) { RTC_DCHECK_RUN_ON(signaling_thread_); + if (remote_description_set) { + // Allow the caller to modify transceivers + // before creating the answer. + remote_description_set(); + } peer_connection_->CreateAnswer( rtc::make_ref_counted<LambdaCreateSessionDescriptionObserver>( [=](std::unique_ptr<SessionDescriptionInterface> answer) { diff --git a/third_party/libwebrtc/test/peer_scenario/peer_scenario_client.h b/third_party/libwebrtc/test/peer_scenario/peer_scenario_client.h index e863757759..cb025e9879 100644 --- a/third_party/libwebrtc/test/peer_scenario/peer_scenario_client.h +++ b/third_party/libwebrtc/test/peer_scenario/peer_scenario_client.h @@ -147,6 +147,7 @@ class PeerScenarioClient { std::function<void(SessionDescriptionInterface*)> munge_offer, std::function<void(std::string)> offer_handler); void SetSdpOfferAndGetAnswer(std::string remote_offer, + std::function<void()> remote_description_set, std::function<void(std::string)> answer_handler); void SetSdpAnswer( std::string remote_answer, diff --git a/third_party/libwebrtc/test/peer_scenario/signaling_route.cc b/third_party/libwebrtc/test/peer_scenario/signaling_route.cc index eeec7c8657..8688c1abd8 100644 --- a/third_party/libwebrtc/test/peer_scenario/signaling_route.cc +++ b/third_party/libwebrtc/test/peer_scenario/signaling_route.cc @@ -59,6 +59,7 @@ void StartSdpNegotiation( CrossTrafficRoute* ret_route, std::function<void(SessionDescriptionInterface* offer)> munge_offer, std::function<void(SessionDescriptionInterface*)> modify_offer, + std::function<void()> callee_remote_description_set, std::function<void(const SessionDescriptionInterface&)> exchange_finished) { caller->CreateAndSetSdp(munge_offer, [=](std::string sdp_offer) { if (modify_offer) { @@ -67,11 +68,14 @@ void StartSdpNegotiation( RTC_CHECK(offer->ToString(&sdp_offer)); } send_route->NetworkDelayedAction(kSdpPacketSize, [=] { - callee->SetSdpOfferAndGetAnswer(sdp_offer, [=](std::string answer) { - ret_route->NetworkDelayedAction(kSdpPacketSize, [=] { - caller->SetSdpAnswer(std::move(answer), std::move(exchange_finished)); - }); - }); + callee->SetSdpOfferAndGetAnswer( + sdp_offer, std::move(callee_remote_description_set), + [=](std::string answer) { + ret_route->NetworkDelayedAction(kSdpPacketSize, [=] { + caller->SetSdpAnswer(std::move(answer), + std::move(exchange_finished)); + }); + }); }); }); } @@ -92,22 +96,39 @@ void SignalingRoute::StartIceSignaling() { } void SignalingRoute::NegotiateSdp( + std::function<void(SessionDescriptionInterface* offer)> munge_offer, + std::function<void(SessionDescriptionInterface* offer)> modify_offer, + std::function<void()> callee_remote_description_set, + std::function<void(const SessionDescriptionInterface& answer)> + exchange_finished) { + StartSdpNegotiation(caller_, callee_, send_route_, ret_route_, munge_offer, + modify_offer, callee_remote_description_set, + exchange_finished); +} + +void SignalingRoute::NegotiateSdp( std::function<void(SessionDescriptionInterface*)> munge_offer, std::function<void(SessionDescriptionInterface*)> modify_offer, std::function<void(const SessionDescriptionInterface&)> exchange_finished) { - StartSdpNegotiation(caller_, callee_, send_route_, ret_route_, munge_offer, - modify_offer, exchange_finished); + NegotiateSdp(munge_offer, modify_offer, {}, exchange_finished); } void SignalingRoute::NegotiateSdp( std::function<void(SessionDescriptionInterface*)> modify_offer, std::function<void(const SessionDescriptionInterface&)> exchange_finished) { - NegotiateSdp({}, modify_offer, exchange_finished); + NegotiateSdp({}, modify_offer, {}, exchange_finished); +} + +void SignalingRoute::NegotiateSdp( + std::function<void()> remote_description_set, + std::function<void(const SessionDescriptionInterface& answer)> + exchange_finished) { + NegotiateSdp({}, {}, remote_description_set, exchange_finished); } void SignalingRoute::NegotiateSdp( std::function<void(const SessionDescriptionInterface&)> exchange_finished) { - NegotiateSdp({}, {}, exchange_finished); + NegotiateSdp({}, {}, {}, exchange_finished); } } // namespace test diff --git a/third_party/libwebrtc/test/peer_scenario/signaling_route.h b/third_party/libwebrtc/test/peer_scenario/signaling_route.h index a95ae5c9f7..9b317d2552 100644 --- a/third_party/libwebrtc/test/peer_scenario/signaling_route.h +++ b/third_party/libwebrtc/test/peer_scenario/signaling_route.h @@ -35,12 +35,21 @@ class SignalingRoute { // The `munge_offer` callback is used to modify an offer between its creation // and set local description. This behavior is forbidden according to the spec // but available here in order to allow test coverage on corner cases. - // The `exchange_finished` callback is called with the answer produced after - // SDP negotations has completed. + // `callee_remote_description_set` is invoked when callee has applied the + // offer but not yet created an answer. The purpose is to allow tests to + // modify transceivers created from the offer. The `exchange_finished` + // callback is called with the answer produced after SDP negotations has + // completed. // TODO(srte): Handle lossy links. void NegotiateSdp( std::function<void(SessionDescriptionInterface* offer)> munge_offer, std::function<void(SessionDescriptionInterface* offer)> modify_offer, + std::function<void()> callee_remote_description_set, + std::function<void(const SessionDescriptionInterface& answer)> + exchange_finished); + void NegotiateSdp( + std::function<void(SessionDescriptionInterface* offer)> munge_offer, + std::function<void(SessionDescriptionInterface* offer)> modify_offer, std::function<void(const SessionDescriptionInterface& answer)> exchange_finished); void NegotiateSdp( @@ -48,6 +57,10 @@ class SignalingRoute { std::function<void(const SessionDescriptionInterface& answer)> exchange_finished); void NegotiateSdp( + std::function<void()> remote_description_set, + std::function<void(const SessionDescriptionInterface& answer)> + exchange_finished); + void NegotiateSdp( std::function<void(const SessionDescriptionInterface& answer)> exchange_finished); SignalingRoute reverse() { diff --git a/third_party/libwebrtc/test/peer_scenario/tests/bwe_ramp_up_test.cc b/third_party/libwebrtc/test/peer_scenario/tests/bwe_ramp_up_test.cc index a7a17bbfd1..f8eaa47858 100644 --- a/third_party/libwebrtc/test/peer_scenario/tests/bwe_ramp_up_test.cc +++ b/third_party/libwebrtc/test/peer_scenario/tests/bwe_ramp_up_test.cc @@ -25,6 +25,9 @@ namespace webrtc { namespace test { using ::testing::SizeIs; +using ::testing::Test; +using ::testing::ValuesIn; +using ::testing::WithParamInterface; rtc::scoped_refptr<const RTCStatsReport> GetStatsAndProcess( PeerScenario& s, @@ -124,5 +127,152 @@ TEST(BweRampupTest, RampUpWithUndemuxableRtpPackets) { // ensure BWE has increased beyond noise levels. EXPECT_GT(final_bwe, initial_bwe + DataRate::KilobitsPerSec(345)); } + +struct InitialProbeTestParams { + DataRate network_capacity; + DataRate expected_bwe_min; +}; +class BweRampupWithInitialProbeTest + : public Test, + public WithParamInterface<InitialProbeTestParams> {}; + +INSTANTIATE_TEST_SUITE_P( + BweRampupWithInitialProbeTest, + BweRampupWithInitialProbeTest, + ValuesIn<InitialProbeTestParams>( + {{ + .network_capacity = DataRate::KilobitsPerSec(3000), + .expected_bwe_min = DataRate::KilobitsPerSec(2500), + }, + { + .network_capacity = webrtc::DataRate::KilobitsPerSec(500), + .expected_bwe_min = webrtc::DataRate::KilobitsPerSec(400), + }})); + +// Test that caller and callee BWE rampup even if no media packets are sent. +// - BandWidthEstimationSettings.allow_probe_without_media must be set. +// - A Video RtpTransceiver with RTX support needs to be negotiated. +TEST_P(BweRampupWithInitialProbeTest, BweRampUpBothDirectionsWithoutMedia) { + PeerScenario s(*::testing::UnitTest::GetInstance()->current_test_info()); + InitialProbeTestParams test_params = GetParam(); + + PeerScenarioClient* caller = s.CreateClient({}); + PeerScenarioClient* callee = s.CreateClient({}); + + auto video_result = caller->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO); + ASSERT_EQ(video_result.error().type(), RTCErrorType::NONE); + + caller->pc()->ReconfigureBandwidthEstimation( + {.allow_probe_without_media = true}); + callee->pc()->ReconfigureBandwidthEstimation( + {.allow_probe_without_media = true}); + + auto node_builder = + s.net()->NodeBuilder().capacity_kbps(test_params.network_capacity.kbps()); + auto caller_node = node_builder.Build().node; + auto callee_node = node_builder.Build().node; + s.net()->CreateRoute(caller->endpoint(), {caller_node}, callee->endpoint()); + s.net()->CreateRoute(callee->endpoint(), {callee_node}, caller->endpoint()); + + auto signaling = + s.ConnectSignaling(caller, callee, {caller_node}, {callee_node}); + signaling.StartIceSignaling(); + + std::atomic<bool> offer_exchange_done(false); + signaling.NegotiateSdp( + [&]() { + // When remote description has been set, a transceiver is created. + // Set the diretion to sendrecv so that it can be used for BWE probing + // from callee -> caller. + ASSERT_THAT(callee->pc()->GetTransceivers(), SizeIs(1)); + ASSERT_TRUE( + callee->pc() + ->GetTransceivers()[0] + ->SetDirectionWithError(RtpTransceiverDirection::kSendRecv) + .ok()); + }, + [&](const SessionDescriptionInterface& answer) { + offer_exchange_done = true; + }); + // Wait for SDP negotiation. + s.WaitAndProcess(&offer_exchange_done); + + // Test that 1s after offer/answer exchange finish, we have a BWE estimate, + // even though no video frames have been sent. + s.ProcessMessages(TimeDelta::Seconds(1)); + + auto callee_inbound_stats = + GetStatsAndProcess(s, callee)->GetStatsOfType<RTCInboundRtpStreamStats>(); + ASSERT_THAT(callee_inbound_stats, SizeIs(1)); + ASSERT_EQ(*callee_inbound_stats[0]->frames_received, 0u); + auto caller_inbound_stats = + GetStatsAndProcess(s, caller)->GetStatsOfType<RTCInboundRtpStreamStats>(); + ASSERT_THAT(caller_inbound_stats, SizeIs(1)); + ASSERT_EQ(*caller_inbound_stats[0]->frames_received, 0u); + + DataRate caller_bwe = GetAvailableSendBitrate(GetStatsAndProcess(s, caller)); + EXPECT_GT(caller_bwe.kbps(), test_params.expected_bwe_min.kbps()); + EXPECT_LE(caller_bwe.kbps(), test_params.network_capacity.kbps()); + DataRate callee_bwe = GetAvailableSendBitrate(GetStatsAndProcess(s, callee)); + EXPECT_GT(callee_bwe.kbps(), test_params.expected_bwe_min.kbps()); + EXPECT_LE(callee_bwe.kbps(), test_params.network_capacity.kbps()); +} + +// Test that we can reconfigure bandwidth estimation and send new BWE probes. +// In this test, camera is stopped, and some times later, the app want to get a +// new BWE estimate. +TEST(BweRampupTest, CanReconfigureBweAfterStopingVideo) { + PeerScenario s(*::testing::UnitTest::GetInstance()->current_test_info()); + PeerScenarioClient* caller = s.CreateClient({}); + PeerScenarioClient* callee = s.CreateClient({}); + + auto node_builder = s.net()->NodeBuilder().capacity_kbps(1000); + auto caller_node = node_builder.Build().node; + auto callee_node = node_builder.Build().node; + s.net()->CreateRoute(caller->endpoint(), {caller_node}, callee->endpoint()); + s.net()->CreateRoute(callee->endpoint(), {callee_node}, caller->endpoint()); + + PeerScenarioClient::VideoSendTrack track = caller->CreateVideo("VIDEO", {}); + + auto signaling = + s.ConnectSignaling(caller, callee, {caller_node}, {callee_node}); + + signaling.StartIceSignaling(); + + std::atomic<bool> offer_exchange_done(false); + signaling.NegotiateSdp([&](const SessionDescriptionInterface& answer) { + offer_exchange_done = true; + }); + // Wait for SDP negotiation. + s.WaitAndProcess(&offer_exchange_done); + + // Send a TCP messages to the receiver using the same downlink node. + // This is done just to force a lower BWE than the link capacity. + webrtc::TcpMessageRoute* tcp_route = s.net()->CreateTcpRoute( + s.net()->CreateRoute({caller_node}), s.net()->CreateRoute({callee_node})); + DataRate bwe_before_restart = DataRate::Zero(); + + std::atomic<bool> message_delivered(false); + tcp_route->SendMessage( + /*size=*/5'00'000, + /*on_received=*/[&]() { message_delivered = true; }); + s.WaitAndProcess(&message_delivered); + bwe_before_restart = GetAvailableSendBitrate(GetStatsAndProcess(s, caller)); + + // Camera is stopped. + track.capturer->Stop(); + s.ProcessMessages(TimeDelta::Seconds(2)); + + // Some time later, the app is interested in restarting BWE since we may want + // to resume video eventually. + caller->pc()->ReconfigureBandwidthEstimation( + {.allow_probe_without_media = true}); + s.ProcessMessages(TimeDelta::Seconds(1)); + DataRate bwe_after_restart = + GetAvailableSendBitrate(GetStatsAndProcess(s, caller)); + EXPECT_GT(bwe_after_restart.kbps(), bwe_before_restart.kbps() + 300); + EXPECT_LT(bwe_after_restart.kbps(), 1000); +} + } // namespace test } // namespace webrtc diff --git a/third_party/libwebrtc/test/peer_scenario/tests/unsignaled_stream_test.cc b/third_party/libwebrtc/test/peer_scenario/tests/unsignaled_stream_test.cc index 4f478b4b2a..dced274e68 100644 --- a/third_party/libwebrtc/test/peer_scenario/tests/unsignaled_stream_test.cc +++ b/third_party/libwebrtc/test/peer_scenario/tests/unsignaled_stream_test.cc @@ -98,7 +98,6 @@ TEST_P(UnsignaledStreamTest, ReplacesUnsignaledStreamOnCompletedSignaling) { PeerScenarioClient::Config config = PeerScenarioClient::Config(); // Disable encryption so that we can inject a fake early media packet without // triggering srtp failures. - config.disable_encryption = true; auto* caller = s.CreateClient(config); auto* callee = s.CreateClient(config); diff --git a/third_party/libwebrtc/test/scenario/video_stream.cc b/third_party/libwebrtc/test/scenario/video_stream.cc index 654aed7c6c..c3f0da7cb7 100644 --- a/third_party/libwebrtc/test/scenario/video_stream.cc +++ b/third_party/libwebrtc/test/scenario/video_stream.cc @@ -491,10 +491,6 @@ void SendVideoStream::UpdateConfig( void SendVideoStream::UpdateActiveLayers(std::vector<bool> active_layers) { sender_->task_queue_.PostTask([=] { MutexLock lock(&mutex_); - if (config_.encoder.codec == - VideoStreamConfig::Encoder::Codec::kVideoCodecVP8) { - send_stream_->StartPerRtpStream(active_layers); - } VideoEncoderConfig encoder_config = CreateVideoEncoderConfig(config_); RTC_CHECK_EQ(encoder_config.simulcast_layers.size(), active_layers.size()); for (size_t i = 0; i < encoder_config.simulcast_layers.size(); ++i) diff --git a/third_party/libwebrtc/test/testsupport/file_utils.cc b/third_party/libwebrtc/test/testsupport/file_utils.cc index 47fed9ac05..afabbaad3f 100644 --- a/third_party/libwebrtc/test/testsupport/file_utils.cc +++ b/third_party/libwebrtc/test/testsupport/file_utils.cc @@ -36,7 +36,7 @@ #include <sys/stat.h> // To check for directory existence. #ifndef S_ISDIR // Not defined in stat.h on Windows. -#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR) +#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) #endif #include <stdio.h> @@ -54,6 +54,7 @@ #include "absl/strings/string_view.h" #include "rtc_base/checks.h" +#include "rtc_base/helpers.h" #include "rtc_base/string_utils.h" #include "rtc_base/strings/string_builder.h" #include "test/testsupport/file_utils_override.h" @@ -94,6 +95,13 @@ std::string OutputPath() { return webrtc::test::internal::OutputPath(); } +std::string OutputPathWithRandomDirectory() { + std::string path = webrtc::test::internal::OutputPath(); + std::string rand_dir = path + rtc::CreateRandomUuid(); + + return CreateDir(rand_dir) ? rand_dir + std::string(kPathDelimiter) : path; +} + std::string WorkingDir() { return webrtc::test::internal::WorkingDir(); } @@ -229,7 +237,12 @@ std::string ResourcePath(absl::string_view name, absl::string_view extension) { std::string JoinFilename(absl::string_view dir, absl::string_view name) { RTC_CHECK(!dir.empty()) << "Special cases not implemented."; rtc::StringBuilder os; - os << dir << kPathDelimiter << name; + os << dir; + // If the directory path already ends with a path delimiter don't append it + if (dir.back() != kPathDelimiter.back()) { + os << kPathDelimiter; + } + os << name; return os.Release(); } diff --git a/third_party/libwebrtc/test/testsupport/file_utils.h b/third_party/libwebrtc/test/testsupport/file_utils.h index ab80ca4454..120c6cb279 100644 --- a/third_party/libwebrtc/test/testsupport/file_utils.h +++ b/third_party/libwebrtc/test/testsupport/file_utils.h @@ -42,6 +42,11 @@ ABSL_CONST_INIT extern const absl::string_view kPathDelimiter; // found, the current working directory ("./") is returned as a fallback. std::string OutputPath(); +// Same as the above but appends a randomly named folder at the end of the path +// Primerly used to provide a solution for stress testing environments to +// prevent colission of files and folders. +std::string OutputPathWithRandomDirectory(); + // Generates an empty file with a unique name in the specified directory and // returns the file name and path. // TODO(titovartem) rename to TempFile and next method to TempFilename diff --git a/third_party/libwebrtc/test/testsupport/file_utils_unittest.cc b/third_party/libwebrtc/test/testsupport/file_utils_unittest.cc index b9de01d09d..1101a63352 100644 --- a/third_party/libwebrtc/test/testsupport/file_utils_unittest.cc +++ b/third_party/libwebrtc/test/testsupport/file_utils_unittest.cc @@ -19,6 +19,7 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "rtc_base/checks.h" +#include "rtc_base/helpers.h" #include "test/gmock.h" #include "test/gtest.h" @@ -119,6 +120,28 @@ TEST_F(FileUtilsTest, OutputPathFromRootWorkingDir) { ASSERT_THAT(result, EndsWith(expected_end)); } +TEST_F(FileUtilsTest, RandomOutputPathFromUnchangedWorkingDir) { + rtc::SetRandomTestMode(true); + std::string fixed_first_uuid = "def01482-f829-429a-bfd4-841706e92cdd"; + std::string expected_end = ExpectedRootDirByPlatform() + fixed_first_uuid + + std::string(kPathDelimiter); + std::string result = webrtc::test::OutputPathWithRandomDirectory(); + + ASSERT_THAT(result, EndsWith(expected_end)); +} + +TEST_F(FileUtilsTest, RandomOutputPathFromRootWorkingDir) { + ASSERT_EQ(0, chdir(kPathDelimiter.data())); + + rtc::SetRandomTestMode(true); + std::string fixed_first_uuid = "def01482-f829-429a-bfd4-841706e92cdd"; + std::string expected_end = ExpectedRootDirByPlatform() + fixed_first_uuid + + std::string(kPathDelimiter); + std::string result = webrtc::test::OutputPathWithRandomDirectory(); + + ASSERT_THAT(result, EndsWith(expected_end)); +} + TEST_F(FileUtilsTest, TempFilename) { std::string temp_filename = webrtc::test::TempFilename( webrtc::test::OutputPath(), "TempFilenameTest"); @@ -147,7 +170,8 @@ TEST_F(FileUtilsTest, GenerateTempFilename) { #define MAYBE_CreateDir CreateDir #endif TEST_F(FileUtilsTest, MAYBE_CreateDir) { - std::string directory = "fileutils-unittest-empty-dir"; + std::string directory = + test::OutputPathWithRandomDirectory() + "fileutils-unittest-empty-dir"; // Make sure it's removed if a previous test has failed: remove(directory.c_str()); ASSERT_TRUE(webrtc::test::CreateDir(directory)); @@ -231,7 +255,7 @@ TEST_F(FileUtilsTest, WriteReadDeleteFilesAndDirs) { // Create an empty temporary directory for this test. const std::string temp_directory = - OutputPath() + Path("TempFileUtilsTestReadDirectory/"); + OutputPathWithRandomDirectory() + Path("TempFileUtilsTestReadDirectory/"); CreateDir(temp_directory); EXPECT_NO_FATAL_FAILURE(CleanDir(temp_directory, &num_deleted_entries)); EXPECT_TRUE(DirExists(temp_directory)); @@ -273,5 +297,15 @@ TEST_F(FileUtilsTest, DirNameStopsAtRoot) { EXPECT_EQ(Path("/"), DirName(Path("/"))); } +TEST_F(FileUtilsTest, JoinFilenameDoesNotAppendExtraPathDelimiterIfExists) { + EXPECT_EQ(JoinFilename(Path("/some/path/"), "file.txt"), + Path("/some/path/file.txt")); +} + +TEST_F(FileUtilsTest, JoinFilenameAppendsPathDelimiterIfMissing) { + EXPECT_EQ(JoinFilename(Path("/some/path"), "file.txt"), + Path("/some/path/file.txt")); +} + } // namespace test } // namespace webrtc diff --git a/third_party/libwebrtc/test/testsupport/test_artifacts.cc b/third_party/libwebrtc/test/testsupport/test_artifacts.cc index 6f062e5fe4..b0ab046e63 100644 --- a/third_party/libwebrtc/test/testsupport/test_artifacts.cc +++ b/third_party/libwebrtc/test/testsupport/test_artifacts.cc @@ -20,7 +20,7 @@ namespace { const std::string& DefaultArtifactPath() { - static const std::string path = webrtc::test::OutputPath(); + static const std::string path = webrtc::test::OutputPathWithRandomDirectory(); return path; } } // namespace @@ -55,8 +55,11 @@ bool WriteToTestArtifactsDir(const char* filename, return false; } - FileWrapper output = FileWrapper::OpenWriteOnly( - JoinFilename(absl::GetFlag(FLAGS_test_artifacts_dir), filename)); + std::string full_path = + JoinFilename(absl::GetFlag(FLAGS_test_artifacts_dir), filename); + FileWrapper output = FileWrapper::OpenWriteOnly(full_path); + + RTC_LOG(LS_INFO) << "Writing test artifacts in: " << full_path; return output.is_open() && output.Write(buffer, length); } diff --git a/third_party/libwebrtc/test/video_codec_tester.cc b/third_party/libwebrtc/test/video_codec_tester.cc index f5fdc07a6b..9aef46d44e 100644 --- a/third_party/libwebrtc/test/video_codec_tester.cc +++ b/third_party/libwebrtc/test/video_codec_tester.cc @@ -772,10 +772,12 @@ class VideoCodecAnalyzer : public VideoCodecTester::VideoCodecStats { class Decoder : public DecodedImageCallback { public: - Decoder(VideoDecoderFactory* decoder_factory, + Decoder(const Environment& env, + VideoDecoderFactory* decoder_factory, const DecoderSettings& decoder_settings, VideoCodecAnalyzer* analyzer) - : decoder_factory_(decoder_factory), + : env_(env), + decoder_factory_(decoder_factory), analyzer_(analyzer), pacer_(decoder_settings.pacing_settings) { RTC_CHECK(analyzer_) << "Analyzer must be provided"; @@ -792,7 +794,7 @@ class Decoder : public DecodedImageCallback { } void Initialize(const SdpVideoFormat& sdp_video_format) { - decoder_ = decoder_factory_->CreateVideoDecoder(sdp_video_format); + decoder_ = decoder_factory_->Create(env_, sdp_video_format); RTC_CHECK(decoder_) << "Could not create decoder for video format " << sdp_video_format.ToString(); @@ -863,6 +865,7 @@ class Decoder : public DecodedImageCallback { return WEBRTC_VIDEO_CODEC_OK; } + const Environment env_; VideoDecoderFactory* decoder_factory_; std::unique_ptr<VideoDecoder> decoder_; VideoCodecAnalyzer* const analyzer_; @@ -982,7 +985,8 @@ class Encoder : public EncodedImageCallback { // layer >X receive encoded lower layers. int num_spatial_layers = ScalabilityModeToNumSpatialLayers(last_superframe_->scalability_mode); - for (int sidx = *last_superframe_->encoded_frame.SpatialIndex() + 1; + for (int sidx = + last_superframe_->encoded_frame.SpatialIndex().value_or(0) + 1; sidx < num_spatial_layers; ++sidx) { last_superframe_->encoded_frame.SetSpatialIndex(sidx); DeliverEncodedFrame(last_superframe_->encoded_frame); @@ -1108,8 +1112,6 @@ class Encoder : public EncodedImageCallback { int result = encoder_->InitEncode(&vc, ves); RTC_CHECK(result == WEBRTC_VIDEO_CODEC_OK); - - SetRates(es); } void SetRates(const EncodingSettings& es) { @@ -1258,6 +1260,29 @@ void ConfigureSimulcast(VideoCodec* vc) { } } +void SetDefaultCodecSpecificSettings(VideoCodec* vc, int num_temporal_layers) { + switch (vc->codecType) { + case kVideoCodecVP8: + *(vc->VP8()) = VideoEncoder::GetDefaultVp8Settings(); + vc->VP8()->SetNumberOfTemporalLayers(num_temporal_layers); + break; + case kVideoCodecVP9: { + *(vc->VP9()) = VideoEncoder::GetDefaultVp9Settings(); + vc->VP9()->SetNumberOfTemporalLayers(num_temporal_layers); + } break; + case kVideoCodecH264: { + *(vc->H264()) = VideoEncoder::GetDefaultH264Settings(); + vc->H264()->SetNumberOfTemporalLayers(num_temporal_layers); + } break; + case kVideoCodecAV1: + case kVideoCodecH265: + break; + case kVideoCodecGeneric: + case kVideoCodecMultiplex: + RTC_CHECK_NOTREACHED(); + } +} + std::tuple<std::vector<DataRate>, ScalabilityMode> SplitBitrateAndUpdateScalabilityMode(std::string codec_type, ScalabilityMode scalability_mode, @@ -1269,11 +1294,11 @@ SplitBitrateAndUpdateScalabilityMode(std::string codec_type, int num_temporal_layers = ScalabilityModeToNumTemporalLayers(scalability_mode); - if (bitrates_kbps.size() > 1 || - (num_spatial_layers == 1 && num_temporal_layers == 1)) { - RTC_CHECK(bitrates_kbps.size() == - static_cast<size_t>(num_spatial_layers * num_temporal_layers)) - << "bitrates must be provided for all layers"; + int num_bitrates = static_cast<int>(bitrates_kbps.size()); + RTC_CHECK(num_bitrates == 1 || num_bitrates == num_spatial_layers || + num_bitrates == num_spatial_layers * num_temporal_layers); + + if (num_bitrates == num_spatial_layers * num_temporal_layers) { std::vector<DataRate> bitrates; for (const auto& bitrate_kbps : bitrates_kbps) { bitrates.push_back(DataRate::KilobitsPerSec(bitrate_kbps)); @@ -1281,59 +1306,93 @@ SplitBitrateAndUpdateScalabilityMode(std::string codec_type, return std::make_tuple(bitrates, scalability_mode); } + int total_bitrate_kbps = + std::accumulate(bitrates_kbps.begin(), bitrates_kbps.end(), 0); + VideoCodec vc; vc.codecType = PayloadStringToCodecType(codec_type); vc.width = width; vc.height = height; - vc.startBitrate = bitrates_kbps.front(); - vc.maxBitrate = bitrates_kbps.front(); + vc.startBitrate = total_bitrate_kbps; + vc.maxBitrate = total_bitrate_kbps; vc.minBitrate = 0; vc.maxFramerate = static_cast<uint32_t>(framerate_fps); vc.numberOfSimulcastStreams = 0; vc.mode = webrtc::VideoCodecMode::kRealtimeVideo; vc.SetScalabilityMode(scalability_mode); + SetDefaultCodecSpecificSettings(&vc, num_temporal_layers); - switch (vc.codecType) { - case kVideoCodecVP8: - // TODO(webrtc:14852): Configure simulcast. - *(vc.VP8()) = VideoEncoder::GetDefaultVp8Settings(); - vc.VP8()->SetNumberOfTemporalLayers(num_temporal_layers); - ConfigureSimulcast(&vc); - break; - case kVideoCodecVP9: { - *(vc.VP9()) = VideoEncoder::GetDefaultVp9Settings(); - vc.VP9()->SetNumberOfTemporalLayers(num_temporal_layers); - const std::vector<SpatialLayer> spatialLayers = GetVp9SvcConfig(vc); - for (size_t i = 0; i < spatialLayers.size(); ++i) { - vc.spatialLayers[i] = spatialLayers[i]; - vc.spatialLayers[i].active = true; - } - } break; - case kVideoCodecAV1: { - bool result = - SetAv1SvcConfig(vc, num_spatial_layers, num_temporal_layers); - RTC_CHECK(result) << "SetAv1SvcConfig failed"; - } break; - case kVideoCodecH264: { - *(vc.H264()) = VideoEncoder::GetDefaultH264Settings(); - vc.H264()->SetNumberOfTemporalLayers(num_temporal_layers); - ConfigureSimulcast(&vc); - } break; - case kVideoCodecH265: - break; - case kVideoCodecGeneric: - case kVideoCodecMultiplex: - RTC_CHECK_NOTREACHED(); - } + if (num_bitrates == num_spatial_layers) { + switch (vc.codecType) { + case kVideoCodecVP8: + case kVideoCodecH264: + case kVideoCodecH265: + vc.numberOfSimulcastStreams = num_spatial_layers; + for (int sidx = 0; sidx < num_spatial_layers; ++sidx) { + SimulcastStream* ss = &vc.simulcastStream[sidx]; + ss->width = width >> (num_spatial_layers - sidx - 1); + ss->height = height >> (num_spatial_layers - sidx - 1); + ss->maxFramerate = vc.maxFramerate; + ss->numberOfTemporalLayers = num_temporal_layers; + ss->maxBitrate = bitrates_kbps[sidx]; + ss->targetBitrate = bitrates_kbps[sidx]; + ss->minBitrate = 0; + ss->qpMax = 0; + ss->active = true; + } + break; + case kVideoCodecVP9: + case kVideoCodecAV1: + for (int sidx = num_spatial_layers - 1; sidx >= 0; --sidx) { + SpatialLayer* ss = &vc.spatialLayers[sidx]; + ss->width = width >> (num_spatial_layers - sidx - 1); + ss->height = height >> (num_spatial_layers - sidx - 1); + ss->maxFramerate = vc.maxFramerate; + ss->numberOfTemporalLayers = num_temporal_layers; + ss->maxBitrate = bitrates_kbps[sidx]; + ss->targetBitrate = bitrates_kbps[sidx]; + ss->minBitrate = 0; + ss->qpMax = 0; + ss->active = true; + } + break; + case kVideoCodecGeneric: + case kVideoCodecMultiplex: + RTC_CHECK_NOTREACHED(); + } + } else { + switch (vc.codecType) { + case kVideoCodecVP8: + case kVideoCodecH264: + case kVideoCodecH265: + ConfigureSimulcast(&vc); + break; + case kVideoCodecVP9: { + const std::vector<SpatialLayer> spatialLayers = GetVp9SvcConfig(vc); + for (size_t i = 0; i < spatialLayers.size(); ++i) { + vc.spatialLayers[i] = spatialLayers[i]; + vc.spatialLayers[i].active = true; + } + } break; + case kVideoCodecAV1: { + bool result = + SetAv1SvcConfig(vc, num_spatial_layers, num_temporal_layers); + RTC_CHECK(result) << "SetAv1SvcConfig failed"; + } break; + case kVideoCodecGeneric: + case kVideoCodecMultiplex: + RTC_CHECK_NOTREACHED(); + } - if (*vc.GetScalabilityMode() != scalability_mode) { - RTC_LOG(LS_WARNING) << "Scalability mode changed from " - << ScalabilityModeToString(scalability_mode) << " to " - << ScalabilityModeToString(*vc.GetScalabilityMode()); - num_spatial_layers = - ScalabilityModeToNumSpatialLayers(*vc.GetScalabilityMode()); - num_temporal_layers = - ScalabilityModeToNumTemporalLayers(*vc.GetScalabilityMode()); + if (*vc.GetScalabilityMode() != scalability_mode) { + RTC_LOG(LS_WARNING) << "Scalability mode changed from " + << ScalabilityModeToString(scalability_mode) << " to " + << ScalabilityModeToString(*vc.GetScalabilityMode()); + num_spatial_layers = + ScalabilityModeToNumSpatialLayers(*vc.GetScalabilityMode()); + num_temporal_layers = + ScalabilityModeToNumTemporalLayers(*vc.GetScalabilityMode()); + } } std::unique_ptr<VideoBitrateAllocator> bitrate_allocator = @@ -1341,7 +1400,7 @@ SplitBitrateAndUpdateScalabilityMode(std::string codec_type, vc); VideoBitrateAllocation bitrate_allocation = bitrate_allocator->Allocate(VideoBitrateAllocationParameters( - 1000 * bitrates_kbps.front(), framerate_fps)); + 1000 * total_bitrate_kbps, framerate_fps)); std::vector<DataRate> bitrates; for (int sidx = 0; sidx < num_spatial_layers; ++sidx) { @@ -1476,13 +1535,14 @@ std::map<uint32_t, EncodingSettings> VideoCodecTester::CreateEncodingSettings( } std::unique_ptr<VideoCodecTester::VideoCodecStats> -VideoCodecTester::RunDecodeTest(CodedVideoSource* video_source, +VideoCodecTester::RunDecodeTest(const Environment& env, + CodedVideoSource* video_source, VideoDecoderFactory* decoder_factory, const DecoderSettings& decoder_settings, const SdpVideoFormat& sdp_video_format) { std::unique_ptr<VideoCodecAnalyzer> analyzer = std::make_unique<VideoCodecAnalyzer>(/*video_source=*/nullptr); - Decoder decoder(decoder_factory, decoder_settings, analyzer.get()); + Decoder decoder(env, decoder_factory, decoder_settings, analyzer.get()); decoder.Initialize(sdp_video_format); while (auto frame = video_source->PullFrame()) { @@ -1522,6 +1582,7 @@ VideoCodecTester::RunEncodeTest( std::unique_ptr<VideoCodecTester::VideoCodecStats> VideoCodecTester::RunEncodeDecodeTest( + const Environment& env, const VideoSourceSettings& source_settings, VideoEncoderFactory* encoder_factory, VideoDecoderFactory* decoder_factory, @@ -1539,8 +1600,8 @@ VideoCodecTester::RunEncodeDecodeTest( ScalabilityModeToNumSpatialLayers(frame_settings.scalability_mode); std::vector<std::unique_ptr<Decoder>> decoders; for (int sidx = 0; sidx < num_spatial_layers; ++sidx) { - auto decoder = std::make_unique<Decoder>(decoder_factory, decoder_settings, - analyzer.get()); + auto decoder = std::make_unique<Decoder>(env, decoder_factory, + decoder_settings, analyzer.get()); decoder->Initialize(frame_settings.sdp_video_format); decoders.push_back(std::move(decoder)); } diff --git a/third_party/libwebrtc/test/video_codec_tester.h b/third_party/libwebrtc/test/video_codec_tester.h index 87cc5f76f8..00b6093dca 100644 --- a/third_party/libwebrtc/test/video_codec_tester.h +++ b/third_party/libwebrtc/test/video_codec_tester.h @@ -199,6 +199,7 @@ class VideoCodecTester { // Decodes video, collects and returns decode metrics. static std::unique_ptr<VideoCodecStats> RunDecodeTest( + const Environment& env, CodedVideoSource* video_source, VideoDecoderFactory* decoder_factory, const DecoderSettings& decoder_settings, @@ -213,6 +214,7 @@ class VideoCodecTester { // Encodes and decodes video, collects and returns encode and decode metrics. static std::unique_ptr<VideoCodecStats> RunEncodeDecodeTest( + const Environment& env, const VideoSourceSettings& source_settings, VideoEncoderFactory* encoder_factory, VideoDecoderFactory* decoder_factory, diff --git a/third_party/libwebrtc/test/video_codec_tester_unittest.cc b/third_party/libwebrtc/test/video_codec_tester_unittest.cc index df5dca90a2..fdd7b37a00 100644 --- a/third_party/libwebrtc/test/video_codec_tester_unittest.cc +++ b/third_party/libwebrtc/test/video_codec_tester_unittest.cc @@ -17,6 +17,8 @@ #include <utility> #include <vector> +#include "api/environment/environment.h" +#include "api/environment/environment_factory.h" #include "api/test/mock_video_decoder.h" #include "api/test/mock_video_decoder_factory.h" #include "api/test/mock_video_encoder.h" @@ -44,13 +46,12 @@ namespace { using ::testing::_; using ::testing::ElementsAre; using ::testing::Field; -using ::testing::Invoke; -using ::testing::InvokeWithoutArgs; using ::testing::NiceMock; using ::testing::Return; using ::testing::SizeIs; using ::testing::UnorderedElementsAreArray; using ::testing::Values; +using ::testing::WithoutArgs; using VideoCodecStats = VideoCodecTester::VideoCodecStats; using VideoSourceSettings = VideoCodecTester::VideoSourceSettings; @@ -200,30 +201,27 @@ class VideoCodecTesterTest : public ::testing::Test { }); NiceMock<MockVideoDecoderFactory> decoder_factory; - ON_CALL(decoder_factory, CreateVideoDecoder) - .WillByDefault([&](const SdpVideoFormat&) { - // Video codec tester destroyes decoder at the end of test. Test - // decoder collects stats which we need to access after test. To keep - // the decode alive we wrap it into a wrapper and pass the wrapper to - // the tester. - class DecoderWrapper : public TestVideoDecoder { - public: - explicit DecoderWrapper(TestVideoDecoder* decoder) - : decoder_(decoder) {} - int32_t Decode(const EncodedImage& encoded_frame, - int64_t render_time_ms) { - return decoder_->Decode(encoded_frame, render_time_ms); - } - int32_t RegisterDecodeCompleteCallback( - DecodedImageCallback* callback) { - return decoder_->RegisterDecodeCompleteCallback(callback); - } - TestVideoDecoder* decoder_; - }; - decoders_.push_back(std::make_unique<NiceMock<TestVideoDecoder>>()); - return std::make_unique<NiceMock<DecoderWrapper>>( - decoders_.back().get()); - }); + ON_CALL(decoder_factory, Create).WillByDefault(WithoutArgs([&] { + // Video codec tester destroyes decoder at the end of test. Test + // decoder collects stats which we need to access after test. To keep + // the decode alive we wrap it into a wrapper and pass the wrapper to + // the tester. + class DecoderWrapper : public TestVideoDecoder { + public: + explicit DecoderWrapper(TestVideoDecoder* decoder) + : decoder_(decoder) {} + int32_t Decode(const EncodedImage& encoded_frame, + int64_t render_time_ms) { + return decoder_->Decode(encoded_frame, render_time_ms); + } + int32_t RegisterDecodeCompleteCallback(DecodedImageCallback* callback) { + return decoder_->RegisterDecodeCompleteCallback(callback); + } + TestVideoDecoder* decoder_; + }; + decoders_.push_back(std::make_unique<NiceMock<TestVideoDecoder>>()); + return std::make_unique<NiceMock<DecoderWrapper>>(decoders_.back().get()); + })); int num_spatial_layers = ScalabilityModeToNumSpatialLayers(scalability_mode); @@ -252,7 +250,7 @@ class VideoCodecTesterTest : public ::testing::Test { std::unique_ptr<VideoCodecStats> stats = VideoCodecTester::RunEncodeDecodeTest( - video_source_settings, &encoder_factory, &decoder_factory, + env_, video_source_settings, &encoder_factory, &decoder_factory, EncoderSettings{}, DecoderSettings{}, encoding_settings); remove(yuv_path.c_str()); @@ -260,6 +258,7 @@ class VideoCodecTesterTest : public ::testing::Test { } protected: + const Environment env_ = CreateEnvironment(); std::vector<std::unique_ptr<TestVideoDecoder>> decoders_; }; @@ -605,6 +604,7 @@ class VideoCodecTesterTestPacing void TearDown() override { remove(source_yuv_file_path_.c_str()); } protected: + const Environment env_ = CreateEnvironment(); std::string source_yuv_file_path_; }; @@ -644,15 +644,14 @@ TEST_P(VideoCodecTesterTestPacing, PaceDecode) { MockCodedVideoSource video_source(kNumFrames, kTargetFramerate); NiceMock<MockVideoDecoderFactory> decoder_factory; - ON_CALL(decoder_factory, CreateVideoDecoder(_)) - .WillByDefault([](const SdpVideoFormat&) { - return std::make_unique<NiceMock<MockVideoDecoder>>(); - }); + ON_CALL(decoder_factory, Create).WillByDefault(WithoutArgs([] { + return std::make_unique<NiceMock<MockVideoDecoder>>(); + })); DecoderSettings decoder_settings; decoder_settings.pacing_settings = pacing_settings; std::vector<Frame> frames = - VideoCodecTester::RunDecodeTest(&video_source, &decoder_factory, + VideoCodecTester::RunDecodeTest(env_, &video_source, &decoder_factory, decoder_settings, SdpVideoFormat("VP8")) ->Slice(/*filter=*/{}, /*merge=*/false); ASSERT_THAT(frames, SizeIs(kNumFrames)); @@ -676,5 +675,137 @@ INSTANTIATE_TEST_SUITE_P( std::make_tuple(PacingSettings{.mode = PacingMode::kConstantRate, .constant_rate = Frequency::Hertz(20)}, /*expected_delta_ms=*/50))); + +struct EncodingSettingsTestParameters { + std::string codec_type; + std::string scalability_mode; + std::vector<int> bitrate_kbps; + std::vector<int> expected_bitrate_kbps; +}; + +class VideoCodecTesterTestEncodingSettings + : public ::testing::TestWithParam<EncodingSettingsTestParameters> {}; + +TEST_P(VideoCodecTesterTestEncodingSettings, CreateEncodingSettings) { + EncodingSettingsTestParameters test_params = GetParam(); + std::map<uint32_t, EncodingSettings> encoding_settings = + VideoCodecTester::CreateEncodingSettings( + test_params.codec_type, test_params.scalability_mode, /*width=*/1280, + /*height=*/720, test_params.bitrate_kbps, /*framerate_fps=*/30, + /*num_frames=*/1); + ASSERT_THAT(encoding_settings, SizeIs(1)); + const std::map<LayerId, LayerSettings>& layers_settings = + encoding_settings.begin()->second.layers_settings; + std::vector<int> configured_bitrate_kbps; + std::transform(layers_settings.begin(), layers_settings.end(), + std::back_inserter(configured_bitrate_kbps), + [](const auto& layer_settings) { + return layer_settings.second.bitrate.kbps(); + }); + EXPECT_EQ(configured_bitrate_kbps, test_params.expected_bitrate_kbps); +} + +INSTANTIATE_TEST_SUITE_P( + Vp8, + VideoCodecTesterTestEncodingSettings, + Values(EncodingSettingsTestParameters{.codec_type = "VP8", + .scalability_mode = "L1T1", + .bitrate_kbps = {1}, + .expected_bitrate_kbps = {1}}, + EncodingSettingsTestParameters{.codec_type = "VP8", + .scalability_mode = "L1T1", + .bitrate_kbps = {10000}, + .expected_bitrate_kbps = {10000}}, + EncodingSettingsTestParameters{ + .codec_type = "VP8", + .scalability_mode = "L1T3", + .bitrate_kbps = {1000}, + .expected_bitrate_kbps = {400, 200, 400}}, + EncodingSettingsTestParameters{ + .codec_type = "VP8", + .scalability_mode = "S3T3", + .bitrate_kbps = {100}, + .expected_bitrate_kbps = {40, 20, 40, 0, 0, 0, 0, 0, 0}}, + EncodingSettingsTestParameters{ + .codec_type = "VP8", + .scalability_mode = "S3T3", + .bitrate_kbps = {10000}, + .expected_bitrate_kbps = {60, 30, 60, 200, 100, 200, 1000, 500, + 1000}}, + EncodingSettingsTestParameters{ + .codec_type = "VP8", + .scalability_mode = "S3T3", + .bitrate_kbps = {100, 200, 300, 400, 500, 600, 700, 800, 900}, + .expected_bitrate_kbps = {100, 200, 300, 400, 500, 600, 700, 800, + 900}})); + +INSTANTIATE_TEST_SUITE_P( + Vp9, + VideoCodecTesterTestEncodingSettings, + Values(EncodingSettingsTestParameters{.codec_type = "VP9", + .scalability_mode = "L1T1", + .bitrate_kbps = {1}, + .expected_bitrate_kbps = {1}}, + EncodingSettingsTestParameters{.codec_type = "VP9", + .scalability_mode = "L1T1", + .bitrate_kbps = {10000}, + .expected_bitrate_kbps = {10000}}, + EncodingSettingsTestParameters{ + .codec_type = "VP9", + .scalability_mode = "L1T3", + .bitrate_kbps = {1000}, + .expected_bitrate_kbps = {540, 163, 297}}, + EncodingSettingsTestParameters{ + .codec_type = "VP9", + .scalability_mode = "L3T3", + .bitrate_kbps = {100}, + .expected_bitrate_kbps = {54, 16, 30, 0, 0, 0, 0, 0, 0}}, + EncodingSettingsTestParameters{ + .codec_type = "VP9", + .scalability_mode = "L3T3", + .bitrate_kbps = {10000}, + .expected_bitrate_kbps = {77, 23, 42, 226, 68, 124, 823, 249, + 452}}, + EncodingSettingsTestParameters{ + .codec_type = "VP9", + .scalability_mode = "L3T3", + .bitrate_kbps = {100, 200, 300, 400, 500, 600, 700, 800, 900}, + .expected_bitrate_kbps = {100, 200, 300, 400, 500, 600, 700, 800, + 900}})); + +INSTANTIATE_TEST_SUITE_P( + Av1, + VideoCodecTesterTestEncodingSettings, + Values(EncodingSettingsTestParameters{.codec_type = "AV1", + .scalability_mode = "L1T1", + .bitrate_kbps = {1}, + .expected_bitrate_kbps = {1}}, + EncodingSettingsTestParameters{.codec_type = "AV1", + .scalability_mode = "L1T1", + .bitrate_kbps = {10000}, + .expected_bitrate_kbps = {10000}}, + EncodingSettingsTestParameters{ + .codec_type = "AV1", + .scalability_mode = "L1T3", + .bitrate_kbps = {1000}, + .expected_bitrate_kbps = {540, 163, 297}}, + EncodingSettingsTestParameters{ + .codec_type = "AV1", + .scalability_mode = "L3T3", + .bitrate_kbps = {100}, + .expected_bitrate_kbps = {54, 16, 30, 0, 0, 0, 0, 0, 0}}, + EncodingSettingsTestParameters{ + .codec_type = "AV1", + .scalability_mode = "L3T3", + .bitrate_kbps = {10000}, + .expected_bitrate_kbps = {77, 23, 42, 226, 68, 124, 823, 249, + 452}}, + EncodingSettingsTestParameters{ + .codec_type = "AV1", + .scalability_mode = "L3T3", + .bitrate_kbps = {100, 200, 300, 400, 500, 600, 700, 800, 900}, + .expected_bitrate_kbps = {100, 200, 300, 400, 500, 600, 700, 800, + 900}})); + } // namespace test } // namespace webrtc |