blob: cf67e5d3b799c75e154d0154b450b39fd3e3df33 [file] [log] [blame] [edit]
/*
* Copyright (c) 2012 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 <cstddef>
#include <cstdio>
#include <map>
#include <memory>
#include <utility>
#include <vector>
#include "api/environment/environment.h"
#include "api/test/create_videocodec_test_fixture.h"
#include "api/test/video/function_video_encoder_factory.h"
#include "api/test/videocodec_test_fixture.h"
#include "api/test/videocodec_test_stats.h"
#include "api/video/encoded_image.h"
#include "api/video/video_codec_type.h"
#include "api/video_codecs/sdp_video_format.h"
#include "media/base/media_constants.h"
#include "media/engine/internal_decoder_factory.h"
#include "media/engine/internal_encoder_factory.h"
#include "media/engine/simulcast_encoder_adapter.h"
#include "modules/video_coding/utility/vp8_header_parser.h"
#include "modules/video_coding/utility/vp9_uncompressed_header_parser.h"
#include "rtc_base/checks.h"
#include "test/gtest.h"
#include "test/testsupport/file_utils.h"
namespace webrtc {
namespace test {
using VideoStatistics = VideoCodecTestStats::VideoStatistics;
namespace {
// Codec settings.
const int kCifWidth = 352;
const int kCifHeight = 288;
const int kNumFramesShort = 100;
const int kNumFramesLong = 300;
const size_t kBitrateRdPerfKbps[] = {100, 200, 300, 400, 500, 600,
700, 800, 1000, 1250, 1400, 1600,
1800, 2000, 2200, 2500};
const size_t kNumFirstFramesToSkipAtRdPerfAnalysis = 60;
class QpFrameChecker : public VideoCodecTestFixture::EncodedFrameChecker {
public:
void CheckEncodedFrame(VideoCodecType codec,
const EncodedImage& encoded_frame) const override {
int qp;
if (codec == kVideoCodecVP8) {
EXPECT_TRUE(vp8::GetQp(encoded_frame.data(), encoded_frame.size(), &qp));
} else if (codec == kVideoCodecVP9) {
EXPECT_TRUE(vp9::GetQp(encoded_frame.data(), encoded_frame.size(), &qp));
} else {
RTC_DCHECK_NOTREACHED();
}
EXPECT_EQ(encoded_frame.qp_, qp) << "Encoder QP != parsed bitstream QP.";
}
};
VideoCodecTestFixture::Config CreateConfig() {
VideoCodecTestFixture::Config config;
config.filename = "foreman_cif";
config.filepath = ResourcePath(config.filename, "yuv");
config.num_frames = kNumFramesLong;
config.use_single_core = true;
return config;
}
void PrintRdPerf(std::map<size_t, std::vector<VideoStatistics>> rd_stats) {
printf("--> Summary\n");
printf("%11s %5s %6s %11s %12s %11s %13s %13s %5s %7s %7s %7s %13s %13s\n",
"uplink_kbps", "width", "height", "spatial_idx", "temporal_idx",
"target_kbps", "downlink_kbps", "framerate_fps", "psnr", "psnr_y",
"psnr_u", "psnr_v", "enc_speed_fps", "dec_speed_fps");
for (const auto& rd_stat : rd_stats) {
const size_t bitrate_kbps = rd_stat.first;
for (const auto& layer_stat : rd_stat.second) {
printf(
"%11zu %5zu %6zu %11zu %12zu %11zu %13zu %13.2f %5.2f %7.2f %7.2f "
"%7.2f"
"%13.2f %13.2f\n",
bitrate_kbps, layer_stat.width, layer_stat.height,
layer_stat.spatial_idx, layer_stat.temporal_idx,
layer_stat.target_bitrate_kbps, layer_stat.bitrate_kbps,
layer_stat.framerate_fps, layer_stat.avg_psnr, layer_stat.avg_psnr_y,
layer_stat.avg_psnr_u, layer_stat.avg_psnr_v,
layer_stat.enc_speed_fps, layer_stat.dec_speed_fps);
}
}
}
} // namespace
#if defined(RTC_ENABLE_VP9)
TEST(VideoCodecTestLibvpx, HighBitrateVP9) {
auto config = CreateConfig();
config.SetCodecSettings(kVp9CodecName, 1, 1, 1, false, true, false, kCifWidth,
kCifHeight);
config.num_frames = kNumFramesShort;
const auto frame_checker = std::make_unique<QpFrameChecker>();
config.encoded_frame_checker = frame_checker.get();
auto fixture = CreateVideoCodecTestFixture(config);
std::vector<RateProfile> rate_profiles = {
{.target_kbps = 500, .input_fps = 30, .frame_num = 0}};
std::vector<RateControlThresholds> rc_thresholds = {
{.max_avg_bitrate_mismatch_percent = 5,
.max_time_to_reach_target_bitrate_sec = 1,
.max_avg_framerate_mismatch_percent = 0,
.max_avg_buffer_level_sec = 1,
.max_max_key_frame_delay_sec = 0.3,
.max_max_delta_frame_delay_sec = 0.1,
.max_num_spatial_resizes = 0,
.max_num_key_frames = 1}};
std::vector<QualityThresholds> quality_thresholds = {{.min_avg_psnr = 37,
.min_min_psnr = 36,
.min_avg_ssim = 0.94,
.min_min_ssim = 0.92}};
fixture->RunTest(rate_profiles, &rc_thresholds, &quality_thresholds, nullptr);
}
TEST(VideoCodecTestLibvpx, ChangeBitrateVP9) {
auto config = CreateConfig();
config.SetCodecSettings(kVp9CodecName, 1, 1, 1, false, true, false, kCifWidth,
kCifHeight);
const auto frame_checker = std::make_unique<QpFrameChecker>();
config.encoded_frame_checker = frame_checker.get();
auto fixture = CreateVideoCodecTestFixture(config);
std::vector<RateProfile> rate_profiles = {
{.target_kbps = 200,
.input_fps = 30,
.frame_num = 0}, // target_kbps, input_fps, frame_num
{.target_kbps = 700, .input_fps = 30, .frame_num = 100},
{.target_kbps = 500, .input_fps = 30, .frame_num = 200}};
std::vector<RateControlThresholds> rc_thresholds = {
{.max_avg_bitrate_mismatch_percent = 5,
.max_time_to_reach_target_bitrate_sec = 2,
.max_avg_framerate_mismatch_percent = 0,
.max_avg_buffer_level_sec = 1,
.max_max_key_frame_delay_sec = 0.5,
.max_max_delta_frame_delay_sec = 0.1,
.max_num_spatial_resizes = 0,
.max_num_key_frames = 1},
{.max_avg_bitrate_mismatch_percent = 15,
.max_time_to_reach_target_bitrate_sec = 3,
.max_avg_framerate_mismatch_percent = 0,
.max_avg_buffer_level_sec = 1,
.max_max_key_frame_delay_sec = 0.5,
.max_max_delta_frame_delay_sec = 0.1,
.max_num_spatial_resizes = 0,
.max_num_key_frames = 0},
{.max_avg_bitrate_mismatch_percent = 11,
.max_time_to_reach_target_bitrate_sec = 2,
.max_avg_framerate_mismatch_percent = 0,
.max_avg_buffer_level_sec = 1,
.max_max_key_frame_delay_sec = 0.5,
.max_max_delta_frame_delay_sec = 0.1,
.max_num_spatial_resizes = 0,
.max_num_key_frames = 0}};
std::vector<QualityThresholds> quality_thresholds = {{.min_avg_psnr = 34,
.min_min_psnr = 33,
.min_avg_ssim = 0.90,
.min_min_ssim = 0.88},
{.min_avg_psnr = 38,
.min_min_psnr = 35,
.min_avg_ssim = 0.95,
.min_min_ssim = 0.91},
{.min_avg_psnr = 35,
.min_min_psnr = 34,
.min_avg_ssim = 0.93,
.min_min_ssim = 0.90}};
fixture->RunTest(rate_profiles, &rc_thresholds, &quality_thresholds, nullptr);
}
TEST(VideoCodecTestLibvpx, ChangeFramerateVP9) {
auto config = CreateConfig();
config.SetCodecSettings(kVp9CodecName, 1, 1, 1, false, true, false, kCifWidth,
kCifHeight);
const auto frame_checker = std::make_unique<QpFrameChecker>();
config.encoded_frame_checker = frame_checker.get();
auto fixture = CreateVideoCodecTestFixture(config);
std::vector<RateProfile> rate_profiles = {
{.target_kbps = 100,
.input_fps = 24,
.frame_num = 0}, // target_kbps, input_fps, frame_num
{.target_kbps = 100, .input_fps = 15, .frame_num = 100},
{.target_kbps = 100, .input_fps = 10, .frame_num = 200}};
// Framerate mismatch should be lower for lower framerate.
std::vector<RateControlThresholds> rc_thresholds = {
{.max_avg_bitrate_mismatch_percent = 10,
.max_time_to_reach_target_bitrate_sec = 2,
.max_avg_framerate_mismatch_percent = 40,
.max_avg_buffer_level_sec = 1,
.max_max_key_frame_delay_sec = 0.5,
.max_max_delta_frame_delay_sec = 0.2,
.max_num_spatial_resizes = 0,
.max_num_key_frames = 1},
{.max_avg_bitrate_mismatch_percent = 8,
.max_time_to_reach_target_bitrate_sec = 2,
.max_avg_framerate_mismatch_percent = 5,
.max_avg_buffer_level_sec = 1,
.max_max_key_frame_delay_sec = 0.5,
.max_max_delta_frame_delay_sec = 0.2,
.max_num_spatial_resizes = 0,
.max_num_key_frames = 0},
{.max_avg_bitrate_mismatch_percent = 5,
.max_time_to_reach_target_bitrate_sec = 2,
.max_avg_framerate_mismatch_percent = 0,
.max_avg_buffer_level_sec = 1,
.max_max_key_frame_delay_sec = 0.5,
.max_max_delta_frame_delay_sec = 0.3,
.max_num_spatial_resizes = 0,
.max_num_key_frames = 0}};
// Quality should be higher for lower framerates for the same content.
std::vector<QualityThresholds> quality_thresholds = {{.min_avg_psnr = 33,
.min_min_psnr = 32,
.min_avg_ssim = 0.88,
.min_min_ssim = 0.86},
{.min_avg_psnr = 33.5,
.min_min_psnr = 32,
.min_avg_ssim = 0.90,
.min_min_ssim = 0.86},
{.min_avg_psnr = 33.5,
.min_min_psnr = 31.5,
.min_avg_ssim = 0.90,
.min_min_ssim = 0.85}};
fixture->RunTest(rate_profiles, &rc_thresholds, &quality_thresholds, nullptr);
}
TEST(VideoCodecTestLibvpx, DenoiserOnVP9) {
auto config = CreateConfig();
config.SetCodecSettings(kVp9CodecName, 1, 1, 1, true, true, false, kCifWidth,
kCifHeight);
config.num_frames = kNumFramesShort;
const auto frame_checker = std::make_unique<QpFrameChecker>();
config.encoded_frame_checker = frame_checker.get();
auto fixture = CreateVideoCodecTestFixture(config);
std::vector<RateProfile> rate_profiles = {
{.target_kbps = 500, .input_fps = 30, .frame_num = 0}};
std::vector<RateControlThresholds> rc_thresholds = {
{.max_avg_bitrate_mismatch_percent = 5,
.max_time_to_reach_target_bitrate_sec = 1,
.max_avg_framerate_mismatch_percent = 0,
.max_avg_buffer_level_sec = 1,
.max_max_key_frame_delay_sec = 0.3,
.max_max_delta_frame_delay_sec = 0.1,
.max_num_spatial_resizes = 0,
.max_num_key_frames = 1}};
std::vector<QualityThresholds> quality_thresholds = {{.min_avg_psnr = 37.5,
.min_min_psnr = 36,
.min_avg_ssim = 0.94,
.min_min_ssim = 0.93}};
fixture->RunTest(rate_profiles, &rc_thresholds, &quality_thresholds, nullptr);
}
TEST(VideoCodecTestLibvpx, VeryLowBitrateVP9) {
auto config = CreateConfig();
config.SetCodecSettings(kVp9CodecName, 1, 1, 1, false, true, true, kCifWidth,
kCifHeight);
const auto frame_checker = std::make_unique<QpFrameChecker>();
config.encoded_frame_checker = frame_checker.get();
auto fixture = CreateVideoCodecTestFixture(config);
std::vector<RateProfile> rate_profiles = {
{.target_kbps = 50, .input_fps = 30, .frame_num = 0}};
std::vector<RateControlThresholds> rc_thresholds = {
{.max_avg_bitrate_mismatch_percent = 15,
.max_time_to_reach_target_bitrate_sec = 3,
.max_avg_framerate_mismatch_percent = 75,
.max_avg_buffer_level_sec = 1,
.max_max_key_frame_delay_sec = 0.5,
.max_max_delta_frame_delay_sec = 0.4,
.max_num_spatial_resizes = 2,
.max_num_key_frames = 1}};
std::vector<QualityThresholds> quality_thresholds = {{.min_avg_psnr = 28,
.min_min_psnr = 25,
.min_avg_ssim = 0.80,
.min_min_ssim = 0.65}};
fixture->RunTest(rate_profiles, &rc_thresholds, &quality_thresholds, nullptr);
}
// TODO(marpan): Add temporal layer test for VP9, once changes are in
// vp9 wrapper for this.
#endif // defined(RTC_ENABLE_VP9)
TEST(VideoCodecTestLibvpx, HighBitrateVP8) {
auto config = CreateConfig();
config.SetCodecSettings(kVp8CodecName, 1, 1, 1, true, true, false, kCifWidth,
kCifHeight);
config.num_frames = kNumFramesShort;
const auto frame_checker = std::make_unique<QpFrameChecker>();
config.encoded_frame_checker = frame_checker.get();
auto fixture = CreateVideoCodecTestFixture(config);
std::vector<RateProfile> rate_profiles = {
{.target_kbps = 500, .input_fps = 30, .frame_num = 0}};
std::vector<RateControlThresholds> rc_thresholds = {
{.max_avg_bitrate_mismatch_percent = 5,
.max_time_to_reach_target_bitrate_sec = 1,
.max_avg_framerate_mismatch_percent = 0,
.max_avg_buffer_level_sec = 1,
.max_max_key_frame_delay_sec = 0.2,
.max_max_delta_frame_delay_sec = 0.1,
.max_num_spatial_resizes = 0,
.max_num_key_frames = 1}};
#if defined(WEBRTC_ARCH_ARM) || defined(WEBRTC_ARCH_ARM64)
std::vector<QualityThresholds> quality_thresholds = {{35, 33, 0.91, 0.89}};
#else
std::vector<QualityThresholds> quality_thresholds = {{.min_avg_psnr = 37,
.min_min_psnr = 35,
.min_avg_ssim = 0.93,
.min_min_ssim = 0.91}};
#endif
fixture->RunTest(rate_profiles, &rc_thresholds, &quality_thresholds, nullptr);
}
TEST(VideoCodecTestLibvpx, MAYBE_ChangeBitrateVP8) {
auto config = CreateConfig();
config.SetCodecSettings(kVp8CodecName, 1, 1, 1, true, true, false, kCifWidth,
kCifHeight);
const auto frame_checker = std::make_unique<QpFrameChecker>();
config.encoded_frame_checker = frame_checker.get();
auto fixture = CreateVideoCodecTestFixture(config);
std::vector<RateProfile> rate_profiles = {
{.target_kbps = 200,
.input_fps = 30,
.frame_num = 0}, // target_kbps, input_fps, frame_num
{.target_kbps = 800, .input_fps = 30, .frame_num = 100},
{.target_kbps = 500, .input_fps = 30, .frame_num = 200}};
std::vector<RateControlThresholds> rc_thresholds = {
{.max_avg_bitrate_mismatch_percent = 5,
.max_time_to_reach_target_bitrate_sec = 1,
.max_avg_framerate_mismatch_percent = 0,
.max_avg_buffer_level_sec = 1,
.max_max_key_frame_delay_sec = 0.2,
.max_max_delta_frame_delay_sec = 0.1,
.max_num_spatial_resizes = 0,
.max_num_key_frames = 1},
{.max_avg_bitrate_mismatch_percent = 15.5,
.max_time_to_reach_target_bitrate_sec = 1,
.max_avg_framerate_mismatch_percent = 0,
.max_avg_buffer_level_sec = 1,
.max_max_key_frame_delay_sec = 0.2,
.max_max_delta_frame_delay_sec = 0.1,
.max_num_spatial_resizes = 0,
.max_num_key_frames = 0},
{.max_avg_bitrate_mismatch_percent = 15,
.max_time_to_reach_target_bitrate_sec = 1,
.max_avg_framerate_mismatch_percent = 0,
.max_avg_buffer_level_sec = 1,
.max_max_key_frame_delay_sec = 0.2,
.max_max_delta_frame_delay_sec = 0.1,
.max_num_spatial_resizes = 0,
.max_num_key_frames = 0}};
#if defined(WEBRTC_ARCH_ARM) || defined(WEBRTC_ARCH_ARM64)
std::vector<QualityThresholds> quality_thresholds = {
{31.8, 31, 0.86, 0.85}, {36, 34.8, 0.92, 0.90}, {33.5, 32, 0.90, 0.88}};
#else
std::vector<QualityThresholds> quality_thresholds = {{.min_avg_psnr = 33,
.min_min_psnr = 32,
.min_avg_ssim = 0.89,
.min_min_ssim = 0.88},
{.min_avg_psnr = 38,
.min_min_psnr = 36,
.min_avg_ssim = 0.94,
.min_min_ssim = 0.93},
{.min_avg_psnr = 35,
.min_min_psnr = 34,
.min_avg_ssim = 0.92,
.min_min_ssim = 0.91}};
#endif
fixture->RunTest(rate_profiles, &rc_thresholds, &quality_thresholds, nullptr);
}
TEST(VideoCodecTestLibvpx, MAYBE_ChangeFramerateVP8) {
auto config = CreateConfig();
config.SetCodecSettings(kVp8CodecName, 1, 1, 1, true, true, false, kCifWidth,
kCifHeight);
const auto frame_checker = std::make_unique<QpFrameChecker>();
config.encoded_frame_checker = frame_checker.get();
auto fixture = CreateVideoCodecTestFixture(config);
std::vector<RateProfile> rate_profiles = {
{.target_kbps = 80,
.input_fps = 24,
.frame_num = 0}, // target_kbps, input_fps, frame_index_rate_update
{.target_kbps = 80, .input_fps = 15, .frame_num = 100},
{.target_kbps = 80, .input_fps = 10, .frame_num = 200}};
#if defined(WEBRTC_ARCH_ARM) || defined(WEBRTC_ARCH_ARM64)
std::vector<RateControlThresholds> rc_thresholds = {
{10, 2.42, 60, 1, 0.3, 0.3, 0, 1},
{10, 2, 30, 1, 0.3, 0.3, 0, 0},
{10, 2, 10, 1, 0.3, 0.2, 0, 0}};
#else
std::vector<RateControlThresholds> rc_thresholds = {
{.max_avg_bitrate_mismatch_percent = 10,
.max_time_to_reach_target_bitrate_sec = 2,
.max_avg_framerate_mismatch_percent = 20,
.max_avg_buffer_level_sec = 1,
.max_max_key_frame_delay_sec = 0.3,
.max_max_delta_frame_delay_sec = 0.15,
.max_num_spatial_resizes = 0,
.max_num_key_frames = 1},
{.max_avg_bitrate_mismatch_percent = 5,
.max_time_to_reach_target_bitrate_sec = 2,
.max_avg_framerate_mismatch_percent = 5,
.max_avg_buffer_level_sec = 1,
.max_max_key_frame_delay_sec = 0.3,
.max_max_delta_frame_delay_sec = 0.15,
.max_num_spatial_resizes = 0,
.max_num_key_frames = 0},
{.max_avg_bitrate_mismatch_percent = 4,
.max_time_to_reach_target_bitrate_sec = 2,
.max_avg_framerate_mismatch_percent = 1,
.max_avg_buffer_level_sec = 1,
.max_max_key_frame_delay_sec = 0.3,
.max_max_delta_frame_delay_sec = 0.2,
.max_num_spatial_resizes = 0,
.max_num_key_frames = 0}};
#endif
#if defined(WEBRTC_ARCH_ARM) || defined(WEBRTC_ARCH_ARM64)
std::vector<QualityThresholds> quality_thresholds = {
{31, 30, 0.85, 0.84}, {31.4, 30.5, 0.86, 0.84}, {30.5, 29, 0.83, 0.78}};
#else
std::vector<QualityThresholds> quality_thresholds = {{.min_avg_psnr = 31,
.min_min_psnr = 30,
.min_avg_ssim = 0.87,
.min_min_ssim = 0.85},
{.min_avg_psnr = 32,
.min_min_psnr = 31,
.min_avg_ssim = 0.88,
.min_min_ssim = 0.85},
{.min_avg_psnr = 32,
.min_min_psnr = 30,
.min_avg_ssim = 0.87,
.min_min_ssim = 0.82}};
#endif
fixture->RunTest(rate_profiles, &rc_thresholds, &quality_thresholds, nullptr);
}
#if defined(WEBRTC_ANDROID)
#define MAYBE_TemporalLayersVP8 DISABLED_TemporalLayersVP8
#else
#define MAYBE_TemporalLayersVP8 TemporalLayersVP8
#endif
TEST(VideoCodecTestLibvpx, MAYBE_TemporalLayersVP8) {
auto config = CreateConfig();
config.SetCodecSettings(kVp8CodecName, 1, 1, 3, true, true, false, kCifWidth,
kCifHeight);
const auto frame_checker = std::make_unique<QpFrameChecker>();
config.encoded_frame_checker = frame_checker.get();
auto fixture = CreateVideoCodecTestFixture(config);
std::vector<RateProfile> rate_profiles = {
{.target_kbps = 200, .input_fps = 30, .frame_num = 0},
{.target_kbps = 400, .input_fps = 30, .frame_num = 150}};
#if defined(WEBRTC_ARCH_ARM) || defined(WEBRTC_ARCH_ARM64)
std::vector<RateControlThresholds> rc_thresholds = {
{10, 1, 2.1, 1, 0.2, 0.1, 0, 1}, {12, 2, 3, 1, 0.2, 0.1, 0, 1}};
#else
std::vector<RateControlThresholds> rc_thresholds = {
{.max_avg_bitrate_mismatch_percent = 5,
.max_time_to_reach_target_bitrate_sec = 1,
.max_avg_framerate_mismatch_percent = 0,
.max_avg_buffer_level_sec = 1,
.max_max_key_frame_delay_sec = 0.2,
.max_max_delta_frame_delay_sec = 0.1,
.max_num_spatial_resizes = 0,
.max_num_key_frames = 1},
{.max_avg_bitrate_mismatch_percent = 10,
.max_time_to_reach_target_bitrate_sec = 2,
.max_avg_framerate_mismatch_percent = 0,
.max_avg_buffer_level_sec = 1,
.max_max_key_frame_delay_sec = 0.2,
.max_max_delta_frame_delay_sec = 0.1,
.max_num_spatial_resizes = 0,
.max_num_key_frames = 1}};
#endif
// Min SSIM drops because of high motion scene with complex backgound (trees).
#if defined(WEBRTC_ARCH_ARM) || defined(WEBRTC_ARCH_ARM64)
std::vector<QualityThresholds> quality_thresholds = {{31, 30, 0.85, 0.83},
{31, 28, 0.85, 0.75}};
#else
std::vector<QualityThresholds> quality_thresholds = {{.min_avg_psnr = 32,
.min_min_psnr = 30,
.min_avg_ssim = 0.88,
.min_min_ssim = 0.85},
{.min_avg_psnr = 33,
.min_min_psnr = 30,
.min_avg_ssim = 0.89,
.min_min_ssim = 0.83}};
#endif
fixture->RunTest(rate_profiles, &rc_thresholds, &quality_thresholds, nullptr);
}
#if defined(WEBRTC_ANDROID)
#define MAYBE_MultiresVP8 DISABLED_MultiresVP8
#else
#define MAYBE_MultiresVP8 MultiresVP8
#endif
TEST(VideoCodecTestLibvpx, MAYBE_MultiresVP8) {
auto config = CreateConfig();
config.filename = "ConferenceMotion_1280_720_50";
config.filepath = ResourcePath(config.filename, "yuv");
config.num_frames = 100;
config.SetCodecSettings(kVp8CodecName, 3, 1, 3, true, true, false, 1280, 720);
const auto frame_checker = std::make_unique<QpFrameChecker>();
config.encoded_frame_checker = frame_checker.get();
auto fixture = CreateVideoCodecTestFixture(config);
std::vector<RateProfile> rate_profiles = {
{.target_kbps = 1500, .input_fps = 30, .frame_num = 0}};
#if defined(WEBRTC_ARCH_ARM) || defined(WEBRTC_ARCH_ARM64)
std::vector<RateControlThresholds> rc_thresholds = {
{4.1, 1.04, 7, 0.18, 0.14, 0.08, 0, 1}};
#else
std::vector<RateControlThresholds> rc_thresholds = {
{.max_avg_bitrate_mismatch_percent = 5,
.max_time_to_reach_target_bitrate_sec = 1,
.max_avg_framerate_mismatch_percent = 5,
.max_avg_buffer_level_sec = 1,
.max_max_key_frame_delay_sec = 0.3,
.max_max_delta_frame_delay_sec = 0.1,
.max_num_spatial_resizes = 0,
.max_num_key_frames = 1}};
#endif
std::vector<QualityThresholds> quality_thresholds = {{.min_avg_psnr = 34,
.min_min_psnr = 32,
.min_avg_ssim = 0.90,
.min_min_ssim = 0.88}};
fixture->RunTest(rate_profiles, &rc_thresholds, &quality_thresholds, nullptr);
}
#if defined(WEBRTC_ANDROID)
#define MAYBE_SimulcastVP8 DISABLED_SimulcastVP8
#else
#define MAYBE_SimulcastVP8 SimulcastVP8
#endif
TEST(VideoCodecTestLibvpx, MAYBE_SimulcastVP8) {
auto config = CreateConfig();
config.filename = "ConferenceMotion_1280_720_50";
config.filepath = ResourcePath(config.filename, "yuv");
config.num_frames = 100;
config.SetCodecSettings(kVp8CodecName, 3, 1, 3, true, true, false, 1280, 720);
const auto frame_checker = std::make_unique<QpFrameChecker>();
config.encoded_frame_checker = frame_checker.get();
InternalEncoderFactory internal_encoder_factory;
auto adapted_encoder_factory = std::make_unique<FunctionVideoEncoderFactory>(
[&](const Environment& env, const SdpVideoFormat& /* format */) {
return std::make_unique<SimulcastEncoderAdapter>(
env, &internal_encoder_factory, nullptr, SdpVideoFormat::VP8());
});
auto internal_decoder_factory = std::make_unique<InternalDecoderFactory>();
auto fixture =
CreateVideoCodecTestFixture(config, std::move(internal_decoder_factory),
std::move(adapted_encoder_factory));
std::vector<RateProfile> rate_profiles = {
{.target_kbps = 1500, .input_fps = 30, .frame_num = 0}};
std::vector<RateControlThresholds> rc_thresholds = {
{.max_avg_bitrate_mismatch_percent = 20,
.max_time_to_reach_target_bitrate_sec = 5,
.max_avg_framerate_mismatch_percent = 90,
.max_avg_buffer_level_sec = 1,
.max_max_key_frame_delay_sec = 0.5,
.max_max_delta_frame_delay_sec = 0.3,
.max_num_spatial_resizes = 0,
.max_num_key_frames = 1}};
std::vector<QualityThresholds> quality_thresholds = {{.min_avg_psnr = 34,
.min_min_psnr = 32,
.min_avg_ssim = 0.90,
.min_min_ssim = 0.88}};
fixture->RunTest(rate_profiles, &rc_thresholds, &quality_thresholds, nullptr);
}
#if defined(WEBRTC_ANDROID)
#define MAYBE_SvcVP9 DISABLED_SvcVP9
#else
#define MAYBE_SvcVP9 SvcVP9
#endif
TEST(VideoCodecTestLibvpx, MAYBE_SvcVP9) {
auto config = CreateConfig();
config.filename = "ConferenceMotion_1280_720_50";
config.filepath = ResourcePath(config.filename, "yuv");
config.num_frames = 100;
config.SetCodecSettings(kVp9CodecName, 1, 3, 3, true, true, false, 1280, 720);
const auto frame_checker = std::make_unique<QpFrameChecker>();
config.encoded_frame_checker = frame_checker.get();
auto fixture = CreateVideoCodecTestFixture(config);
std::vector<RateProfile> rate_profiles = {
{.target_kbps = 1500, .input_fps = 30, .frame_num = 0}};
std::vector<RateControlThresholds> rc_thresholds = {
{.max_avg_bitrate_mismatch_percent = 5,
.max_time_to_reach_target_bitrate_sec = 1,
.max_avg_framerate_mismatch_percent = 5,
.max_avg_buffer_level_sec = 1,
.max_max_key_frame_delay_sec = 0.3,
.max_max_delta_frame_delay_sec = 0.1,
.max_num_spatial_resizes = 0,
.max_num_key_frames = 1}};
std::vector<QualityThresholds> quality_thresholds = {{.min_avg_psnr = 36,
.min_min_psnr = 34,
.min_avg_ssim = 0.93,
.min_min_ssim = 0.90}};
fixture->RunTest(rate_profiles, &rc_thresholds, &quality_thresholds, nullptr);
}
TEST(VideoCodecTestLibvpx, DISABLED_MultiresVP8RdPerf) {
auto config = CreateConfig();
config.filename = "FourPeople_1280x720_30";
config.filepath = ResourcePath(config.filename, "yuv");
config.num_frames = 300;
config.print_frame_level_stats = true;
config.SetCodecSettings(kVp8CodecName, 3, 1, 3, true, true, false, 1280, 720);
const auto frame_checker = std::make_unique<QpFrameChecker>();
config.encoded_frame_checker = frame_checker.get();
auto fixture = CreateVideoCodecTestFixture(config);
std::map<size_t, std::vector<VideoStatistics>> rd_stats;
for (size_t bitrate_kbps : kBitrateRdPerfKbps) {
std::vector<RateProfile> rate_profiles = {
{.target_kbps = bitrate_kbps, .input_fps = 30, .frame_num = 0}};
fixture->RunTest(rate_profiles, nullptr, nullptr, nullptr);
rd_stats[bitrate_kbps] =
fixture->GetStats().SliceAndCalcLayerVideoStatistic(
kNumFirstFramesToSkipAtRdPerfAnalysis, config.num_frames - 1);
}
PrintRdPerf(rd_stats);
}
TEST(VideoCodecTestLibvpx, DISABLED_SvcVP9RdPerf) {
auto config = CreateConfig();
config.filename = "FourPeople_1280x720_30";
config.filepath = ResourcePath(config.filename, "yuv");
config.num_frames = 300;
config.print_frame_level_stats = true;
config.SetCodecSettings(kVp9CodecName, 1, 3, 3, true, true, false, 1280, 720);
const auto frame_checker = std::make_unique<QpFrameChecker>();
config.encoded_frame_checker = frame_checker.get();
auto fixture = CreateVideoCodecTestFixture(config);
std::map<size_t, std::vector<VideoStatistics>> rd_stats;
for (size_t bitrate_kbps : kBitrateRdPerfKbps) {
std::vector<RateProfile> rate_profiles = {
{.target_kbps = bitrate_kbps, .input_fps = 30, .frame_num = 0}};
fixture->RunTest(rate_profiles, nullptr, nullptr, nullptr);
rd_stats[bitrate_kbps] =
fixture->GetStats().SliceAndCalcLayerVideoStatistic(
kNumFirstFramesToSkipAtRdPerfAnalysis, config.num_frames - 1);
}
PrintRdPerf(rd_stats);
}
} // namespace test
} // namespace webrtc