Validate frame consistency when writing DependencyDescriptor
To write DependencyDescriptor frame properties should be consistent with the FrameDependencyStructure. Historically that was ensured by webrtc codec wrappers, but with with frame transform api interface there are now more ways to inject video frame for packetizing. Thus DependencyDescriptorWriter should be more protective to avoid crashes. Bug: chromium:379282549 Change-Id: I98f226ff09c32154e18888c8e811e7981567ad45 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/371301 Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Reviewed-by: Åsa Persson <asapersson@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43551}
This commit is contained in:
parent
74ace1a6e3
commit
200fd82771
@ -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<int>(frame_id - last_frame_id_[0][0])};
|
||||
|
||||
if (is_keyframe) {
|
||||
RTC_DCHECK_EQ(temporal_index, 0);
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user