In DependencyDescriptor rtp header extension drop partial chain support
i.e. when chain are used, require each decode target to be protected by some chain. where previously it was allowed to mark decode target as unprotected. See https://github.com/AOMediaCodec/av1-rtp-spec/pull/125 Bug: webrtc:10342 Change-Id: Ia2800036e890db44bb1162abfa1a497ff68f3b24 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/178807 Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Björn Terelius <terelius@webrtc.org> Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31772}
This commit is contained in:

committed by
Commit Bot

parent
0bc68bd164
commit
a5d9c1a45c
@ -91,8 +91,7 @@ struct FrameDependencyStructure {
|
||||
int num_decode_targets = 0;
|
||||
int num_chains = 0;
|
||||
// If chains are used (num_chains > 0), maps decode target index into index of
|
||||
// the chain protecting that target or |num_chains| value if decode target is
|
||||
// not protected by a chain.
|
||||
// the chain protecting that target.
|
||||
absl::InlinedVector<int, 10> decode_target_protected_by_chain;
|
||||
absl::InlinedVector<RenderResolution, 4> resolutions;
|
||||
std::vector<FrameDependencyTemplate> templates;
|
||||
|
@ -50,13 +50,10 @@ std::bitset<32> ActiveChains(
|
||||
if (dt < active_decode_targets.size() && !active_decode_targets[dt]) {
|
||||
continue;
|
||||
}
|
||||
// chain_idx == num_chains is valid and means the decode target is
|
||||
// not protected by any chain.
|
||||
int chain_idx = decode_target_protected_by_chain[dt];
|
||||
if (chain_idx < num_chains) {
|
||||
RTC_DCHECK_LT(chain_idx, num_chains);
|
||||
active_chains.set(chain_idx);
|
||||
}
|
||||
}
|
||||
return active_chains;
|
||||
}
|
||||
|
||||
@ -109,20 +106,19 @@ void ActiveDecodeTargetsHelper::OnFrame(
|
||||
return;
|
||||
}
|
||||
last_active_decode_targets_ = active_decode_targets;
|
||||
|
||||
if (active_decode_targets.none()) {
|
||||
RTC_LOG(LS_ERROR) << "It is invalid to produce a frame (" << frame_id
|
||||
<< ") while there are no active decode targets";
|
||||
return;
|
||||
}
|
||||
last_active_chains_ = ActiveChains(decode_target_protected_by_chain,
|
||||
num_chains, active_decode_targets);
|
||||
// Frames that are part of inactive chains might not be produced by the
|
||||
// encoder. Thus stop sending `active_decode_target` bitmask when it is sent
|
||||
// on all active chains rather than on all chains.
|
||||
unsent_on_chain_ = last_active_chains_;
|
||||
if (unsent_on_chain_.none()) {
|
||||
// Active decode targets are not protected by any chains. To be on the
|
||||
// safe side always send the active_decode_targets_bitmask from now on.
|
||||
RTC_LOG(LS_WARNING)
|
||||
<< "Active decode targets protected by no chains. (In)active decode "
|
||||
"targets information will be send overreliably.";
|
||||
unsent_on_chain_.set(1);
|
||||
}
|
||||
RTC_DCHECK(!unsent_on_chain_.none());
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
@ -241,29 +241,6 @@ TEST(ActiveDecodeTargetsHelperTest, ReturnsNulloptWhenChainsAreNotUsed) {
|
||||
EXPECT_EQ(helper.ActiveDecodeTargetsBitmask(), absl::nullopt);
|
||||
}
|
||||
|
||||
TEST(ActiveDecodeTargetsHelperTest,
|
||||
KeepReturningBitmaskWhenAllChainsAreInactive) {
|
||||
// Two decode targets, but single chain.
|
||||
// 2nd decode target is not protected by any chain.
|
||||
constexpr int kDecodeTargetProtectedByChain[] = {0, 1};
|
||||
|
||||
ActiveDecodeTargetsHelper helper;
|
||||
int chain_diffs_key[] = {0};
|
||||
helper.OnFrame(kDecodeTargetProtectedByChain, /*active_decode_targets=*/0b10,
|
||||
/*is_keyframe=*/true,
|
||||
/*frame_id=*/0, chain_diffs_key);
|
||||
EXPECT_EQ(helper.ActiveDecodeTargetsBitmask(), 0b10u);
|
||||
|
||||
// Even though previous frame is part of the only chain, that inactive chain
|
||||
// doesn't provide guaranted delivery.
|
||||
int chain_diffs_delta[] = {1};
|
||||
helper.OnFrame(kDecodeTargetProtectedByChain,
|
||||
/*active_decode_targets=*/0b10,
|
||||
/*is_keyframe=*/false,
|
||||
/*frame_id=*/1, chain_diffs_delta);
|
||||
EXPECT_EQ(helper.ActiveDecodeTargetsBitmask(), 0b10u);
|
||||
}
|
||||
|
||||
TEST(ActiveDecodeTargetsHelperTest, Supports32DecodeTargets) {
|
||||
std::bitset<32> some;
|
||||
std::vector<int> decode_target_protected_by_chain(32);
|
||||
|
@ -146,7 +146,7 @@ void RtpDependencyDescriptorReader::ReadTemplateChains() {
|
||||
if (structure->num_chains == 0)
|
||||
return;
|
||||
for (int i = 0; i < structure->num_decode_targets; ++i) {
|
||||
uint32_t protected_by_chain = ReadNonSymmetric(structure->num_chains + 1);
|
||||
uint32_t protected_by_chain = ReadNonSymmetric(structure->num_chains);
|
||||
structure->decode_target_protected_by_chain.push_back(protected_by_chain);
|
||||
}
|
||||
for (FrameDependencyTemplate& frame_template : structure->templates) {
|
||||
|
@ -111,8 +111,8 @@ int RtpDependencyDescriptorWriter::StructureSizeBits() const {
|
||||
structure_.num_chains, structure_.num_decode_targets + 1);
|
||||
if (structure_.num_chains > 0) {
|
||||
for (int protected_by : structure_.decode_target_protected_by_chain) {
|
||||
bits += rtc::BitBufferWriter::SizeNonSymmetricBits(
|
||||
protected_by, structure_.num_chains + 1);
|
||||
bits += rtc::BitBufferWriter::SizeNonSymmetricBits(protected_by,
|
||||
structure_.num_chains);
|
||||
}
|
||||
bits += 4 * structure_.templates.size() * structure_.num_chains;
|
||||
}
|
||||
@ -288,8 +288,8 @@ void RtpDependencyDescriptorWriter::WriteTemplateChains() {
|
||||
structure_.num_decode_targets);
|
||||
for (int protected_by : structure_.decode_target_protected_by_chain) {
|
||||
RTC_DCHECK_GE(protected_by, 0);
|
||||
RTC_DCHECK_LE(protected_by, structure_.num_chains);
|
||||
WriteNonSymmetric(protected_by, structure_.num_chains + 1);
|
||||
RTC_DCHECK_LT(protected_by, structure_.num_chains);
|
||||
WriteNonSymmetric(protected_by, structure_.num_chains);
|
||||
}
|
||||
for (const auto& frame_template : structure_.templates) {
|
||||
RTC_DCHECK_EQ(frame_template.chain_diffs.size(), structure_.num_chains);
|
||||
|
@ -567,8 +567,7 @@ TEST_P(RtpSenderVideoTest, PropagatesChainDiffsIntoDependencyDescriptor) {
|
||||
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.decode_target_protected_by_chain = {0, 0};
|
||||
video_structure.templates = {
|
||||
FrameDependencyTemplate().S(0).T(0).Dtis("SS").ChainDiffs({1}),
|
||||
};
|
||||
|
@ -104,7 +104,7 @@ TEST_P(ScalabilityStructureTest,
|
||||
} else {
|
||||
EXPECT_THAT(structure.decode_target_protected_by_chain,
|
||||
AllOf(SizeIs(structure.num_decode_targets), Each(Ge(0)),
|
||||
Each(Le(structure.num_chains))));
|
||||
Each(Lt(structure.num_chains))));
|
||||
}
|
||||
EXPECT_THAT(structure.templates,
|
||||
SizeIs(Lt(size_t{DependencyDescriptor::kMaxTemplates})));
|
||||
|
Reference in New Issue
Block a user