In dependency descritpor add active decode targets bitmask field
to follow spec draft change.
Bug: webrtc:10342
Change-Id: I8cd9f26a2061ecd62a3a7826c4086141203ee5cd
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/159022
Reviewed-by: Sam Zackrisson <saza@webrtc.org>
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29726}
diff --git a/common_video/generic_frame_descriptor/generic_frame_info.h b/common_video/generic_frame_descriptor/generic_frame_info.h
index 3916530..2aff0e3 100644
--- a/common_video/generic_frame_descriptor/generic_frame_info.h
+++ b/common_video/generic_frame_descriptor/generic_frame_info.h
@@ -97,6 +97,7 @@
int frame_number = 0;
FrameDependencyTemplate frame_dependencies;
absl::optional<RenderResolution> resolution;
+ absl::optional<uint32_t> active_decode_targets_bitmask;
std::unique_ptr<FrameDependencyStructure> attached_structure;
};
diff --git a/modules/rtp_rtcp/source/rtp_dependency_descriptor_reader.cc b/modules/rtp_rtcp/source/rtp_dependency_descriptor_reader.cc
index 5170578..5103d7f 100644
--- a/modules/rtp_rtcp/source/rtp_dependency_descriptor_reader.cc
+++ b/modules/rtp_rtcp/source/rtp_dependency_descriptor_reader.cc
@@ -41,10 +41,15 @@
structure_ = descriptor->attached_structure
? descriptor->attached_structure.get()
: structure;
- if (structure_ == nullptr) {
+ if (structure_ == nullptr || parsing_failed_) {
parsing_failed_ = true;
return;
}
+ if (active_decode_targets_present_flag_) {
+ descriptor->active_decode_targets_bitmask =
+ ReadBits(structure_->num_decode_targets);
+ }
+
ReadFrameDependencyDefinition();
}
@@ -190,12 +195,16 @@
return;
}
bool template_dependency_structure_present_flag = ReadBits(1);
+ active_decode_targets_present_flag_ = ReadBits(1);
custom_dtis_flag_ = ReadBits(1);
custom_fdiffs_flag_ = ReadBits(1);
custom_chains_flag_ = ReadBits(1);
if (template_dependency_structure_present_flag) {
ReadTemplateDependencyStructure();
RTC_DCHECK(descriptor_->attached_structure);
+ descriptor_->active_decode_targets_bitmask =
+ (uint64_t{1} << descriptor_->attached_structure->num_decode_targets) -
+ 1;
}
}
diff --git a/modules/rtp_rtcp/source/rtp_dependency_descriptor_reader.h b/modules/rtp_rtcp/source/rtp_dependency_descriptor_reader.h
index e16fba8..11df2f4 100644
--- a/modules/rtp_rtcp/source/rtp_dependency_descriptor_reader.h
+++ b/modules/rtp_rtcp/source/rtp_dependency_descriptor_reader.h
@@ -63,6 +63,7 @@
// when reading is complete.
rtc::BitBuffer buffer_;
int frame_dependency_template_id_ = 0;
+ bool active_decode_targets_present_flag_ = false;
bool custom_dtis_flag_ = false;
bool custom_fdiffs_flag_ = false;
bool custom_chains_flag_ = false;
diff --git a/modules/rtp_rtcp/source/rtp_dependency_descriptor_writer.cc b/modules/rtp_rtcp/source/rtp_dependency_descriptor_writer.cc
index ea10e37..1190acf 100644
--- a/modules/rtp_rtcp/source/rtp_dependency_descriptor_writer.cc
+++ b/modules/rtp_rtcp/source/rtp_dependency_descriptor_writer.cc
@@ -80,8 +80,13 @@
int RtpDependencyDescriptorWriter::ValueSizeBits() const {
static constexpr int kMandatoryFields = 1 + 1 + 6 + 16;
int value_size_bits = kMandatoryFields + best_template_.extra_size_bits;
- if (descriptor_.attached_structure)
- value_size_bits += 10 + StructureSizeBits();
+ if (HasExtendedFields()) {
+ value_size_bits += 11;
+ if (descriptor_.attached_structure)
+ value_size_bits += StructureSizeBits();
+ if (ShouldWriteActiveDecodeTargetsBitmask())
+ value_size_bits += structure_.num_decode_targets;
+ }
return value_size_bits;
}
@@ -124,15 +129,7 @@
result.need_custom_chains =
descriptor_.frame_dependencies.chain_diffs != frame_template->chain_diffs;
- if (!result.need_custom_fdiffs && !result.need_custom_dtis &&
- !result.need_custom_chains) {
- // Perfect match.
- result.extra_size_bits = 0;
- return result;
- }
- // If structure should be attached, then there will be ExtendedFields anyway,
- // so do not count 10 bits for them as extra.
- result.extra_size_bits = descriptor_.attached_structure ? 0 : 10;
+ result.extra_size_bits = 0;
if (result.need_custom_fdiffs) {
result.extra_size_bits +=
2 * (1 + descriptor_.frame_dependencies.frame_diffs.size());
@@ -176,8 +173,21 @@
}
}
+bool RtpDependencyDescriptorWriter::ShouldWriteActiveDecodeTargetsBitmask()
+ const {
+ if (!descriptor_.active_decode_targets_bitmask)
+ return false;
+ const uint64_t all_decode_targets_bitmask =
+ (uint64_t{1} << structure_.num_decode_targets) - 1;
+ if (descriptor_.attached_structure &&
+ descriptor_.active_decode_targets_bitmask == all_decode_targets_bitmask)
+ return false;
+ return true;
+}
+
bool RtpDependencyDescriptorWriter::HasExtendedFields() const {
- return best_template_.extra_size_bits > 0 || descriptor_.attached_structure;
+ return best_template_.extra_size_bits > 0 || descriptor_.attached_structure ||
+ descriptor_.active_decode_targets_bitmask;
}
uint64_t RtpDependencyDescriptorWriter::TemplateId() const {
@@ -306,11 +316,17 @@
uint64_t template_dependency_structure_present_flag =
descriptor_.attached_structure ? 1u : 0u;
WriteBits(template_dependency_structure_present_flag, 1);
+ uint64_t active_decode_targets_present_flag =
+ ShouldWriteActiveDecodeTargetsBitmask() ? 1u : 0u;
+ WriteBits(active_decode_targets_present_flag, 1);
WriteBits(best_template_.need_custom_dtis, 1);
WriteBits(best_template_.need_custom_fdiffs, 1);
WriteBits(best_template_.need_custom_chains, 1);
- if (descriptor_.attached_structure)
+ if (template_dependency_structure_present_flag)
WriteTemplateDependencyStructure();
+ if (active_decode_targets_present_flag)
+ WriteBits(*descriptor_.active_decode_targets_bitmask,
+ structure_.num_decode_targets);
}
void RtpDependencyDescriptorWriter::WriteFrameDependencyDefinition() {
diff --git a/modules/rtp_rtcp/source/rtp_dependency_descriptor_writer.h b/modules/rtp_rtcp/source/rtp_dependency_descriptor_writer.h
index 750c7ed..5274f2d 100644
--- a/modules/rtp_rtcp/source/rtp_dependency_descriptor_writer.h
+++ b/modules/rtp_rtcp/source/rtp_dependency_descriptor_writer.h
@@ -50,6 +50,7 @@
int StructureSizeBits() const;
TemplateMatch CalculateMatch(TemplateIterator frame_template) const;
void FindBestTemplate();
+ bool ShouldWriteActiveDecodeTargetsBitmask() const;
bool HasExtendedFields() const;
uint64_t TemplateId() const;
diff --git a/test/fuzzers/rtp_dependency_descriptor_fuzzer.cc b/test/fuzzers/rtp_dependency_descriptor_fuzzer.cc
index fbe7ac3..0736bba 100644
--- a/test/fuzzers/rtp_dependency_descriptor_fuzzer.cc
+++ b/test/fuzzers/rtp_dependency_descriptor_fuzzer.cc
@@ -21,19 +21,6 @@
#include "test/fuzzers/fuzz_data_helper.h"
namespace webrtc {
-namespace {
-
-bool AreSame(const DependencyDescriptor& lhs, const DependencyDescriptor& rhs) {
- return lhs.first_packet_in_frame == rhs.first_packet_in_frame &&
- lhs.last_packet_in_frame == rhs.last_packet_in_frame &&
- (lhs.attached_structure != nullptr) ==
- (rhs.attached_structure != nullptr) &&
- lhs.frame_number == rhs.frame_number &&
- lhs.resolution == rhs.resolution &&
- lhs.frame_dependencies == rhs.frame_dependencies;
-}
-
-} // namespace
void FuzzOneInput(const uint8_t* data, size_t size) {
FrameDependencyStructure structure1;
@@ -80,7 +67,23 @@
DependencyDescriptor descriptor2;
RTC_CHECK(RtpDependencyDescriptorExtension::Parse(
write_buffer, structure2.get(), &descriptor2));
- RTC_CHECK(AreSame(descriptor1, descriptor2));
+ // Check descriptor1 and descriptor2 have same values.
+ RTC_CHECK_EQ(descriptor1.first_packet_in_frame,
+ descriptor2.first_packet_in_frame);
+ RTC_CHECK_EQ(descriptor1.last_packet_in_frame,
+ descriptor2.last_packet_in_frame);
+ RTC_CHECK_EQ(descriptor1.attached_structure != nullptr,
+ descriptor2.attached_structure != nullptr);
+ // Using value_or would miss invalid corner case when one value is nullopt
+ // while another one is 0, but for other errors would produce much nicer
+ // error message than using RTC_CHECK(optional1 == optional2);
+ // If logger would support pretty printing optional values, value_or can be
+ // removed.
+ RTC_CHECK_EQ(descriptor1.active_decode_targets_bitmask.value_or(0),
+ descriptor2.active_decode_targets_bitmask.value_or(0));
+ RTC_CHECK_EQ(descriptor1.frame_number, descriptor2.frame_number);
+ RTC_CHECK(descriptor1.resolution == descriptor2.resolution);
+ RTC_CHECK(descriptor1.frame_dependencies == descriptor2.frame_dependencies);
if (descriptor2.attached_structure) {
structure2 = std::move(descriptor2.attached_structure);