diff --git a/modules/rtp_rtcp/BUILD.gn b/modules/rtp_rtcp/BUILD.gn index 0ac6900e65..c9a3161111 100644 --- a/modules/rtp_rtcp/BUILD.gn +++ b/modules/rtp_rtcp/BUILD.gn @@ -463,6 +463,7 @@ if (rtc_include_tests) { "source/rtcp_sender_unittest.cc", "source/rtcp_transceiver_impl_unittest.cc", "source/rtcp_transceiver_unittest.cc", + "source/rtp_dependency_descriptor_extension_unittest.cc", "source/rtp_fec_unittest.cc", "source/rtp_format_h264_unittest.cc", "source/rtp_format_unittest.cc", diff --git a/modules/rtp_rtcp/source/rtp_dependency_descriptor_extension_unittest.cc b/modules/rtp_rtcp/source/rtp_dependency_descriptor_extension_unittest.cc new file mode 100644 index 0000000000..244bef8579 --- /dev/null +++ b/modules/rtp_rtcp/source/rtp_dependency_descriptor_extension_unittest.cc @@ -0,0 +1,73 @@ +/* + * 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. + */ + +#include "modules/rtp_rtcp/source/rtp_dependency_descriptor_extension.h" + +#include "api/array_view.h" +#include "api/transport/rtp/dependency_descriptor.h" +#include "common_video/generic_frame_descriptor/generic_frame_info.h" + +#include "test/gmock.h" + +namespace webrtc { +namespace { + +using ::testing::Each; + +TEST(RtpDependencyDescriptorExtensionTest, Writer3BytesForPerfectTemplate) { + uint8_t buffer[3]; + FrameDependencyStructure structure; + structure.num_decode_targets = 2; + structure.num_chains = 2; + structure.templates = {GenericFrameInfo::Builder() + .Dtis("SR") + .Fdiffs({1}) + .ChainDiffs({2, 2}) + .Build()}; + DependencyDescriptor descriptor; + descriptor.frame_dependencies = structure.templates[0]; + + EXPECT_EQ(RtpDependencyDescriptorExtension::ValueSize(structure, descriptor), + 3u); + EXPECT_TRUE( + RtpDependencyDescriptorExtension::Write(buffer, structure, descriptor)); +} + +TEST(RtpDependencyDescriptorExtensionTest, WriteZeroInUnusedBits) { + uint8_t buffer[32]; + std::memset(buffer, 0xff, sizeof(buffer)); + FrameDependencyStructure structure; + structure.num_decode_targets = 2; + structure.num_chains = 2; + structure.templates = {GenericFrameInfo::Builder() + .Dtis("SR") + .Fdiffs({1}) + .ChainDiffs({1, 1}) + .Build()}; + DependencyDescriptor descriptor; + descriptor.frame_dependencies = structure.templates[0]; + descriptor.frame_dependencies.frame_diffs = {2}; + + // To test unused bytes are zeroed, need a buffer large enough. + size_t value_size = + RtpDependencyDescriptorExtension::ValueSize(structure, descriptor); + ASSERT_LT(value_size, sizeof(buffer)); + + ASSERT_TRUE( + RtpDependencyDescriptorExtension::Write(buffer, structure, descriptor)); + + const uint8_t* unused_bytes = buffer + value_size; + size_t num_unused_bytes = buffer + sizeof(buffer) - unused_bytes; + // Check remaining bytes are zeroed. + EXPECT_THAT(rtc::MakeArrayView(unused_bytes, num_unused_bytes), Each(0)); +} + +} // 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 d933a94128..df5310b6ba 100644 --- a/modules/rtp_rtcp/source/rtp_dependency_descriptor_writer.cc +++ b/modules/rtp_rtcp/source/rtp_dependency_descriptor_writer.cc @@ -75,9 +75,12 @@ bool RtpDependencyDescriptorWriter::Write() { WriteFrameDependencyDefinition(); } size_t remaining_bits = bit_writer_.RemainingBitCount(); - if (remaining_bits > 0) { - // Zero remaining memory to avoid leaving it uninitialized. - WriteBits(/*val=*/0, remaining_bits); + // Zero remaining memory to avoid leaving it uninitialized. + if (remaining_bits % 64 != 0) { + WriteBits(/*val=*/0, remaining_bits % 64); + } + for (size_t i = 0; i < remaining_bits / 64; ++i) { + WriteBits(/*val=*/0, 64); } return !build_failed_; }