blob: 01e147cd1fe4d7cb79e166ccdbe40f52b3f319f1 [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 <vector>
#include "api/environment/environment.h"
#include "api/rtp_header_extension_id.h"
#include "api/rtp_parameters.h"
#include "api/task_queue/task_queue_base.h"
#include "api/test/video/function_video_decoder_factory.h"
#include "api/test/video/function_video_encoder_factory.h"
#include "api/video/video_codec_type.h"
#include "api/video_codecs/sdp_video_format.h"
#include "call/video_receive_stream.h"
#include "call/video_send_stream.h"
#include "modules/video_coding/codecs/vp8/include/vp8.h"
#include "rtc_base/checks.h"
#include "rtc_base/task_queue_for_test.h"
#include "rtc_base/thread.h"
#include "test/call_test.h"
#include "test/gtest.h"
#include "test/video_test_constants.h"
#include "video/config/video_encoder_config.h"
namespace webrtc {
namespace {
RtpExtension GetCorruptionExtension() {
return RtpExtension(RtpExtension::kCorruptionDetectionUri,
RtpHeaderExtensionId(1),
/*encrypt=*/true);
}
} // namespace
class CorruptionDetectionTest : public test::CallTest {
public:
CorruptionDetectionTest() { RegisterRtpExtension(GetCorruptionExtension()); }
};
TEST_F(
CorruptionDetectionTest,
ReportsCorruptionStatsIfSendStreamIsConfiguredToEnableCorruptionDetection) {
class StatsObserver : public test::EndToEndTest {
public:
StatsObserver()
: EndToEndTest(test::VideoTestConstants::kLongTimeout),
encoder_factory_(
[](const Environment& env, const SdpVideoFormat& format) {
return CreateVp8Encoder(env);
}),
decoder_factory_(
[](const Environment& env, const SdpVideoFormat& format) {
return CreateVp8Decoder(env);
}) {}
private:
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
encoder_config->codec_type = kVideoCodecVP8;
send_config->encoder_settings.enable_frame_instrumentation_generator =
true;
send_config->encoder_settings.encoder_factory = &encoder_factory_;
send_config->rtp.payload_name = "VP8";
send_config->rtp.extensions.clear();
send_config->rtp.extensions.push_back(GetCorruptionExtension());
for (auto& receive_config : *receive_configs) {
receive_config.decoder_factory = &decoder_factory_;
RTC_CHECK(!receive_config.decoders.empty());
receive_config.decoders[0].video_format =
SdpVideoFormat(send_config->rtp.payload_name);
}
}
void OnVideoStreamsCreated(VideoSendStream* send_stream,
const std::vector<VideoReceiveStreamInterface*>&
receive_streams) override {
receive_streams_ = receive_streams;
task_queue_ = TaskQueueBase::Current();
}
void PerformTest() override {
constexpr int kMaxIterations = 200;
bool corruption_score_reported = false;
for (int i = 0; i < kMaxIterations; ++i) {
Thread::SleepMs(10);
VideoReceiveStreamInterface::Stats stats;
SendTask(task_queue_, [&]() {
ASSERT_EQ(receive_streams_.size(), 1u);
stats = receive_streams_[0]->GetStats();
});
if (stats.corruption_score_count > 0) {
corruption_score_reported = true;
ASSERT_TRUE(stats.corruption_score_sum.has_value());
EXPECT_TRUE(stats.corruption_score_squared_sum.has_value());
double average_score =
*stats.corruption_score_sum / stats.corruption_score_count;
EXPECT_GE(average_score, 0);
EXPECT_LE(average_score, 1);
break;
}
}
EXPECT_TRUE(corruption_score_reported);
}
std::vector<VideoReceiveStreamInterface*> receive_streams_;
TaskQueueBase* task_queue_ = nullptr;
test::FunctionVideoEncoderFactory encoder_factory_;
test::FunctionVideoDecoderFactory decoder_factory_;
} test;
RunBaseTest(&test);
}
} // namespace webrtc