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 "common_video/corruption_detection_converters.h"
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "common_video/corruption_detection_message.h"
|
#include "common_video/corruption_detection_message.h"
|
||||||
#include "common_video/frame_instrumentation_data.h"
|
#include "common_video/frame_instrumentation_data.h"
|
||||||
@ -20,6 +21,30 @@ namespace webrtc {
|
|||||||
|
|
||||||
namespace {
|
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,
|
int GetSequenceIndexForMessage(int sequence_index,
|
||||||
bool communicate_upper_bits) {
|
bool communicate_upper_bits) {
|
||||||
return communicate_upper_bits ? (sequence_index >> 7)
|
return communicate_upper_bits ? (sequence_index >> 7)
|
||||||
@ -28,6 +53,31 @@ int GetSequenceIndexForMessage(int sequence_index,
|
|||||||
|
|
||||||
} // namespace
|
} // 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>
|
std::optional<CorruptionDetectionMessage>
|
||||||
ConvertFrameInstrumentationDataToCorruptionDetectionMessage(
|
ConvertFrameInstrumentationDataToCorruptionDetectionMessage(
|
||||||
const FrameInstrumentationData& data) {
|
const FrameInstrumentationData& data) {
|
||||||
|
|||||||
@ -18,6 +18,10 @@
|
|||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
|
std::optional<FrameInstrumentationData>
|
||||||
|
ConvertCorruptionDetectionMessageToFrameInstrumentationData(
|
||||||
|
const CorruptionDetectionMessage& message,
|
||||||
|
int previous_sequence_index);
|
||||||
std::optional<CorruptionDetectionMessage>
|
std::optional<CorruptionDetectionMessage>
|
||||||
ConvertFrameInstrumentationDataToCorruptionDetectionMessage(
|
ConvertFrameInstrumentationDataToCorruptionDetectionMessage(
|
||||||
const FrameInstrumentationData& frame_instrumentation_data);
|
const FrameInstrumentationData& frame_instrumentation_data);
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
#include "common_video/corruption_detection_converters.h"
|
#include "common_video/corruption_detection_converters.h"
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "common_video/corruption_detection_message.h"
|
#include "common_video/corruption_detection_message.h"
|
||||||
#include "common_video/frame_instrumentation_data.h"
|
#include "common_video/frame_instrumentation_data.h"
|
||||||
@ -23,7 +24,8 @@ namespace {
|
|||||||
using ::testing::_;
|
using ::testing::_;
|
||||||
using ::testing::ElementsAre;
|
using ::testing::ElementsAre;
|
||||||
|
|
||||||
TEST(CorruptionDetectionConvertersTest, ConvertsValidData) {
|
TEST(FrameInstrumentationDataToCorruptionDetectionMessageTest,
|
||||||
|
ConvertsValidData) {
|
||||||
FrameInstrumentationData data = {.sequence_index = 1,
|
FrameInstrumentationData data = {.sequence_index = 1,
|
||||||
.communicate_upper_bits = false,
|
.communicate_upper_bits = false,
|
||||||
.std_dev = 1.0,
|
.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));
|
EXPECT_THAT(message->sample_values(), ElementsAre(1.0, 2.0, 3.0, 4.0, 5.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CorruptionDetectionConvertersTest,
|
TEST(FrameInstrumentationDataToCorruptionDetectionMessageTest,
|
||||||
ReturnsNulloptWhenSequenceIndexIsNegative) {
|
ReturnsNulloptWhenSequenceIndexIsNegative) {
|
||||||
FrameInstrumentationData data = {.sequence_index = -1,
|
FrameInstrumentationData data = {.sequence_index = -1,
|
||||||
.communicate_upper_bits = false,
|
.communicate_upper_bits = false,
|
||||||
@ -56,7 +58,7 @@ TEST(CorruptionDetectionConvertersTest,
|
|||||||
ASSERT_FALSE(message.has_value());
|
ASSERT_FALSE(message.has_value());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CorruptionDetectionConvertersTest,
|
TEST(FrameInstrumentationDataToCorruptionDetectionMessageTest,
|
||||||
ReturnsNulloptWhenSequenceIndexIsTooLarge) {
|
ReturnsNulloptWhenSequenceIndexIsTooLarge) {
|
||||||
// Sequence index must be at max 14 bits.
|
// Sequence index must be at max 14 bits.
|
||||||
FrameInstrumentationData data = {.sequence_index = 0x4000,
|
FrameInstrumentationData data = {.sequence_index = 0x4000,
|
||||||
@ -71,7 +73,7 @@ TEST(CorruptionDetectionConvertersTest,
|
|||||||
ASSERT_FALSE(message.has_value());
|
ASSERT_FALSE(message.has_value());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CorruptionDetectionConvertersTest,
|
TEST(FrameInstrumentationDataToCorruptionDetectionMessageTest,
|
||||||
ReturnsNulloptWhenThereAreNoSampleValues) {
|
ReturnsNulloptWhenThereAreNoSampleValues) {
|
||||||
// FrameInstrumentationData must by definition have at least one sample value.
|
// FrameInstrumentationData must by definition have at least one sample value.
|
||||||
FrameInstrumentationData data = {.sequence_index = 1,
|
FrameInstrumentationData data = {.sequence_index = 1,
|
||||||
@ -86,7 +88,7 @@ TEST(CorruptionDetectionConvertersTest,
|
|||||||
ASSERT_FALSE(message.has_value());
|
ASSERT_FALSE(message.has_value());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CorruptionDetectionConvertersTest,
|
TEST(FrameInstrumentationDataToCorruptionDetectionMessageTest,
|
||||||
ReturnsNulloptWhenNotSpecifyingSampleValues) {
|
ReturnsNulloptWhenNotSpecifyingSampleValues) {
|
||||||
FrameInstrumentationData data = {.sequence_index = 1,
|
FrameInstrumentationData data = {.sequence_index = 1,
|
||||||
.communicate_upper_bits = false,
|
.communicate_upper_bits = false,
|
||||||
@ -99,7 +101,7 @@ TEST(CorruptionDetectionConvertersTest,
|
|||||||
ASSERT_FALSE(message.has_value());
|
ASSERT_FALSE(message.has_value());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CorruptionDetectionConvertersTest,
|
TEST(FrameInstrumentationDataToCorruptionDetectionMessageTest,
|
||||||
ConvertsSequenceIndexWhenSetToUseUpperBits) {
|
ConvertsSequenceIndexWhenSetToUseUpperBits) {
|
||||||
FrameInstrumentationData data = {.sequence_index = 0b0000'0110'0000'0101,
|
FrameInstrumentationData data = {.sequence_index = 0b0000'0110'0000'0101,
|
||||||
.communicate_upper_bits = true,
|
.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));
|
EXPECT_THAT(message->sample_values(), ElementsAre(1.0, 2.0, 3.0, 4.0, 5.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CorruptionDetectionConvertersTest,
|
TEST(FrameInstrumentationDataToCorruptionDetectionMessageTest,
|
||||||
ConvertsSequenceIndexWhenSetToUseLowerBits) {
|
ConvertsSequenceIndexWhenSetToUseLowerBits) {
|
||||||
FrameInstrumentationData data = {.sequence_index = 0b0000'0110'0000'0101,
|
FrameInstrumentationData data = {.sequence_index = 0b0000'0110'0000'0101,
|
||||||
.communicate_upper_bits = false,
|
.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));
|
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,
|
FrameInstrumentationSyncData data = {.sequence_index = 1,
|
||||||
.communicate_upper_bits = true};
|
.communicate_upper_bits = true};
|
||||||
|
|
||||||
@ -151,7 +154,8 @@ TEST(CorruptionDetectionConvertersTest, ConvertsValidSyncData) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if GTEST_HAS_DEATH_TEST
|
#if GTEST_HAS_DEATH_TEST
|
||||||
TEST(CorruptionDetectionConvertersTest, FailsWhenSetToNotCommunicateUpperBits) {
|
TEST(FrameInstrumentationSyncDataToCorruptionDetectionMessageTest,
|
||||||
|
FailsWhenSetToNotCommunicateUpperBits) {
|
||||||
FrameInstrumentationSyncData data = {.sequence_index = 1,
|
FrameInstrumentationSyncData data = {.sequence_index = 1,
|
||||||
.communicate_upper_bits = false};
|
.communicate_upper_bits = false};
|
||||||
|
|
||||||
@ -160,7 +164,7 @@ TEST(CorruptionDetectionConvertersTest, FailsWhenSetToNotCommunicateUpperBits) {
|
|||||||
}
|
}
|
||||||
#endif // GTEST_HAS_DEATH_TEST
|
#endif // GTEST_HAS_DEATH_TEST
|
||||||
|
|
||||||
TEST(CorruptionDetectionConvertersTest,
|
TEST(FrameInstrumentationSyncDataToCorruptionDetectionMessageTest,
|
||||||
ReturnsNulloptWhenSyncSequenceIndexIsNegative) {
|
ReturnsNulloptWhenSyncSequenceIndexIsNegative) {
|
||||||
FrameInstrumentationSyncData data = {.sequence_index = -1,
|
FrameInstrumentationSyncData data = {.sequence_index = -1,
|
||||||
.communicate_upper_bits = true};
|
.communicate_upper_bits = true};
|
||||||
@ -170,7 +174,7 @@ TEST(CorruptionDetectionConvertersTest,
|
|||||||
ASSERT_FALSE(message.has_value());
|
ASSERT_FALSE(message.has_value());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CorruptionDetectionConvertersTest,
|
TEST(FrameInstrumentationSyncDataToCorruptionDetectionMessageTest,
|
||||||
ReturnsNulloptWhenSyncSequenceIndexIsTooLarge) {
|
ReturnsNulloptWhenSyncSequenceIndexIsTooLarge) {
|
||||||
FrameInstrumentationSyncData data = {.sequence_index = 0x4000,
|
FrameInstrumentationSyncData data = {.sequence_index = 0x4000,
|
||||||
.communicate_upper_bits = true};
|
.communicate_upper_bits = true};
|
||||||
@ -180,5 +184,123 @@ TEST(CorruptionDetectionConvertersTest,
|
|||||||
ASSERT_FALSE(message.has_value());
|
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
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user