Simulate generic dependency structure for VP8
This will be used as a fall-back when the encoder adapter doesn't
provide any dependency structure. This ensures we can always generate a
dependency descriptor RTP header extension for VP8.
Before, when switching between encoder adapters where the old one
generated a dependency structure but the new one didn't we had to make
sure the structure was cleared so that packets weren't sent with the
dependency structure from the previous adapter. This will not be a
problem anymore since the new adapter will use the simulated dependency
structure.
Bug: b/227749056
Change-Id: I8463c48a9dcde4b8d32c519819dd8a92acd8e43b
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/262765
Commit-Queue: Emil Lundmark <lndmrk@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36930}
diff --git a/call/rtp_video_sender_unittest.cc b/call/rtp_video_sender_unittest.cc
index 8c69d1b..e59ea74 100644
--- a/call/rtp_video_sender_unittest.cc
+++ b/call/rtp_video_sender_unittest.cc
@@ -34,13 +34,14 @@
#include "video/send_delay_stats.h"
#include "video/send_statistics_proxy.h"
+namespace webrtc {
+namespace {
+
using ::testing::_;
using ::testing::NiceMock;
using ::testing::SaveArg;
using ::testing::SizeIs;
-namespace webrtc {
-namespace {
const int8_t kPayloadType = 96;
const uint32_t kSsrc1 = 12345;
const uint32_t kSsrc2 = 23456;
@@ -744,6 +745,53 @@
sent_packets.back().HasExtension<RtpDependencyDescriptorExtension>());
}
+TEST(RtpVideoSenderTest,
+ SupportsDependencyDescriptorForVp8NotProvidedByEncoder) {
+ constexpr uint8_t kPayload[1] = {'a'};
+ RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {});
+ RtpHeaderExtensionMap extensions;
+ extensions.Register<RtpDependencyDescriptorExtension>(
+ kDependencyDescriptorExtensionId);
+ std::vector<RtpPacket> sent_packets;
+ ON_CALL(test.transport(), SendRtp)
+ .WillByDefault(
+ [&](const uint8_t* packet, size_t length, const PacketOptions&) {
+ EXPECT_TRUE(
+ sent_packets.emplace_back(&extensions).Parse(packet, length));
+ return true;
+ });
+ test.SetActive(true);
+
+ EncodedImage key_frame_image;
+ key_frame_image._frameType = VideoFrameType::kVideoFrameKey;
+ key_frame_image.SetEncodedData(
+ EncodedImageBuffer::Create(kPayload, sizeof(kPayload)));
+ CodecSpecificInfo key_frame_info;
+ key_frame_info.codecType = VideoCodecType::kVideoCodecVP8;
+ ASSERT_EQ(
+ test.router()->OnEncodedImage(key_frame_image, &key_frame_info).error,
+ EncodedImageCallback::Result::OK);
+
+ EncodedImage delta_image;
+ delta_image._frameType = VideoFrameType::kVideoFrameDelta;
+ delta_image.SetEncodedData(
+ EncodedImageBuffer::Create(kPayload, sizeof(kPayload)));
+ CodecSpecificInfo delta_info;
+ delta_info.codecType = VideoCodecType::kVideoCodecVP8;
+ ASSERT_EQ(test.router()->OnEncodedImage(delta_image, &delta_info).error,
+ EncodedImageCallback::Result::OK);
+
+ test.AdvanceTime(TimeDelta::Millis(123));
+
+ DependencyDescriptor key_frame_dd;
+ DependencyDescriptor delta_dd;
+ ASSERT_THAT(sent_packets, SizeIs(2));
+ EXPECT_TRUE(sent_packets[0].GetExtension<RtpDependencyDescriptorExtension>(
+ /*structure=*/nullptr, &key_frame_dd));
+ EXPECT_TRUE(sent_packets[1].GetExtension<RtpDependencyDescriptorExtension>(
+ key_frame_dd.attached_structure.get(), &delta_dd));
+}
+
TEST(RtpVideoSenderTest, SupportsDependencyDescriptorForVp9) {
RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {});
test.SetActive(true);
@@ -958,64 +1006,6 @@
sent_packets.back().HasExtension<RtpDependencyDescriptorExtension>());
}
-TEST(RtpVideoSenderTest,
- SupportsStoppingUsingDependencyDescriptorForVp8Simulcast) {
- RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {}, kPayloadType, {});
- test.SetActive(true);
-
- RtpHeaderExtensionMap extensions;
- extensions.Register<RtpDependencyDescriptorExtension>(
- kDependencyDescriptorExtensionId);
- std::vector<RtpPacket> sent_packets;
- ON_CALL(test.transport(), SendRtp)
- .WillByDefault([&](const uint8_t* packet, size_t length,
- const PacketOptions& options) {
- sent_packets.emplace_back(&extensions);
- EXPECT_TRUE(sent_packets.back().Parse(packet, length));
- return true;
- });
-
- const uint8_t kPayload[1] = {'a'};
- EncodedImage encoded_image;
- encoded_image.SetTimestamp(1);
- encoded_image.capture_time_ms_ = 2;
- encoded_image.SetEncodedData(
- EncodedImageBuffer::Create(kPayload, sizeof(kPayload)));
- // VP8 simulcast uses spatial index to communicate simulcast stream.
- encoded_image.SetSpatialIndex(1);
-
- CodecSpecificInfo codec_specific;
- codec_specific.codecType = VideoCodecType::kVideoCodecVP8;
- codec_specific.template_structure.emplace();
- codec_specific.template_structure->num_decode_targets = 1;
- codec_specific.template_structure->templates = {
- FrameDependencyTemplate().T(0).Dtis("S")};
-
- // Send two tiny images, mapping to single RTP packets.
- // Send in a key frame.
- encoded_image._frameType = VideoFrameType::kVideoFrameKey;
- codec_specific.generic_frame_info =
- GenericFrameInfo::Builder().T(0).Dtis("S").Build();
- codec_specific.generic_frame_info->encoder_buffers = {{0, false, true}};
- EXPECT_EQ(test.router()->OnEncodedImage(encoded_image, &codec_specific).error,
- EncodedImageCallback::Result::OK);
- test.AdvanceTime(TimeDelta::Millis(33));
- ASSERT_THAT(sent_packets, SizeIs(1));
- EXPECT_TRUE(
- sent_packets.back().HasExtension<RtpDependencyDescriptorExtension>());
-
- // Send in a new key frame without the support for the dependency descriptor.
- encoded_image._frameType = VideoFrameType::kVideoFrameKey;
- codec_specific.template_structure = absl::nullopt;
- codec_specific.generic_frame_info = absl::nullopt;
- EXPECT_EQ(test.router()->OnEncodedImage(encoded_image, &codec_specific).error,
- EncodedImageCallback::Result::OK);
- test.AdvanceTime(TimeDelta::Millis(33));
- ASSERT_THAT(sent_packets, SizeIs(2));
- EXPECT_FALSE(
- sent_packets.back().HasExtension<RtpDependencyDescriptorExtension>());
-}
-
TEST(RtpVideoSenderTest, CanSetZeroBitrate) {
RtpVideoSenderTestFixture test({kSsrc1}, {kRtxSsrc1}, kPayloadType, {});
test.router()->OnBitrateUpdated(CreateBitrateAllocationUpdate(0),