Embed FrameDependencyTemplate builder helpers directly into the struct

Bug: None
Change-Id: I4c13bdabd08dd6a6011cb534c765c1dd09f218d1
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/176843
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Björn Terelius <terelius@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31500}
This commit is contained in:
Danil Chapovalov 2020-06-11 13:23:45 +02:00 committed by Commit Bot
parent f4a9991cce
commit 24263f4ffb
24 changed files with 242 additions and 316 deletions

View File

@ -20,9 +20,14 @@ rtc_source_set("rtp_source") {
rtc_source_set("dependency_descriptor") { rtc_source_set("dependency_descriptor") {
visibility = [ "*" ] visibility = [ "*" ]
sources = [ "dependency_descriptor.h" ] sources = [
"dependency_descriptor.cc",
"dependency_descriptor.h",
]
deps = [ "../../../rtc_base:checks" ]
absl_deps = [ absl_deps = [
"//third_party/abseil-cpp/absl/container:inlined_vector", "//third_party/abseil-cpp/absl/container:inlined_vector",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:optional", "//third_party/abseil-cpp/absl/types:optional",
] ]
} }

View File

@ -0,0 +1,48 @@
/*
* 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 "api/transport/rtp/dependency_descriptor.h"
#include "absl/container/inlined_vector.h"
#include "absl/strings/string_view.h"
#include "rtc_base/checks.h"
namespace webrtc {
namespace webrtc_impl {
absl::InlinedVector<DecodeTargetIndication, 10> StringToDecodeTargetIndications(
absl::string_view symbols) {
absl::InlinedVector<DecodeTargetIndication, 10> dtis;
dtis.reserve(symbols.size());
for (char symbol : symbols) {
DecodeTargetIndication indication;
switch (symbol) {
case '-':
indication = DecodeTargetIndication::kNotPresent;
break;
case 'D':
indication = DecodeTargetIndication::kDiscardable;
break;
case 'R':
indication = DecodeTargetIndication::kRequired;
break;
case 'S':
indication = DecodeTargetIndication::kSwitch;
break;
default:
RTC_NOTREACHED();
}
dtis.push_back(indication);
}
return dtis;
}
} // namespace webrtc_impl
} // namespace webrtc

View File

@ -13,10 +13,12 @@
#include <stdint.h> #include <stdint.h>
#include <initializer_list>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "absl/container/inlined_vector.h" #include "absl/container/inlined_vector.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h" #include "absl/types/optional.h"
namespace webrtc { namespace webrtc {
@ -52,6 +54,13 @@ enum class DecodeTargetIndication {
}; };
struct FrameDependencyTemplate { struct FrameDependencyTemplate {
// Setters are named briefly to chain them when building the template.
FrameDependencyTemplate& S(int spatial_layer);
FrameDependencyTemplate& T(int temporal_layer);
FrameDependencyTemplate& Dtis(absl::string_view dtis);
FrameDependencyTemplate& FrameDiffs(std::initializer_list<int> diffs);
FrameDependencyTemplate& ChainDiffs(std::initializer_list<int> diffs);
friend bool operator==(const FrameDependencyTemplate& lhs, friend bool operator==(const FrameDependencyTemplate& lhs,
const FrameDependencyTemplate& rhs) { const FrameDependencyTemplate& rhs) {
return lhs.spatial_id == rhs.spatial_id && return lhs.spatial_id == rhs.spatial_id &&
@ -99,6 +108,37 @@ struct DependencyDescriptor {
std::unique_ptr<FrameDependencyStructure> attached_structure; std::unique_ptr<FrameDependencyStructure> attached_structure;
}; };
// Below are implementation details.
namespace webrtc_impl {
absl::InlinedVector<DecodeTargetIndication, 10> StringToDecodeTargetIndications(
absl::string_view indication_symbols);
} // namespace webrtc_impl
inline FrameDependencyTemplate& FrameDependencyTemplate::S(int spatial_layer) {
this->spatial_id = spatial_layer;
return *this;
}
inline FrameDependencyTemplate& FrameDependencyTemplate::T(int temporal_layer) {
this->temporal_id = temporal_layer;
return *this;
}
inline FrameDependencyTemplate& FrameDependencyTemplate::Dtis(
absl::string_view dtis) {
this->decode_target_indications =
webrtc_impl::StringToDecodeTargetIndications(dtis);
return *this;
}
inline FrameDependencyTemplate& FrameDependencyTemplate::FrameDiffs(
std::initializer_list<int> diffs) {
this->frame_diffs.assign(diffs.begin(), diffs.end());
return *this;
}
inline FrameDependencyTemplate& FrameDependencyTemplate::ChainDiffs(
std::initializer_list<int> diffs) {
this->chain_diffs.assign(diffs.begin(), diffs.end());
return *this;
}
} // namespace webrtc } // namespace webrtc
#endif // API_TRANSPORT_RTP_DEPENDENCY_DESCRIPTOR_H_ #endif // API_TRANSPORT_RTP_DEPENDENCY_DESCRIPTOR_H_

View File

@ -705,9 +705,9 @@ TEST(RtpVideoSenderTest, SupportsDependencyDescriptor) {
codec_specific.template_structure.emplace(); codec_specific.template_structure.emplace();
codec_specific.template_structure->num_decode_targets = 1; codec_specific.template_structure->num_decode_targets = 1;
codec_specific.template_structure->templates = { codec_specific.template_structure->templates = {
GenericFrameInfo::Builder().T(0).Dtis("S").Build(), FrameDependencyTemplate().T(0).Dtis("S"),
GenericFrameInfo::Builder().T(0).Dtis("S").Fdiffs({2}).Build(), FrameDependencyTemplate().T(0).Dtis("S").FrameDiffs({2}),
GenericFrameInfo::Builder().T(1).Dtis("D").Fdiffs({1}).Build(), FrameDependencyTemplate().T(1).Dtis("D").FrameDiffs({1}),
}; };
// Send two tiny images, mapping to single RTP packets. // Send two tiny images, mapping to single RTP packets.
@ -769,9 +769,9 @@ TEST(RtpVideoSenderTest, SupportsStoppingUsingDependencyDescriptor) {
codec_specific.template_structure.emplace(); codec_specific.template_structure.emplace();
codec_specific.template_structure->num_decode_targets = 1; codec_specific.template_structure->num_decode_targets = 1;
codec_specific.template_structure->templates = { codec_specific.template_structure->templates = {
GenericFrameInfo::Builder().T(0).Dtis("S").Build(), FrameDependencyTemplate().T(0).Dtis("S"),
GenericFrameInfo::Builder().T(0).Dtis("S").Fdiffs({2}).Build(), FrameDependencyTemplate().T(0).Dtis("S").FrameDiffs({2}),
GenericFrameInfo::Builder().T(1).Dtis("D").Fdiffs({1}).Build(), FrameDependencyTemplate().T(1).Dtis("D").FrameDiffs({1}),
}; };
// Send two tiny images, mapping to single RTP packets. // Send two tiny images, mapping to single RTP packets.

View File

@ -15,33 +15,6 @@
namespace webrtc { namespace webrtc {
absl::InlinedVector<DecodeTargetIndication, 10>
GenericFrameInfo::DecodeTargetInfo(absl::string_view indication_symbols) {
absl::InlinedVector<DecodeTargetIndication, 10> decode_targets;
for (char symbol : indication_symbols) {
DecodeTargetIndication indication;
switch (symbol) {
case '-':
indication = DecodeTargetIndication::kNotPresent;
break;
case 'D':
indication = DecodeTargetIndication::kDiscardable;
break;
case 'R':
indication = DecodeTargetIndication::kRequired;
break;
case 'S':
indication = DecodeTargetIndication::kSwitch;
break;
default:
RTC_NOTREACHED();
}
decode_targets.push_back(indication);
}
return decode_targets;
}
GenericFrameInfo::GenericFrameInfo() = default; GenericFrameInfo::GenericFrameInfo() = default;
GenericFrameInfo::GenericFrameInfo(const GenericFrameInfo&) = default; GenericFrameInfo::GenericFrameInfo(const GenericFrameInfo&) = default;
GenericFrameInfo::~GenericFrameInfo() = default; GenericFrameInfo::~GenericFrameInfo() = default;
@ -65,19 +38,8 @@ GenericFrameInfo::Builder& GenericFrameInfo::Builder::S(int spatial_id) {
GenericFrameInfo::Builder& GenericFrameInfo::Builder::Dtis( GenericFrameInfo::Builder& GenericFrameInfo::Builder::Dtis(
absl::string_view indication_symbols) { absl::string_view indication_symbols) {
info_.decode_target_indications = DecodeTargetInfo(indication_symbols); info_.decode_target_indications =
return *this; webrtc_impl::StringToDecodeTargetIndications(indication_symbols);
}
GenericFrameInfo::Builder& GenericFrameInfo::Builder::Fdiffs(
std::initializer_list<int> frame_diffs) {
info_.frame_diffs.assign(frame_diffs.begin(), frame_diffs.end());
return *this;
}
GenericFrameInfo::Builder& GenericFrameInfo::Builder::ChainDiffs(
std::initializer_list<int> chain_diffs) {
info_.chain_diffs.assign(chain_diffs.begin(), chain_diffs.end());
return *this; return *this;
} }

View File

@ -32,9 +32,6 @@ struct CodecBufferUsage {
}; };
struct GenericFrameInfo : public FrameDependencyTemplate { struct GenericFrameInfo : public FrameDependencyTemplate {
static absl::InlinedVector<DecodeTargetIndication, 10> DecodeTargetInfo(
absl::string_view indication_symbols);
class Builder; class Builder;
GenericFrameInfo(); GenericFrameInfo();
@ -54,8 +51,6 @@ class GenericFrameInfo::Builder {
Builder& T(int temporal_id); Builder& T(int temporal_id);
Builder& S(int spatial_id); Builder& S(int spatial_id);
Builder& Dtis(absl::string_view indication_symbols); Builder& Dtis(absl::string_view indication_symbols);
Builder& Fdiffs(std::initializer_list<int> frame_diffs);
Builder& ChainDiffs(std::initializer_list<int> chain_diffs);
private: private:
GenericFrameInfo info_; GenericFrameInfo info_;

View File

@ -26,11 +26,8 @@ TEST(RtpDependencyDescriptorExtensionTest, Writer3BytesForPerfectTemplate) {
FrameDependencyStructure structure; FrameDependencyStructure structure;
structure.num_decode_targets = 2; structure.num_decode_targets = 2;
structure.num_chains = 2; structure.num_chains = 2;
structure.templates = {GenericFrameInfo::Builder() structure.templates = {
.Dtis("SR") FrameDependencyTemplate().Dtis("SR").FrameDiffs({1}).ChainDiffs({2, 2})};
.Fdiffs({1})
.ChainDiffs({2, 2})
.Build()};
DependencyDescriptor descriptor; DependencyDescriptor descriptor;
descriptor.frame_dependencies = structure.templates[0]; descriptor.frame_dependencies = structure.templates[0];
@ -46,11 +43,8 @@ TEST(RtpDependencyDescriptorExtensionTest, WriteZeroInUnusedBits) {
FrameDependencyStructure structure; FrameDependencyStructure structure;
structure.num_decode_targets = 2; structure.num_decode_targets = 2;
structure.num_chains = 2; structure.num_chains = 2;
structure.templates = {GenericFrameInfo::Builder() structure.templates = {
.Dtis("SR") FrameDependencyTemplate().Dtis("SR").FrameDiffs({1}).ChainDiffs({1, 1})};
.Fdiffs({1})
.ChainDiffs({1, 1})
.Build()};
DependencyDescriptor descriptor; DependencyDescriptor descriptor;
descriptor.frame_dependencies = structure.templates[0]; descriptor.frame_dependencies = structure.templates[0];
descriptor.frame_dependencies.frame_diffs = {2}; descriptor.frame_dependencies.frame_diffs = {2};

View File

@ -548,9 +548,9 @@ TEST_P(RtpSenderVideoTest, SendsDependencyDescriptorWhenVideoStructureIsSet) {
FrameDependencyStructure video_structure; FrameDependencyStructure video_structure;
video_structure.num_decode_targets = 2; video_structure.num_decode_targets = 2;
video_structure.templates = { video_structure.templates = {
GenericFrameInfo::Builder().S(0).T(0).Dtis("SS").Build(), FrameDependencyTemplate().S(0).T(0).Dtis("SS"),
GenericFrameInfo::Builder().S(1).T(0).Dtis("-S").Build(), FrameDependencyTemplate().S(1).T(0).Dtis("-S"),
GenericFrameInfo::Builder().S(1).T(1).Dtis("-D").Build(), FrameDependencyTemplate().S(1).T(1).Dtis("-D"),
}; };
rtp_sender_video_.SetVideoStructure(&video_structure); rtp_sender_video_.SetVideoStructure(&video_structure);
@ -619,7 +619,7 @@ TEST_P(RtpSenderVideoTest, PropagatesChainDiffsIntoDependencyDescriptor) {
// First decode target is protected by the only chain, second one - is not. // 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, 1};
video_structure.templates = { video_structure.templates = {
GenericFrameInfo::Builder().S(0).T(0).Dtis("SS").ChainDiffs({1}).Build(), FrameDependencyTemplate().S(0).T(0).Dtis("SS").ChainDiffs({1}),
}; };
rtp_sender_video_.SetVideoStructure(&video_structure); rtp_sender_video_.SetVideoStructure(&video_structure);
@ -651,14 +651,14 @@ TEST_P(RtpSenderVideoTest,
FrameDependencyStructure video_structure1; FrameDependencyStructure video_structure1;
video_structure1.num_decode_targets = 2; video_structure1.num_decode_targets = 2;
video_structure1.templates = { video_structure1.templates = {
GenericFrameInfo::Builder().S(0).T(0).Dtis("SS").Build(), FrameDependencyTemplate().S(0).T(0).Dtis("SS"),
GenericFrameInfo::Builder().S(0).T(1).Dtis("D-").Build(), FrameDependencyTemplate().S(0).T(1).Dtis("D-"),
}; };
FrameDependencyStructure video_structure2; FrameDependencyStructure video_structure2;
video_structure2.num_decode_targets = 2; video_structure2.num_decode_targets = 2;
video_structure2.templates = { video_structure2.templates = {
GenericFrameInfo::Builder().S(0).T(0).Dtis("SS").Build(), FrameDependencyTemplate().S(0).T(0).Dtis("SS"),
GenericFrameInfo::Builder().S(0).T(1).Dtis("R-").Build(), FrameDependencyTemplate().S(0).T(1).Dtis("R-"),
}; };
// Send 1st key frame. // Send 1st key frame.
@ -741,7 +741,7 @@ TEST_P(RtpSenderVideoTest,
FrameDependencyStructure video_structure; FrameDependencyStructure video_structure;
video_structure.num_decode_targets = 1; video_structure.num_decode_targets = 1;
video_structure.templates = {GenericFrameInfo::Builder().Dtis("S").Build()}; video_structure.templates = {FrameDependencyTemplate().Dtis("S")};
rtp_sender_video.SetVideoStructure(&video_structure); rtp_sender_video.SetVideoStructure(&video_structure);
// Send key frame. // Send key frame.

View File

@ -43,16 +43,14 @@ ScalabilityStructureL1T2::StreamConfig() const {
} }
FrameDependencyStructure ScalabilityStructureL1T2::DependencyStructure() const { FrameDependencyStructure ScalabilityStructureL1T2::DependencyStructure() const {
using Builder = GenericFrameInfo::Builder;
FrameDependencyStructure structure; FrameDependencyStructure structure;
structure.num_decode_targets = 2; structure.num_decode_targets = 2;
structure.num_chains = 1; structure.num_chains = 1;
structure.decode_target_protected_by_chain = {0, 0}; structure.decode_target_protected_by_chain = {0, 0};
structure.templates = { structure.templates.resize(3);
Builder().T(0).Dtis("SS").ChainDiffs({0}).Build(), structure.templates[0].T(0).Dtis("SS").ChainDiffs({0});
Builder().T(0).Dtis("SS").ChainDiffs({2}).Fdiffs({2}).Build(), structure.templates[1].T(0).Dtis("SS").ChainDiffs({2}).FrameDiffs({2});
Builder().T(1).Dtis("-D").ChainDiffs({1}).Fdiffs({1}).Build(), structure.templates[2].T(1).Dtis("-D").ChainDiffs({1}).FrameDiffs({1});
};
return structure; return structure;
} }

View File

@ -43,18 +43,16 @@ ScalabilityStructureL1T3::StreamConfig() const {
} }
FrameDependencyStructure ScalabilityStructureL1T3::DependencyStructure() const { FrameDependencyStructure ScalabilityStructureL1T3::DependencyStructure() const {
using Builder = GenericFrameInfo::Builder;
FrameDependencyStructure structure; FrameDependencyStructure structure;
structure.num_decode_targets = 3; structure.num_decode_targets = 3;
structure.num_chains = 1; structure.num_chains = 1;
structure.decode_target_protected_by_chain = {0, 0, 0}; structure.decode_target_protected_by_chain = {0, 0, 0};
structure.templates = { structure.templates.resize(5);
Builder().T(0).Dtis("SSS").ChainDiffs({0}).Build(), structure.templates[0].T(0).Dtis("SSS").ChainDiffs({0});
Builder().T(0).Dtis("SSS").ChainDiffs({4}).Fdiffs({4}).Build(), structure.templates[1].T(0).Dtis("SSS").ChainDiffs({4}).FrameDiffs({4});
Builder().T(1).Dtis("-DS").ChainDiffs({2}).Fdiffs({2}).Build(), structure.templates[2].T(1).Dtis("-DS").ChainDiffs({2}).FrameDiffs({2});
Builder().T(2).Dtis("--D").ChainDiffs({1}).Fdiffs({1}).Build(), structure.templates[3].T(2).Dtis("--D").ChainDiffs({1}).FrameDiffs({1});
Builder().T(2).Dtis("--D").ChainDiffs({3}).Fdiffs({1}).Build(), structure.templates[4].T(2).Dtis("--D").ChainDiffs({3}).FrameDiffs({1});
};
return structure; return structure;
} }

View File

@ -44,17 +44,15 @@ ScalabilityStructureL2T1::StreamConfig() const {
} }
FrameDependencyStructure ScalabilityStructureL2T1::DependencyStructure() const { FrameDependencyStructure ScalabilityStructureL2T1::DependencyStructure() const {
using Builder = GenericFrameInfo::Builder;
FrameDependencyStructure structure; FrameDependencyStructure structure;
structure.num_decode_targets = 2; structure.num_decode_targets = 2;
structure.num_chains = 2; structure.num_chains = 2;
structure.decode_target_protected_by_chain = {0, 1}; structure.decode_target_protected_by_chain = {0, 1};
structure.templates = { structure.templates.resize(4);
Builder().S(0).Dtis("SR").Fdiffs({2}).ChainDiffs({2, 1}).Build(), structure.templates[0].S(0).Dtis("SR").ChainDiffs({2, 1}).FrameDiffs({2});
Builder().S(0).Dtis("SS").ChainDiffs({0, 0}).Build(), structure.templates[1].S(0).Dtis("SS").ChainDiffs({0, 0});
Builder().S(1).Dtis("-R").Fdiffs({2, 1}).ChainDiffs({1, 1}).Build(), structure.templates[2].S(1).Dtis("-R").ChainDiffs({1, 1}).FrameDiffs({2, 1});
Builder().S(1).Dtis("-S").Fdiffs({1}).ChainDiffs({1, 1}).Build(), structure.templates[3].S(1).Dtis("-S").ChainDiffs({1, 1}).FrameDiffs({1});
};
return structure; return structure;
} }

View File

@ -43,17 +43,15 @@ ScalabilityStructureL2T1Key::StreamConfig() const {
FrameDependencyStructure ScalabilityStructureL2T1Key::DependencyStructure() FrameDependencyStructure ScalabilityStructureL2T1Key::DependencyStructure()
const { const {
using Builder = GenericFrameInfo::Builder;
FrameDependencyStructure structure; FrameDependencyStructure structure;
structure.num_decode_targets = 2; structure.num_decode_targets = 2;
structure.num_chains = 2; structure.num_chains = 2;
structure.decode_target_protected_by_chain = {0, 1}; structure.decode_target_protected_by_chain = {0, 1};
structure.templates = { structure.templates.resize(4);
Builder().S(0).Dtis("S-").Fdiffs({2}).ChainDiffs({2, 1}).Build(), structure.templates[0].S(0).Dtis("S-").ChainDiffs({2, 1}).FrameDiffs({2});
Builder().S(0).Dtis("SS").ChainDiffs({0, 0}).Build(), structure.templates[1].S(0).Dtis("SS").ChainDiffs({0, 0});
Builder().S(1).Dtis("-S").Fdiffs({2}).ChainDiffs({1, 2}).Build(), structure.templates[2].S(1).Dtis("-S").ChainDiffs({1, 2}).FrameDiffs({2});
Builder().S(1).Dtis("-S").Fdiffs({1}).ChainDiffs({1, 1}).Build(), structure.templates[3].S(1).Dtis("-S").ChainDiffs({1, 1}).FrameDiffs({1});
};
return structure; return structure;
} }

View File

@ -48,31 +48,18 @@ ScalabilityStructureL2T2::StreamConfig() const {
} }
FrameDependencyStructure ScalabilityStructureL2T2::DependencyStructure() const { FrameDependencyStructure ScalabilityStructureL2T2::DependencyStructure() const {
using Builder = GenericFrameInfo::Builder;
FrameDependencyStructure structure; FrameDependencyStructure structure;
structure.num_decode_targets = 4; structure.num_decode_targets = 4;
structure.num_chains = 2; structure.num_chains = 2;
structure.decode_target_protected_by_chain = {0, 0, 1, 1}; structure.decode_target_protected_by_chain = {0, 0, 1, 1};
structure.templates = { structure.templates.resize(6);
Builder().S(0).T(0).Dtis("SSSS").ChainDiffs({0, 0}).Build(), auto& templates = structure.templates;
Builder().S(0).T(0).Dtis("SSRR").Fdiffs({4}).ChainDiffs({4, 3}).Build(), templates[0].S(0).T(0).Dtis("SSSS").ChainDiffs({0, 0});
Builder().S(0).T(1).Dtis("-D-R").Fdiffs({2}).ChainDiffs({2, 1}).Build(), templates[1].S(0).T(0).Dtis("SSRR").ChainDiffs({4, 3}).FrameDiffs({4});
Builder().S(1).T(0).Dtis("--SS").Fdiffs({1}).ChainDiffs({1, 1}).Build(), templates[2].S(0).T(1).Dtis("-D-R").ChainDiffs({2, 1}).FrameDiffs({2});
Builder() templates[3].S(1).T(0).Dtis("--SS").ChainDiffs({1, 1}).FrameDiffs({1});
.S(1) templates[4].S(1).T(0).Dtis("--SS").ChainDiffs({1, 1}).FrameDiffs({4, 1});
.T(0) templates[5].S(1).T(1).Dtis("---D").ChainDiffs({3, 2}).FrameDiffs({2, 1});
.Dtis("--SS")
.Fdiffs({4, 1})
.ChainDiffs({1, 1})
.Build(),
Builder()
.S(1)
.T(1)
.Dtis("---D")
.Fdiffs({2, 1})
.ChainDiffs({3, 2})
.Build(),
};
return structure; return structure;
} }

View File

@ -48,19 +48,18 @@ ScalabilityStructureL2T2Key::StreamConfig() const {
FrameDependencyStructure ScalabilityStructureL2T2Key::DependencyStructure() FrameDependencyStructure ScalabilityStructureL2T2Key::DependencyStructure()
const { const {
using Builder = GenericFrameInfo::Builder;
FrameDependencyStructure structure; FrameDependencyStructure structure;
structure.num_decode_targets = 4; structure.num_decode_targets = 4;
structure.num_chains = 2; structure.num_chains = 2;
structure.decode_target_protected_by_chain = {0, 0, 1, 1}; structure.decode_target_protected_by_chain = {0, 0, 1, 1};
structure.templates = { structure.templates.resize(6);
Builder().S(0).T(0).Dtis("SSSS").ChainDiffs({0, 0}).Build(), auto& templates = structure.templates;
Builder().S(0).T(0).Dtis("SS--").Fdiffs({4}).ChainDiffs({4, 3}).Build(), templates[0].S(0).T(0).Dtis("SSSS").ChainDiffs({0, 0});
Builder().S(0).T(1).Dtis("-D--").Fdiffs({2}).ChainDiffs({2, 1}).Build(), templates[1].S(0).T(0).Dtis("SS--").ChainDiffs({4, 3}).FrameDiffs({4});
Builder().S(1).T(0).Dtis("--SS").Fdiffs({1}).ChainDiffs({1, 1}).Build(), templates[2].S(0).T(1).Dtis("-D--").ChainDiffs({2, 1}).FrameDiffs({2});
Builder().S(1).T(0).Dtis("--SS").Fdiffs({4}).ChainDiffs({1, 4}).Build(), templates[3].S(1).T(0).Dtis("--SS").ChainDiffs({1, 1}).FrameDiffs({1});
Builder().S(1).T(1).Dtis("---D").Fdiffs({2}).ChainDiffs({3, 2}).Build(), templates[4].S(1).T(0).Dtis("--SS").ChainDiffs({1, 4}).FrameDiffs({4});
}; templates[5].S(1).T(1).Dtis("---D").ChainDiffs({3, 2}).FrameDiffs({2});
return structure; return structure;
} }

View File

@ -24,7 +24,6 @@ constexpr auto kNotPresent = DecodeTargetIndication::kNotPresent;
constexpr auto kDiscardable = DecodeTargetIndication::kDiscardable; constexpr auto kDiscardable = DecodeTargetIndication::kDiscardable;
constexpr auto kSwitch = DecodeTargetIndication::kSwitch; constexpr auto kSwitch = DecodeTargetIndication::kSwitch;
// decode targets: S0T0, S0T1, S1T0, S1T1
constexpr DecodeTargetIndication kDtis[6][4] = { constexpr DecodeTargetIndication kDtis[6][4] = {
{kSwitch, kSwitch, kSwitch, kSwitch}, // kKey, S0T0 {kSwitch, kSwitch, kSwitch, kSwitch}, // kKey, S0T0
{kNotPresent, kNotPresent, kSwitch, kSwitch}, // kKey, S1T0 {kNotPresent, kNotPresent, kSwitch, kSwitch}, // kKey, S1T0
@ -48,20 +47,19 @@ ScalabilityStructureL2T2KeyShift::StreamConfig() const {
FrameDependencyStructure ScalabilityStructureL2T2KeyShift::DependencyStructure() FrameDependencyStructure ScalabilityStructureL2T2KeyShift::DependencyStructure()
const { const {
using Builder = GenericFrameInfo::Builder;
FrameDependencyStructure structure; FrameDependencyStructure structure;
structure.num_decode_targets = 4; structure.num_decode_targets = 4;
structure.num_chains = 2; structure.num_chains = 2;
structure.decode_target_protected_by_chain = {0, 0, 1, 1}; structure.decode_target_protected_by_chain = {0, 0, 1, 1};
structure.templates = { structure.templates.resize(7);
Builder().S(0).T(0).Dtis("SSSS").ChainDiffs({0, 0}).Build(), auto& templates = structure.templates;
Builder().S(0).T(0).Dtis("SS--").Fdiffs({2}).ChainDiffs({2, 1}).Build(), templates[0].S(0).T(0).Dtis("SSSS").ChainDiffs({0, 0});
Builder().S(0).T(0).Dtis("SS--").Fdiffs({4}).ChainDiffs({4, 1}).Build(), templates[1].S(0).T(0).Dtis("SS--").ChainDiffs({2, 1}).FrameDiffs({2});
Builder().S(0).T(1).Dtis("-D--").Fdiffs({2}).ChainDiffs({2, 3}).Build(), templates[2].S(0).T(0).Dtis("SS--").ChainDiffs({4, 1}).FrameDiffs({4});
Builder().S(1).T(0).Dtis("--SS").Fdiffs({1}).ChainDiffs({1, 1}).Build(), templates[3].S(0).T(1).Dtis("-D--").ChainDiffs({2, 3}).FrameDiffs({2});
Builder().S(1).T(0).Dtis("--SS").Fdiffs({4}).ChainDiffs({3, 4}).Build(), templates[4].S(1).T(0).Dtis("--SS").ChainDiffs({1, 1}).FrameDiffs({1});
Builder().S(1).T(1).Dtis("---D").Fdiffs({2}).ChainDiffs({1, 2}).Build(), templates[5].S(1).T(0).Dtis("--SS").ChainDiffs({3, 4}).FrameDiffs({4});
}; templates[6].S(1).T(1).Dtis("---D").ChainDiffs({1, 2}).FrameDiffs({2});
return structure; return structure;
} }

View File

@ -45,19 +45,18 @@ ScalabilityStructureL3T1::StreamConfig() const {
} }
FrameDependencyStructure ScalabilityStructureL3T1::DependencyStructure() const { FrameDependencyStructure ScalabilityStructureL3T1::DependencyStructure() const {
using Builder = GenericFrameInfo::Builder;
FrameDependencyStructure structure; FrameDependencyStructure structure;
structure.num_decode_targets = 3; structure.num_decode_targets = 3;
structure.num_chains = 3; structure.num_chains = 3;
structure.decode_target_protected_by_chain = {0, 1, 2}; structure.decode_target_protected_by_chain = {0, 1, 2};
structure.templates = { auto& templates = structure.templates;
Builder().S(0).Dtis("SRR").ChainDiffs({3, 2, 1}).Fdiffs({3}).Build(), templates.resize(6);
Builder().S(0).Dtis("SSS").ChainDiffs({0, 0, 0}).Build(), templates[0].S(0).Dtis("SRR").ChainDiffs({3, 2, 1}).FrameDiffs({3});
Builder().S(1).Dtis("-SR").ChainDiffs({1, 1, 1}).Fdiffs({3, 1}).Build(), templates[1].S(0).Dtis("SSS").ChainDiffs({0, 0, 0});
Builder().S(1).Dtis("-SS").ChainDiffs({1, 1, 1}).Fdiffs({1}).Build(), templates[2].S(1).Dtis("-SR").ChainDiffs({1, 1, 1}).FrameDiffs({3, 1});
Builder().S(2).Dtis("--S").ChainDiffs({2, 1, 1}).Fdiffs({3, 1}).Build(), templates[3].S(1).Dtis("-SS").ChainDiffs({1, 1, 1}).FrameDiffs({1});
Builder().S(2).Dtis("--S").ChainDiffs({2, 1, 1}).Fdiffs({1}).Build(), templates[4].S(2).Dtis("--S").ChainDiffs({2, 1, 1}).FrameDiffs({3, 1});
}; templates[5].S(2).Dtis("--S").ChainDiffs({2, 1, 1}).FrameDiffs({1});
return structure; return structure;
} }

View File

@ -89,112 +89,31 @@ ScalabilityStructureL3T3::StreamConfig() const {
} }
FrameDependencyStructure ScalabilityStructureL3T3::DependencyStructure() const { FrameDependencyStructure ScalabilityStructureL3T3::DependencyStructure() const {
using Builder = GenericFrameInfo::Builder;
FrameDependencyStructure structure; FrameDependencyStructure structure;
structure.num_decode_targets = 9; structure.num_decode_targets = 9;
structure.num_chains = 3; structure.num_chains = 3;
structure.decode_target_protected_by_chain = {0, 0, 0, 1, 1, 1, 2, 2, 2}; structure.decode_target_protected_by_chain = {0, 0, 0, 1, 1, 1, 2, 2, 2};
structure.templates = { auto& t = structure.templates;
Builder().S(0).T(0).Dtis("SSSSSSSSS").ChainDiffs({0, 0, 0}).Build(), t.resize(15);
Builder() // Templates are shown in the order frames following them appear in the
.S(0) // stream, but in `structure.templates` array templates are sorted by
.T(0) // (`spatial_id`, `temporal_id`) since that is a dependency descriptor
.Dtis("SSSRRRRRR") // requirement. Indexes are written in hex for nicer alignment.
.Fdiffs({12}) t[0x1].S(0).T(0).Dtis("SSSSSSSSS").ChainDiffs({0, 0, 0});
.ChainDiffs({12, 11, 10}) t[0x6].S(1).T(0).Dtis("---SSSSSS").ChainDiffs({1, 1, 1}).FrameDiffs({1});
.Build(), t[0xB].S(2).T(0).Dtis("------SSS").ChainDiffs({2, 1, 1}).FrameDiffs({1});
Builder() t[0x3].S(0).T(2).Dtis("--D--R--R").ChainDiffs({3, 2, 1}).FrameDiffs({3});
.S(0) t[0x8].S(1).T(2).Dtis("-----D--R").ChainDiffs({4, 3, 2}).FrameDiffs({3, 1});
.T(1) t[0xD].S(2).T(2).Dtis("--------D").ChainDiffs({5, 4, 3}).FrameDiffs({3, 1});
.Dtis("-DS-RR-RR") t[0x2].S(0).T(1).Dtis("-DS-RR-RR").ChainDiffs({6, 5, 4}).FrameDiffs({6});
.Fdiffs({6}) t[0x7].S(1).T(1).Dtis("----DS-RR").ChainDiffs({7, 6, 5}).FrameDiffs({6, 1});
.ChainDiffs({6, 5, 4}) t[0xC].S(2).T(1).Dtis("-------DS").ChainDiffs({8, 7, 6}).FrameDiffs({6, 1});
.Build(), t[0x4].S(0).T(2).Dtis("--D--R--R").ChainDiffs({9, 8, 7}).FrameDiffs({3});
Builder() t[0x9].S(1).T(2).Dtis("-----D--R").ChainDiffs({10, 9, 8}).FrameDiffs({3, 1});
.S(0) t[0xE].S(2).T(2).Dtis("--------D").ChainDiffs({11, 10, 9}).FrameDiffs({3, 1});
.T(2) t[0x0].S(0).T(0).Dtis("SSSRRRRRR").ChainDiffs({12, 11, 10}).FrameDiffs({12});
.Dtis("--D--R--R") t[0x5].S(1).T(0).Dtis("---SSSRRR").ChainDiffs({1, 1, 1}).FrameDiffs({12, 1});
.Fdiffs({3}) t[0xA].S(2).T(0).Dtis("------SSS").ChainDiffs({2, 1, 1}).FrameDiffs({12, 1});
.ChainDiffs({3, 2, 1})
.Build(),
Builder()
.S(0)
.T(2)
.Dtis("--D--R--R")
.Fdiffs({3})
.ChainDiffs({9, 8, 7})
.Build(),
Builder()
.S(1)
.T(0)
.Dtis("---SSSSSS")
.Fdiffs({1})
.ChainDiffs({1, 1, 1})
.Build(),
Builder()
.S(1)
.T(0)
.Dtis("---SSSRRR")
.Fdiffs({12, 1})
.ChainDiffs({1, 1, 1})
.Build(),
Builder()
.S(1)
.T(1)
.Dtis("----DS-RR")
.Fdiffs({6, 1})
.ChainDiffs({7, 6, 5})
.Build(),
Builder()
.S(1)
.T(2)
.Dtis("-----D--R")
.Fdiffs({3, 1})
.ChainDiffs({4, 3, 2})
.Build(),
Builder()
.S(1)
.T(2)
.Dtis("-----D--R")
.Fdiffs({3, 1})
.ChainDiffs({10, 9, 8})
.Build(),
Builder()
.S(2)
.T(0)
.Dtis("------SSS")
.Fdiffs({1})
.ChainDiffs({2, 1, 1})
.Build(),
Builder()
.S(2)
.T(0)
.Dtis("------SSS")
.Fdiffs({12, 1})
.ChainDiffs({2, 1, 1})
.Build(),
Builder()
.S(2)
.T(1)
.Dtis("-------DS")
.Fdiffs({6, 1})
.ChainDiffs({8, 7, 6})
.Build(),
Builder()
.S(2)
.T(2)
.Dtis("--------D")
.Fdiffs({3, 1})
.ChainDiffs({5, 4, 3})
.Build(),
Builder()
.S(2)
.T(2)
.Dtis("--------D")
.Fdiffs({3, 1})
.ChainDiffs({11, 10, 9})
.Build(),
};
return structure; return structure;
} }

View File

@ -41,17 +41,15 @@ ScalabilityStructureS2T1::StreamConfig() const {
} }
FrameDependencyStructure ScalabilityStructureS2T1::DependencyStructure() const { FrameDependencyStructure ScalabilityStructureS2T1::DependencyStructure() const {
using Builder = GenericFrameInfo::Builder;
FrameDependencyStructure structure; FrameDependencyStructure structure;
structure.num_decode_targets = 2; structure.num_decode_targets = 2;
structure.num_chains = 2; structure.num_chains = 2;
structure.decode_target_protected_by_chain = {0, 1}; structure.decode_target_protected_by_chain = {0, 1};
structure.templates = { structure.templates.resize(4);
Builder().S(0).Dtis("S-").Fdiffs({2}).ChainDiffs({2, 1}).Build(), structure.templates[0].S(0).Dtis("S-").ChainDiffs({2, 1}).FrameDiffs({2});
Builder().S(0).Dtis("S-").ChainDiffs({0, 0}).Build(), structure.templates[1].S(0).Dtis("S-").ChainDiffs({0, 0});
Builder().S(1).Dtis("-S").Fdiffs({2}).ChainDiffs({1, 2}).Build(), structure.templates[2].S(1).Dtis("-S").ChainDiffs({1, 2}).FrameDiffs({2});
Builder().S(1).Dtis("-S").ChainDiffs({1, 0}).Build(), structure.templates[3].S(1).Dtis("-S").ChainDiffs({1, 0});
};
return structure; return structure;
} }

View File

@ -608,58 +608,52 @@ FrameDependencyStructure DefaultTemporalLayers::GetTemplateStructure(
FrameDependencyStructure template_structure; FrameDependencyStructure template_structure;
template_structure.num_decode_targets = num_layers; template_structure.num_decode_targets = num_layers;
using Builder = GenericFrameInfo::Builder;
switch (num_layers) { switch (num_layers) {
case 1: { case 1: {
template_structure.templates = { template_structure.templates.resize(2);
Builder().T(0).Dtis("S").Build(), template_structure.templates[0].T(0).Dtis("S");
Builder().T(0).Dtis("S").Fdiffs({1}).Build(), template_structure.templates[1].T(0).Dtis("S").FrameDiffs({1});
};
return template_structure; return template_structure;
} }
case 2: { case 2: {
template_structure.templates = { template_structure.templates.resize(5);
Builder().T(0).Dtis("SS").Build(), template_structure.templates[0].T(0).Dtis("SS");
Builder().T(0).Dtis("SS").Fdiffs({2}).Build(), template_structure.templates[1].T(0).Dtis("SS").FrameDiffs({2});
Builder().T(0).Dtis("SR").Fdiffs({2}).Build(), template_structure.templates[2].T(0).Dtis("SR").FrameDiffs({2});
Builder().T(1).Dtis("-S").Fdiffs({1}).Build(), template_structure.templates[3].T(1).Dtis("-S").FrameDiffs({1});
Builder().T(1).Dtis("-D").Fdiffs({1, 2}).Build(), template_structure.templates[4].T(1).Dtis("-D").FrameDiffs({2, 1});
};
return template_structure; return template_structure;
} }
case 3: { case 3: {
if (field_trial::IsEnabled("WebRTC-UseShortVP8TL3Pattern")) { if (field_trial::IsEnabled("WebRTC-UseShortVP8TL3Pattern")) {
template_structure.templates = { template_structure.templates.resize(5);
Builder().T(0).Dtis("SSS").Build(), template_structure.templates[0].T(0).Dtis("SSS");
Builder().T(0).Dtis("SSS").Fdiffs({4}).Build(), template_structure.templates[1].T(0).Dtis("SSS").FrameDiffs({4});
Builder().T(1).Dtis("-DR").Fdiffs({2}).Build(), template_structure.templates[2].T(1).Dtis("-DR").FrameDiffs({2});
Builder().T(2).Dtis("--S").Fdiffs({1}).Build(), template_structure.templates[3].T(2).Dtis("--S").FrameDiffs({1});
Builder().T(2).Dtis("--D").Fdiffs({1, 2}).Build(), template_structure.templates[4].T(2).Dtis("--D").FrameDiffs({2, 1});
};
} else { } else {
template_structure.templates = { template_structure.templates.resize(7);
Builder().T(0).Dtis("SSS").Build(), template_structure.templates[0].T(0).Dtis("SSS");
Builder().T(0).Dtis("SSS").Fdiffs({4}).Build(), template_structure.templates[1].T(0).Dtis("SSS").FrameDiffs({4});
Builder().T(0).Dtis("SRR").Fdiffs({4}).Build(), template_structure.templates[2].T(0).Dtis("SRR").FrameDiffs({4});
Builder().T(1).Dtis("-SS").Fdiffs({2}).Build(), template_structure.templates[3].T(1).Dtis("-SS").FrameDiffs({2});
Builder().T(1).Dtis("-DS").Fdiffs({2, 4}).Build(), template_structure.templates[4].T(1).Dtis("-DS").FrameDiffs({4, 2});
Builder().T(2).Dtis("--D").Fdiffs({1}).Build(), template_structure.templates[5].T(2).Dtis("--D").FrameDiffs({1});
Builder().T(2).Dtis("--D").Fdiffs({1, 3}).Build(), template_structure.templates[6].T(2).Dtis("--D").FrameDiffs({3, 1});
};
} }
return template_structure; return template_structure;
} }
case 4: { case 4: {
template_structure.templates = { template_structure.templates.resize(8);
Builder().T(0).Dtis("SSSS").Build(), template_structure.templates[0].T(0).Dtis("SSSS");
Builder().T(0).Dtis("SSSS").Fdiffs({8}).Build(), template_structure.templates[1].T(0).Dtis("SSSS").FrameDiffs({8});
Builder().T(1).Dtis("-SRR").Fdiffs({4}).Build(), template_structure.templates[2].T(1).Dtis("-SRR").FrameDiffs({4});
Builder().T(1).Dtis("-SRR").Fdiffs({4, 8}).Build(), template_structure.templates[3].T(1).Dtis("-SRR").FrameDiffs({4, 8});
Builder().T(2).Dtis("--SR").Fdiffs({2}).Build(), template_structure.templates[4].T(2).Dtis("--SR").FrameDiffs({2});
Builder().T(2).Dtis("--SR").Fdiffs({2, 4}).Build(), template_structure.templates[5].T(2).Dtis("--SR").FrameDiffs({2, 4});
Builder().T(3).Dtis("---D").Fdiffs({1}).Build(), template_structure.templates[6].T(3).Dtis("---D").FrameDiffs({1});
Builder().T(3).Dtis("---D").Fdiffs({1, 3}).Build(), template_structure.templates[7].T(3).Dtis("---D").FrameDiffs({1, 3});
};
return template_structure; return template_structure;
} }
default: default:

View File

@ -75,7 +75,7 @@ class DefaultTemporalLayers final : public Vp8FrameBufferController {
DependencyInfo(absl::string_view indication_symbols, DependencyInfo(absl::string_view indication_symbols,
Vp8FrameConfig frame_config) Vp8FrameConfig frame_config)
: decode_target_indications( : decode_target_indications(
GenericFrameInfo::DecodeTargetInfo(indication_symbols)), webrtc_impl::StringToDecodeTargetIndications(indication_symbols)),
frame_config(frame_config) {} frame_config(frame_config) {}
absl::InlinedVector<DecodeTargetIndication, 10> decode_target_indications; absl::InlinedVector<DecodeTargetIndication, 10> decode_target_indications;

View File

@ -36,6 +36,7 @@ constexpr int kMinTimeBetweenSyncs = kOneSecond90Khz * 2;
constexpr int kMaxTimeBetweenSyncs = kOneSecond90Khz * 4; constexpr int kMaxTimeBetweenSyncs = kOneSecond90Khz * 4;
constexpr int kQpDeltaThresholdForSync = 8; constexpr int kQpDeltaThresholdForSync = 8;
constexpr int kMinBitrateKbpsForQpBoost = 500; constexpr int kMinBitrateKbpsForQpBoost = 500;
constexpr auto kSwitch = DecodeTargetIndication::kSwitch;
} // namespace } // namespace
const double ScreenshareLayers::kMaxTL0FpsReduction = 2.5; const double ScreenshareLayers::kMaxTL0FpsReduction = 2.5;
@ -319,8 +320,7 @@ void ScreenshareLayers::OnEncodeDone(size_t stream_index,
if (number_of_temporal_layers_ == 1) { if (number_of_temporal_layers_ == 1) {
vp8_info.temporalIdx = kNoTemporalIdx; vp8_info.temporalIdx = kNoTemporalIdx;
vp8_info.layerSync = false; vp8_info.layerSync = false;
generic_frame_info.decode_target_indications = generic_frame_info.decode_target_indications = {kSwitch};
GenericFrameInfo::DecodeTargetInfo("S");
generic_frame_info.encoder_buffers.emplace_back( generic_frame_info.encoder_buffers.emplace_back(
0, /*referenced=*/!is_keyframe, /*updated=*/true); 0, /*referenced=*/!is_keyframe, /*updated=*/true);
} else { } else {
@ -344,8 +344,7 @@ void ScreenshareLayers::OnEncodeDone(size_t stream_index,
active_layer_ = 1; active_layer_ = 1;
info->template_structure = info->template_structure =
GetTemplateStructure(number_of_temporal_layers_); GetTemplateStructure(number_of_temporal_layers_);
generic_frame_info.decode_target_indications = generic_frame_info.decode_target_indications = {kSwitch, kSwitch};
GenericFrameInfo::DecodeTargetInfo("SS");
} else if (active_layer_ >= 0 && layers_[active_layer_].state == } else if (active_layer_ >= 0 && layers_[active_layer_].state ==
TemporalLayer::State::kKeyFrame) { TemporalLayer::State::kKeyFrame) {
layers_[active_layer_].state = TemporalLayer::State::kNormal; layers_[active_layer_].state = TemporalLayer::State::kNormal;
@ -429,21 +428,18 @@ FrameDependencyStructure ScreenshareLayers::GetTemplateStructure(
FrameDependencyStructure template_structure; FrameDependencyStructure template_structure;
template_structure.num_decode_targets = num_layers; template_structure.num_decode_targets = num_layers;
using Builder = GenericFrameInfo::Builder;
switch (num_layers) { switch (num_layers) {
case 1: { case 1: {
template_structure.templates = { template_structure.templates.resize(2);
Builder().T(0).Dtis("S").Build(), template_structure.templates[0].T(0).Dtis("S");
Builder().T(0).Dtis("S").Fdiffs({1}).Build(), template_structure.templates[1].T(0).Dtis("S").FrameDiffs({1});
};
return template_structure; return template_structure;
} }
case 2: { case 2: {
template_structure.templates = { template_structure.templates.resize(3);
Builder().T(0).Dtis("SS").Build(), template_structure.templates[0].T(0).Dtis("SS");
Builder().T(0).Dtis("SS").Fdiffs({1}).Build(), template_structure.templates[1].T(0).Dtis("SS").FrameDiffs({1});
Builder().T(1).Dtis("-S").Fdiffs({1}).Build(), template_structure.templates[2].T(1).Dtis("-S").FrameDiffs({1});
};
return template_structure; return template_structure;
} }
default: default:

View File

@ -78,7 +78,7 @@ class ScreenshareLayers final : public Vp8FrameBufferController {
DependencyInfo(absl::string_view indication_symbols, DependencyInfo(absl::string_view indication_symbols,
Vp8FrameConfig frame_config) Vp8FrameConfig frame_config)
: decode_target_indications( : decode_target_indications(
GenericFrameInfo::DecodeTargetInfo(indication_symbols)), webrtc_impl::StringToDecodeTargetIndications(indication_symbols)),
frame_config(frame_config) {} frame_config(frame_config) {}
absl::InlinedVector<DecodeTargetIndication, 10> decode_target_indications; absl::InlinedVector<DecodeTargetIndication, 10> decode_target_indications;

View File

@ -970,8 +970,8 @@ class RtpVideoStreamReceiver2DependencyDescriptorTest
FrameDependencyStructure stream_structure; FrameDependencyStructure stream_structure;
stream_structure.num_decode_targets = 1; stream_structure.num_decode_targets = 1;
stream_structure.templates = { stream_structure.templates = {
GenericFrameInfo::Builder().Dtis("S").Build(), FrameDependencyTemplate().Dtis("S"),
GenericFrameInfo::Builder().Dtis("S").Fdiffs({1}).Build(), FrameDependencyTemplate().Dtis("S").FrameDiffs({1}),
}; };
return stream_structure; return stream_structure;
} }

View File

@ -963,8 +963,8 @@ class RtpVideoStreamReceiverDependencyDescriptorTest
FrameDependencyStructure stream_structure; FrameDependencyStructure stream_structure;
stream_structure.num_decode_targets = 1; stream_structure.num_decode_targets = 1;
stream_structure.templates = { stream_structure.templates = {
GenericFrameInfo::Builder().Dtis("S").Build(), FrameDependencyTemplate().Dtis("S"),
GenericFrameInfo::Builder().Dtis("S").Fdiffs({1}).Build(), FrameDependencyTemplate().Dtis("S").FrameDiffs({1}),
}; };
return stream_structure; return stream_structure;
} }