diff --git a/common_video/generic_frame_descriptor/generic_frame_info.cc b/common_video/generic_frame_descriptor/generic_frame_info.cc index ca61072799..ef78fac7b0 100644 --- a/common_video/generic_frame_descriptor/generic_frame_info.cc +++ b/common_video/generic_frame_descriptor/generic_frame_info.cc @@ -71,8 +71,13 @@ GenericFrameInfo::Builder& GenericFrameInfo::Builder::Dtis( GenericFrameInfo::Builder& GenericFrameInfo::Builder::Fdiffs( std::initializer_list frame_diffs) { - info_.frame_diffs.insert(info_.frame_diffs.end(), frame_diffs.begin(), - frame_diffs.end()); + info_.frame_diffs.assign(frame_diffs.begin(), frame_diffs.end()); + return *this; +} + +GenericFrameInfo::Builder& GenericFrameInfo::Builder::ChainDiffs( + std::initializer_list chain_diffs) { + info_.chain_diffs.assign(chain_diffs.begin(), chain_diffs.end()); return *this; } diff --git a/common_video/generic_frame_descriptor/generic_frame_info.h b/common_video/generic_frame_descriptor/generic_frame_info.h index b602ee06a6..ba3265bb37 100644 --- a/common_video/generic_frame_descriptor/generic_frame_info.h +++ b/common_video/generic_frame_descriptor/generic_frame_info.h @@ -54,6 +54,7 @@ class GenericFrameInfo::Builder { Builder& S(int spatial_id); Builder& Dtis(absl::string_view indication_symbols); Builder& Fdiffs(std::initializer_list frame_diffs); + Builder& ChainDiffs(std::initializer_list chain_diffs); private: GenericFrameInfo info_; diff --git a/modules/rtp_rtcp/source/rtp_sender_video.cc b/modules/rtp_rtcp/source/rtp_sender_video.cc index b903b9f001..8dbcc90763 100644 --- a/modules/rtp_rtcp/source/rtp_sender_video.cc +++ b/modules/rtp_rtcp/source/rtp_sender_video.cc @@ -251,8 +251,6 @@ void RTPSenderVideo::SetVideoStructureUnderLock( video_structure_ = std::make_unique(*video_structure); video_structure_->structure_id = structure_id; - // TODO(bugs.webrtc.org/10342): Support chains. - video_structure_->num_chains = 0; } void RTPSenderVideo::AddRtpHeaderExtensions( @@ -336,6 +334,8 @@ void RTPSenderVideo::AddRtpHeaderExtensions( descriptor.frame_dependencies.frame_diffs.push_back( video_header.generic->frame_id - dep); } + descriptor.frame_dependencies.chain_diffs = + video_header.generic->chain_diffs; descriptor.frame_dependencies.decode_target_indications = video_header.generic->decode_target_indications; RTC_DCHECK_EQ( diff --git a/modules/rtp_rtcp/source/rtp_sender_video_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_video_unittest.cc index 21c4da05ab..75fa6c8fab 100644 --- a/modules/rtp_rtcp/source/rtp_sender_video_unittest.cc +++ b/modules/rtp_rtcp/source/rtp_sender_video_unittest.cc @@ -45,6 +45,7 @@ namespace webrtc { namespace { using ::testing::_; +using ::testing::ContainerEq; using ::testing::ElementsAre; using ::testing::ElementsAreArray; using ::testing::IsEmpty; @@ -606,6 +607,40 @@ TEST_P(RtpSenderVideoTest, SendsDependencyDescriptorWhenVideoStructureIsSet) { ElementsAre(1, 501)); } +TEST_P(RtpSenderVideoTest, PropagatesChainDiffsIntoDependencyDescriptor) { + const int64_t kFrameId = 100000; + uint8_t kFrame[100]; + rtp_module_->RegisterRtpHeaderExtension( + RtpDependencyDescriptorExtension::kUri, kDependencyDescriptorId); + FrameDependencyStructure video_structure; + video_structure.num_decode_targets = 2; + video_structure.num_chains = 1; + // First decode target is protected by the only chain, second one - is not. + video_structure.decode_target_protected_by_chain = {0, 1}; + video_structure.templates = { + GenericFrameInfo::Builder().S(0).T(0).Dtis("SS").ChainDiffs({1}).Build(), + }; + rtp_sender_video_.SetVideoStructure(&video_structure); + + RTPVideoHeader hdr; + RTPVideoHeader::GenericDescriptorInfo& generic = hdr.generic.emplace(); + generic.frame_id = kFrameId; + generic.decode_target_indications = {DecodeTargetIndication::kSwitch, + DecodeTargetIndication::kSwitch}; + generic.chain_diffs = {2}; + hdr.frame_type = VideoFrameType::kVideoFrameKey; + rtp_sender_video_.SendVideo(kPayload, kType, kTimestamp, 0, kFrame, nullptr, + hdr, kDefaultExpectedRetransmissionTimeMs); + + ASSERT_EQ(transport_.packets_sent(), 1); + DependencyDescriptor descriptor_key; + ASSERT_TRUE(transport_.last_sent_packet() + .GetExtension( + nullptr, &descriptor_key)); + EXPECT_THAT(descriptor_key.frame_dependencies.chain_diffs, + ContainerEq(generic.chain_diffs)); +} + TEST_P(RtpSenderVideoTest, SetDiffentVideoStructureAvoidsCollisionWithThePreviousStructure) { const int64_t kFrameId = 100000; diff --git a/modules/rtp_rtcp/source/rtp_video_header.h b/modules/rtp_rtcp/source/rtp_video_header.h index 7071463be4..5785ea9a54 100644 --- a/modules/rtp_rtcp/source/rtp_video_header.h +++ b/modules/rtp_rtcp/source/rtp_video_header.h @@ -23,7 +23,7 @@ #include "api/video/video_frame_type.h" #include "api/video/video_rotation.h" #include "api/video/video_timing.h" -#include "common_types.h" // NOLINT(build/include) +#include "common_types.h" // NOLINT(build/include_directory) #include "modules/video_coding/codecs/h264/include/h264_globals.h" #include "modules/video_coding/codecs/vp8/include/vp8_globals.h" #include "modules/video_coding/codecs/vp9/include/vp9_globals.h" @@ -53,6 +53,7 @@ struct RTPVideoHeader { int temporal_index = 0; absl::InlinedVector decode_target_indications; absl::InlinedVector dependencies; + absl::InlinedVector chain_diffs; }; RTPVideoHeader();