Add generic mapping functions for automatic corruption detection
The functions will be used to map a frame's QP to its optimal standard deviation for the Gaussian kernel for the filter applied in the automatic corruption detection algorithm. Bug: b/358039777 Change-Id: Idb3b8cfdbd4a405151c660df87205e3949f9b085 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/359380 Commit-Queue: Fanny Linderborg <linderborg@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Cr-Commit-Position: refs/heads/main@{#42777}
This commit is contained in:
parent
cfd83744d9
commit
4fffeabba3
@ -8,6 +8,18 @@
|
||||
|
||||
import("../../webrtc.gni")
|
||||
|
||||
rtc_library("generic_mapping_functions") {
|
||||
sources = [
|
||||
"generic_mapping_functions.cc",
|
||||
"generic_mapping_functions.h",
|
||||
]
|
||||
deps = [
|
||||
"../../api/video:video_frame",
|
||||
"../../api/video_codecs:video_codecs_api",
|
||||
"../../rtc_base:checks",
|
||||
]
|
||||
}
|
||||
|
||||
rtc_library("halton_sequence") {
|
||||
sources = [
|
||||
"halton_sequence.cc",
|
||||
@ -17,6 +29,16 @@ rtc_library("halton_sequence") {
|
||||
}
|
||||
|
||||
if (rtc_include_tests) {
|
||||
rtc_library("generic_mapping_functions_unittest") {
|
||||
testonly = true
|
||||
sources = [ "generic_mapping_functions_unittest.cc" ]
|
||||
deps = [
|
||||
":generic_mapping_functions",
|
||||
"../../api/video:video_frame",
|
||||
"../../test/:test_support",
|
||||
]
|
||||
}
|
||||
|
||||
rtc_library("halton_sequence_unittest") {
|
||||
testonly = true
|
||||
sources = [ "halton_sequence_unittest.cc" ]
|
||||
@ -29,6 +51,9 @@ if (rtc_include_tests) {
|
||||
rtc_library("corruption_detection_tests") {
|
||||
testonly = true
|
||||
sources = []
|
||||
deps = [ ":halton_sequence_unittest" ]
|
||||
deps = [
|
||||
":generic_mapping_functions_unittest",
|
||||
":halton_sequence_unittest",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
82
video/corruption_detection/generic_mapping_functions.cc
Normal file
82
video/corruption_detection/generic_mapping_functions.cc
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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 "video/corruption_detection/generic_mapping_functions.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "api/video/video_codec_type.h"
|
||||
#include "api/video_codecs/video_codec.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace {
|
||||
|
||||
constexpr int kLumaThreshold = 5;
|
||||
constexpr int kChromaThresholdVp8 = 6;
|
||||
constexpr int kChromaThresholdVp9 = 4;
|
||||
constexpr int kChromaThresholdAv1 = 4;
|
||||
constexpr int kChromaThresholdH264 = 2;
|
||||
|
||||
int LumaThreshold(VideoCodecType codec_type) {
|
||||
return kLumaThreshold;
|
||||
}
|
||||
|
||||
int ChromaThreshold(VideoCodecType codec_type) {
|
||||
switch (codec_type) {
|
||||
case VideoCodecType::kVideoCodecVP8:
|
||||
return kChromaThresholdVp8;
|
||||
case VideoCodecType::kVideoCodecVP9:
|
||||
return kChromaThresholdVp9;
|
||||
case VideoCodecType::kVideoCodecAV1:
|
||||
return kChromaThresholdAv1;
|
||||
case VideoCodecType::kVideoCodecH264:
|
||||
return kChromaThresholdH264;
|
||||
default:
|
||||
RTC_FATAL() << "Codec type " << CodecTypeToPayloadString(codec_type)
|
||||
<< " is not supported.";
|
||||
}
|
||||
}
|
||||
|
||||
double ExponentialFunction(double a, double b, double c, int qp) {
|
||||
return a * std::exp(b * qp - c);
|
||||
}
|
||||
|
||||
double RationalFunction(double a, double b, double c, int qp) {
|
||||
return (-a * qp) / (qp + b) + c;
|
||||
}
|
||||
|
||||
// Maps QP to the optimal standard deviation for the Gausian kernel.
|
||||
// Observe that the values below can be changed unnoticed.
|
||||
double MapQpToOptimalStdDev(int qp, VideoCodecType codec_type) {
|
||||
switch (codec_type) {
|
||||
case VideoCodecType::kVideoCodecVP8:
|
||||
return ExponentialFunction(0.006, 0.01857465, -4.26470513, qp);
|
||||
case VideoCodecType::kVideoCodecVP9:
|
||||
return RationalFunction(1, -257, 0.3, qp);
|
||||
case VideoCodecType::kVideoCodecAV1:
|
||||
return RationalFunction(0.69, -256, 0.42, qp);
|
||||
case VideoCodecType::kVideoCodecH264:
|
||||
return ExponentialFunction(0.016, 0.13976962, -1.40179328, qp);
|
||||
default:
|
||||
RTC_FATAL() << "Codec type " << CodecTypeToPayloadString(codec_type)
|
||||
<< " is not supported.";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
FilterSettings GetCorruptionFilterSettings(int qp, VideoCodecType codec_type) {
|
||||
return FilterSettings{.std_dev = MapQpToOptimalStdDev(qp, codec_type),
|
||||
.luma_error_threshold = LumaThreshold(codec_type),
|
||||
.chroma_error_threshold = ChromaThreshold(codec_type)};
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
28
video/corruption_detection/generic_mapping_functions.h
Normal file
28
video/corruption_detection/generic_mapping_functions.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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 VIDEO_CORRUPTION_DETECTION_GENERIC_MAPPING_FUNCTIONS_H_
|
||||
#define VIDEO_CORRUPTION_DETECTION_GENERIC_MAPPING_FUNCTIONS_H_
|
||||
|
||||
#include "api/video/video_codec_type.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct FilterSettings {
|
||||
double std_dev = 0.0;
|
||||
int luma_error_threshold = 0;
|
||||
int chroma_error_threshold = 0;
|
||||
};
|
||||
|
||||
FilterSettings GetCorruptionFilterSettings(int qp, VideoCodecType codec_type);
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // VIDEO_CORRUPTION_DETECTION_GENERIC_MAPPING_FUNCTIONS_H_
|
||||
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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 "video/corruption_detection/generic_mapping_functions.h"
|
||||
|
||||
#include "api/video/video_codec_type.h"
|
||||
#include "test/gmock.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace {
|
||||
|
||||
using ::testing::DoubleNear;
|
||||
using ::testing::FieldsAre;
|
||||
|
||||
constexpr double kMaxAbsoluteError = 1e-4;
|
||||
|
||||
constexpr int kLumaThreshold = 5;
|
||||
constexpr int kChromaThresholdVp8 = 6;
|
||||
constexpr int kChromaThresholdVp9 = 4;
|
||||
constexpr int kChromaThresholdAv1 = 4;
|
||||
constexpr int kChromaThresholdH264 = 2;
|
||||
|
||||
TEST(GenericMappingFunctionsTest, TestVp8) {
|
||||
constexpr VideoCodecType kCodecType = VideoCodecType::kVideoCodecVP8;
|
||||
EXPECT_THAT(GetCorruptionFilterSettings(
|
||||
/*qp=*/10, kCodecType),
|
||||
FieldsAre(DoubleNear(0.5139, kMaxAbsoluteError), kLumaThreshold,
|
||||
kChromaThresholdVp8));
|
||||
EXPECT_THAT(GetCorruptionFilterSettings(
|
||||
/*qp=*/100, kCodecType),
|
||||
FieldsAre(DoubleNear(2.7351, kMaxAbsoluteError), kLumaThreshold,
|
||||
kChromaThresholdVp8));
|
||||
EXPECT_THAT(GetCorruptionFilterSettings(/*qp=*/127, kCodecType),
|
||||
FieldsAre(DoubleNear(4.5162, kMaxAbsoluteError), kLumaThreshold,
|
||||
kChromaThresholdVp8));
|
||||
}
|
||||
|
||||
TEST(GenericMappingFunctionsTest, TestVp9) {
|
||||
constexpr VideoCodecType kCodecType = VideoCodecType::kVideoCodecVP9;
|
||||
EXPECT_THAT(GetCorruptionFilterSettings(/*qp=*/10, kCodecType),
|
||||
FieldsAre(DoubleNear(0.3405, kMaxAbsoluteError), kLumaThreshold,
|
||||
kChromaThresholdVp9));
|
||||
EXPECT_THAT(GetCorruptionFilterSettings(/*qp=*/100, kCodecType),
|
||||
FieldsAre(DoubleNear(0.9369, kMaxAbsoluteError), kLumaThreshold,
|
||||
kChromaThresholdVp9));
|
||||
EXPECT_THAT(GetCorruptionFilterSettings(/*qp=*/200, kCodecType),
|
||||
FieldsAre(DoubleNear(3.8088, kMaxAbsoluteError), kLumaThreshold,
|
||||
kChromaThresholdVp9));
|
||||
EXPECT_THAT(GetCorruptionFilterSettings(/*qp=*/255, kCodecType),
|
||||
FieldsAre(DoubleNear(127.8, kMaxAbsoluteError), kLumaThreshold,
|
||||
kChromaThresholdVp9));
|
||||
}
|
||||
|
||||
TEST(GenericMappingFunctionsTest, TestAv1) {
|
||||
constexpr VideoCodecType kCodecType = VideoCodecType::kVideoCodecAV1;
|
||||
EXPECT_THAT(GetCorruptionFilterSettings(/*qp=*/10, kCodecType),
|
||||
FieldsAre(DoubleNear(0.4480, kMaxAbsoluteError), kLumaThreshold,
|
||||
kChromaThresholdAv1));
|
||||
EXPECT_THAT(GetCorruptionFilterSettings(/*qp=*/100, kCodecType),
|
||||
FieldsAre(DoubleNear(0.8623, kMaxAbsoluteError), kLumaThreshold,
|
||||
kChromaThresholdAv1));
|
||||
EXPECT_THAT(GetCorruptionFilterSettings(/*qp=*/200, kCodecType),
|
||||
FieldsAre(DoubleNear(2.8842, kMaxAbsoluteError), kLumaThreshold,
|
||||
kChromaThresholdAv1));
|
||||
EXPECT_THAT(GetCorruptionFilterSettings(/*qp=*/255, kCodecType),
|
||||
FieldsAre(DoubleNear(176.37, kMaxAbsoluteError), kLumaThreshold,
|
||||
kChromaThresholdAv1));
|
||||
}
|
||||
|
||||
TEST(GenericMappingFunctionsTest, TestH264) {
|
||||
constexpr VideoCodecType kCodecType = VideoCodecType::kVideoCodecH264;
|
||||
EXPECT_THAT(GetCorruptionFilterSettings(/*qp=*/10, kCodecType),
|
||||
FieldsAre(DoubleNear(0.263, kMaxAbsoluteError), kLumaThreshold,
|
||||
kChromaThresholdH264));
|
||||
EXPECT_THAT(GetCorruptionFilterSettings(/*qp=*/30, kCodecType),
|
||||
FieldsAre(DoubleNear(4.3047, kMaxAbsoluteError), kLumaThreshold,
|
||||
kChromaThresholdH264));
|
||||
EXPECT_THAT(GetCorruptionFilterSettings(/*qp=*/51, kCodecType),
|
||||
FieldsAre(DoubleNear(81.0346, kMaxAbsoluteError), kLumaThreshold,
|
||||
kChromaThresholdH264));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace webrtc
|
||||
Loading…
x
Reference in New Issue
Block a user