| /* | |
| * 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); | |
| } | |
| TEST(VideoCodecTestLibvpx, Vp9L1T3) { | |
| auto config = CreateConfig(); | |
| config.SetCodecSettings(kVp9CodecName, 1, 1, /*num_temporal_layers=*/3, true, | |
| true, false, kCifWidth, kCifHeight); | |
| auto fixture = CreateVideoCodecTestFixture(config); | |
| std::vector<RateControlThresholds> rc_thresholds = { | |
| {.max_avg_bitrate_mismatch_percent = 60, | |
| .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<RateProfile> rate_profiles = { | |
| {.target_kbps = 500, .input_fps = 30, .frame_num = 0}}; | |
| fixture->RunTest(rate_profiles, &rc_thresholds, nullptr, nullptr); | |
| } | |
| #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 |