Add converters for corruption detection structs

Bug: webrtc:358039777
Change-Id: I05b99fe05023e83236f37fd53d96993696989ca6
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/361823
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Fanny Linderborg <linderborg@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#43007}
This commit is contained in:
Fanny Linderborg 2024-09-11 13:39:44 +02:00 committed by WebRTC LUCI CQ
parent e25b15e22b
commit 97d0427080
4 changed files with 306 additions and 0 deletions

View file

@ -8,6 +8,18 @@
import("../webrtc.gni")
rtc_library("corruption_detection_converters") {
sources = [
"corruption_detection_converters.cc",
"corruption_detection_converters.h",
]
deps = [
":corruption_detection_message",
":frame_instrumentation_data",
"../rtc_base:checks",
]
}
rtc_library("corruption_detection_message") {
sources = [ "corruption_detection_message.h" ]
deps = [
@ -125,6 +137,17 @@ if (rtc_include_tests && !build_with_chromium) {
}
}
rtc_library("corruption_detection_converters_unittest") {
testonly = true
sources = [ "corruption_detection_converters_unittest.cc" ]
deps = [
":corruption_detection_converters",
":corruption_detection_message",
":frame_instrumentation_data",
"../test:test_support",
]
}
rtc_library("corruption_detection_message_unittest") {
testonly = true
sources = [ "corruption_detection_message_unittest.cc" ]
@ -161,6 +184,7 @@ if (rtc_include_tests && !build_with_chromium) {
deps = [
":common_video",
":corruption_detection_converters_unittest",
":corruption_detection_message_unittest",
"../api:scoped_refptr",
"../api/units:time_delta",

View file

@ -0,0 +1,69 @@
/*
* Copyright 2024 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 "common_video/corruption_detection_converters.h"
#include <optional>
#include "common_video/corruption_detection_message.h"
#include "common_video/frame_instrumentation_data.h"
#include "rtc_base/checks.h"
namespace webrtc {
namespace {
int GetSequenceIndexForMessage(int sequence_index,
bool communicate_upper_bits) {
return communicate_upper_bits ? (sequence_index >> 7)
: (sequence_index & 0b0111'1111);
}
} // namespace
std::optional<CorruptionDetectionMessage>
ConvertFrameInstrumentationDataToCorruptionDetectionMessage(
const FrameInstrumentationData& data) {
if (data.sequence_index < 0 || data.sequence_index > 0b0011'1111'1111'1111) {
return std::nullopt;
}
// Frame instrumentation data must have sample values.
if (data.sample_values.empty()) {
return std::nullopt;
}
return CorruptionDetectionMessage::Builder()
.WithSequenceIndex(GetSequenceIndexForMessage(
data.sequence_index, data.communicate_upper_bits))
.WithInterpretSequenceIndexAsMostSignificantBits(
data.communicate_upper_bits)
.WithStdDev(data.std_dev)
.WithLumaErrorThreshold(data.luma_error_threshold)
.WithChromaErrorThreshold(data.chroma_error_threshold)
.WithSampleValues(data.sample_values)
.Build();
}
std::optional<CorruptionDetectionMessage>
ConvertFrameInstrumentationSyncDataToCorruptionDetectionMessage(
const FrameInstrumentationSyncData& data) {
RTC_DCHECK(data.communicate_upper_bits)
<< "FrameInstrumentationSyncData data must always send the upper bits.";
if (data.sequence_index < 0 || data.sequence_index > 0b0011'1111'1111'1111) {
return std::nullopt;
}
return CorruptionDetectionMessage::Builder()
.WithSequenceIndex(GetSequenceIndexForMessage(
data.sequence_index, data.communicate_upper_bits))
.WithInterpretSequenceIndexAsMostSignificantBits(true)
.Build();
}
} // namespace webrtc

View file

@ -0,0 +1,29 @@
/*
* Copyright 2024 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.
*/
#ifndef COMMON_VIDEO_CORRUPTION_DETECTION_CONVERTERS_H_
#define COMMON_VIDEO_CORRUPTION_DETECTION_CONVERTERS_H_
#include <optional>
#include "common_video/corruption_detection_message.h"
#include "common_video/frame_instrumentation_data.h"
namespace webrtc {
std::optional<CorruptionDetectionMessage>
ConvertFrameInstrumentationDataToCorruptionDetectionMessage(
const FrameInstrumentationData& frame_instrumentation_data);
std::optional<CorruptionDetectionMessage>
ConvertFrameInstrumentationSyncDataToCorruptionDetectionMessage(
const FrameInstrumentationSyncData& frame_instrumentation_sync_data);
} // namespace webrtc
#endif // COMMON_VIDEO_CORRUPTION_DETECTION_CONVERTERS_H_

View file

@ -0,0 +1,184 @@
/*
* Copyright 2024 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 "common_video/corruption_detection_converters.h"
#include <optional>
#include "common_video/corruption_detection_message.h"
#include "common_video/frame_instrumentation_data.h"
#include "test/gmock.h"
#include "test/gtest.h"
namespace webrtc {
namespace {
using ::testing::_;
using ::testing::ElementsAre;
TEST(CorruptionDetectionConvertersTest, ConvertsValidData) {
FrameInstrumentationData data = {.sequence_index = 1,
.communicate_upper_bits = false,
.std_dev = 1.0,
.luma_error_threshold = 5,
.chroma_error_threshold = 5,
.sample_values = {1.0, 2.0, 3.0, 4.0, 5.0}};
std::optional<CorruptionDetectionMessage> message =
ConvertFrameInstrumentationDataToCorruptionDetectionMessage(data);
ASSERT_TRUE(message.has_value());
EXPECT_EQ(message->sequence_index(), 1);
EXPECT_FALSE(message->interpret_sequence_index_as_most_significant_bits());
EXPECT_EQ(message->std_dev(), 1.0);
EXPECT_EQ(message->luma_error_threshold(), 5);
EXPECT_EQ(message->chroma_error_threshold(), 5);
EXPECT_THAT(message->sample_values(), ElementsAre(1.0, 2.0, 3.0, 4.0, 5.0));
}
TEST(CorruptionDetectionConvertersTest,
ReturnsNulloptWhenSequenceIndexIsNegative) {
FrameInstrumentationData data = {.sequence_index = -1,
.communicate_upper_bits = false,
.std_dev = 1.0,
.luma_error_threshold = 5,
.chroma_error_threshold = 5,
.sample_values = {1.0, 2.0, 3.0, 4.0, 5.0}};
std::optional<CorruptionDetectionMessage> message =
ConvertFrameInstrumentationDataToCorruptionDetectionMessage(data);
ASSERT_FALSE(message.has_value());
}
TEST(CorruptionDetectionConvertersTest,
ReturnsNulloptWhenSequenceIndexIsTooLarge) {
// Sequence index must be at max 14 bits.
FrameInstrumentationData data = {.sequence_index = 0x4000,
.communicate_upper_bits = false,
.std_dev = 1.0,
.luma_error_threshold = 5,
.chroma_error_threshold = 5,
.sample_values = {1.0, 2.0, 3.0, 4.0, 5.0}};
std::optional<CorruptionDetectionMessage> message =
ConvertFrameInstrumentationDataToCorruptionDetectionMessage(data);
ASSERT_FALSE(message.has_value());
}
TEST(CorruptionDetectionConvertersTest,
ReturnsNulloptWhenThereAreNoSampleValues) {
// FrameInstrumentationData must by definition have at least one sample value.
FrameInstrumentationData data = {.sequence_index = 1,
.communicate_upper_bits = false,
.std_dev = 1.0,
.luma_error_threshold = 5,
.chroma_error_threshold = 5,
.sample_values = {}};
std::optional<CorruptionDetectionMessage> message =
ConvertFrameInstrumentationDataToCorruptionDetectionMessage(data);
ASSERT_FALSE(message.has_value());
}
TEST(CorruptionDetectionConvertersTest,
ReturnsNulloptWhenNotSpecifyingSampleValues) {
FrameInstrumentationData data = {.sequence_index = 1,
.communicate_upper_bits = false,
.std_dev = 1.0,
.luma_error_threshold = 5,
.chroma_error_threshold = 5};
std::optional<CorruptionDetectionMessage> message =
ConvertFrameInstrumentationDataToCorruptionDetectionMessage(data);
ASSERT_FALSE(message.has_value());
}
TEST(CorruptionDetectionConvertersTest,
ConvertsSequenceIndexWhenSetToUseUpperBits) {
FrameInstrumentationData data = {.sequence_index = 0b0000'0110'0000'0101,
.communicate_upper_bits = true,
.std_dev = 1.0,
.luma_error_threshold = 5,
.chroma_error_threshold = 5,
.sample_values = {1.0, 2.0, 3.0, 4.0, 5.0}};
std::optional<CorruptionDetectionMessage> message =
ConvertFrameInstrumentationDataToCorruptionDetectionMessage(data);
ASSERT_TRUE(message.has_value());
EXPECT_EQ(message->sequence_index(), 0b0000'1100);
EXPECT_TRUE(message->interpret_sequence_index_as_most_significant_bits());
EXPECT_EQ(message->std_dev(), 1.0);
EXPECT_EQ(message->luma_error_threshold(), 5);
EXPECT_EQ(message->chroma_error_threshold(), 5);
EXPECT_THAT(message->sample_values(), ElementsAre(1.0, 2.0, 3.0, 4.0, 5.0));
}
TEST(CorruptionDetectionConvertersTest,
ConvertsSequenceIndexWhenSetToUseLowerBits) {
FrameInstrumentationData data = {.sequence_index = 0b0000'0110'0000'0101,
.communicate_upper_bits = false,
.std_dev = 1.0,
.luma_error_threshold = 5,
.chroma_error_threshold = 5,
.sample_values = {1.0, 2.0, 3.0, 4.0, 5.0}};
std::optional<CorruptionDetectionMessage> message =
ConvertFrameInstrumentationDataToCorruptionDetectionMessage(data);
ASSERT_TRUE(message.has_value());
EXPECT_EQ(message->sequence_index(), 0b0000'0101);
EXPECT_FALSE(message->interpret_sequence_index_as_most_significant_bits());
EXPECT_EQ(message->std_dev(), 1.0);
EXPECT_EQ(message->luma_error_threshold(), 5);
EXPECT_EQ(message->chroma_error_threshold(), 5);
EXPECT_THAT(message->sample_values(), ElementsAre(1.0, 2.0, 3.0, 4.0, 5.0));
}
TEST(CorruptionDetectionConvertersTest, ConvertsValidSyncData) {
FrameInstrumentationSyncData data = {.sequence_index = 1,
.communicate_upper_bits = true};
std::optional<CorruptionDetectionMessage> message =
ConvertFrameInstrumentationSyncDataToCorruptionDetectionMessage(data);
ASSERT_TRUE(message.has_value());
EXPECT_EQ(message->sequence_index(), 0);
EXPECT_TRUE(message->interpret_sequence_index_as_most_significant_bits());
}
#if GTEST_HAS_DEATH_TEST
TEST(CorruptionDetectionConvertersTest, FailsWhenSetToNotCommunicateUpperBits) {
FrameInstrumentationSyncData data = {.sequence_index = 1,
.communicate_upper_bits = false};
EXPECT_DEATH(
ConvertFrameInstrumentationSyncDataToCorruptionDetectionMessage(data), _);
}
#endif // GTEST_HAS_DEATH_TEST
TEST(CorruptionDetectionConvertersTest,
ReturnsNulloptWhenSyncSequenceIndexIsNegative) {
FrameInstrumentationSyncData data = {.sequence_index = -1,
.communicate_upper_bits = true};
std::optional<CorruptionDetectionMessage> message =
ConvertFrameInstrumentationSyncDataToCorruptionDetectionMessage(data);
ASSERT_FALSE(message.has_value());
}
TEST(CorruptionDetectionConvertersTest,
ReturnsNulloptWhenSyncSequenceIndexIsTooLarge) {
FrameInstrumentationSyncData data = {.sequence_index = 0x4000,
.communicate_upper_bits = true};
std::optional<CorruptionDetectionMessage> message =
ConvertFrameInstrumentationSyncDataToCorruptionDetectionMessage(data);
ASSERT_FALSE(message.has_value());
}
} // namespace
} // namespace webrtc