diff --git a/video/corruption_detection/halton_frame_sampler.cc b/video/corruption_detection/halton_frame_sampler.cc index 9f11244d6e..ea11217d9a 100644 --- a/video/corruption_detection/halton_frame_sampler.cc +++ b/video/corruption_detection/halton_frame_sampler.cc @@ -101,21 +101,21 @@ double GetFilteredElement(int width, const uint8_t* data, int row, int column, - double stddev) { + double std_dev) { RTC_CHECK_GE(row, 0); RTC_CHECK_LT(row, height); RTC_CHECK_GE(column, 0); RTC_CHECK_LT(column, width); RTC_CHECK_GE(stride, width); - RTC_CHECK_GE(stddev, 0.0); + RTC_CHECK_GE(std_dev, 0.0); - if (stddev == 0.0) { + if (std_dev == 0.0) { return data[row * stride + column]; } const double kCutoff = 0.2; const int kMaxDistance = - std::ceil(sqrt(-2.0 * std::log(kCutoff) * std::pow(stddev, 2.0))) - 1; + std::ceil(sqrt(-2.0 * std::log(kCutoff) * std::pow(std_dev, 2.0))) - 1; RTC_CHECK_GE(kMaxDistance, 0); if (kMaxDistance == 0) { return data[row * stride + column]; @@ -129,7 +129,7 @@ double GetFilteredElement(int width, c < std::min(column + kMaxDistance + 1, width); ++c) { double weight = std::exp(-1.0 * (std::pow(row - r, 2) + std::pow(column - c, 2)) / - (2.0 * std::pow(stddev, 2))); + (2.0 * std::pow(std_dev, 2))); element_sum += data[r * stride + c] * weight; total_weight += weight; } @@ -142,7 +142,7 @@ std::vector GetSampleValuesForFrame( std::vector sample_coordinates, int scaled_width, int scaled_height, - double stddev_gaussian_blur) { + double std_dev_gaussian_blur) { // Validate input. if (i420_frame_buffer == nullptr) { RTC_LOG(LS_WARNING) << "The framebuffer must not be nullptr"; @@ -167,10 +167,10 @@ std::vector GetSampleValuesForFrame( << scaled_width << ", height=" << scaled_height << ".\n"; return {}; } - if (stddev_gaussian_blur <= 0.0) { - RTC_LOG(LS_WARNING) << "The standard deviation for the Gaussian blur must " - "be larger than 0: " - << stddev_gaussian_blur << ".\n"; + if (std_dev_gaussian_blur < 0.0) { + RTC_LOG(LS_WARNING) + << "The standard deviation for the Gaussian blur must not be negative: " + << std_dev_gaussian_blur << ".\n"; return {}; } @@ -211,7 +211,7 @@ std::vector GetSampleValuesForFrame( value_for_coordinate = GetFilteredElement( scaled_i420_buffer->width(), scaled_i420_buffer->height(), scaled_i420_buffer->StrideY(), scaled_i420_buffer->DataY(), row, - column, stddev_gaussian_blur); + column, std_dev_gaussian_blur); filtered_samples.push_back( {.value = value_for_coordinate, .plane = ImagePlane::kLuma}); } else if (row < scaled_i420_buffer->ChromaHeight()) { @@ -220,7 +220,7 @@ std::vector GetSampleValuesForFrame( value_for_coordinate = GetFilteredElement( scaled_i420_buffer->ChromaWidth(), scaled_i420_buffer->ChromaHeight(), scaled_i420_buffer->StrideU(), scaled_i420_buffer->DataU(), row, - column, stddev_gaussian_blur); + column, std_dev_gaussian_blur); filtered_samples.push_back( {.value = value_for_coordinate, .plane = ImagePlane::kChroma}); } else { @@ -230,7 +230,7 @@ std::vector GetSampleValuesForFrame( value_for_coordinate = GetFilteredElement( scaled_i420_buffer->ChromaWidth(), scaled_i420_buffer->ChromaHeight(), scaled_i420_buffer->StrideV(), scaled_i420_buffer->DataV(), row, - column, stddev_gaussian_blur); + column, std_dev_gaussian_blur); filtered_samples.push_back( {.value = value_for_coordinate, .plane = ImagePlane::kChroma}); } diff --git a/video/corruption_detection/halton_frame_sampler.h b/video/corruption_detection/halton_frame_sampler.h index 9908c565f2..ea63a8f486 100644 --- a/video/corruption_detection/halton_frame_sampler.h +++ b/video/corruption_detection/halton_frame_sampler.h @@ -64,14 +64,14 @@ class HaltonFrameSampler { // 1. Scale the frame buffer to the resolution given by `scaled_width` and // `scaled_height`. // 2. Scale the `sample_coordinates` to the frame's resolution. -// 3. Apply the Gaussian filtering given by `stddev_gaussian_blur`. +// 3. Apply the Gaussian filtering given by `std_dev_gaussian_blur`. // 4. Fetch the values at the scaled coordinates in the filtered frame. std::vector GetSampleValuesForFrame( scoped_refptr i420_frame_buffer, std::vector sample_coordinates, int scaled_width, int scaled_height, - double stddev_gaussian_blur); + double std_dev_gaussian_blur); double GetFilteredElement(int width, int height, @@ -79,7 +79,7 @@ double GetFilteredElement(int width, const uint8_t* data, int row, int column, - double stddev); + double std_dev); } // namespace webrtc diff --git a/video/corruption_detection/halton_frame_sampler_unittest.cc b/video/corruption_detection/halton_frame_sampler_unittest.cc index f159f11a3f..747884b9b5 100644 --- a/video/corruption_detection/halton_frame_sampler_unittest.cc +++ b/video/corruption_detection/halton_frame_sampler_unittest.cc @@ -35,7 +35,7 @@ using Coordinates = HaltonFrameSampler::Coordinates; // Defaults for sampling tests. const int kDefaultScaledWidth = 4; const int kDefaultScaledHeight = 4; -const double kDefaultStddevGaussianBlur = 0.02; +const double kDefaultStdDevGaussianBlur = 0.02; #if GTEST_HAS_DEATH_TEST // Defaults for blurring tests. @@ -46,7 +46,7 @@ const uint8_t kDefaultData[kDefaultWidth * kDefaultHeight] = { 20, 196, 250, 115, 139, 39, 99, 197, 21, 166, 254, 28, 227, 54, 64, 46}; const int kDefaultRow = 3; const int kDefaultColumn = 2; -const double kDefaultStddev = 1.12; +const double kDefaultStdDev = 1.12; #endif // GTEST_HAS_DEATH_TEST scoped_refptr MakeDefaultI420FrameBuffer() { @@ -81,10 +81,10 @@ TEST(GaussianFilteringTest, ShouldReturnFilteredValueWhenInputIsValid) { 21, 166, 254, 28, 227, 54, 64, 46}; const int kRow = 3; const int kColumn = 2; - const double kStddev = 1.12; + const double kStdDev = 1.12; EXPECT_THAT(GetFilteredElement(kWidth, kHeight, kStride, kData, kRow, kColumn, - kStddev), + kStdDev), DoubleEq(103.9558797428683)); } @@ -97,10 +97,10 @@ TEST(GaussianFilteringTest, 21, 166, 254, 28, 227, 54, 64, 46}; const int kRow = 3; const int kColumn = 2; - const double kStddev = 0.0; + const double kStdDev = 0.0; EXPECT_THAT(GetFilteredElement(kWidth, kHeight, kStride, kData, kRow, kColumn, - kStddev), + kStdDev), DoubleEq(64.0)); } @@ -108,37 +108,37 @@ TEST(GaussianFilteringTest, TEST(GaussianFilteringTest, ShouldCrashWhenRowIsNegative) { EXPECT_DEATH( GetFilteredElement(kDefaultWidth, kDefaultHeight, kDefaultStride, - kDefaultData, -1, kDefaultColumn, kDefaultStddev), + kDefaultData, -1, kDefaultColumn, kDefaultStdDev), _); } TEST(GaussianFilteringTest, ShouldCrashWhenRowIsOutOfRange) { EXPECT_DEATH( GetFilteredElement(kDefaultWidth, 4, kDefaultStride, kDefaultData, 4, - kDefaultColumn, kDefaultStddev), + kDefaultColumn, kDefaultStdDev), _); } TEST(GaussianFilteringTest, ShouldCrashWhenColumnIsNegative) { EXPECT_DEATH( GetFilteredElement(kDefaultWidth, kDefaultHeight, kDefaultStride, - kDefaultData, kDefaultRow, -1, kDefaultStddev), + kDefaultData, kDefaultRow, -1, kDefaultStdDev), _); } TEST(GaussianFilteringTest, ShouldCrashWhenColumnIsOutOfRange) { EXPECT_DEATH(GetFilteredElement(4, kDefaultHeight, kDefaultStride, - kDefaultData, kDefaultRow, 4, kDefaultStddev), + kDefaultData, kDefaultRow, 4, kDefaultStdDev), _); } TEST(GaussianFilteringTest, ShouldCrashWhenStrideIsSmallerThanWidth) { EXPECT_DEATH(GetFilteredElement(4, kDefaultHeight, 3, kDefaultData, - kDefaultRow, kDefaultColumn, kDefaultStddev), + kDefaultRow, kDefaultColumn, kDefaultStdDev), _); } -TEST(GaussianFilteringTest, ShouldCrashWhenStddevIsNegative) { +TEST(GaussianFilteringTest, ShouldCrashWhenStdDevIsNegative) { EXPECT_DEATH( GetFilteredElement(kDefaultWidth, kDefaultHeight, kDefaultStride, kDefaultData, kDefaultRow, kDefaultColumn, -1.0), @@ -166,7 +166,7 @@ TEST(HaltonFrameSamplerGaussianFilteringTest, EXPECT_THAT(GetSampleValuesForFrame(nullptr, kDefaultSampleCoordinates, kDefaultScaledWidth, kDefaultScaledHeight, - kDefaultStddevGaussianBlur), + kDefaultStdDevGaussianBlur), IsEmpty()); } @@ -177,7 +177,7 @@ TEST(HaltonFrameSamplerGaussianFilteringTest, EXPECT_THAT( GetSampleValuesForFrame(kDefaultI420Buffer, {}, kDefaultScaledWidth, - kDefaultScaledHeight, kDefaultStddevGaussianBlur), + kDefaultScaledHeight, kDefaultStdDevGaussianBlur), IsEmpty()); } @@ -193,7 +193,7 @@ TEST(HaltonFrameSamplerGaussianFilteringTest, EXPECT_THAT(GetSampleValuesForFrame(kDefaultI420Buffer, kSampleCoordinates, kDefaultScaledWidth, kDefaultScaledHeight, - kDefaultStddevGaussianBlur), + kDefaultStdDevGaussianBlur), IsEmpty()); } @@ -206,7 +206,7 @@ TEST(HaltonFrameSamplerGaussianFilteringTest, EXPECT_THAT( GetSampleValuesForFrame(kDefaultI420Buffer, kDefaultSampleCoordinates, 0, - kDefaultScaledHeight, kDefaultStddevGaussianBlur), + kDefaultScaledHeight, kDefaultStdDevGaussianBlur), IsEmpty()); } @@ -219,12 +219,12 @@ TEST(HaltonFrameSamplerGaussianFilteringTest, EXPECT_THAT(GetSampleValuesForFrame( kDefaultI420Buffer, kDefaultSampleCoordinates, - kDefaultScaledWidth, 0, kDefaultStddevGaussianBlur), + kDefaultScaledWidth, 0, kDefaultStdDevGaussianBlur), IsEmpty()); } TEST(HaltonFrameSamplerGaussianFilteringTest, - ShouldReturnEmptyListGivenInvalidInputStddevZero) { + ShouldReturnEmptyListGivenInvalidInputStdDevNegative) { const scoped_refptr kDefaultI420Buffer = MakeDefaultI420FrameBuffer(); const std::vector kDefaultSampleCoordinates = @@ -232,10 +232,48 @@ TEST(HaltonFrameSamplerGaussianFilteringTest, EXPECT_THAT( GetSampleValuesForFrame(kDefaultI420Buffer, kDefaultSampleCoordinates, - kDefaultScaledWidth, kDefaultScaledHeight, 0.0), + kDefaultScaledWidth, kDefaultScaledHeight, -1.0), IsEmpty()); } +TEST(HaltonFrameSamplerGaussianFilteringTest, + ShouldReturnGivenValueWhenStdDevZero) { + // 4x4 i420 frame data. + const int kLumaWidth = 4; + const int kLumaHeight = 4; + const int kChromaWidth = 2; + const uint8_t kYContent[16] = {20, 196, 250, 115, 139, 39, 99, 197, + 21, 166, 254, 28, 227, 54, 64, 46}; + const uint8_t kUContent[4] = {156, 203, 36, 128}; + const uint8_t kVContent[4] = {112, 2, 0, 24}; + const scoped_refptr kI420Buffer = + I420Buffer::Copy(kLumaWidth, kLumaHeight, kYContent, kLumaWidth, + kUContent, kChromaWidth, kVContent, kChromaWidth); + + // Coordinates in all planes. + const std::vector kSampleCoordinates = { + {.row = 0.2, .column = 0.7}, + {.row = 0.5, .column = 0.9}, + {.row = 0.3, .column = 0.7}, + {.row = 0.8, .column = 0.4}}; + + // No scaling. + const int kScaledWidth = kLumaWidth; + const int kScaledHeight = kLumaHeight; + + EXPECT_THAT( + GetSampleValuesForFrame(kI420Buffer, kSampleCoordinates, kScaledWidth, + kScaledHeight, 0.0), + ElementsAre(AllOf(Field(&FilteredSample::value, DoubleEq(156.0)), + Field(&FilteredSample::plane, ImagePlane::kChroma)), + AllOf(Field(&FilteredSample::value, DoubleEq(2.0)), + Field(&FilteredSample::plane, ImagePlane::kChroma)), + AllOf(Field(&FilteredSample::value, DoubleEq(36.0)), + Field(&FilteredSample::plane, ImagePlane::kChroma)), + AllOf(Field(&FilteredSample::value, DoubleEq(64.0)), + Field(&FilteredSample::plane, ImagePlane::kLuma)))); +} + TEST(HaltonFrameSamplerGaussianFilteringTest, ShouldReturnGivenValueWhenNoScalingOrFilteringIsDefined) { // 4x4 i420 frame data. @@ -262,11 +300,11 @@ TEST(HaltonFrameSamplerGaussianFilteringTest, const int kScaledHeight = kLumaHeight; // No filtering. - const double kStddevGaussianBlur = 0.02; + const double kStdDevGaussianBlur = 0.02; EXPECT_THAT( GetSampleValuesForFrame(kI420Buffer, kSampleCoordinates, kScaledWidth, - kScaledHeight, kStddevGaussianBlur), + kScaledHeight, kStdDevGaussianBlur), ElementsAre(AllOf(Field(&FilteredSample::value, DoubleEq(156.0)), Field(&FilteredSample::plane, ImagePlane::kChroma)), AllOf(Field(&FilteredSample::value, DoubleEq(2.0)), @@ -303,11 +341,11 @@ TEST(HaltonFrameSamplerGaussianFilteringTest, const int kScaledHeight = 10; // No filtering. - const double kStddevGaussianBlur = 0.02; + const double kStdDevGaussianBlur = 0.02; EXPECT_THAT( GetSampleValuesForFrame(kI420Buffer, kSampleCoordinates, kScaledWidth, - kScaledHeight, kStddevGaussianBlur), + kScaledHeight, kStdDevGaussianBlur), ElementsAre(AllOf(Field(&FilteredSample::value, DoubleEq(96.0)), Field(&FilteredSample::plane, ImagePlane::kChroma)), AllOf(Field(&FilteredSample::value, DoubleEq(30.0)), @@ -344,11 +382,11 @@ TEST(HaltonFrameSamplerGaussianFilteringTest, const int kScaledHeight = kLumaHeight; // With filtering (kernel size 2x2). - const double kStddevGaussianBlur = 1.12; + const double kStdDevGaussianBlur = 1.12; EXPECT_THAT( GetSampleValuesForFrame(kI420Buffer, kSampleCoordinates, kScaledWidth, - kScaledHeight, kStddevGaussianBlur), + kScaledHeight, kStdDevGaussianBlur), ElementsAre( AllOf(Field(&FilteredSample::value, DoubleEq(133.93909141543787)), Field(&FilteredSample::plane, ImagePlane::kChroma)),