Add converter from CorruptionDetectionMessage To FrameInstrumentationData
Bug: webrtc:358039777 Change-Id: I041b9a84e1f93d7e7a3d31b8f0f33c94eeca76a6 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/363700 Commit-Queue: Erik Språng <sprang@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Auto-Submit: Fanny Linderborg <linderborg@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43081}
This commit is contained in:
parent
b04af61b4e
commit
a2d515584e
@ -11,6 +11,7 @@
|
||||
#include "common_video/corruption_detection_converters.h"
|
||||
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include "common_video/corruption_detection_message.h"
|
||||
#include "common_video/frame_instrumentation_data.h"
|
||||
@ -20,6 +21,30 @@ namespace webrtc {
|
||||
|
||||
namespace {
|
||||
|
||||
int GetFullSequenceIndex(int previous_sequence_index,
|
||||
int sequence_index_update,
|
||||
bool update_the_most_significant_bits) {
|
||||
RTC_CHECK_GE(previous_sequence_index, 0)
|
||||
<< "previous_sequence_index must not be negative";
|
||||
RTC_CHECK_LE(previous_sequence_index, 0x7FFF)
|
||||
<< "previous_sequence_index must be at most 15 bits";
|
||||
RTC_CHECK_GE(sequence_index_update, 0)
|
||||
<< "sequence_index_update must not be negative";
|
||||
RTC_CHECK_LE(sequence_index_update, 0b0111'1111)
|
||||
<< "sequence_index_update must be at most 7 bits";
|
||||
if (update_the_most_significant_bits) {
|
||||
// Reset LSB.
|
||||
return sequence_index_update << 7;
|
||||
}
|
||||
int upper_bits = previous_sequence_index & 0b0011'1111'1000'0000;
|
||||
if (sequence_index_update < (previous_sequence_index & 0b0111'1111)) {
|
||||
// Assume one and only one wraparound has happened.
|
||||
upper_bits += 0b1000'0000;
|
||||
}
|
||||
// Replace the lowest bits with the bits from the update.
|
||||
return upper_bits + sequence_index_update;
|
||||
}
|
||||
|
||||
int GetSequenceIndexForMessage(int sequence_index,
|
||||
bool communicate_upper_bits) {
|
||||
return communicate_upper_bits ? (sequence_index >> 7)
|
||||
@ -28,6 +53,31 @@ int GetSequenceIndexForMessage(int sequence_index,
|
||||
|
||||
} // namespace
|
||||
|
||||
std::optional<FrameInstrumentationData>
|
||||
ConvertCorruptionDetectionMessageToFrameInstrumentationData(
|
||||
const CorruptionDetectionMessage& message,
|
||||
int previous_sequence_index) {
|
||||
if (previous_sequence_index < 0) {
|
||||
return std::nullopt;
|
||||
}
|
||||
if (message.sample_values().empty()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
int full_sequence_index = GetFullSequenceIndex(
|
||||
previous_sequence_index, message.sequence_index(),
|
||||
message.interpret_sequence_index_as_most_significant_bits());
|
||||
std::vector<double> sample_values(message.sample_values().cbegin(),
|
||||
message.sample_values().cend());
|
||||
return FrameInstrumentationData{
|
||||
.sequence_index = full_sequence_index,
|
||||
.communicate_upper_bits =
|
||||
message.interpret_sequence_index_as_most_significant_bits(),
|
||||
.std_dev = message.std_dev(),
|
||||
.luma_error_threshold = message.luma_error_threshold(),
|
||||
.chroma_error_threshold = message.chroma_error_threshold(),
|
||||
.sample_values = sample_values};
|
||||
}
|
||||
|
||||
std::optional<CorruptionDetectionMessage>
|
||||
ConvertFrameInstrumentationDataToCorruptionDetectionMessage(
|
||||
const FrameInstrumentationData& data) {
|
||||
|
||||
@ -18,6 +18,10 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
std::optional<FrameInstrumentationData>
|
||||
ConvertCorruptionDetectionMessageToFrameInstrumentationData(
|
||||
const CorruptionDetectionMessage& message,
|
||||
int previous_sequence_index);
|
||||
std::optional<CorruptionDetectionMessage>
|
||||
ConvertFrameInstrumentationDataToCorruptionDetectionMessage(
|
||||
const FrameInstrumentationData& frame_instrumentation_data);
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include "common_video/corruption_detection_converters.h"
|
||||
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include "common_video/corruption_detection_message.h"
|
||||
#include "common_video/frame_instrumentation_data.h"
|
||||
@ -23,7 +24,8 @@ namespace {
|
||||
using ::testing::_;
|
||||
using ::testing::ElementsAre;
|
||||
|
||||
TEST(CorruptionDetectionConvertersTest, ConvertsValidData) {
|
||||
TEST(FrameInstrumentationDataToCorruptionDetectionMessageTest,
|
||||
ConvertsValidData) {
|
||||
FrameInstrumentationData data = {.sequence_index = 1,
|
||||
.communicate_upper_bits = false,
|
||||
.std_dev = 1.0,
|
||||
@ -42,7 +44,7 @@ TEST(CorruptionDetectionConvertersTest, ConvertsValidData) {
|
||||
EXPECT_THAT(message->sample_values(), ElementsAre(1.0, 2.0, 3.0, 4.0, 5.0));
|
||||
}
|
||||
|
||||
TEST(CorruptionDetectionConvertersTest,
|
||||
TEST(FrameInstrumentationDataToCorruptionDetectionMessageTest,
|
||||
ReturnsNulloptWhenSequenceIndexIsNegative) {
|
||||
FrameInstrumentationData data = {.sequence_index = -1,
|
||||
.communicate_upper_bits = false,
|
||||
@ -56,7 +58,7 @@ TEST(CorruptionDetectionConvertersTest,
|
||||
ASSERT_FALSE(message.has_value());
|
||||
}
|
||||
|
||||
TEST(CorruptionDetectionConvertersTest,
|
||||
TEST(FrameInstrumentationDataToCorruptionDetectionMessageTest,
|
||||
ReturnsNulloptWhenSequenceIndexIsTooLarge) {
|
||||
// Sequence index must be at max 14 bits.
|
||||
FrameInstrumentationData data = {.sequence_index = 0x4000,
|
||||
@ -71,7 +73,7 @@ TEST(CorruptionDetectionConvertersTest,
|
||||
ASSERT_FALSE(message.has_value());
|
||||
}
|
||||
|
||||
TEST(CorruptionDetectionConvertersTest,
|
||||
TEST(FrameInstrumentationDataToCorruptionDetectionMessageTest,
|
||||
ReturnsNulloptWhenThereAreNoSampleValues) {
|
||||
// FrameInstrumentationData must by definition have at least one sample value.
|
||||
FrameInstrumentationData data = {.sequence_index = 1,
|
||||
@ -86,7 +88,7 @@ TEST(CorruptionDetectionConvertersTest,
|
||||
ASSERT_FALSE(message.has_value());
|
||||
}
|
||||
|
||||
TEST(CorruptionDetectionConvertersTest,
|
||||
TEST(FrameInstrumentationDataToCorruptionDetectionMessageTest,
|
||||
ReturnsNulloptWhenNotSpecifyingSampleValues) {
|
||||
FrameInstrumentationData data = {.sequence_index = 1,
|
||||
.communicate_upper_bits = false,
|
||||
@ -99,7 +101,7 @@ TEST(CorruptionDetectionConvertersTest,
|
||||
ASSERT_FALSE(message.has_value());
|
||||
}
|
||||
|
||||
TEST(CorruptionDetectionConvertersTest,
|
||||
TEST(FrameInstrumentationDataToCorruptionDetectionMessageTest,
|
||||
ConvertsSequenceIndexWhenSetToUseUpperBits) {
|
||||
FrameInstrumentationData data = {.sequence_index = 0b0000'0110'0000'0101,
|
||||
.communicate_upper_bits = true,
|
||||
@ -119,7 +121,7 @@ TEST(CorruptionDetectionConvertersTest,
|
||||
EXPECT_THAT(message->sample_values(), ElementsAre(1.0, 2.0, 3.0, 4.0, 5.0));
|
||||
}
|
||||
|
||||
TEST(CorruptionDetectionConvertersTest,
|
||||
TEST(FrameInstrumentationDataToCorruptionDetectionMessageTest,
|
||||
ConvertsSequenceIndexWhenSetToUseLowerBits) {
|
||||
FrameInstrumentationData data = {.sequence_index = 0b0000'0110'0000'0101,
|
||||
.communicate_upper_bits = false,
|
||||
@ -139,7 +141,8 @@ TEST(CorruptionDetectionConvertersTest,
|
||||
EXPECT_THAT(message->sample_values(), ElementsAre(1.0, 2.0, 3.0, 4.0, 5.0));
|
||||
}
|
||||
|
||||
TEST(CorruptionDetectionConvertersTest, ConvertsValidSyncData) {
|
||||
TEST(FrameInstrumentationSyncDataToCorruptionDetectionMessageTest,
|
||||
ConvertsValidSyncData) {
|
||||
FrameInstrumentationSyncData data = {.sequence_index = 1,
|
||||
.communicate_upper_bits = true};
|
||||
|
||||
@ -151,7 +154,8 @@ TEST(CorruptionDetectionConvertersTest, ConvertsValidSyncData) {
|
||||
}
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
TEST(CorruptionDetectionConvertersTest, FailsWhenSetToNotCommunicateUpperBits) {
|
||||
TEST(FrameInstrumentationSyncDataToCorruptionDetectionMessageTest,
|
||||
FailsWhenSetToNotCommunicateUpperBits) {
|
||||
FrameInstrumentationSyncData data = {.sequence_index = 1,
|
||||
.communicate_upper_bits = false};
|
||||
|
||||
@ -160,7 +164,7 @@ TEST(CorruptionDetectionConvertersTest, FailsWhenSetToNotCommunicateUpperBits) {
|
||||
}
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
TEST(CorruptionDetectionConvertersTest,
|
||||
TEST(FrameInstrumentationSyncDataToCorruptionDetectionMessageTest,
|
||||
ReturnsNulloptWhenSyncSequenceIndexIsNegative) {
|
||||
FrameInstrumentationSyncData data = {.sequence_index = -1,
|
||||
.communicate_upper_bits = true};
|
||||
@ -170,7 +174,7 @@ TEST(CorruptionDetectionConvertersTest,
|
||||
ASSERT_FALSE(message.has_value());
|
||||
}
|
||||
|
||||
TEST(CorruptionDetectionConvertersTest,
|
||||
TEST(FrameInstrumentationSyncDataToCorruptionDetectionMessageTest,
|
||||
ReturnsNulloptWhenSyncSequenceIndexIsTooLarge) {
|
||||
FrameInstrumentationSyncData data = {.sequence_index = 0x4000,
|
||||
.communicate_upper_bits = true};
|
||||
@ -180,5 +184,123 @@ TEST(CorruptionDetectionConvertersTest,
|
||||
ASSERT_FALSE(message.has_value());
|
||||
}
|
||||
|
||||
TEST(CorruptionDetectionMessageToFrameInstrumentationData,
|
||||
FailWhenPreviousSequenceIndexIsNegative) {
|
||||
std::vector<double> sample_values = {1.0, 2.0, 3.0, 4.0, 5.0};
|
||||
std::optional<CorruptionDetectionMessage> message =
|
||||
CorruptionDetectionMessage::Builder()
|
||||
.WithSampleValues(sample_values)
|
||||
.Build();
|
||||
ASSERT_TRUE(message.has_value());
|
||||
|
||||
EXPECT_FALSE(
|
||||
ConvertCorruptionDetectionMessageToFrameInstrumentationData(*message, -1)
|
||||
.has_value());
|
||||
}
|
||||
|
||||
TEST(CorruptionDetectionMessageToFrameInstrumentationData,
|
||||
FailWhenNoSampleValuesAreProvided) {
|
||||
std::optional<CorruptionDetectionMessage> message =
|
||||
CorruptionDetectionMessage::Builder().Build();
|
||||
ASSERT_TRUE(message.has_value());
|
||||
|
||||
EXPECT_FALSE(
|
||||
ConvertCorruptionDetectionMessageToFrameInstrumentationData(*message, 0)
|
||||
.has_value());
|
||||
}
|
||||
|
||||
TEST(CorruptionDetectionMessageToFrameInstrumentationData,
|
||||
IgnorePreviousSequenceIndexWhenSetToUpdateTheMostSignificantBits) {
|
||||
std::vector<double> sample_values = {1.0, 2.0, 3.0, 4.0, 5.0};
|
||||
std::optional<CorruptionDetectionMessage> message =
|
||||
CorruptionDetectionMessage::Builder()
|
||||
.WithSequenceIndex(11)
|
||||
.WithInterpretSequenceIndexAsMostSignificantBits(true)
|
||||
.WithSampleValues(sample_values)
|
||||
.Build();
|
||||
ASSERT_TRUE(message.has_value());
|
||||
|
||||
std::optional<FrameInstrumentationData> data =
|
||||
ConvertCorruptionDetectionMessageToFrameInstrumentationData(*message, 12);
|
||||
|
||||
ASSERT_TRUE(data.has_value());
|
||||
EXPECT_EQ(data->sequence_index, 0b0101'1000'0000);
|
||||
}
|
||||
|
||||
TEST(CorruptionDetectionMessageToFrameInstrumentationData,
|
||||
UseMessageSequenceIndexWhenHigherThanPrevious) {
|
||||
std::vector<double> sample_values = {1.0, 2.0, 3.0, 4.0, 5.0};
|
||||
std::optional<CorruptionDetectionMessage> message =
|
||||
CorruptionDetectionMessage::Builder()
|
||||
.WithSequenceIndex(11)
|
||||
.WithInterpretSequenceIndexAsMostSignificantBits(false)
|
||||
.WithSampleValues(sample_values)
|
||||
.Build();
|
||||
ASSERT_TRUE(message.has_value());
|
||||
|
||||
std::optional<FrameInstrumentationData> data =
|
||||
ConvertCorruptionDetectionMessageToFrameInstrumentationData(*message, 0);
|
||||
|
||||
ASSERT_TRUE(data.has_value());
|
||||
EXPECT_EQ(data->sequence_index, 11);
|
||||
}
|
||||
|
||||
TEST(CorruptionDetectionMessageToFrameInstrumentationData,
|
||||
IncreaseThePreviousIdxUntilLsbsAreEqualToTheUpdateWhenTheUpdateIsLsbs) {
|
||||
std::vector<double> sample_values = {1.0, 2.0, 3.0, 4.0, 5.0};
|
||||
std::optional<CorruptionDetectionMessage> message =
|
||||
CorruptionDetectionMessage::Builder()
|
||||
.WithSequenceIndex(11)
|
||||
.WithInterpretSequenceIndexAsMostSignificantBits(false)
|
||||
.WithSampleValues(sample_values)
|
||||
.Build();
|
||||
ASSERT_TRUE(message.has_value());
|
||||
|
||||
std::optional<FrameInstrumentationData> data =
|
||||
ConvertCorruptionDetectionMessageToFrameInstrumentationData(*message,
|
||||
1 + 128);
|
||||
|
||||
ASSERT_TRUE(data.has_value());
|
||||
EXPECT_EQ(data->sequence_index, 11 + 128);
|
||||
}
|
||||
|
||||
TEST(CorruptionDetectionMessageToFrameInstrumentationData,
|
||||
IgnoreIndexUpdateWhenTheLowerBitsSuppliedAreTheSameAsInThePreviousIndex) {
|
||||
std::vector<double> sample_values = {1.0, 2.0, 3.0, 4.0, 5.0};
|
||||
std::optional<CorruptionDetectionMessage> message =
|
||||
CorruptionDetectionMessage::Builder()
|
||||
.WithSequenceIndex(11)
|
||||
.WithInterpretSequenceIndexAsMostSignificantBits(false)
|
||||
.WithSampleValues(sample_values)
|
||||
.Build();
|
||||
ASSERT_TRUE(message.has_value());
|
||||
|
||||
std::optional<FrameInstrumentationData> data =
|
||||
ConvertCorruptionDetectionMessageToFrameInstrumentationData(*message,
|
||||
11 + 128);
|
||||
|
||||
ASSERT_TRUE(data.has_value());
|
||||
EXPECT_EQ(data->sequence_index, 11 + 128);
|
||||
}
|
||||
|
||||
TEST(
|
||||
CorruptionDetectionMessageToFrameInstrumentationData,
|
||||
IncreaseTheMsbsByOneAndSetTheMessagesLsbWhenMessageLsbIsLowerThanPrevious) {
|
||||
std::vector<double> sample_values = {1.0, 2.0, 3.0, 4.0, 5.0};
|
||||
std::optional<CorruptionDetectionMessage> message =
|
||||
CorruptionDetectionMessage::Builder()
|
||||
.WithSequenceIndex(11)
|
||||
.WithInterpretSequenceIndexAsMostSignificantBits(false)
|
||||
.WithSampleValues(sample_values)
|
||||
.Build();
|
||||
ASSERT_TRUE(message.has_value());
|
||||
|
||||
std::optional<FrameInstrumentationData> data =
|
||||
ConvertCorruptionDetectionMessageToFrameInstrumentationData(*message, 12);
|
||||
|
||||
ASSERT_TRUE(data.has_value());
|
||||
EXPECT_EQ(data->sequence_index, 11 + 128);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace webrtc
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user