diff --git a/webrtc/modules/video_coding/codecs/test/plot_videoprocessor_integrationtest.cc b/webrtc/modules/video_coding/codecs/test/plot_videoprocessor_integrationtest.cc index d0829853ac..cb1578bce0 100644 --- a/webrtc/modules/video_coding/codecs/test/plot_videoprocessor_integrationtest.cc +++ b/webrtc/modules/video_coding/codecs/test/plot_videoprocessor_integrationtest.cc @@ -67,9 +67,8 @@ class PlotVideoProcessorIntegrationTest rate_profile.num_frames = kNumFramesLong; // Codec/network settings. - ProcessParams process_settings(kHwCodec, kUseSingleCore, kPacketLoss, - kKeyFrameInterval, filename, kVerboseLogging, - kBatchMode); + SetProcessParams(&config_, kHwCodec, kUseSingleCore, kPacketLoss, + kKeyFrameInterval, filename, kVerboseLogging, kBatchMode); SetCodecSettings(&config_, &codec_settings_, codec_type_, kNumTemporalLayers, kErrorConcealmentOn, kDenoisingOn, kFrameDropperOn, kSpatialResizeOn, kResilienceOn, width, @@ -94,8 +93,8 @@ class PlotVideoProcessorIntegrationTest 1); // num_key_frames // clang-format on - ProcessFramesAndVerify(quality_thresholds, rate_profile, process_settings, - rc_thresholds, &kVisualizationParams); + ProcessFramesAndVerify(quality_thresholds, rate_profile, rc_thresholds, + &kVisualizationParams); } const int bitrate_; diff --git a/webrtc/modules/video_coding/codecs/test/videoprocessor.cc b/webrtc/modules/video_coding/codecs/test/videoprocessor.cc index ef971a85d8..8d60307e8c 100644 --- a/webrtc/modules/video_coding/codecs/test/videoprocessor.cc +++ b/webrtc/modules/video_coding/codecs/test/videoprocessor.cc @@ -164,6 +164,7 @@ void VideoProcessorImpl::Init() { << "Failed to initialize VideoDecoder"; if (config_.verbose) { + printf("Filename: %s\n", config_.filename.c_str()); printf("Video Processor:\n"); printf(" #CPU cores used : %d\n", num_cores); printf(" Total # of frames: %d\n", diff --git a/webrtc/modules/video_coding/codecs/test/videoprocessor.h b/webrtc/modules/video_coding/codecs/test/videoprocessor.h index 973eca3499..d0b21de585 100644 --- a/webrtc/modules/video_coding/codecs/test/videoprocessor.h +++ b/webrtc/modules/video_coding/codecs/test/videoprocessor.h @@ -60,6 +60,9 @@ struct TestConfig { // different configurations shall be managed. int test_number = 0; + // 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; @@ -78,9 +81,8 @@ struct TestConfig { // from packet loss. ExcludeFrameTypes exclude_frame_types = kExcludeOnlyFirstKeyFrame; - // The length of a single frame of the input video file. This value is - // calculated out of the width and height according to the video format - // specification. Must be set before processing. + // The length of a single frame of the input video file. Calculated out of the + // width and height according to the video format specification (i.e. YUV). size_t frame_length_in_bytes = 0; // Force the encoder and decoder to use a single core for processing. @@ -91,12 +93,11 @@ struct TestConfig { // If set to false, the maximum number of available cores will be used. bool use_single_core = false; - // If set to a value >0 this setting forces the encoder to create a keyframe - // every Nth frame. Note that the encoder may create a keyframe in other - // locations in addition to the interval that is set using this parameter. - // 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. + // 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; // The codec settings to use for the test (target bitrate, video size, @@ -106,6 +107,15 @@ struct TestConfig { // If printing of information to stdout shall be performed during processing. bool verbose = true; + + // If HW or SW codec should be used. + bool hw_codec = false; + + // In batch mode, the VideoProcessor is fed all the frames for processing + // before any metrics are calculated. This is useful for pipelining HW codecs, + // for which some calculated metrics otherwise would be incorrect. The + // downside with batch mode is that mid-test rate allocation is not supported. + bool batch_mode = false; }; // Handles encoding/decoding of video using the VideoEncoder/VideoDecoder diff --git a/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc b/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc index ee6c2f20e7..0fa595b7ca 100644 --- a/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc +++ b/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc @@ -47,18 +47,17 @@ TEST_F(VideoProcessorIntegrationTest, Process0PercentPacketLossH264) { rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1; rate_profile.num_frames = kNumFramesShort; // Codec/network settings. - ProcessParams process_settings(kHwCodec, kUseSingleCore, 0.0f, -1, - kForemanCif, kVerboseLogging, kBatchMode); + SetProcessParams(&config_, kHwCodec, kUseSingleCore, 0.0f, -1, kForemanCif, + kVerboseLogging, kBatchMode); SetCodecSettings(&config_, &codec_settings_, kVideoCodecH264, 1, false, false, true, false, kResilienceOn, kCifWidth, kCifHeight); // Thresholds for expected quality. - QualityThresholds quality_thresholds; - SetQualityThresholds(&quality_thresholds, 35.0, 25.0, 0.93, 0.70); + QualityThresholds quality_thresholds(35.0, 25.0, 0.93, 0.70); // Thresholds for rate control. RateControlThresholds rc_thresholds[1]; SetRateControlThresholds(rc_thresholds, 0, 2, 60, 20, 10, 20, 0, 1); - ProcessFramesAndVerify(quality_thresholds, rate_profile, process_settings, - rc_thresholds, nullptr /* visualization_params */); + ProcessFramesAndVerify(quality_thresholds, rate_profile, rc_thresholds, + nullptr /* visualization_params */); } #endif // defined(WEBRTC_VIDEOPROCESSOR_H264_TESTS) @@ -77,18 +76,17 @@ TEST_F(VideoProcessorIntegrationTest, Process0PercentPacketLossVP9) { rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1; rate_profile.num_frames = kNumFramesShort; // Codec/network settings. - ProcessParams process_settings(kHwCodec, kUseSingleCore, 0.0f, -1, - kForemanCif, kVerboseLogging, kBatchMode); + SetProcessParams(&config_, kHwCodec, kUseSingleCore, 0.0f, -1, kForemanCif, + kVerboseLogging, kBatchMode); SetCodecSettings(&config_, &codec_settings_, kVideoCodecVP9, 1, false, false, true, false, kResilienceOn, kCifWidth, kCifHeight); // Thresholds for expected quality. - QualityThresholds quality_thresholds; - SetQualityThresholds(&quality_thresholds, 37.0, 36.0, 0.93, 0.92); + QualityThresholds quality_thresholds(37.0, 36.0, 0.93, 0.92); // Thresholds for rate control. RateControlThresholds rc_thresholds[1]; SetRateControlThresholds(rc_thresholds, 0, 0, 40, 20, 10, 20, 0, 1); - ProcessFramesAndVerify(quality_thresholds, rate_profile, process_settings, - rc_thresholds, nullptr /* visualization_params */); + ProcessFramesAndVerify(quality_thresholds, rate_profile, rc_thresholds, + nullptr /* visualization_params */); } // VP9: Run with 5% packet loss and fixed bitrate. Quality should be a bit @@ -100,18 +98,17 @@ TEST_F(VideoProcessorIntegrationTest, Process5PercentPacketLossVP9) { rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1; rate_profile.num_frames = kNumFramesShort; // Codec/network settings. - ProcessParams process_settings(kHwCodec, kUseSingleCore, 0.05f, -1, - kForemanCif, kVerboseLogging, kBatchMode); + SetProcessParams(&config_, kHwCodec, kUseSingleCore, 0.05f, -1, kForemanCif, + kVerboseLogging, kBatchMode); SetCodecSettings(&config_, &codec_settings_, kVideoCodecVP9, 1, false, false, true, false, kResilienceOn, kCifWidth, kCifHeight); // Thresholds for expected quality. - QualityThresholds quality_thresholds; - SetQualityThresholds(&quality_thresholds, 17.0, 14.0, 0.45, 0.36); + QualityThresholds quality_thresholds(17.0, 14.0, 0.45, 0.36); // Thresholds for rate control. RateControlThresholds rc_thresholds[1]; SetRateControlThresholds(rc_thresholds, 0, 0, 40, 20, 10, 20, 0, 1); - ProcessFramesAndVerify(quality_thresholds, rate_profile, process_settings, - rc_thresholds, nullptr /* visualization_params */); + ProcessFramesAndVerify(quality_thresholds, rate_profile, rc_thresholds, + nullptr /* visualization_params */); } // VP9: Run with no packet loss, with varying bitrate (3 rate updates): @@ -127,20 +124,19 @@ TEST_F(VideoProcessorIntegrationTest, ProcessNoLossChangeBitRateVP9) { rate_profile.frame_index_rate_update[3] = kNumFramesLong + 1; rate_profile.num_frames = kNumFramesLong; // Codec/network settings. - ProcessParams process_settings(kHwCodec, kUseSingleCore, 0.0f, -1, - kForemanCif, kVerboseLogging, kBatchMode); + SetProcessParams(&config_, kHwCodec, kUseSingleCore, 0.0f, -1, kForemanCif, + kVerboseLogging, kBatchMode); SetCodecSettings(&config_, &codec_settings_, kVideoCodecVP9, 1, false, false, true, false, kResilienceOn, kCifWidth, kCifHeight); // Thresholds for expected quality. - QualityThresholds quality_thresholds; - SetQualityThresholds(&quality_thresholds, 35.5, 30.0, 0.90, 0.85); + QualityThresholds quality_thresholds(35.5, 30.0, 0.90, 0.85); // Thresholds for rate control. RateControlThresholds rc_thresholds[3]; SetRateControlThresholds(rc_thresholds, 0, 0, 30, 20, 20, 35, 0, 1); SetRateControlThresholds(rc_thresholds, 1, 2, 0, 20, 20, 60, 0, 0); SetRateControlThresholds(rc_thresholds, 2, 0, 0, 25, 20, 40, 0, 0); - ProcessFramesAndVerify(quality_thresholds, rate_profile, process_settings, - rc_thresholds, nullptr /* visualization_params */); + ProcessFramesAndVerify(quality_thresholds, rate_profile, rc_thresholds, + nullptr /* visualization_params */); } // VP9: Run with no packet loss, with an update (decrease) in frame rate. @@ -161,20 +157,19 @@ TEST_F(VideoProcessorIntegrationTest, rate_profile.frame_index_rate_update[3] = kNumFramesLong + 1; rate_profile.num_frames = kNumFramesLong; // Codec/network settings. - ProcessParams process_settings(kHwCodec, kUseSingleCore, 0.0f, -1, - kForemanCif, kVerboseLogging, kBatchMode); + SetProcessParams(&config_, kHwCodec, kUseSingleCore, 0.0f, -1, kForemanCif, + kVerboseLogging, kBatchMode); SetCodecSettings(&config_, &codec_settings_, kVideoCodecVP9, 1, false, false, true, false, kResilienceOn, kCifWidth, kCifHeight); // Thresholds for expected quality. - QualityThresholds quality_thresholds; - SetQualityThresholds(&quality_thresholds, 31.5, 18.0, 0.80, 0.43); + QualityThresholds quality_thresholds(31.5, 18.0, 0.80, 0.43); // Thresholds for rate control. RateControlThresholds rc_thresholds[3]; SetRateControlThresholds(rc_thresholds, 0, 45, 50, 95, 15, 45, 0, 1); SetRateControlThresholds(rc_thresholds, 1, 20, 0, 50, 10, 30, 0, 0); SetRateControlThresholds(rc_thresholds, 2, 5, 0, 30, 5, 25, 0, 0); - ProcessFramesAndVerify(quality_thresholds, rate_profile, process_settings, - rc_thresholds, nullptr /* visualization_params */); + ProcessFramesAndVerify(quality_thresholds, rate_profile, rc_thresholds, + nullptr /* visualization_params */); } // VP9: Run with no packet loss and denoiser on. One key frame (first frame). @@ -185,18 +180,17 @@ TEST_F(VideoProcessorIntegrationTest, ProcessNoLossDenoiserOnVP9) { rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1; rate_profile.num_frames = kNumFramesShort; // Codec/network settings. - ProcessParams process_settings(kHwCodec, kUseSingleCore, 0.0f, -1, - kForemanCif, kVerboseLogging, kBatchMode); + SetProcessParams(&config_, kHwCodec, kUseSingleCore, 0.0f, -1, kForemanCif, + kVerboseLogging, kBatchMode); SetCodecSettings(&config_, &codec_settings_, kVideoCodecVP9, 1, false, true, true, false, kResilienceOn, kCifWidth, kCifHeight); // Thresholds for expected quality. - QualityThresholds quality_thresholds; - SetQualityThresholds(&quality_thresholds, 36.8, 35.8, 0.92, 0.91); + QualityThresholds quality_thresholds(36.8, 35.8, 0.92, 0.91); // Thresholds for rate control. RateControlThresholds rc_thresholds[1]; SetRateControlThresholds(rc_thresholds, 0, 0, 40, 20, 10, 20, 0, 1); - ProcessFramesAndVerify(quality_thresholds, rate_profile, process_settings, - rc_thresholds, nullptr /* visualization_params */); + ProcessFramesAndVerify(quality_thresholds, rate_profile, rc_thresholds, + nullptr /* visualization_params */); } // Run with no packet loss, at low bitrate. @@ -211,18 +205,17 @@ TEST_F(VideoProcessorIntegrationTest, rate_profile.frame_index_rate_update[1] = kNumFramesLong + 1; rate_profile.num_frames = kNumFramesLong; // Codec/network settings. - ProcessParams process_settings(kHwCodec, kUseSingleCore, 0.0f, -1, - kForemanCif, kVerboseLogging, kBatchMode); + SetProcessParams(&config_, kHwCodec, kUseSingleCore, 0.0f, -1, kForemanCif, + kVerboseLogging, kBatchMode); SetCodecSettings(&config_, &codec_settings_, kVideoCodecVP9, 1, false, false, true, true, kResilienceOn, kCifWidth, kCifHeight); // Thresholds for expected quality. - QualityThresholds quality_thresholds; - SetQualityThresholds(&quality_thresholds, 24.0, 13.0, 0.65, 0.37); + QualityThresholds quality_thresholds(24.0, 13.0, 0.65, 0.37); // Thresholds for rate control. RateControlThresholds rc_thresholds[1]; SetRateControlThresholds(rc_thresholds, 0, 228, 70, 160, 15, 80, 1, 1); - ProcessFramesAndVerify(quality_thresholds, rate_profile, process_settings, - rc_thresholds, nullptr /* visualization_params */); + ProcessFramesAndVerify(quality_thresholds, rate_profile, rc_thresholds, + nullptr /* visualization_params */); } // TODO(marpan): Add temporal layer test for VP9, once changes are in @@ -240,18 +233,17 @@ TEST_F(VideoProcessorIntegrationTest, ProcessZeroPacketLoss) { rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1; rate_profile.num_frames = kNumFramesShort; // Codec/network settings. - ProcessParams process_settings(kHwCodec, kUseSingleCore, 0.0f, -1, - kForemanCif, kVerboseLogging, kBatchMode); + SetProcessParams(&config_, kHwCodec, kUseSingleCore, 0.0f, -1, kForemanCif, + kVerboseLogging, kBatchMode); SetCodecSettings(&config_, &codec_settings_, kVideoCodecVP8, 1, false, true, true, false, kResilienceOn, kCifWidth, kCifHeight); // Thresholds for expected quality. - QualityThresholds quality_thresholds; - SetQualityThresholds(&quality_thresholds, 34.95, 33.0, 0.90, 0.89); + QualityThresholds quality_thresholds(34.95, 33.0, 0.90, 0.89); // Thresholds for rate control. RateControlThresholds rc_thresholds[1]; SetRateControlThresholds(rc_thresholds, 0, 0, 40, 20, 10, 15, 0, 1); - ProcessFramesAndVerify(quality_thresholds, rate_profile, process_settings, - rc_thresholds, nullptr /* visualization_params */); + ProcessFramesAndVerify(quality_thresholds, rate_profile, rc_thresholds, + nullptr /* visualization_params */); } // VP8: Run with 5% packet loss and fixed bitrate. Quality should be a bit @@ -263,18 +255,17 @@ TEST_F(VideoProcessorIntegrationTest, Process5PercentPacketLoss) { rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1; rate_profile.num_frames = kNumFramesShort; // Codec/network settings. - ProcessParams process_settings(kHwCodec, kUseSingleCore, 0.05f, -1, - kForemanCif, kVerboseLogging, kBatchMode); + SetProcessParams(&config_, kHwCodec, kUseSingleCore, 0.05f, -1, kForemanCif, + kVerboseLogging, kBatchMode); SetCodecSettings(&config_, &codec_settings_, kVideoCodecVP8, 1, false, true, true, false, kResilienceOn, kCifWidth, kCifHeight); // Thresholds for expected quality. - QualityThresholds quality_thresholds; - SetQualityThresholds(&quality_thresholds, 20.0, 16.0, 0.60, 0.40); + QualityThresholds quality_thresholds(20.0, 16.0, 0.60, 0.40); // Thresholds for rate control. RateControlThresholds rc_thresholds[1]; SetRateControlThresholds(rc_thresholds, 0, 0, 40, 20, 10, 15, 0, 1); - ProcessFramesAndVerify(quality_thresholds, rate_profile, process_settings, - rc_thresholds, nullptr /* visualization_params */); + ProcessFramesAndVerify(quality_thresholds, rate_profile, rc_thresholds, + nullptr /* visualization_params */); } // VP8: Run with 10% packet loss and fixed bitrate. Quality should be lower. @@ -286,18 +277,17 @@ TEST_F(VideoProcessorIntegrationTest, Process10PercentPacketLoss) { rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1; rate_profile.num_frames = kNumFramesShort; // Codec/network settings. - ProcessParams process_settings(kHwCodec, kUseSingleCore, 0.1f, -1, - kForemanCif, kVerboseLogging, kBatchMode); + SetProcessParams(&config_, kHwCodec, kUseSingleCore, 0.1f, -1, kForemanCif, + kVerboseLogging, kBatchMode); SetCodecSettings(&config_, &codec_settings_, kVideoCodecVP8, 1, false, true, true, false, kResilienceOn, kCifWidth, kCifHeight); // Thresholds for expected quality. - QualityThresholds quality_thresholds; - SetQualityThresholds(&quality_thresholds, 19.0, 16.0, 0.50, 0.35); + QualityThresholds quality_thresholds(19.0, 16.0, 0.50, 0.35); // Thresholds for rate control. RateControlThresholds rc_thresholds[1]; SetRateControlThresholds(rc_thresholds, 0, 0, 40, 20, 10, 15, 0, 1); - ProcessFramesAndVerify(quality_thresholds, rate_profile, process_settings, - rc_thresholds, nullptr /* visualization_params */); + ProcessFramesAndVerify(quality_thresholds, rate_profile, rc_thresholds, + nullptr /* visualization_params */); } // This test is identical to VideoProcessorIntegrationTest.ProcessZeroPacketLoss @@ -311,19 +301,17 @@ TEST_F(VideoProcessorIntegrationTest, ProcessInBatchMode) { rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1; rate_profile.num_frames = kNumFramesShort; // Codec/network settings. - ProcessParams process_settings(kHwCodec, kUseSingleCore, 0.0f, -1, - kForemanCif, kVerboseLogging, - true /* batch_mode */); + SetProcessParams(&config_, kHwCodec, kUseSingleCore, 0.0f, -1, kForemanCif, + kVerboseLogging, true /* batch_mode */); SetCodecSettings(&config_, &codec_settings_, kVideoCodecVP8, 1, false, true, true, false, kResilienceOn, kCifWidth, kCifHeight); // Thresholds for expected quality. - QualityThresholds quality_thresholds; - SetQualityThresholds(&quality_thresholds, 34.95, 33.0, 0.90, 0.89); + QualityThresholds quality_thresholds(34.95, 33.0, 0.90, 0.89); // Thresholds for rate control. RateControlThresholds rc_thresholds[1]; SetRateControlThresholds(rc_thresholds, 0, 0, 40, 20, 10, 15, 0, 1); - ProcessFramesAndVerify(quality_thresholds, rate_profile, process_settings, - rc_thresholds, nullptr /* visualization_params */); + ProcessFramesAndVerify(quality_thresholds, rate_profile, rc_thresholds, + nullptr /* visualization_params */); } #endif // !defined(WEBRTC_IOS) @@ -357,20 +345,19 @@ TEST_F(VideoProcessorIntegrationTest, MAYBE_ProcessNoLossChangeBitRateVP8) { rate_profile.frame_index_rate_update[3] = kNumFramesLong + 1; rate_profile.num_frames = kNumFramesLong; // Codec/network settings. - ProcessParams process_settings(kHwCodec, kUseSingleCore, 0.0f, -1, - kForemanCif, kVerboseLogging, kBatchMode); + SetProcessParams(&config_, kHwCodec, kUseSingleCore, 0.0f, -1, kForemanCif, + kVerboseLogging, kBatchMode); SetCodecSettings(&config_, &codec_settings_, kVideoCodecVP8, 1, false, true, true, false, kResilienceOn, kCifWidth, kCifHeight); // Thresholds for expected quality. - QualityThresholds quality_thresholds; - SetQualityThresholds(&quality_thresholds, 34.0, 32.0, 0.85, 0.80); + QualityThresholds quality_thresholds(34.0, 32.0, 0.85, 0.80); // Thresholds for rate control. RateControlThresholds rc_thresholds[3]; SetRateControlThresholds(rc_thresholds, 0, 0, 45, 20, 10, 15, 0, 1); SetRateControlThresholds(rc_thresholds, 1, 0, 0, 25, 20, 10, 0, 0); SetRateControlThresholds(rc_thresholds, 2, 0, 0, 25, 15, 10, 0, 0); - ProcessFramesAndVerify(quality_thresholds, rate_profile, process_settings, - rc_thresholds, nullptr /* visualization_params */); + ProcessFramesAndVerify(quality_thresholds, rate_profile, rc_thresholds, + nullptr /* visualization_params */); } // VP8: Run with no packet loss, with an update (decrease) in frame rate. @@ -399,20 +386,19 @@ TEST_F(VideoProcessorIntegrationTest, rate_profile.frame_index_rate_update[3] = kNumFramesLong + 1; rate_profile.num_frames = kNumFramesLong; // Codec/network settings. - ProcessParams process_settings(kHwCodec, kUseSingleCore, 0.0f, -1, - kForemanCif, kVerboseLogging, kBatchMode); + SetProcessParams(&config_, kHwCodec, kUseSingleCore, 0.0f, -1, kForemanCif, + kVerboseLogging, kBatchMode); SetCodecSettings(&config_, &codec_settings_, kVideoCodecVP8, 1, false, true, true, false, kResilienceOn, kCifWidth, kCifHeight); // Thresholds for expected quality. - QualityThresholds quality_thresholds; - SetQualityThresholds(&quality_thresholds, 31.0, 22.0, 0.80, 0.65); + QualityThresholds quality_thresholds(31.0, 22.0, 0.80, 0.65); // Thresholds for rate control. RateControlThresholds rc_thresholds[3]; SetRateControlThresholds(rc_thresholds, 0, 40, 20, 75, 15, 60, 0, 1); SetRateControlThresholds(rc_thresholds, 1, 10, 0, 25, 10, 35, 0, 0); SetRateControlThresholds(rc_thresholds, 2, 0, 0, 20, 10, 15, 0, 0); - ProcessFramesAndVerify(quality_thresholds, rate_profile, process_settings, - rc_thresholds, nullptr /* visualization_params */); + ProcessFramesAndVerify(quality_thresholds, rate_profile, rc_thresholds, + nullptr /* visualization_params */); } // VP8: Run with no packet loss, with 3 temporal layers, with a rate update in @@ -436,19 +422,18 @@ TEST_F(VideoProcessorIntegrationTest, MAYBE_ProcessNoLossTemporalLayersVP8) { rate_profile.frame_index_rate_update[2] = kNumFramesLong + 1; rate_profile.num_frames = kNumFramesLong; // Codec/network settings. - ProcessParams process_settings(kHwCodec, kUseSingleCore, 0.0f, -1, - kForemanCif, kVerboseLogging, kBatchMode); + SetProcessParams(&config_, kHwCodec, kUseSingleCore, 0.0f, -1, kForemanCif, + kVerboseLogging, kBatchMode); SetCodecSettings(&config_, &codec_settings_, kVideoCodecVP8, 3, false, true, true, false, kResilienceOn, kCifWidth, kCifHeight); // Thresholds for expected quality. - QualityThresholds quality_thresholds; - SetQualityThresholds(&quality_thresholds, 32.5, 30.0, 0.85, 0.80); + QualityThresholds quality_thresholds(32.5, 30.0, 0.85, 0.80); // Thresholds for rate control. RateControlThresholds rc_thresholds[2]; SetRateControlThresholds(rc_thresholds, 0, 0, 20, 30, 10, 10, 0, 1); SetRateControlThresholds(rc_thresholds, 1, 0, 0, 30, 15, 10, 0, 0); - ProcessFramesAndVerify(quality_thresholds, rate_profile, process_settings, - rc_thresholds, nullptr /* visualization_params */); + ProcessFramesAndVerify(quality_thresholds, rate_profile, rc_thresholds, + nullptr /* visualization_params */); } } // namespace test } // namespace webrtc diff --git a/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.h b/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.h index c07c213417..3d9d8af972 100644 --- a/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.h +++ b/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.h @@ -61,43 +61,21 @@ const int kMaxNumTemporalLayers = 3; const int kPercTargetvsActualMismatch = 20; const int kBaseKeyFrameInterval = 3000; -// Process and network settings. -struct ProcessParams { - ProcessParams(bool hw_codec, - bool use_single_core, - float packet_loss_probability, - int key_frame_interval, - std::string filename, - bool verbose_logging, - bool batch_mode) - : hw_codec(hw_codec), - use_single_core(use_single_core), - key_frame_interval(key_frame_interval), - packet_loss_probability(packet_loss_probability), - filename(filename), - verbose_logging(verbose_logging), - batch_mode(batch_mode) {} - - bool hw_codec; - bool use_single_core; - int key_frame_interval; - float packet_loss_probability; // [0.0, 1.0]. - std::string filename; - bool verbose_logging; - - // In batch mode, the VideoProcessor is fed all the frames for processing - // before any metrics are calculated. This is useful for pipelining HW codecs, - // for which some calculated metrics otherwise would be incorrect. The - // downside with batch mode is that mid-test rate allocation is not supported. - bool batch_mode; -}; - // Thresholds for the quality metrics. Defaults are maximally minimal. struct QualityThresholds { + QualityThresholds() {} + QualityThresholds(double min_avg_psnr, + double min_min_psnr, + double min_avg_ssim, + double min_min_ssim) + : min_avg_psnr(min_avg_psnr), + min_min_psnr(min_min_psnr), + min_avg_ssim(min_avg_ssim), + min_min_ssim(min_min_ssim) {} double min_avg_psnr = std::numeric_limits::min(); double min_min_psnr = std::numeric_limits::min(); - double min_avg_ssim = 0; - double min_min_ssim = 0; + double min_avg_ssim = 0.0; + double min_min_ssim = 0.0; }; // The sequence of bit rate and frame rate changes for the encoder, the frame @@ -166,8 +144,8 @@ class VideoProcessorIntegrationTest : public testing::Test { } virtual ~VideoProcessorIntegrationTest() = default; - void CreateEncoderAndDecoder(bool hw_codec) { - if (hw_codec) { + void CreateEncoderAndDecoder() { + if (config_.hw_codec) { #if defined(WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED) #if defined(WEBRTC_ANDROID) // In general, external codecs should be destroyed by the factories that @@ -233,28 +211,8 @@ class VideoProcessorIntegrationTest : public testing::Test { } } - void SetUpCodecConfig(const ProcessParams& process, - const VisualizationParams* visualization_params) { - CreateEncoderAndDecoder(process.hw_codec); - - // Configure input filename. - config_.input_filename = test::ResourcePath(process.filename, "yuv"); - if (process.verbose_logging) - printf("Filename: %s\n", process.filename.c_str()); - // Generate an output filename in a safe way. - config_.output_filename = test::TempFilename( - test::OutputPath(), "videoprocessor_integrationtest"); - - config_.frame_length_in_bytes = - CalcBufferSize(VideoType::kI420, config_.codec_settings->width, - config_.codec_settings->height); - config_.verbose = process.verbose_logging; - config_.use_single_core = process.use_single_core; - - // Key frame interval and packet loss are set for each test. - config_.keyframe_interval = process.key_frame_interval; - config_.networking_config.packet_loss_probability = - process.packet_loss_probability; + void SetUpObjects(const VisualizationParams* visualization_params) { + CreateEncoderAndDecoder(); // Create file objects for quality analysis. analysis_frame_reader_.reset(new test::YuvFrameReaderImpl( @@ -269,10 +227,10 @@ class VideoProcessorIntegrationTest : public testing::Test { if (visualization_params) { // clang-format off const std::string output_filename_base = - test::OutputPath() + process.filename + + test::OutputPath() + config_.filename + "_cd-" + CodecTypeToPayloadName( config_.codec_settings->codecType).value_or("") + - "_hw-" + std::to_string(process.hw_codec) + + "_hw-" + std::to_string(config_.hw_codec) + "_fr-" + std::to_string(start_frame_rate_) + "_br-" + std::to_string( static_cast(config_.codec_settings->startBitrate)); @@ -308,8 +266,8 @@ class VideoProcessorIntegrationTest : public testing::Test { processor_->Init(); } - // Reset quantities after each encoder update, update the target - // per-frame bandwidth. + // Reset quantities after each encoder update, update the target per-frame + // bandwidth. void ResetRateControlMetrics(int num_frames_to_hit_target) { for (int i = 0; i < num_temporal_layers_; i++) { num_frames_per_update_[i] = 0; @@ -324,7 +282,7 @@ class VideoProcessorIntegrationTest : public testing::Test { float max_key_size = kScaleKeyFrameSize * kOptimalBufferSize * frame_rate_; // We don't know exact target size of the key frames (except for first one), // but the minimum in libvpx is ~|3 * per_frame_bandwidth| and maximum is - // set by |max_key_size_ * per_frame_bandwidth|. Take middle point/average + // set by |max_key_size_ * per_frame_bandwidth|. Take middle point/average // as reference for mismatch. Note key frames always correspond to base // layer frame in this test. target_size_key_frame_ = 0.5 * (3 + max_key_size) * per_frame_bandwidth_[0]; @@ -454,8 +412,8 @@ class VideoProcessorIntegrationTest : public testing::Test { EXPECT_GT(ssim_result.min, quality_thresholds.min_min_ssim); } - void VerifyQpParser(const ProcessParams& process, int frame_number) { - if (!process.hw_codec && + void VerifyQpParser(int frame_number) { + if (!config_.hw_codec && (config_.codec_settings->codecType == kVideoCodecVP8 || config_.codec_settings->codecType == kVideoCodecVP9)) { EXPECT_EQ(processor_->GetQpFromEncoder(frame_number), @@ -531,9 +489,8 @@ class VideoProcessorIntegrationTest : public testing::Test { // const std::vector&, so we can ensure that the user // does not expect us to do mid-clip rate updates when we are not able to, // e.g., when we are operating in batch mode. - void ProcessFramesAndVerify(QualityThresholds quality_thresholds, - RateProfile rate_profile, - ProcessParams process, + void ProcessFramesAndVerify(const QualityThresholds& quality_thresholds, + const RateProfile& rate_profile, RateControlThresholds* rc_thresholds, const VisualizationParams* visualization_params) { // Codec/config settings. @@ -541,7 +498,7 @@ class VideoProcessorIntegrationTest : public testing::Test { num_temporal_layers_ = NumberOfTemporalLayers(config_.codec_settings); config_.codec_settings->startBitrate = rate_profile.target_bit_rate[0]; start_frame_rate_ = rate_profile.input_frame_rate[0]; - SetUpCodecConfig(process, visualization_params); + SetUpObjects(visualization_params); // Update the temporal layers and the codec with the initial rates. bit_rate_ = rate_profile.target_bit_rate[0]; frame_rate_ = rate_profile.input_frame_rate[0]; @@ -558,7 +515,7 @@ class VideoProcessorIntegrationTest : public testing::Test { ResetRateControlMetrics( rate_profile.frame_index_rate_update[update_index + 1]); - if (process.batch_mode) { + if (config_.batch_mode) { // In batch mode, we calculate the metrics for all frames after all frames // have been sent for encoding. @@ -577,14 +534,14 @@ class VideoProcessorIntegrationTest : public testing::Test { // In online mode, we calculate the metrics for a given frame right after // it has been sent for encoding. - if (process.hw_codec) { + if (config_.hw_codec) { LOG(LS_WARNING) << "HW codecs should mostly be run in batch mode, " "since they may be pipelining."; } while (frame_number < num_frames) { EXPECT_TRUE(processor_->ProcessFrame(frame_number)); - VerifyQpParser(process, frame_number); + VerifyQpParser(frame_number); ++num_frames_per_update_[TemporalLayerIndexForFrame(frame_number)]; ++num_frames_total_; UpdateRateControlMetrics(frame_number); @@ -656,6 +613,28 @@ class VideoProcessorIntegrationTest : public testing::Test { } } + static void SetProcessParams(test::TestConfig* config, + bool hw_codec, + bool use_single_core, + float packet_loss_probability, + int key_frame_interval, + std::string filename, + bool verbose_logging, + bool batch_mode) { + // Configure input filename. + config->filename = filename; + config->input_filename = test::ResourcePath(filename, "yuv"); + // Generate an output filename in a safe way. + config->output_filename = test::TempFilename( + test::OutputPath(), "videoprocessor_integrationtest"); + config->hw_codec = hw_codec; + config->use_single_core = use_single_core; + config->keyframe_interval = key_frame_interval; + config->networking_config.packet_loss_probability = packet_loss_probability; + config->verbose = verbose_logging; + config->batch_mode = batch_mode; + } + static void SetCodecSettings(test::TestConfig* config, VideoCodec* codec_settings, VideoCodecType codec_type, @@ -702,17 +681,9 @@ class VideoProcessorIntegrationTest : public testing::Test { RTC_NOTREACHED(); break; } - } - static void SetQualityThresholds(QualityThresholds* quality_thresholds, - double min_avg_psnr, - double min_min_psnr, - double min_avg_ssim, - double min_min_ssim) { - quality_thresholds->min_avg_psnr = min_avg_psnr; - quality_thresholds->min_min_psnr = min_min_psnr; - quality_thresholds->min_avg_ssim = min_avg_ssim; - quality_thresholds->min_min_ssim = min_min_ssim; + config->frame_length_in_bytes = + CalcBufferSize(VideoType::kI420, width, height); } static void SetRateProfile(RateProfile* rate_profile,