From 2d27fb5a33689d730ef615c172d5b0d793e09b04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=85sa=20Persson?= Date: Thu, 19 Oct 2017 14:05:50 +0200 Subject: [PATCH] Move TestConfig to separate file. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move functions Set/PrintCodecSettings, NumberOfTemporalLayers to TestConfig. Add function NumberOfCores. Bug: none Change-Id: Ic33d79681d59d62bf34d9c9ff056a751ed3f8da8 Reviewed-on: https://webrtc-review.googlesource.com/13120 Commit-Queue: Åsa Persson Reviewed-by: Rasmus Brandt Cr-Commit-Position: refs/heads/master@{#20358} --- modules/video_coding/BUILD.gn | 3 + modules/video_coding/codecs/test/stats.cc | 5 + .../video_coding/codecs/test/test_config.cc | 140 ++++++++++++++++++ .../video_coding/codecs/test/test_config.h | 111 ++++++++++++++ .../codecs/test/test_config_unittest.cc | 55 +++++++ .../codecs/test/videoprocessor.cc | 91 +----------- .../video_coding/codecs/test/videoprocessor.h | 74 +-------- .../test/videoprocessor_integrationtest.cc | 91 +++--------- .../test/videoprocessor_integrationtest.h | 14 +- .../videoprocessor_integrationtest_libvpx.cc | 48 +++--- ...deoprocessor_integrationtest_mediacodec.cc | 8 +- ...videoprocessor_integrationtest_openh264.cc | 8 +- ...processor_integrationtest_parameterized.cc | 6 +- 13 files changed, 382 insertions(+), 272 deletions(-) create mode 100644 modules/video_coding/codecs/test/test_config.cc create mode 100644 modules/video_coding/codecs/test/test_config.h create mode 100644 modules/video_coding/codecs/test/test_config_unittest.cc diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn index d6547d869d..9aaf700220 100644 --- a/modules/video_coding/BUILD.gn +++ b/modules/video_coding/BUILD.gn @@ -367,6 +367,8 @@ if (rtc_include_tests) { "codecs/test/predictive_packet_manipulator.h", "codecs/test/stats.cc", "codecs/test/stats.h", + "codecs/test/test_config.cc", + "codecs/test/test_config.h", "codecs/test/video_codec_test.cc", "codecs/test/video_codec_test.h", "codecs/test/videoprocessor.cc", @@ -501,6 +503,7 @@ if (rtc_include_tests) { sources = [ "codecs/test/packet_manipulator_unittest.cc", "codecs/test/stats_unittest.cc", + "codecs/test/test_config_unittest.cc", "codecs/test/videoprocessor_unittest.cc", "codecs/vp8/default_temporal_layers_unittest.cc", "codecs/vp8/screenshare_layers_unittest.cc", diff --git a/modules/video_coding/codecs/test/stats.cc b/modules/video_coding/codecs/test/stats.cc index 490d2d5161..7024764a97 100644 --- a/modules/video_coding/codecs/test/stats.cc +++ b/modules/video_coding/codecs/test/stats.cc @@ -74,6 +74,7 @@ void Stats::PrintSummary() const { size_t total_encoded_delta_frame_size_bytes = 0; size_t num_key_frames = 0; size_t num_delta_frames = 0; + int num_encode_failures = 0; for (const FrameStatistic& stat : stats_) { total_encoding_time_us += stat.encode_time_us; @@ -86,9 +87,13 @@ void Stats::PrintSummary() const { total_encoded_delta_frame_size_bytes += stat.encoded_frame_size_bytes; ++num_delta_frames; } + if (stat.encode_return_code != 0) { + ++num_encode_failures; + } } // Encoding stats. + printf("# Encoded frame failures: %d\n", num_encode_failures); printf("Encoding time:\n"); auto frame_it = std::min_element(stats_.begin(), stats_.end(), LessForEncodeTime); diff --git a/modules/video_coding/codecs/test/test_config.cc b/modules/video_coding/codecs/test/test_config.cc new file mode 100644 index 0000000000..042c2b6f3c --- /dev/null +++ b/modules/video_coding/codecs/test/test_config.cc @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2017 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 "modules/video_coding/codecs/test/test_config.h" + +#include + +#include "modules/video_coding/include/video_codec_interface.h" +#include "rtc_base/checks.h" +#include "system_wrappers/include/cpu_info.h" +#include "test/video_codec_settings.h" + +namespace webrtc { +namespace test { + +namespace { +const int kBaseKeyFrameInterval = 3000; +} // namespace + +void TestConfig::SetCodecSettings(VideoCodecType codec_type, + int num_temporal_layers, + bool error_concealment_on, + bool denoising_on, + bool frame_dropper_on, + bool spatial_resize_on, + bool resilience_on, + int width, + int height) { + webrtc::test::CodecSettings(codec_type, &codec_settings); + + // TODO(brandtr): Move the setting of |width| and |height| to the tests, and + // DCHECK that they are set before initializing the codec instead. + codec_settings.width = width; + codec_settings.height = height; + + switch (codec_settings.codecType) { + case kVideoCodecVP8: + codec_settings.VP8()->resilience = + resilience_on ? kResilientStream : kResilienceOff; + codec_settings.VP8()->numberOfTemporalLayers = num_temporal_layers; + codec_settings.VP8()->denoisingOn = denoising_on; + codec_settings.VP8()->errorConcealmentOn = error_concealment_on; + codec_settings.VP8()->automaticResizeOn = spatial_resize_on; + codec_settings.VP8()->frameDroppingOn = frame_dropper_on; + codec_settings.VP8()->keyFrameInterval = kBaseKeyFrameInterval; + break; + case kVideoCodecVP9: + codec_settings.VP9()->resilienceOn = resilience_on; + codec_settings.VP9()->numberOfTemporalLayers = num_temporal_layers; + codec_settings.VP9()->denoisingOn = denoising_on; + codec_settings.VP9()->frameDroppingOn = frame_dropper_on; + codec_settings.VP9()->keyFrameInterval = kBaseKeyFrameInterval; + codec_settings.VP9()->automaticResizeOn = spatial_resize_on; + break; + case kVideoCodecH264: + codec_settings.H264()->frameDroppingOn = frame_dropper_on; + codec_settings.H264()->keyFrameInterval = kBaseKeyFrameInterval; + break; + default: + RTC_NOTREACHED(); + break; + } +} + +int TestConfig::NumberOfCores() const { + return use_single_core ? 1 : CpuInfo::DetectNumberOfCores(); +} + +int TestConfig::NumberOfTemporalLayers() const { + if (codec_settings.codecType == kVideoCodecVP8) { + return codec_settings.VP8().numberOfTemporalLayers; + } else if (codec_settings.codecType == kVideoCodecVP9) { + return codec_settings.VP9().numberOfTemporalLayers; + } else { + return 1; + } +} + +void TestConfig::Print() const { + printf("Video config:\n"); + printf(" Filename : %s\n", filename.c_str()); + printf(" # CPU cores used : %u\n", NumberOfCores()); + PrintCodecSettings(); + printf("\n"); +} + +void TestConfig::PrintCodecSettings() const { + printf(" Codec settings:\n"); + printf(" Codec type : %s\n", + CodecTypeToPayloadString(codec_settings.codecType)); + printf(" Start bitrate : %d kbps\n", codec_settings.startBitrate); + printf(" Max bitrate : %d kbps\n", codec_settings.maxBitrate); + printf(" Min bitrate : %d kbps\n", codec_settings.minBitrate); + printf(" Width : %d\n", codec_settings.width); + printf(" Height : %d\n", codec_settings.height); + printf(" Max frame rate : %d\n", codec_settings.maxFramerate); + printf(" QPmax : %d\n", codec_settings.qpMax); + if (codec_settings.codecType == kVideoCodecVP8) { + printf(" Complexity : %d\n", codec_settings.VP8().complexity); + printf(" Resilience : %d\n", codec_settings.VP8().resilience); + printf(" # temporal layers : %d\n", + codec_settings.VP8().numberOfTemporalLayers); + printf(" Denoising : %d\n", codec_settings.VP8().denoisingOn); + printf(" Error concealment : %d\n", + codec_settings.VP8().errorConcealmentOn); + printf(" Automatic resize : %d\n", + codec_settings.VP8().automaticResizeOn); + printf(" Frame dropping : %d\n", codec_settings.VP8().frameDroppingOn); + printf(" Key frame interval: %d\n", codec_settings.VP8().keyFrameInterval); + } else if (codec_settings.codecType == kVideoCodecVP9) { + printf(" Complexity : %d\n", codec_settings.VP9().complexity); + printf(" Resilience : %d\n", codec_settings.VP9().resilienceOn); + printf(" # temporal layers : %d\n", + codec_settings.VP9().numberOfTemporalLayers); + printf(" Denoising : %d\n", codec_settings.VP9().denoisingOn); + printf(" Frame dropping : %d\n", codec_settings.VP9().frameDroppingOn); + printf(" Key frame interval: %d\n", codec_settings.VP9().keyFrameInterval); + printf(" Adaptive QP mode : %d\n", codec_settings.VP9().adaptiveQpMode); + printf(" Automatic resize : %d\n", + codec_settings.VP9().automaticResizeOn); + printf(" # spatial layers : %d\n", + codec_settings.VP9().numberOfSpatialLayers); + printf(" Flexible mode : %d\n", codec_settings.VP9().flexibleMode); + } else if (codec_settings.codecType == kVideoCodecH264) { + printf(" Frame dropping : %d\n", codec_settings.H264().frameDroppingOn); + printf(" Key frame interval: %d\n", + codec_settings.H264().keyFrameInterval); + printf(" Profile : %d\n", codec_settings.H264().profile); + } +} + +} // namespace test +} // namespace webrtc diff --git a/modules/video_coding/codecs/test/test_config.h b/modules/video_coding/codecs/test/test_config.h new file mode 100644 index 0000000000..06aa08cc7e --- /dev/null +++ b/modules/video_coding/codecs/test/test_config.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2017 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. + */ + +#ifndef MODULES_VIDEO_CODING_CODECS_TEST_TEST_CONFIG_H_ +#define MODULES_VIDEO_CODING_CODECS_TEST_TEST_CONFIG_H_ + +#include + +#include "common_types.h" // NOLINT(build/include) +#include "modules/video_coding/codecs/h264/include/h264_globals.h" +#include "modules/video_coding/codecs/test/packet_manipulator.h" + +namespace webrtc { +namespace test { + +// Defines which frame types shall be excluded from packet loss and when. +enum ExcludeFrameTypes { + // Will exclude the first keyframe in the video sequence from packet loss. + // Following keyframes will be targeted for packet loss. + kExcludeOnlyFirstKeyFrame, + // Exclude all keyframes from packet loss, no matter where in the video + // sequence they occur. + kExcludeAllKeyFrames +}; + +// Test configuration for a test run. +struct TestConfig { + void SetCodecSettings(VideoCodecType codec_type, + int num_temporal_layers, + bool error_concealment_on, + bool denoising_on, + bool frame_dropper_on, + bool spatial_resize_on, + bool resilience_on, + int width, + int height); + + int NumberOfCores() const; + int NumberOfTemporalLayers() const; + void Print() const; + void PrintCodecSettings() const; + + // Plain name of YUV file to process without file extension. + std::string filename; + + // File to process. This must be a video file in the YUV format. + std::string input_filename; + + // File to write to during processing for the test. Will be a video file in + // the YUV format. + std::string output_filename; + + // Number of frames to process. + int num_frames = 0; + + // Configurations related to networking. + NetworkingConfig networking_config; + + // Decides how the packet loss simulations shall exclude certain frames from + // packet loss. + ExcludeFrameTypes exclude_frame_types = kExcludeOnlyFirstKeyFrame; + + // Force the encoder and decoder to use a single core for processing. + // Using a single core is necessary to get a deterministic behavior for the + // encoded frames - using multiple cores will produce different encoded frames + // since multiple cores are competing to consume the byte budget for each + // frame in parallel. + // If set to false, the maximum number of available cores will be used. + bool use_single_core = false; + + // Should cpu usage be measured? + // If set to true, the encoding will run in real-time. + bool measure_cpu = false; + + // If > 0: forces the encoder to create a keyframe every Nth frame. + // Note that the encoder may create a keyframe in other locations in addition + // to this setting. Forcing key frames may also affect encoder planning + // optimizations in a negative way, since it will suddenly be forced to + // produce an expensive key frame. + int keyframe_interval = 0; + + // Codec settings to use. + webrtc::VideoCodec codec_settings; + + // If printing of information to stdout shall be performed during processing. + bool verbose = true; + + // Should hardware accelerated codecs be used? + bool hw_encoder = false; + bool hw_decoder = false; + + // Should the hardware codecs be wrapped in software fallbacks? + bool sw_fallback_encoder = false; + bool sw_fallback_decoder = false; + + // RTP H264 packetization mode. + H264PacketizationMode packetization_mode = + webrtc::H264PacketizationMode::NonInterleaved; +}; + +} // namespace test +} // namespace webrtc + +#endif // MODULES_VIDEO_CODING_CODECS_TEST_TEST_CONFIG_H_ diff --git a/modules/video_coding/codecs/test/test_config_unittest.cc b/modules/video_coding/codecs/test/test_config_unittest.cc new file mode 100644 index 0000000000..0ec784c0e7 --- /dev/null +++ b/modules/video_coding/codecs/test/test_config_unittest.cc @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2017 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 "modules/video_coding/codecs/test/test_config.h" +#include "test/gtest.h" +#include "test/video_codec_settings.h" + +namespace webrtc { +namespace test { + +namespace { +const int kNumTemporalLayers = 2; +} // namespace + +TEST(TestConfig, NumberOfCoresWithUseSingleCore) { + TestConfig config; + config.use_single_core = true; + EXPECT_EQ(1, config.NumberOfCores()); +} + +TEST(TestConfig, NumberOfCoresWithoutUseSingleCore) { + TestConfig config; + config.use_single_core = false; + EXPECT_GE(config.NumberOfCores(), 1); +} + +TEST(TestConfig, NumberOfTemporalLayersIsOne) { + TestConfig config; + webrtc::test::CodecSettings(kVideoCodecH264, &config.codec_settings); + EXPECT_EQ(1, config.NumberOfTemporalLayers()); +} + +TEST(TestConfig, NumberOfTemporalLayers_Vp8) { + TestConfig config; + webrtc::test::CodecSettings(kVideoCodecVP8, &config.codec_settings); + config.codec_settings.VP8()->numberOfTemporalLayers = kNumTemporalLayers; + EXPECT_EQ(kNumTemporalLayers, config.NumberOfTemporalLayers()); +} + +TEST(TestConfig, NumberOfTemporalLayers_Vp9) { + TestConfig config; + webrtc::test::CodecSettings(kVideoCodecVP9, &config.codec_settings); + config.codec_settings.VP9()->numberOfTemporalLayers = kNumTemporalLayers; + EXPECT_EQ(kNumTemporalLayers, config.NumberOfTemporalLayers()); +} + +} // namespace test +} // namespace webrtc diff --git a/modules/video_coding/codecs/test/videoprocessor.cc b/modules/video_coding/codecs/test/videoprocessor.cc index 9553dd72c5..60e7c4a086 100644 --- a/modules/video_coding/codecs/test/videoprocessor.cc +++ b/modules/video_coding/codecs/test/videoprocessor.cc @@ -10,8 +10,6 @@ #include "modules/video_coding/codecs/test/videoprocessor.h" -#include - #include #include #include @@ -23,9 +21,7 @@ #include "modules/video_coding/include/video_codec_initializer.h" #include "modules/video_coding/utility/default_video_bitrate_allocator.h" #include "rtc_base/checks.h" -#include "rtc_base/logging.h" #include "rtc_base/timeutils.h" -#include "system_wrappers/include/cpu_info.h" #include "test/gtest.h" namespace webrtc { @@ -47,51 +43,6 @@ std::unique_ptr CreateBitrateAllocator( std::move(tl_factory))); } -void PrintCodecSettings(const VideoCodec& codec_settings) { - printf(" Codec settings:\n"); - printf(" Codec type : %s\n", - CodecTypeToPayloadString(codec_settings.codecType)); - printf(" Start bitrate : %d kbps\n", codec_settings.startBitrate); - printf(" Max bitrate : %d kbps\n", codec_settings.maxBitrate); - printf(" Min bitrate : %d kbps\n", codec_settings.minBitrate); - printf(" Width : %d\n", codec_settings.width); - printf(" Height : %d\n", codec_settings.height); - printf(" Max frame rate : %d\n", codec_settings.maxFramerate); - printf(" QPmax : %d\n", codec_settings.qpMax); - if (codec_settings.codecType == kVideoCodecVP8) { - printf(" Complexity : %d\n", codec_settings.VP8().complexity); - printf(" Resilience : %d\n", codec_settings.VP8().resilience); - printf(" # temporal layers : %d\n", - codec_settings.VP8().numberOfTemporalLayers); - printf(" Denoising : %d\n", codec_settings.VP8().denoisingOn); - printf(" Error concealment : %d\n", - codec_settings.VP8().errorConcealmentOn); - printf(" Automatic resize : %d\n", - codec_settings.VP8().automaticResizeOn); - printf(" Frame dropping : %d\n", codec_settings.VP8().frameDroppingOn); - printf(" Key frame interval: %d\n", codec_settings.VP8().keyFrameInterval); - } else if (codec_settings.codecType == kVideoCodecVP9) { - printf(" Complexity : %d\n", codec_settings.VP9().complexity); - printf(" Resilience : %d\n", codec_settings.VP9().resilienceOn); - printf(" # temporal layers : %d\n", - codec_settings.VP9().numberOfTemporalLayers); - printf(" Denoising : %d\n", codec_settings.VP9().denoisingOn); - printf(" Frame dropping : %d\n", codec_settings.VP9().frameDroppingOn); - printf(" Key frame interval: %d\n", codec_settings.VP9().keyFrameInterval); - printf(" Adaptive QP mode : %d\n", codec_settings.VP9().adaptiveQpMode); - printf(" Automatic resize : %d\n", - codec_settings.VP9().automaticResizeOn); - printf(" # spatial layers : %d\n", - codec_settings.VP9().numberOfSpatialLayers); - printf(" Flexible mode : %d\n", codec_settings.VP9().flexibleMode); - } else if (codec_settings.codecType == kVideoCodecH264) { - printf(" Frame dropping : %d\n", codec_settings.H264().frameDroppingOn); - printf(" Key frame interval: %d\n", - codec_settings.H264().keyFrameInterval); - printf(" Profile : %d\n", codec_settings.H264().profile); - } -} - void VerifyQpParser(const EncodedImage& encoded_frame, const TestConfig& config) { if (config.hw_encoder) @@ -135,10 +86,6 @@ int GetElapsedTimeMicroseconds(int64_t start_ns, int64_t stop_ns) { } // namespace -int TestConfig::NumberOfCores() const { - return use_single_core ? 1 : CpuInfo::DetectNumberOfCores(); -} - VideoProcessor::VideoProcessor(webrtc::VideoEncoder* encoder, webrtc::VideoDecoder* decoder, FrameReader* analysis_frame_reader, @@ -191,35 +138,16 @@ void VideoProcessor::Init() { << "Failed to register decode complete callback"; // Initialize the encoder and decoder. - int num_cores = config_.NumberOfCores(); RTC_CHECK_EQ( - encoder_->InitEncode(&config_.codec_settings, num_cores, + encoder_->InitEncode(&config_.codec_settings, config_.NumberOfCores(), config_.networking_config.max_payload_size_in_bytes), WEBRTC_VIDEO_CODEC_OK) << "Failed to initialize VideoEncoder"; - RTC_CHECK_EQ(decoder_->InitDecode(&config_.codec_settings, num_cores), - WEBRTC_VIDEO_CODEC_OK) + RTC_CHECK_EQ( + decoder_->InitDecode(&config_.codec_settings, config_.NumberOfCores()), + WEBRTC_VIDEO_CODEC_OK) << "Failed to initialize VideoDecoder"; - - if (config_.verbose) { - printf("Video Processor:\n"); - printf(" Filename : %s\n", config_.filename.c_str()); - printf(" Total # of frames: %d\n", - analysis_frame_reader_->NumberOfFrames()); - printf(" # CPU cores used : %d\n", num_cores); - const char* encoder_name = encoder_->ImplementationName(); - printf(" Encoder implementation name: %s\n", encoder_name); - const char* decoder_name = decoder_->ImplementationName(); - printf(" Decoder implementation name: %s\n", decoder_name); - if (strcmp(encoder_name, decoder_name) == 0) { - printf(" Codec implementation name : %s_%s\n", - CodecTypeToPayloadString(config_.codec_settings.codecType), - encoder_->ImplementationName()); - } - PrintCodecSettings(config_.codec_settings); - printf("\n"); - } } void VideoProcessor::Release() { @@ -269,12 +197,6 @@ void VideoProcessor::ProcessFrame() { frame_stat->encode_start_ns = rtc::TimeNanos(); frame_stat->encode_return_code = encoder_->Encode(source_frame, nullptr, &frame_types); - - if (frame_stat->encode_return_code != WEBRTC_VIDEO_CODEC_OK) { - LOG(LS_WARNING) << "Failed to encode frame " << last_inputed_frame_num_ - << ", return code: " << frame_stat->encode_return_code - << "."; - } } void VideoProcessor::SetRates(int bitrate_kbps, int framerate_fps) { @@ -457,9 +379,8 @@ void VideoProcessor::FrameDecoded(const VideoFrame& image) { RTC_CHECK_GT(frame_number, last_decoded_frame_num_); last_decoded_frame_num_ = frame_number; - // Check if frame size is different from the original size, and if so, - // scale back to original size. This is needed for the PSNR and SSIM - // calculations. + // Check if frame size is different from the original size, and if so, scale + // back to original size. This is needed for the PSNR and SSIM calculations. size_t extracted_length; rtc::Buffer extracted_buffer; if (image.width() != config_.codec_settings.width || diff --git a/modules/video_coding/codecs/test/videoprocessor.h b/modules/video_coding/codecs/test/videoprocessor.h index af7a33a1db..d82ae9a87a 100644 --- a/modules/video_coding/codecs/test/videoprocessor.h +++ b/modules/video_coding/codecs/test/videoprocessor.h @@ -21,6 +21,7 @@ #include "modules/video_coding/codecs/h264/include/h264_globals.h" #include "modules/video_coding/codecs/test/packet_manipulator.h" #include "modules/video_coding/codecs/test/stats.h" +#include "modules/video_coding/codecs/test/test_config.h" #include "modules/video_coding/include/video_codec_interface.h" #include "modules/video_coding/utility/ivf_file_writer.h" #include "modules/video_coding/utility/vp8_header_parser.h" @@ -39,79 +40,6 @@ class VideoBitrateAllocator; namespace test { -// Defines which frame types shall be excluded from packet loss and when. -enum ExcludeFrameTypes { - // Will exclude the first keyframe in the video sequence from packet loss. - // Following keyframes will be targeted for packet loss. - kExcludeOnlyFirstKeyFrame, - // Exclude all keyframes from packet loss, no matter where in the video - // sequence they occur. - kExcludeAllKeyFrames -}; - -// Test configuration for a test run. -struct TestConfig { - // Returns the number of cores to use. - int NumberOfCores() const; - - // Plain name of YUV file to process without file extension. - std::string filename; - - // File to process. This must be a video file in the YUV format. - std::string input_filename; - - // File to write to during processing for the test. Will be a video file - // in the YUV format. - std::string output_filename; - - // Number of frames to process. - int num_frames = 0; - - // Configurations related to networking. - NetworkingConfig networking_config; - - // Decides how the packet loss simulations shall exclude certain frames - // from packet loss. - ExcludeFrameTypes exclude_frame_types = kExcludeOnlyFirstKeyFrame; - - // Force the encoder and decoder to use a single core for processing. - // Using a single core is necessary to get a deterministic behavior for the - // encoded frames - using multiple cores will produce different encoded frames - // since multiple cores are competing to consume the byte budget for each - // frame in parallel. - // If set to false, the maximum number of available cores will be used. - bool use_single_core = false; - - // Should cpu usage be measured? - // If set to true, the encoding will run in real-time. - bool measure_cpu = false; - - // If > 0: forces the encoder to create a keyframe every Nth frame. - // Note that the encoder may create a keyframe in other locations in addition - // to this setting. Forcing key frames may also affect encoder planning - // optimizations in a negative way, since it will suddenly be forced to - // produce an expensive key frame. - int keyframe_interval = 0; - - // Codec settings to use. - webrtc::VideoCodec codec_settings; - - // If printing of information to stdout shall be performed during processing. - bool verbose = true; - - // Should hardware accelerated codecs be used? - bool hw_encoder = false; - bool hw_decoder = false; - - // Should the hardware codecs be wrapped in software fallbacks? - bool sw_fallback_encoder = false; - bool sw_fallback_decoder = false; - - // RTP H264 packetization mode. - H264PacketizationMode packetization_mode = - H264PacketizationMode::NonInterleaved; -}; - // Handles encoding/decoding of video using the VideoEncoder/VideoDecoder // interfaces. This is done in a sequential manner in order to be able to // measure times properly. diff --git a/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc b/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc index f54302ad7a..05c9c60ca2 100644 --- a/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc +++ b/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc @@ -32,12 +32,10 @@ #include "rtc_base/cpu_time.h" #include "rtc_base/event.h" #include "rtc_base/file.h" -#include "rtc_base/logging.h" #include "rtc_base/ptr_util.h" #include "system_wrappers/include/sleep.h" #include "test/testsupport/fileutils.h" #include "test/testsupport/metrics/video_metrics.h" -#include "test/video_codec_settings.h" namespace webrtc { namespace test { @@ -45,7 +43,6 @@ namespace test { namespace { const int kMaxBitrateMismatchPercent = 20; -const int kBaseKeyFrameInterval = 3000; // Parameters from VP8 wrapper, which control target size of key frames. const float kInitialBufferSize = 0.5f; @@ -68,16 +65,6 @@ void PrintQualityMetrics(const QualityMetricsResult& psnr_result, printf("\n"); } -int NumberOfTemporalLayers(const VideoCodec& codec_settings) { - if (codec_settings.codecType == kVideoCodecVP8) { - return codec_settings.VP8().numberOfTemporalLayers; - } else if (codec_settings.codecType == kVideoCodecVP9) { - return codec_settings.VP9().numberOfTemporalLayers; - } else { - return 1; - } -} - bool RunEncodeInRealTime(const TestConfig& config) { if (config.measure_cpu) { return true; @@ -132,54 +119,6 @@ VideoProcessorIntegrationTest::VideoProcessorIntegrationTest() { VideoProcessorIntegrationTest::~VideoProcessorIntegrationTest() = default; -void VideoProcessorIntegrationTest::SetCodecSettings(TestConfig* config, - VideoCodecType codec_type, - int num_temporal_layers, - bool error_concealment_on, - bool denoising_on, - bool frame_dropper_on, - bool spatial_resize_on, - bool resilience_on, - int width, - int height) { - webrtc::test::CodecSettings(codec_type, &config->codec_settings); - - // TODO(brandtr): Move the setting of |width| and |height| to the tests, and - // DCHECK that they are set before initializing the codec instead. - config->codec_settings.width = width; - config->codec_settings.height = height; - - switch (config->codec_settings.codecType) { - case kVideoCodecVP8: - config->codec_settings.VP8()->resilience = - resilience_on ? kResilientStream : kResilienceOff; - config->codec_settings.VP8()->numberOfTemporalLayers = - num_temporal_layers; - config->codec_settings.VP8()->denoisingOn = denoising_on; - config->codec_settings.VP8()->errorConcealmentOn = error_concealment_on; - config->codec_settings.VP8()->automaticResizeOn = spatial_resize_on; - config->codec_settings.VP8()->frameDroppingOn = frame_dropper_on; - config->codec_settings.VP8()->keyFrameInterval = kBaseKeyFrameInterval; - break; - case kVideoCodecVP9: - config->codec_settings.VP9()->resilienceOn = resilience_on; - config->codec_settings.VP9()->numberOfTemporalLayers = - num_temporal_layers; - config->codec_settings.VP9()->denoisingOn = denoising_on; - config->codec_settings.VP9()->frameDroppingOn = frame_dropper_on; - config->codec_settings.VP9()->keyFrameInterval = kBaseKeyFrameInterval; - config->codec_settings.VP9()->automaticResizeOn = spatial_resize_on; - break; - case kVideoCodecH264: - config->codec_settings.H264()->frameDroppingOn = frame_dropper_on; - config->codec_settings.H264()->keyFrameInterval = kBaseKeyFrameInterval; - break; - default: - RTC_NOTREACHED(); - break; - } -} - // Processes all frames in the clip and verifies the result. void VideoProcessorIntegrationTest::ProcessFramesAndMaybeVerify( const std::vector& rate_profiles, @@ -195,6 +134,7 @@ void VideoProcessorIntegrationTest::ProcessFramesAndMaybeVerify( SetUpAndInitObjects(&task_queue, rate_profiles[0].target_kbps, rate_profiles[0].input_fps, visualization_params); + MaybePrintSettings(); // Set initial rates. int rate_update_index = 0; @@ -540,8 +480,7 @@ void VideoProcessorIntegrationTest::VerifyRateControlMetrics( EXPECT_LE(actual_.BitrateMismatchPercent(target_.kbps), rc_threshold.max_bitrate_mismatch_percent); - const int num_temporal_layers = - NumberOfTemporalLayers(config_.codec_settings); + const int num_temporal_layers = config_.NumberOfTemporalLayers(); for (int i = 0; i < num_temporal_layers; ++i) { EXPECT_LE(actual_.DeltaFrameSizeMismatchPercent(i), rc_threshold.max_delta_framesize_mismatch_percent); @@ -568,8 +507,7 @@ void VideoProcessorIntegrationTest::PrintRateControlMetrics( printf(" Key frame rate mismatch: %d\n", actual_.KeyFrameSizeMismatchPercent()); - const int num_temporal_layers = - NumberOfTemporalLayers(config_.codec_settings); + const int num_temporal_layers = config_.NumberOfTemporalLayers(); for (int i = 0; i < num_temporal_layers; ++i) { printf(" Temporal layer #%d:\n", i); printf(" Layer target bitrate : %f\n", target_.kbps_layer[i]); @@ -586,6 +524,24 @@ void VideoProcessorIntegrationTest::PrintRateControlMetrics( printf("\n"); } +void VideoProcessorIntegrationTest::MaybePrintSettings() const { + if (!config_.verbose) + return; + + config_.Print(); + printf(" Total # of frames: %d\n", analysis_frame_reader_->NumberOfFrames()); + const char* encoder_name = encoder_->ImplementationName(); + const char* decoder_name = decoder_->ImplementationName(); + printf(" Encoder implementation name: %s\n", encoder_name); + printf(" Decoder implementation name: %s\n", decoder_name); + if (strcmp(encoder_name, decoder_name) == 0) { + printf(" Codec implementation name : %s_%s\n", + CodecTypeToPayloadString(config_.codec_settings.codecType), + encoder_name); + } + printf("\n"); +} + void VideoProcessorIntegrationTest::VerifyBitstream( int frame_number, const BitstreamThresholds& bs_thresholds) { @@ -598,7 +554,7 @@ void VideoProcessorIntegrationTest::VerifyBitstream( int VideoProcessorIntegrationTest::TemporalLayerIndexForFrame( int frame_number) const { int tl_idx = -1; - switch (NumberOfTemporalLayers(config_.codec_settings)) { + switch (config_.NumberOfTemporalLayers()) { case 1: tl_idx = 0; break; @@ -659,8 +615,7 @@ void VideoProcessorIntegrationTest::ResetRateControlMetrics( } void VideoProcessorIntegrationTest::SetRatesPerTemporalLayer() { - const int num_temporal_layers = - NumberOfTemporalLayers(config_.codec_settings); + const int num_temporal_layers = config_.NumberOfTemporalLayers(); RTC_DCHECK_LE(num_temporal_layers, kMaxNumTemporalLayers); for (int i = 0; i < num_temporal_layers; ++i) { diff --git a/modules/video_coding/codecs/test/videoprocessor_integrationtest.h b/modules/video_coding/codecs/test/videoprocessor_integrationtest.h index 827edc1854..6b0d33d833 100644 --- a/modules/video_coding/codecs/test/videoprocessor_integrationtest.h +++ b/modules/video_coding/codecs/test/videoprocessor_integrationtest.h @@ -20,6 +20,7 @@ #include "media/engine/webrtcvideoencoderfactory.h" #include "modules/video_coding/codecs/test/packet_manipulator.h" #include "modules/video_coding/codecs/test/stats.h" +#include "modules/video_coding/codecs/test/test_config.h" #include "modules/video_coding/codecs/test/videoprocessor.h" #include "modules/video_coding/utility/ivf_file_writer.h" #include "test/gtest.h" @@ -93,17 +94,6 @@ class VideoProcessorIntegrationTest : public testing::Test { VideoProcessorIntegrationTest(); ~VideoProcessorIntegrationTest() override; - static void SetCodecSettings(TestConfig* config, - VideoCodecType codec_type, - int num_temporal_layers, - bool error_concealment_on, - bool denoising_on, - bool frame_dropper_on, - bool spatial_resize_on, - bool resilience_on, - int width, - int height); - void ProcessFramesAndMaybeVerify( const std::vector& rate_profiles, const std::vector* rc_thresholds, @@ -183,6 +173,8 @@ class VideoProcessorIntegrationTest : public testing::Test { void VerifyBitstream(int frame_number, const BitstreamThresholds& bs_thresholds); + void MaybePrintSettings() const; + // Codecs. std::unique_ptr encoder_; std::unique_ptr decoder_; diff --git a/modules/video_coding/codecs/test/videoprocessor_integrationtest_libvpx.cc b/modules/video_coding/codecs/test/videoprocessor_integrationtest_libvpx.cc index 7ba146eebf..f6f9b45a81 100644 --- a/modules/video_coding/codecs/test/videoprocessor_integrationtest_libvpx.cc +++ b/modules/video_coding/codecs/test/videoprocessor_integrationtest_libvpx.cc @@ -57,8 +57,8 @@ class VideoProcessorIntegrationTestLibvpx // VP9: Run with no packet loss and fixed bitrate. Quality should be very high. // One key frame (first frame only) in sequence. TEST_F(VideoProcessorIntegrationTestLibvpx, Process0PercentPacketLossVP9) { - SetCodecSettings(&config_, kVideoCodecVP9, 1, false, false, true, false, - kResilienceOn, kCifWidth, kCifHeight); + config_.SetCodecSettings(kVideoCodecVP9, 1, false, false, true, false, + kResilienceOn, kCifWidth, kCifHeight); config_.num_frames = kNumFramesShort; std::vector rate_profiles = {{500, 30, kNumFramesShort + 1}}; @@ -78,8 +78,8 @@ TEST_F(VideoProcessorIntegrationTestLibvpx, Process0PercentPacketLossVP9) { TEST_F(VideoProcessorIntegrationTestLibvpx, Process5PercentPacketLossVP9) { config_.networking_config.packet_loss_probability = 0.05f; config_.num_frames = kNumFramesShort; - SetCodecSettings(&config_, kVideoCodecVP9, 1, false, false, true, false, - kResilienceOn, kCifWidth, kCifHeight); + config_.SetCodecSettings(kVideoCodecVP9, 1, false, false, true, false, + kResilienceOn, kCifWidth, kCifHeight); std::vector rate_profiles = {{500, 30, kNumFramesShort + 1}}; @@ -98,8 +98,8 @@ TEST_F(VideoProcessorIntegrationTestLibvpx, Process5PercentPacketLossVP9) { // target rate/per-frame bandwidth (for each rate update) is within limits. // One key frame (first frame only) in sequence. TEST_F(VideoProcessorIntegrationTestLibvpx, ProcessNoLossChangeBitRateVP9) { - SetCodecSettings(&config_, kVideoCodecVP9, 1, false, false, true, false, - kResilienceOn, kCifWidth, kCifHeight); + config_.SetCodecSettings(kVideoCodecVP9, 1, false, false, true, false, + kResilienceOn, kCifWidth, kCifHeight); std::vector rate_profiles = { {200, 30, 100}, // target_kbps, input_fps, frame_index_rate_update @@ -126,8 +126,8 @@ TEST_F(VideoProcessorIntegrationTestLibvpx, ProcessNoLossChangeBitRateVP9) { // metrics averaged over whole sequence run. TEST_F(VideoProcessorIntegrationTestLibvpx, ProcessNoLossChangeFrameRateFrameDropVP9) { - SetCodecSettings(&config_, kVideoCodecVP9, 1, false, false, true, false, - kResilienceOn, kCifWidth, kCifHeight); + config_.SetCodecSettings(kVideoCodecVP9, 1, false, false, true, false, + kResilienceOn, kCifWidth, kCifHeight); std::vector rate_profiles = { {100, 24, 100}, // target_kbps, input_fps, frame_index_rate_update @@ -148,8 +148,8 @@ TEST_F(VideoProcessorIntegrationTestLibvpx, // VP9: Run with no packet loss and denoiser on. One key frame (first frame). TEST_F(VideoProcessorIntegrationTestLibvpx, ProcessNoLossDenoiserOnVP9) { - SetCodecSettings(&config_, kVideoCodecVP9, 1, false, true, true, false, - kResilienceOn, kCifWidth, kCifHeight); + config_.SetCodecSettings(kVideoCodecVP9, 1, false, true, true, false, + kResilienceOn, kCifWidth, kCifHeight); config_.num_frames = kNumFramesShort; std::vector rate_profiles = {{500, 30, kNumFramesShort + 1}}; @@ -169,8 +169,8 @@ TEST_F(VideoProcessorIntegrationTestLibvpx, ProcessNoLossDenoiserOnVP9) { // Resize happens on delta frame. Expect only one key frame (first frame). TEST_F(VideoProcessorIntegrationTestLibvpx, DISABLED_ProcessNoLossSpatialResizeFrameDropVP9) { - SetCodecSettings(&config_, kVideoCodecVP9, 1, false, false, true, true, - kResilienceOn, kCifWidth, kCifHeight); + config_.SetCodecSettings(kVideoCodecVP9, 1, false, false, true, true, + kResilienceOn, kCifWidth, kCifHeight); std::vector rate_profiles = {{50, 30, kNumFramesLong + 1}}; @@ -193,8 +193,8 @@ TEST_F(VideoProcessorIntegrationTestLibvpx, // One key frame (first frame only) in sequence. Setting |key_frame_interval| // to -1 below means no periodic key frames in test. TEST_F(VideoProcessorIntegrationTestLibvpx, ProcessZeroPacketLoss) { - SetCodecSettings(&config_, kVideoCodecVP8, 1, false, true, true, false, - kResilienceOn, kCifWidth, kCifHeight); + config_.SetCodecSettings(kVideoCodecVP8, 1, false, true, true, false, + kResilienceOn, kCifWidth, kCifHeight); config_.num_frames = kNumFramesShort; std::vector rate_profiles = {{500, 30, kNumFramesShort + 1}}; @@ -213,8 +213,8 @@ TEST_F(VideoProcessorIntegrationTestLibvpx, ProcessZeroPacketLoss) { // lower. One key frame (first frame only) in sequence. TEST_F(VideoProcessorIntegrationTestLibvpx, Process5PercentPacketLoss) { config_.networking_config.packet_loss_probability = 0.05f; - SetCodecSettings(&config_, kVideoCodecVP8, 1, false, true, true, false, - kResilienceOn, kCifWidth, kCifHeight); + config_.SetCodecSettings(kVideoCodecVP8, 1, false, true, true, false, + kResilienceOn, kCifWidth, kCifHeight); config_.num_frames = kNumFramesShort; std::vector rate_profiles = {{500, 30, kNumFramesShort + 1}}; @@ -233,8 +233,8 @@ TEST_F(VideoProcessorIntegrationTestLibvpx, Process5PercentPacketLoss) { // One key frame (first frame only) in sequence. TEST_F(VideoProcessorIntegrationTestLibvpx, Process10PercentPacketLoss) { config_.networking_config.packet_loss_probability = 0.1f; - SetCodecSettings(&config_, kVideoCodecVP8, 1, false, true, true, false, - kResilienceOn, kCifWidth, kCifHeight); + config_.SetCodecSettings(kVideoCodecVP8, 1, false, true, true, false, + kResilienceOn, kCifWidth, kCifHeight); config_.num_frames = kNumFramesShort; std::vector rate_profiles = {{500, 30, kNumFramesShort + 1}}; @@ -273,8 +273,8 @@ TEST_F(VideoProcessorIntegrationTestLibvpx, Process10PercentPacketLoss) { #endif TEST_F(VideoProcessorIntegrationTestLibvpx, MAYBE_ProcessNoLossChangeBitRateVP8) { - SetCodecSettings(&config_, kVideoCodecVP8, 1, false, true, true, false, - kResilienceOn, kCifWidth, kCifHeight); + config_.SetCodecSettings(kVideoCodecVP8, 1, false, true, true, false, + kResilienceOn, kCifWidth, kCifHeight); std::vector rate_profiles = { {200, 30, 100}, // target_kbps, input_fps, frame_index_rate_update @@ -309,8 +309,8 @@ TEST_F(VideoProcessorIntegrationTestLibvpx, #endif TEST_F(VideoProcessorIntegrationTestLibvpx, MAYBE_ProcessNoLossChangeFrameRateFrameDropVP8) { - SetCodecSettings(&config_, kVideoCodecVP8, 1, false, true, true, false, - kResilienceOn, kCifWidth, kCifHeight); + config_.SetCodecSettings(kVideoCodecVP8, 1, false, true, true, false, + kResilienceOn, kCifWidth, kCifHeight); std::vector rate_profiles = { {80, 24, 100}, // target_kbps, input_fps, frame_index_rate_update @@ -343,8 +343,8 @@ TEST_F(VideoProcessorIntegrationTestLibvpx, #endif TEST_F(VideoProcessorIntegrationTestLibvpx, MAYBE_ProcessNoLossTemporalLayersVP8) { - SetCodecSettings(&config_, kVideoCodecVP8, 3, false, true, true, false, - kResilienceOn, kCifWidth, kCifHeight); + config_.SetCodecSettings(kVideoCodecVP8, 3, false, true, true, false, + kResilienceOn, kCifWidth, kCifHeight); std::vector rate_profiles = {{200, 30, 150}, {400, 30, kNumFramesLong + 1}}; diff --git a/modules/video_coding/codecs/test/videoprocessor_integrationtest_mediacodec.cc b/modules/video_coding/codecs/test/videoprocessor_integrationtest_mediacodec.cc index 9f033085c5..8ad02b34e7 100644 --- a/modules/video_coding/codecs/test/videoprocessor_integrationtest_mediacodec.cc +++ b/modules/video_coding/codecs/test/videoprocessor_integrationtest_mediacodec.cc @@ -41,8 +41,8 @@ class VideoProcessorIntegrationTestMediaCodec }; TEST_F(VideoProcessorIntegrationTestMediaCodec, ForemanCif500kbpsVp8) { - SetCodecSettings(&config_, kVideoCodecVP8, 1, false, false, false, false, - false, 352, 288); + config_.SetCodecSettings(kVideoCodecVP8, 1, false, false, false, false, false, + 352, 288); std::vector rate_profiles = {{500, 30, kForemanNumFrames + 1}}; @@ -67,8 +67,8 @@ TEST_F(VideoProcessorIntegrationTestMediaCodec, config_.filename = "foreman_320x240"; config_.input_filename = ResourcePath(config_.filename, "yuv"); config_.sw_fallback_encoder = true; - SetCodecSettings(&config_, kVideoCodecVP8, 1, false, false, false, false, - false, 320, 240); + config_.SetCodecSettings(kVideoCodecVP8, 1, false, false, false, false, false, + 320, 240); std::vector rate_profiles = { {100, 10, 80}, // Start below |low_kbps|. diff --git a/modules/video_coding/codecs/test/videoprocessor_integrationtest_openh264.cc b/modules/video_coding/codecs/test/videoprocessor_integrationtest_openh264.cc index d4c42ffc18..400d4b2992 100644 --- a/modules/video_coding/codecs/test/videoprocessor_integrationtest_openh264.cc +++ b/modules/video_coding/codecs/test/videoprocessor_integrationtest_openh264.cc @@ -55,8 +55,8 @@ class VideoProcessorIntegrationTestOpenH264 // with H264. Therefore ProcessXPercentPacketLossH264, X != 0, unittests have // not been added. TEST_F(VideoProcessorIntegrationTestOpenH264, Process0PercentPacketLoss) { - SetCodecSettings(&config_, kVideoCodecH264, 1, false, false, true, false, - kResilienceOn, kCifWidth, kCifHeight); + config_.SetCodecSettings(kVideoCodecH264, 1, false, false, true, false, + kResilienceOn, kCifWidth, kCifHeight); std::vector rate_profiles = {{500, 30, kNumFrames + 1}}; @@ -75,8 +75,8 @@ TEST_F(VideoProcessorIntegrationTestOpenH264, Process0PercentPacketLoss) { TEST_F(VideoProcessorIntegrationTestOpenH264, ProcessNoLossSingleNalUnit) { config_.packetization_mode = H264PacketizationMode::SingleNalUnit; config_.networking_config.max_payload_size_in_bytes = 500; - SetCodecSettings(&config_, kVideoCodecH264, 1, false, false, true, false, - kResilienceOn, kCifWidth, kCifHeight); + config_.SetCodecSettings(kVideoCodecH264, 1, false, false, true, false, + kResilienceOn, kCifWidth, kCifHeight); std::vector rate_profiles = {{500, 30, kNumFrames + 1}}; diff --git a/modules/video_coding/codecs/test/videoprocessor_integrationtest_parameterized.cc b/modules/video_coding/codecs/test/videoprocessor_integrationtest_parameterized.cc index 613ef602ee..a4c3cbc7e7 100644 --- a/modules/video_coding/codecs/test/videoprocessor_integrationtest_parameterized.cc +++ b/modules/video_coding/codecs/test/videoprocessor_integrationtest_parameterized.cc @@ -68,9 +68,9 @@ class VideoProcessorIntegrationTestParameterized config_.hw_encoder = hw_codec_; config_.hw_decoder = hw_codec_; config_.num_frames = kNumFrames; - SetCodecSettings(&config_, codec_type_, kNumTemporalLayers, - kErrorConcealmentOn, kDenoisingOn, kFrameDropperOn, - kSpatialResizeOn, kResilienceOn, width, height); + config_.SetCodecSettings(codec_type_, kNumTemporalLayers, + kErrorConcealmentOn, kDenoisingOn, kFrameDropperOn, + kSpatialResizeOn, kResilienceOn, width, height); std::vector rate_profiles = { {bitrate_, framerate, kNumFrames + 1}};