blob: c8e29b39924161e2f64493bcbd0570212a419d3e [file]
/*
* 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 "api/video/corruption_detection/frame_instrumentation_evaluation.h"
#include <cstdint>
#include <memory>
#include <vector>
#include "api/scoped_refptr.h"
#include "api/video/corruption_detection/frame_instrumentation_data.h"
#include "api/video/i420_buffer.h"
#include "api/video/video_content_type.h"
#include "api/video/video_frame.h"
#include "test/gmock.h"
#include "test/gtest.h"
namespace webrtc {
namespace {
using ::testing::_;
using ::testing::AllOf;
using ::testing::Ge;
using ::testing::Le;
class MockCorruptionScoreObserver : public CorruptionScoreObserver {
public:
MOCK_METHOD(void, OnCorruptionScore, (double, VideoContentType), (override));
};
scoped_refptr<I420Buffer> MakeI420FrameBufferWithDifferentPixelValues() {
// Create an I420 frame of size 4x4.
const int kDefaultLumaWidth = 4;
const int kDefaultLumaHeight = 4;
const int kDefaultChromaWidth = 2;
std::vector<uint8_t> kDefaultYContent = {1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16};
std::vector<uint8_t> kDefaultUContent = {17, 18, 19, 20};
std::vector<uint8_t> kDefaultVContent = {21, 22, 23, 24};
return I420Buffer::Copy(kDefaultLumaWidth, kDefaultLumaHeight,
kDefaultYContent.data(), kDefaultLumaWidth,
kDefaultUContent.data(), kDefaultChromaWidth,
kDefaultVContent.data(), kDefaultChromaWidth);
}
TEST(FrameInstrumentationEvaluationTest,
HaveNoCorruptionScoreWhenNoSampleValuesAreProvided) {
FrameInstrumentationData data;
VideoFrame frame =
VideoFrame::Builder()
.set_video_frame_buffer(MakeI420FrameBufferWithDifferentPixelValues())
.build();
MockCorruptionScoreObserver observer;
std::unique_ptr<FrameInstrumentationEvaluation> evaluator =
FrameInstrumentationEvaluation::Create(&observer);
EXPECT_CALL(observer, OnCorruptionScore).Times(0);
evaluator->OnInstrumentedFrame(data, frame, VideoContentType::UNSPECIFIED);
}
TEST(FrameInstrumentationEvaluationTest,
HaveACorruptionScoreWhenSampleValuesAreProvided) {
FrameInstrumentationData data;
data.SetStdDev(1.0);
data.SetSampleValues({12, 12, 12, 12, 12, 12, 12, 12});
VideoFrame frame =
VideoFrame::Builder()
.set_video_frame_buffer(MakeI420FrameBufferWithDifferentPixelValues())
.build();
MockCorruptionScoreObserver observer;
std::unique_ptr<FrameInstrumentationEvaluation> evaluator =
FrameInstrumentationEvaluation::Create(&observer);
EXPECT_CALL(observer, OnCorruptionScore(1.0, VideoContentType::SCREENSHARE));
evaluator->OnInstrumentedFrame(data, frame, VideoContentType::SCREENSHARE);
}
TEST(FrameInstrumentationEvaluationTest,
ApplyThresholdsWhenNonNegativeThresholdsAreProvided) {
FrameInstrumentationData data;
data.SetStdDev(1.0);
data.SetLumaErrorThreshold(8);
data.SetChromaErrorThreshold(8);
data.SetSampleValues({12, 12, 12, 12, 12, 12, 12, 12});
VideoFrame frame =
VideoFrame::Builder()
.set_video_frame_buffer(MakeI420FrameBufferWithDifferentPixelValues())
.build();
MockCorruptionScoreObserver observer;
std::unique_ptr<FrameInstrumentationEvaluation> evaluator =
FrameInstrumentationEvaluation::Create(&observer);
EXPECT_CALL(observer, OnCorruptionScore(AllOf(Ge(0.0), Le(1.0)), _));
evaluator->OnInstrumentedFrame(data, frame, VideoContentType::UNSPECIFIED);
}
TEST(FrameInstrumentationEvaluationTest,
ApplyStdDevWhenNonNegativeStdDevIsProvided) {
FrameInstrumentationData data;
data.SetStdDev(0.6);
data.SetLumaErrorThreshold(8);
data.SetChromaErrorThreshold(8);
data.SetSampleValues({12, 12, 12, 12, 12, 12, 12, 12});
VideoFrame frame =
VideoFrame::Builder()
.set_video_frame_buffer(MakeI420FrameBufferWithDifferentPixelValues())
.build();
MockCorruptionScoreObserver observer;
std::unique_ptr<FrameInstrumentationEvaluation> evaluator =
FrameInstrumentationEvaluation::Create(&observer);
EXPECT_CALL(observer, OnCorruptionScore(AllOf(Ge(0.0), Le(1.0)), _));
evaluator->OnInstrumentedFrame(data, frame, VideoContentType::UNSPECIFIED);
}
TEST(FrameInstrumentationEvaluationTest, ApplySequenceIndexWhenProvided) {
FrameInstrumentationData data;
data.SetSequenceIndex(1);
data.SetStdDev(0.6);
data.SetLumaErrorThreshold(8);
data.SetChromaErrorThreshold(8);
data.SetSampleValues({12, 12, 12, 12, 12, 12, 12, 12});
VideoFrame frame =
VideoFrame::Builder()
.set_video_frame_buffer(MakeI420FrameBufferWithDifferentPixelValues())
.build();
MockCorruptionScoreObserver observer;
std::unique_ptr<FrameInstrumentationEvaluation> evaluator =
FrameInstrumentationEvaluation::Create(&observer);
EXPECT_CALL(observer, OnCorruptionScore(AllOf(Ge(0.0), Le(1.0)), _));
evaluator->OnInstrumentedFrame(data, frame, VideoContentType::UNSPECIFIED);
}
} // namespace
} // namespace webrtc