diff --git a/call/rtp_payload_params.cc b/call/rtp_payload_params.cc index acc9e3ca18..ffe62eb40a 100644 --- a/call/rtp_payload_params.cc +++ b/call/rtp_payload_params.cc @@ -483,6 +483,10 @@ void RtpPayloadParams::H264ToGeneric(const CodecSpecificInfoH264& h264_info, temporal_index, DecodeTargetIndication::kNotPresent); std::fill(it, generic.decode_target_indications.end(), DecodeTargetIndication::kSwitch); + generic.chain_diffs = { + (is_keyframe || last_frame_id_[0][0] < 0) + ? 0 + : static_cast(frame_id - last_frame_id_[0][0])}; if (is_keyframe) { RTC_DCHECK_EQ(temporal_index, 0); diff --git a/modules/rtp_rtcp/BUILD.gn b/modules/rtp_rtcp/BUILD.gn index 3bbddc78d1..1f4a0ca48d 100644 --- a/modules/rtp_rtcp/BUILD.gn +++ b/modules/rtp_rtcp/BUILD.gn @@ -136,6 +136,7 @@ rtc_library("rtp_rtcp_format") { "../../rtc_base:event_tracer", "../../rtc_base:logging", "../../rtc_base:macromagic", + "../../rtc_base:safe_compare", "../../rtc_base:safe_conversions", "../../rtc_base:stringutils", "../../rtc_base/network:ecn_marking", diff --git a/modules/rtp_rtcp/source/rtp_dependency_descriptor_extension_unittest.cc b/modules/rtp_rtcp/source/rtp_dependency_descriptor_extension_unittest.cc index 148e4f973b..e666d4ac38 100644 --- a/modules/rtp_rtcp/source/rtp_dependency_descriptor_extension_unittest.cc +++ b/modules/rtp_rtcp/source/rtp_dependency_descriptor_extension_unittest.cc @@ -132,5 +132,48 @@ TEST(RtpDependencyDescriptorExtensionTest, FailsToWriteInvalidDescriptor) { descriptor)); } +TEST(RtpDependencyDescriptorExtensionTest, + FailsToWriteWhenNumberOfChainsMismatch) { + uint8_t buffer[256]; + FrameDependencyStructure structure; + structure.num_decode_targets = 2; + structure.num_chains = 2; + structure.templates = { + FrameDependencyTemplate().T(0).Dtis("SR").ChainDiffs({2, 2})}; + DependencyDescriptor descriptor; + descriptor.frame_dependencies = structure.templates[0]; + + // Structure has 2 chains, but frame provide 1 chain diff, + descriptor.frame_dependencies.chain_diffs = {2}; + + EXPECT_EQ( + RtpDependencyDescriptorExtension::ValueSize(structure, 0b11, descriptor), + 0u); + EXPECT_FALSE(RtpDependencyDescriptorExtension::Write(buffer, structure, 0b11, + descriptor)); +} + +TEST(RtpDependencyDescriptorExtensionTest, + FailsToWriteWhenNumberOfDecodeTargetsMismatch) { + uint8_t buffer[256]; + FrameDependencyStructure structure; + structure.num_decode_targets = 2; + structure.num_chains = 2; + structure.templates = { + FrameDependencyTemplate().T(0).Dtis("SR").ChainDiffs({2, 2})}; + DependencyDescriptor descriptor; + descriptor.frame_dependencies = structure.templates[0]; + + // Structure has 2 decode targets, but frame provide 1 indication, + descriptor.frame_dependencies.decode_target_indications = { + DecodeTargetIndication::kSwitch}; + + EXPECT_EQ( + RtpDependencyDescriptorExtension::ValueSize(structure, 0b11, descriptor), + 0u); + EXPECT_FALSE(RtpDependencyDescriptorExtension::Write(buffer, structure, 0b11, + descriptor)); +} + } // namespace } // namespace webrtc diff --git a/modules/rtp_rtcp/source/rtp_dependency_descriptor_writer.cc b/modules/rtp_rtcp/source/rtp_dependency_descriptor_writer.cc index 31df783064..59a327a4bf 100644 --- a/modules/rtp_rtcp/source/rtp_dependency_descriptor_writer.cc +++ b/modules/rtp_rtcp/source/rtp_dependency_descriptor_writer.cc @@ -20,6 +20,7 @@ #include "api/transport/rtp/dependency_descriptor.h" #include "rtc_base/bit_buffer.h" #include "rtc_base/checks.h" +#include "rtc_base/numerics/safe_compare.h" namespace webrtc { namespace { @@ -62,6 +63,17 @@ RtpDependencyDescriptorWriter::RtpDependencyDescriptorWriter( structure_(structure), active_chains_(active_chains), bit_writer_(data.data(), data.size()) { + if (rtc::SafeNe(descriptor.frame_dependencies.chain_diffs.size(), + structure_.num_chains)) { + build_failed_ = true; + return; + } + if (rtc::SafeNe( + descriptor.frame_dependencies.decode_target_indications.size(), + structure_.num_decode_targets)) { + build_failed_ = true; + return; + } FindBestTemplate(); } diff --git a/video/rtp_video_stream_receiver2_unittest.cc b/video/rtp_video_stream_receiver2_unittest.cc index b2f407e9f6..fed4adb710 100644 --- a/video/rtp_video_stream_receiver2_unittest.cc +++ b/video/rtp_video_stream_receiver2_unittest.cc @@ -1308,7 +1308,7 @@ TEST_F(RtpVideoStreamReceiver2DependencyDescriptorTest, UnwrapsFrameId) { deltaframe1_descriptor.frame_number = 0xfffe; DependencyDescriptor deltaframe2_descriptor; - deltaframe1_descriptor.frame_dependencies = stream_structure.templates[1]; + deltaframe2_descriptor.frame_dependencies = stream_structure.templates[1]; deltaframe2_descriptor.frame_number = 0x0002; // Parser should unwrap frame ids correctly even if packets were reordered by