| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTEST_H
_ | 11 #ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTEST_H
_ |
| 12 #define WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTEST_H
_ | 12 #define WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTEST_H
_ |
| 13 | 13 |
| 14 #include <math.h> | 14 #include <math.h> |
| 15 | 15 |
| 16 #include <limits> | 16 #include <limits> |
| 17 #include <memory> | 17 #include <memory> |
| 18 #include <string> | 18 #include <string> |
| 19 #include <utility> | 19 #include <utility> |
| 20 | 20 |
| 21 #if defined(WEBRTC_ANDROID) | 21 #if defined(WEBRTC_ANDROID) |
| 22 #include "webrtc/modules/video_coding/codecs/test/android_test_initializer.h" | 22 #include "webrtc/modules/video_coding/codecs/test/android_test_initializer.h" |
| 23 #include "webrtc/sdk/android/src/jni/androidmediadecoder_jni.h" | 23 #include "webrtc/sdk/android/src/jni/androidmediadecoder_jni.h" |
| 24 #include "webrtc/sdk/android/src/jni/androidmediaencoder_jni.h" | 24 #include "webrtc/sdk/android/src/jni/androidmediaencoder_jni.h" |
| 25 #elif defined(WEBRTC_IOS) | 25 #elif defined(WEBRTC_IOS) |
| 26 #include "webrtc/modules/video_coding/codecs/test/objc_codec_h264_test.h" | 26 #include "webrtc/modules/video_coding/codecs/test/objc_codec_h264_test.h" |
| 27 #endif | 27 #endif |
| 28 | 28 |
| 29 #include "webrtc/media/engine/internaldecoderfactory.h" |
| 30 #include "webrtc/media/engine/internalencoderfactory.h" |
| 29 #include "webrtc/media/engine/webrtcvideodecoderfactory.h" | 31 #include "webrtc/media/engine/webrtcvideodecoderfactory.h" |
| 30 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" | 32 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" |
| 31 #include "webrtc/modules/video_coding/codecs/h264/include/h264.h" | |
| 32 #include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h" | 33 #include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h" |
| 33 #include "webrtc/modules/video_coding/codecs/test/videoprocessor.h" | 34 #include "webrtc/modules/video_coding/codecs/test/videoprocessor.h" |
| 34 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" | |
| 35 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" | 35 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" |
| 36 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h" | |
| 37 #include "webrtc/modules/video_coding/include/video_codec_interface.h" | 36 #include "webrtc/modules/video_coding/include/video_codec_interface.h" |
| 38 #include "webrtc/modules/video_coding/include/video_coding.h" | 37 #include "webrtc/modules/video_coding/include/video_coding.h" |
| 39 #include "webrtc/modules/video_coding/utility/ivf_file_writer.h" | 38 #include "webrtc/modules/video_coding/utility/ivf_file_writer.h" |
| 40 #include "webrtc/rtc_base/checks.h" | 39 #include "webrtc/rtc_base/checks.h" |
| 41 #include "webrtc/rtc_base/file.h" | 40 #include "webrtc/rtc_base/file.h" |
| 42 #include "webrtc/rtc_base/logging.h" | 41 #include "webrtc/rtc_base/logging.h" |
| 43 #include "webrtc/rtc_base/ptr_util.h" | 42 #include "webrtc/rtc_base/ptr_util.h" |
| 44 #include "webrtc/test/gtest.h" | 43 #include "webrtc/test/gtest.h" |
| 45 #include "webrtc/test/testsupport/fileutils.h" | 44 #include "webrtc/test/testsupport/fileutils.h" |
| 46 #include "webrtc/test/testsupport/frame_reader.h" | 45 #include "webrtc/test/testsupport/frame_reader.h" |
| 47 #include "webrtc/test/testsupport/frame_writer.h" | 46 #include "webrtc/test/testsupport/frame_writer.h" |
| 48 #include "webrtc/test/testsupport/metrics/video_metrics.h" | 47 #include "webrtc/test/testsupport/metrics/video_metrics.h" |
| 49 #include "webrtc/test/testsupport/packet_reader.h" | 48 #include "webrtc/test/testsupport/packet_reader.h" |
| 50 #include "webrtc/typedefs.h" | 49 #include "webrtc/typedefs.h" |
| 51 | 50 |
| 52 namespace webrtc { | 51 namespace webrtc { |
| 53 namespace test { | 52 namespace test { |
| 54 // Maximum number of rate updates (i.e., calls to encoder to change bitrate | 53 |
| 55 // and/or frame rate) for the current tests. | |
| 56 const int kMaxNumRateUpdates = 3; | 54 const int kMaxNumRateUpdates = 3; |
| 57 | |
| 58 // Maximum number of temporal layers to use in tests. | |
| 59 const int kMaxNumTemporalLayers = 3; | 55 const int kMaxNumTemporalLayers = 3; |
| 60 | 56 |
| 61 const int kPercTargetvsActualMismatch = 20; | 57 const int kPercTargetvsActualMismatch = 20; |
| 62 const int kBaseKeyFrameInterval = 3000; | 58 const int kBaseKeyFrameInterval = 3000; |
| 63 | 59 |
| 60 // Parameters from VP8 wrapper, which control target size of key frames. |
| 61 const float kInitialBufferSize = 0.5f; |
| 62 const float kOptimalBufferSize = 0.6f; |
| 63 const float kScaleKeyFrameSize = 0.5f; |
| 64 |
| 64 // Thresholds for the quality metrics. Defaults are maximally minimal. | 65 // Thresholds for the quality metrics. Defaults are maximally minimal. |
| 65 struct QualityThresholds { | 66 struct QualityThresholds { |
| 66 QualityThresholds() {} | 67 QualityThresholds() {} |
| 67 QualityThresholds(double min_avg_psnr, | 68 QualityThresholds(double min_avg_psnr, |
| 68 double min_min_psnr, | 69 double min_min_psnr, |
| 69 double min_avg_ssim, | 70 double min_avg_ssim, |
| 70 double min_min_ssim) | 71 double min_min_ssim) |
| 71 : min_avg_psnr(min_avg_psnr), | 72 : min_avg_psnr(min_avg_psnr), |
| 72 min_min_psnr(min_min_psnr), | 73 min_min_psnr(min_min_psnr), |
| 73 min_avg_ssim(min_avg_ssim), | 74 min_avg_ssim(min_avg_ssim), |
| (...skipping 28 matching lines...) Expand all Loading... |
| 102 int num_spatial_resizes; // Set to -1 to disable check. | 103 int num_spatial_resizes; // Set to -1 to disable check. |
| 103 int num_key_frames; // Set to -1 to disable check. | 104 int num_key_frames; // Set to -1 to disable check. |
| 104 }; | 105 }; |
| 105 | 106 |
| 106 // Should video files be saved persistently to disk for post-run visualization? | 107 // Should video files be saved persistently to disk for post-run visualization? |
| 107 struct VisualizationParams { | 108 struct VisualizationParams { |
| 108 bool save_encoded_ivf; | 109 bool save_encoded_ivf; |
| 109 bool save_decoded_y4m; | 110 bool save_decoded_y4m; |
| 110 }; | 111 }; |
| 111 | 112 |
| 112 #if !defined(WEBRTC_IOS) | |
| 113 const int kNumFramesShort = 100; | |
| 114 #endif | |
| 115 const int kNumFramesLong = 299; | |
| 116 | |
| 117 // Parameters from VP8 wrapper, which control target size of key frames. | |
| 118 const float kInitialBufferSize = 0.5f; | |
| 119 const float kOptimalBufferSize = 0.6f; | |
| 120 const float kScaleKeyFrameSize = 0.5f; | |
| 121 | |
| 122 // Integration test for video processor. Encodes+decodes a clip and | 113 // Integration test for video processor. Encodes+decodes a clip and |
| 123 // writes it to the output directory. After completion, quality metrics | 114 // writes it to the output directory. After completion, quality metrics |
| 124 // (PSNR and SSIM) and rate control metrics are computed and compared to given | 115 // (PSNR and SSIM) and rate control metrics are computed and compared to given |
| 125 // thresholds, to verify that the quality and encoder response is acceptable. | 116 // thresholds, to verify that the quality and encoder response is acceptable. |
| 126 // The rate control tests allow us to verify the behavior for changing bit rate, | 117 // The rate control tests allow us to verify the behavior for changing bit rate, |
| 127 // changing frame rate, frame dropping/spatial resize, and temporal layers. | 118 // changing frame rate, frame dropping/spatial resize, and temporal layers. |
| 128 // The thresholds for the rate control metrics are set to be fairly | 119 // The thresholds for the rate control metrics are set to be fairly |
| 129 // conservative, so failure should only happen when some significant regression | 120 // conservative, so failure should only happen when some significant regression |
| 130 // or breakdown occurs. | 121 // or breakdown occurs. |
| 131 class VideoProcessorIntegrationTest : public testing::Test { | 122 class VideoProcessorIntegrationTest : public testing::Test { |
| 132 protected: | 123 protected: |
| 133 VideoProcessorIntegrationTest() { | 124 VideoProcessorIntegrationTest() { |
| 134 #if defined(WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED) && \ | 125 #if defined(WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED) && \ |
| 135 defined(WEBRTC_ANDROID) | 126 defined(WEBRTC_ANDROID) |
| 136 InitializeAndroidObjects(); | 127 InitializeAndroidObjects(); |
| 137 | |
| 138 external_encoder_factory_.reset( | |
| 139 new webrtc_jni::MediaCodecVideoEncoderFactory()); | |
| 140 external_decoder_factory_.reset( | |
| 141 new webrtc_jni::MediaCodecVideoDecoderFactory()); | |
| 142 #endif | 128 #endif |
| 143 } | 129 } |
| 144 virtual ~VideoProcessorIntegrationTest() = default; | 130 ~VideoProcessorIntegrationTest() override = default; |
| 145 | 131 |
| 146 void CreateEncoderAndDecoder() { | 132 void CreateEncoderAndDecoder() { |
| 147 if (config_.hw_codec) { | 133 if (config_.hw_codec) { |
| 148 #if defined(WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED) | 134 #if defined(WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED) |
| 149 #if defined(WEBRTC_ANDROID) | 135 #if defined(WEBRTC_ANDROID) |
| 150 // In general, external codecs should be destroyed by the factories that | 136 encoder_factory_.reset(new webrtc_jni::MediaCodecVideoEncoderFactory()); |
| 151 // allocated them. For the particular case of the Android | 137 decoder_factory_.reset(new webrtc_jni::MediaCodecVideoDecoderFactory()); |
| 152 // MediaCodecVideo{En,De}coderFactory's, however, it turns out that it is | |
| 153 // fine for the std::unique_ptr to destroy the owned codec directly. | |
| 154 switch (config_.codec_settings.codecType) { | |
| 155 case kVideoCodecH264: | |
| 156 encoder_.reset(external_encoder_factory_->CreateVideoEncoder( | |
| 157 cricket::VideoCodec(cricket::kH264CodecName))); | |
| 158 decoder_.reset( | |
| 159 external_decoder_factory_->CreateVideoDecoder(kVideoCodecH264)); | |
| 160 break; | |
| 161 case kVideoCodecVP8: | |
| 162 encoder_.reset(external_encoder_factory_->CreateVideoEncoder( | |
| 163 cricket::VideoCodec(cricket::kVp8CodecName))); | |
| 164 decoder_.reset( | |
| 165 external_decoder_factory_->CreateVideoDecoder(kVideoCodecVP8)); | |
| 166 break; | |
| 167 case kVideoCodecVP9: | |
| 168 encoder_.reset(external_encoder_factory_->CreateVideoEncoder( | |
| 169 cricket::VideoCodec(cricket::kVp9CodecName))); | |
| 170 decoder_.reset( | |
| 171 external_decoder_factory_->CreateVideoDecoder(kVideoCodecVP9)); | |
| 172 break; | |
| 173 default: | |
| 174 RTC_NOTREACHED(); | |
| 175 break; | |
| 176 } | |
| 177 #elif defined(WEBRTC_IOS) | 138 #elif defined(WEBRTC_IOS) |
| 178 ASSERT_EQ(kVideoCodecH264, config_.codec_settings.codecType) | 139 EXPECT_EQ(kVideoCodecH264, config_.codec_settings.codecType) |
| 179 << "iOS HW codecs only support H264."; | 140 << "iOS HW codecs only support H264."; |
| 180 std::unique_ptr<cricket::WebRtcVideoEncoderFactory> encoder_factory = | 141 encoder_factory_ = CreateObjCEncoderFactory(); |
| 181 CreateObjCEncoderFactory(); | 142 decoder_factory_ = CreateObjCDecoderFactory(); |
| 182 std::unique_ptr<cricket::WebRtcVideoDecoderFactory> decoder_factory = | |
| 183 CreateObjCDecoderFactory(); | |
| 184 cricket::VideoCodec codecInfo = encoder_factory->supported_codecs().at(0); | |
| 185 encoder_.reset(encoder_factory->CreateVideoEncoder(codecInfo)); | |
| 186 decoder_.reset(decoder_factory->CreateVideoDecoder(kVideoCodecH264)); | |
| 187 #else | 143 #else |
| 188 RTC_NOTREACHED() << "Only support HW codecs on Android and iOS."; | 144 RTC_NOTREACHED() << "Only support HW codecs on Android and iOS."; |
| 189 #endif | 145 #endif |
| 190 #endif // WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED | 146 #endif // WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED |
| 191 RTC_CHECK(encoder_) << "HW encoder not successfully created."; | 147 } else { |
| 192 RTC_CHECK(decoder_) << "HW decoder not successfully created."; | 148 // SW codecs. |
| 193 return; | 149 encoder_factory_.reset(new cricket::InternalEncoderFactory()); |
| 150 decoder_factory_.reset(new cricket::InternalDecoderFactory()); |
| 194 } | 151 } |
| 195 | 152 |
| 196 // SW codecs. | |
| 197 switch (config_.codec_settings.codecType) { | 153 switch (config_.codec_settings.codecType) { |
| 198 case kVideoCodecH264: | |
| 199 encoder_.reset( | |
| 200 H264Encoder::Create(cricket::VideoCodec(cricket::kH264CodecName))); | |
| 201 decoder_.reset(H264Decoder::Create()); | |
| 202 break; | |
| 203 case kVideoCodecVP8: | 154 case kVideoCodecVP8: |
| 204 encoder_.reset(VP8Encoder::Create()); | 155 encoder_ = encoder_factory_->CreateVideoEncoder( |
| 205 decoder_.reset(VP8Decoder::Create()); | 156 cricket::VideoCodec(cricket::kVp8CodecName)); |
| 157 decoder_ = decoder_factory_->CreateVideoDecoder(kVideoCodecVP8); |
| 206 break; | 158 break; |
| 207 case kVideoCodecVP9: | 159 case kVideoCodecVP9: |
| 208 encoder_.reset(VP9Encoder::Create()); | 160 encoder_ = encoder_factory_->CreateVideoEncoder( |
| 209 decoder_.reset(VP9Decoder::Create()); | 161 cricket::VideoCodec(cricket::kVp9CodecName)); |
| 162 decoder_ = decoder_factory_->CreateVideoDecoder(kVideoCodecVP9); |
| 163 break; |
| 164 case kVideoCodecH264: |
| 165 // TODO(brandtr): Generalize so that we support multiple profiles here. |
| 166 encoder_ = encoder_factory_->CreateVideoEncoder( |
| 167 cricket::VideoCodec(cricket::kH264CodecName)); |
| 168 decoder_ = decoder_factory_->CreateVideoDecoder(kVideoCodecH264); |
| 210 break; | 169 break; |
| 211 default: | 170 default: |
| 212 RTC_NOTREACHED(); | 171 RTC_NOTREACHED(); |
| 213 break; | 172 break; |
| 214 } | 173 } |
| 174 |
| 175 RTC_CHECK(encoder_) << "Encoder not successfully created."; |
| 176 RTC_CHECK(decoder_) << "Decoder not successfully created."; |
| 215 } | 177 } |
| 216 | 178 |
| 217 void SetUpObjects(const VisualizationParams* visualization_params) { | 179 void DestroyEncoderAndDecoder() { |
| 180 encoder_factory_->DestroyVideoEncoder(encoder_); |
| 181 decoder_factory_->DestroyVideoDecoder(decoder_); |
| 182 } |
| 183 |
| 184 void SetUpObjects(const VisualizationParams* visualization_params, |
| 185 const int initial_bitrate_kbps, |
| 186 const int initial_framerate_fps) { |
| 218 CreateEncoderAndDecoder(); | 187 CreateEncoderAndDecoder(); |
| 219 | 188 |
| 220 // Create file objects for quality analysis. | 189 // Create file objects for quality analysis. |
| 221 analysis_frame_reader_.reset(new test::YuvFrameReaderImpl( | 190 analysis_frame_reader_.reset(new YuvFrameReaderImpl( |
| 222 config_.input_filename, config_.codec_settings.width, | 191 config_.input_filename, config_.codec_settings.width, |
| 223 config_.codec_settings.height)); | 192 config_.codec_settings.height)); |
| 224 analysis_frame_writer_.reset(new test::YuvFrameWriterImpl( | 193 analysis_frame_writer_.reset(new YuvFrameWriterImpl( |
| 225 config_.output_filename, config_.codec_settings.width, | 194 config_.output_filename, config_.codec_settings.width, |
| 226 config_.codec_settings.height)); | 195 config_.codec_settings.height)); |
| 227 RTC_CHECK(analysis_frame_reader_->Init()); | 196 RTC_CHECK(analysis_frame_reader_->Init()); |
| 228 RTC_CHECK(analysis_frame_writer_->Init()); | 197 RTC_CHECK(analysis_frame_writer_->Init()); |
| 229 | 198 |
| 230 if (visualization_params) { | 199 if (visualization_params) { |
| 200 const std::string codec_name = |
| 201 CodecTypeToPayloadName(config_.codec_settings.codecType) |
| 202 .value_or("unknown"); |
| 203 const std::string implementation_type = config_.hw_codec ? "hw" : "sw"; |
| 231 // clang-format off | 204 // clang-format off |
| 232 const std::string output_filename_base = | 205 const std::string output_filename_base = |
| 233 test::OutputPath() + config_.filename + | 206 OutputPath() + config_.filename + "-" + |
| 234 "_cd-" + CodecTypeToPayloadName( | 207 codec_name + "-" + implementation_type + "-" + |
| 235 config_.codec_settings.codecType).value_or("") + | 208 std::to_string(initial_bitrate_kbps); |
| 236 "_hw-" + std::to_string(config_.hw_codec) + | |
| 237 "_br-" + std::to_string( | |
| 238 static_cast<int>(config_.codec_settings.startBitrate)); | |
| 239 // clang-format on | 209 // clang-format on |
| 240 if (visualization_params->save_encoded_ivf) { | 210 if (visualization_params->save_encoded_ivf) { |
| 241 rtc::File post_encode_file = | 211 rtc::File post_encode_file = |
| 242 rtc::File::Create(output_filename_base + "_encoded.ivf"); | 212 rtc::File::Create(output_filename_base + "_encoded.ivf"); |
| 243 encoded_frame_writer_ = | 213 encoded_frame_writer_ = |
| 244 IvfFileWriter::Wrap(std::move(post_encode_file), 0); | 214 IvfFileWriter::Wrap(std::move(post_encode_file), 0); |
| 245 } | 215 } |
| 246 if (visualization_params->save_decoded_y4m) { | 216 if (visualization_params->save_decoded_y4m) { |
| 247 decoded_frame_writer_.reset(new test::Y4mFrameWriterImpl( | 217 decoded_frame_writer_.reset(new Y4mFrameWriterImpl( |
| 248 output_filename_base + "_decoded.y4m", config_.codec_settings.width, | 218 output_filename_base + "_decoded.y4m", config_.codec_settings.width, |
| 249 config_.codec_settings.height, start_frame_rate_)); | 219 config_.codec_settings.height, initial_framerate_fps)); |
| 250 RTC_CHECK(decoded_frame_writer_->Init()); | 220 RTC_CHECK(decoded_frame_writer_->Init()); |
| 251 } | 221 } |
| 252 } | 222 } |
| 253 | 223 |
| 254 packet_manipulator_.reset(new test::PacketManipulatorImpl( | 224 packet_manipulator_.reset(new PacketManipulatorImpl( |
| 255 &packet_reader_, config_.networking_config, config_.verbose)); | 225 &packet_reader_, config_.networking_config, config_.verbose)); |
| 256 processor_ = rtc::MakeUnique<VideoProcessor>( | 226 processor_ = rtc::MakeUnique<VideoProcessor>( |
| 257 encoder_.get(), decoder_.get(), analysis_frame_reader_.get(), | 227 encoder_, decoder_, analysis_frame_reader_.get(), |
| 258 analysis_frame_writer_.get(), packet_manipulator_.get(), config_, | 228 analysis_frame_writer_.get(), packet_manipulator_.get(), config_, |
| 259 &stats_, encoded_frame_writer_.get(), decoded_frame_writer_.get()); | 229 &stats_, encoded_frame_writer_.get(), decoded_frame_writer_.get()); |
| 260 processor_->Init(); | 230 processor_->Init(); |
| 261 } | 231 } |
| 262 | 232 |
| 263 // Reset quantities after each encoder update, update the target per-frame | 233 // Reset quantities after each encoder update, update the target per-frame |
| 264 // bandwidth. | 234 // bandwidth. |
| 265 void ResetRateControlMetrics(int num_frames_to_hit_target) { | 235 void ResetRateControlMetrics(int num_frames_to_hit_target) { |
| 266 for (int i = 0; i < num_temporal_layers_; i++) { | 236 const int num_temporal_layers = |
| 237 NumberOfTemporalLayers(config_.codec_settings); |
| 238 for (int i = 0; i < num_temporal_layers; i++) { |
| 267 num_frames_per_update_[i] = 0; | 239 num_frames_per_update_[i] = 0; |
| 268 sum_frame_size_mismatch_[i] = 0.0f; | 240 sum_frame_size_mismatch_[i] = 0.0f; |
| 269 sum_encoded_frame_size_[i] = 0.0f; | 241 sum_encoded_frame_size_[i] = 0.0f; |
| 270 encoding_bitrate_[i] = 0.0f; | 242 encoding_bitrate_[i] = 0.0f; |
| 271 // Update layer per-frame-bandwidth. | 243 // Update layer per-frame-bandwidth. |
| 272 per_frame_bandwidth_[i] = static_cast<float>(bit_rate_layer_[i]) / | 244 per_frame_bandwidth_[i] = static_cast<float>(bit_rate_layer_[i]) / |
| 273 static_cast<float>(frame_rate_layer_[i]); | 245 static_cast<float>(frame_rate_layer_[i]); |
| 274 } | 246 } |
| 275 // Set maximum size of key frames, following setting in the VP8 wrapper. | 247 // Set maximum size of key frames, following setting in the VP8 wrapper. |
| 276 float max_key_size = kScaleKeyFrameSize * kOptimalBufferSize * frame_rate_; | 248 float max_key_size = kScaleKeyFrameSize * kOptimalBufferSize * frame_rate_; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 if (num_key_frames_ > 0) { | 326 if (num_key_frames_ > 0) { |
| 355 int perc_key_frame_size_mismatch = | 327 int perc_key_frame_size_mismatch = |
| 356 100 * sum_key_frame_size_mismatch_ / num_key_frames_; | 328 100 * sum_key_frame_size_mismatch_ / num_key_frames_; |
| 357 printf( | 329 printf( |
| 358 " # key frames : %d\n" | 330 " # key frames : %d\n" |
| 359 " Key frame rate mismatch: %d\n", | 331 " Key frame rate mismatch: %d\n", |
| 360 num_key_frames_, perc_key_frame_size_mismatch); | 332 num_key_frames_, perc_key_frame_size_mismatch); |
| 361 EXPECT_LE(perc_key_frame_size_mismatch, | 333 EXPECT_LE(perc_key_frame_size_mismatch, |
| 362 rc_expected.max_key_frame_size_mismatch); | 334 rc_expected.max_key_frame_size_mismatch); |
| 363 } | 335 } |
| 364 for (int i = 0; i < num_temporal_layers_; i++) { | 336 const int num_temporal_layers = |
| 337 NumberOfTemporalLayers(config_.codec_settings); |
| 338 for (int i = 0; i < num_temporal_layers; i++) { |
| 365 printf(" Temporal layer #%d:\n", i); | 339 printf(" Temporal layer #%d:\n", i); |
| 366 int perc_frame_size_mismatch = | 340 int perc_frame_size_mismatch = |
| 367 100 * sum_frame_size_mismatch_[i] / num_frames_per_update_[i]; | 341 100 * sum_frame_size_mismatch_[i] / num_frames_per_update_[i]; |
| 368 int perc_encoding_rate_mismatch = | 342 int perc_encoding_rate_mismatch = |
| 369 100 * fabs(encoding_bitrate_[i] - bit_rate_layer_[i]) / | 343 100 * fabs(encoding_bitrate_[i] - bit_rate_layer_[i]) / |
| 370 bit_rate_layer_[i]; | 344 bit_rate_layer_[i]; |
| 371 printf( | 345 printf( |
| 372 " Target layer bitrate : %f\n" | 346 " Target layer bitrate : %f\n" |
| 373 " Layer frame rate : %f\n" | 347 " Layer frame rate : %f\n" |
| 374 " Layer per frame bandwidth : %f\n" | 348 " Layer per frame bandwidth : %f\n" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 388 EXPECT_LE(num_frames_to_hit_target_, rc_expected.max_time_hit_target); | 362 EXPECT_LE(num_frames_to_hit_target_, rc_expected.max_time_hit_target); |
| 389 EXPECT_LE(num_dropped_frames, rc_expected.max_num_dropped_frames); | 363 EXPECT_LE(num_dropped_frames, rc_expected.max_num_dropped_frames); |
| 390 if (rc_expected.num_spatial_resizes >= 0) { | 364 if (rc_expected.num_spatial_resizes >= 0) { |
| 391 EXPECT_EQ(rc_expected.num_spatial_resizes, num_resize_actions); | 365 EXPECT_EQ(rc_expected.num_spatial_resizes, num_resize_actions); |
| 392 } | 366 } |
| 393 if (rc_expected.num_key_frames >= 0) { | 367 if (rc_expected.num_key_frames >= 0) { |
| 394 EXPECT_EQ(rc_expected.num_key_frames, num_key_frames_); | 368 EXPECT_EQ(rc_expected.num_key_frames, num_key_frames_); |
| 395 } | 369 } |
| 396 } | 370 } |
| 397 | 371 |
| 398 void VerifyQuality(const test::QualityMetricsResult& psnr_result, | 372 void VerifyQuality(const QualityMetricsResult& psnr_result, |
| 399 const test::QualityMetricsResult& ssim_result, | 373 const QualityMetricsResult& ssim_result, |
| 400 const QualityThresholds& quality_thresholds) { | 374 const QualityThresholds& quality_thresholds) { |
| 401 EXPECT_GT(psnr_result.average, quality_thresholds.min_avg_psnr); | 375 EXPECT_GT(psnr_result.average, quality_thresholds.min_avg_psnr); |
| 402 EXPECT_GT(psnr_result.min, quality_thresholds.min_min_psnr); | 376 EXPECT_GT(psnr_result.min, quality_thresholds.min_min_psnr); |
| 403 EXPECT_GT(ssim_result.average, quality_thresholds.min_avg_ssim); | 377 EXPECT_GT(ssim_result.average, quality_thresholds.min_avg_ssim); |
| 404 EXPECT_GT(ssim_result.min, quality_thresholds.min_min_ssim); | 378 EXPECT_GT(ssim_result.min, quality_thresholds.min_min_ssim); |
| 405 } | 379 } |
| 406 | 380 |
| 407 void VerifyQpParser(int frame_number) { | 381 void VerifyQpParser(int frame_number) { |
| 408 if (!config_.hw_codec && | 382 if (!config_.hw_codec && |
| 409 (config_.codec_settings.codecType == kVideoCodecVP8 || | 383 (config_.codec_settings.codecType == kVideoCodecVP8 || |
| 410 config_.codec_settings.codecType == kVideoCodecVP9)) { | 384 config_.codec_settings.codecType == kVideoCodecVP9)) { |
| 411 EXPECT_EQ(processor_->GetQpFromEncoder(frame_number), | 385 EXPECT_EQ(processor_->GetQpFromEncoder(frame_number), |
| 412 processor_->GetQpFromBitstream(frame_number)); | 386 processor_->GetQpFromBitstream(frame_number)); |
| 413 } | 387 } |
| 414 } | 388 } |
| 415 | 389 |
| 416 int NumberOfTemporalLayers(const VideoCodec& codec_settings) { | 390 int NumberOfTemporalLayers(const VideoCodec& codec_settings) { |
| 417 if (codec_settings.codecType == kVideoCodecVP8) { | 391 if (codec_settings.codecType == kVideoCodecVP8) { |
| 418 return codec_settings.VP8().numberOfTemporalLayers; | 392 return codec_settings.VP8().numberOfTemporalLayers; |
| 419 } else if (codec_settings.codecType == kVideoCodecVP9) { | 393 } else if (codec_settings.codecType == kVideoCodecVP9) { |
| 420 return codec_settings.VP9().numberOfTemporalLayers; | 394 return codec_settings.VP9().numberOfTemporalLayers; |
| 421 } else { | 395 } else { |
| 422 return 1; | 396 return 1; |
| 423 } | 397 } |
| 424 } | 398 } |
| 425 | 399 |
| 426 // Temporal layer index corresponding to frame number, for up to 3 layers. | 400 // Temporal layer index corresponding to frame number, for up to 3 layers. |
| 427 int TemporalLayerIndexForFrame(int frame_number) { | 401 int TemporalLayerIndexForFrame(int frame_number) { |
| 402 const int num_temporal_layers = |
| 403 NumberOfTemporalLayers(config_.codec_settings); |
| 428 int tl_idx = -1; | 404 int tl_idx = -1; |
| 429 switch (num_temporal_layers_) { | 405 switch (num_temporal_layers) { |
| 430 case 1: | 406 case 1: |
| 431 tl_idx = 0; | 407 tl_idx = 0; |
| 432 break; | 408 break; |
| 433 case 2: | 409 case 2: |
| 434 // temporal layer 0: 0 2 4 ... | 410 // temporal layer 0: 0 2 4 ... |
| 435 // temporal layer 1: 1 3 | 411 // temporal layer 1: 1 3 |
| 436 tl_idx = (frame_number % 2 == 0) ? 0 : 1; | 412 tl_idx = (frame_number % 2 == 0) ? 0 : 1; |
| 437 break; | 413 break; |
| 438 case 3: | 414 case 3: |
| 439 // temporal layer 0: 0 4 8 ... | 415 // temporal layer 0: 0 4 8 ... |
| 440 // temporal layer 1: 2 6 | 416 // temporal layer 1: 2 6 |
| 441 // temporal layer 2: 1 3 5 7 | 417 // temporal layer 2: 1 3 5 7 |
| 442 if (frame_number % 4 == 0) { | 418 if (frame_number % 4 == 0) { |
| 443 tl_idx = 0; | 419 tl_idx = 0; |
| 444 } else if ((frame_number + 2) % 4 == 0) { | 420 } else if ((frame_number + 2) % 4 == 0) { |
| 445 tl_idx = 1; | 421 tl_idx = 1; |
| 446 } else if ((frame_number + 1) % 2 == 0) { | 422 } else if ((frame_number + 1) % 2 == 0) { |
| 447 tl_idx = 2; | 423 tl_idx = 2; |
| 448 } | 424 } |
| 449 break; | 425 break; |
| 450 default: | 426 default: |
| 451 RTC_NOTREACHED(); | 427 RTC_NOTREACHED(); |
| 452 break; | 428 break; |
| 453 } | 429 } |
| 454 return tl_idx; | 430 return tl_idx; |
| 455 } | 431 } |
| 456 | 432 |
| 457 // Set the bit rate and frame rate per temporal layer, for up to 3 layers. | 433 // Set the bit rate and frame rate per temporal layer, for up to 3 layers. |
| 458 void SetTemporalLayerRates() { | 434 void SetTemporalLayerRates() { |
| 459 RTC_DCHECK_LE(num_temporal_layers_, kMaxNumTemporalLayers); | 435 const int num_temporal_layers = |
| 460 for (int i = 0; i < num_temporal_layers_; i++) { | 436 NumberOfTemporalLayers(config_.codec_settings); |
| 461 float bit_rate_ratio = | 437 RTC_DCHECK_LE(num_temporal_layers, kMaxNumTemporalLayers); |
| 462 kVp8LayerRateAlloction[num_temporal_layers_ - 1][i]; | 438 for (int i = 0; i < num_temporal_layers; i++) { |
| 439 float bit_rate_ratio = kVp8LayerRateAlloction[num_temporal_layers - 1][i]; |
| 463 if (i > 0) { | 440 if (i > 0) { |
| 464 float bit_rate_delta_ratio = | 441 float bit_rate_delta_ratio = |
| 465 kVp8LayerRateAlloction[num_temporal_layers_ - 1][i] - | 442 kVp8LayerRateAlloction[num_temporal_layers - 1][i] - |
| 466 kVp8LayerRateAlloction[num_temporal_layers_ - 1][i - 1]; | 443 kVp8LayerRateAlloction[num_temporal_layers - 1][i - 1]; |
| 467 bit_rate_layer_[i] = bit_rate_ * bit_rate_delta_ratio; | 444 bit_rate_layer_[i] = bit_rate_ * bit_rate_delta_ratio; |
| 468 } else { | 445 } else { |
| 469 bit_rate_layer_[i] = bit_rate_ * bit_rate_ratio; | 446 bit_rate_layer_[i] = bit_rate_ * bit_rate_ratio; |
| 470 } | 447 } |
| 471 frame_rate_layer_[i] = | 448 frame_rate_layer_[i] = |
| 472 frame_rate_ / static_cast<float>(1 << (num_temporal_layers_ - 1)); | 449 frame_rate_ / static_cast<float>(1 << (num_temporal_layers - 1)); |
| 473 } | 450 } |
| 474 if (num_temporal_layers_ == 3) { | 451 if (num_temporal_layers == 3) { |
| 475 frame_rate_layer_[2] = frame_rate_ / 2.0f; | 452 frame_rate_layer_[2] = frame_rate_ / 2.0f; |
| 476 } | 453 } |
| 477 } | 454 } |
| 478 | 455 |
| 479 // Processes all frames in the clip and verifies the result. | 456 // Processes all frames in the clip and verifies the result. |
| 480 // TODO(brandtr): Change the second last argument to be a | 457 // TODO(brandtr): Change the second last argument to be a |
| 481 // const std::vector<RateControlThresholds>&, so we can ensure that the user | 458 // const std::vector<RateControlThresholds>&, so we can ensure that the user |
| 482 // does not expect us to do mid-clip rate updates when we are not able to, | 459 // does not expect us to do mid-clip rate updates when we are not able to, |
| 483 // e.g., when we are operating in batch mode. | 460 // e.g., when we are operating in batch mode. |
| 484 void ProcessFramesAndVerify(const QualityThresholds& quality_thresholds, | 461 void ProcessFramesAndVerify(const QualityThresholds& quality_thresholds, |
| 485 const RateProfile& rate_profile, | 462 const RateProfile& rate_profile, |
| 486 RateControlThresholds* rc_thresholds, | 463 RateControlThresholds* rc_thresholds, |
| 487 const VisualizationParams* visualization_params) { | 464 const VisualizationParams* visualization_params) { |
| 488 // Codec/config settings. | |
| 489 num_temporal_layers_ = NumberOfTemporalLayers(config_.codec_settings); | |
| 490 config_.codec_settings.startBitrate = rate_profile.target_bit_rate[0]; | 465 config_.codec_settings.startBitrate = rate_profile.target_bit_rate[0]; |
| 491 start_frame_rate_ = rate_profile.input_frame_rate[0]; | 466 SetUpObjects(visualization_params, rate_profile.target_bit_rate[0], |
| 492 SetUpObjects(visualization_params); | 467 rate_profile.input_frame_rate[0]); |
| 493 // Update the temporal layers and the codec with the initial rates. | 468 |
| 469 // Set initial rates. |
| 494 bit_rate_ = rate_profile.target_bit_rate[0]; | 470 bit_rate_ = rate_profile.target_bit_rate[0]; |
| 495 frame_rate_ = rate_profile.input_frame_rate[0]; | 471 frame_rate_ = rate_profile.input_frame_rate[0]; |
| 496 SetTemporalLayerRates(); | 472 SetTemporalLayerRates(); |
| 497 // Set the initial target size for key frame. | 473 // Set the initial target size for key frame. |
| 498 target_size_key_frame_initial_ = | 474 target_size_key_frame_initial_ = |
| 499 0.5 * kInitialBufferSize * bit_rate_layer_[0]; | 475 0.5 * kInitialBufferSize * bit_rate_layer_[0]; |
| 500 processor_->SetRates(bit_rate_, frame_rate_); | 476 processor_->SetRates(bit_rate_, frame_rate_); |
| 501 | 477 |
| 502 // Process each frame, up to |num_frames|. | 478 // Process each frame, up to |num_frames|. |
| 503 int frame_number = 0; | 479 int frame_number = 0; |
| 504 int update_index = 0; | 480 int update_index = 0; |
| 505 int num_frames = rate_profile.num_frames; | 481 int num_frames = rate_profile.num_frames; |
| 506 ResetRateControlMetrics( | 482 ResetRateControlMetrics( |
| 507 rate_profile.frame_index_rate_update[update_index + 1]); | 483 rate_profile.frame_index_rate_update[update_index + 1]); |
| 508 | 484 |
| 509 if (config_.batch_mode) { | 485 if (config_.batch_mode) { |
| 510 // In batch mode, we calculate the metrics for all frames after all frames | 486 // In batch mode, we calculate the metrics for all frames after all frames |
| 511 // have been sent for encoding. | 487 // have been sent for encoding. |
| 512 | 488 |
| 513 // TODO(brandtr): Refactor "frame number accounting" so we don't have to | 489 // TODO(brandtr): Refactor "frame number accounting" so we don't have to |
| 514 // call ProcessFrame num_frames+1 times here. | 490 // call ProcessFrame num_frames+1 times here. |
| 515 for (frame_number = 0; frame_number <= num_frames; ++frame_number) { | 491 for (frame_number = 0; frame_number <= num_frames; ++frame_number) { |
| 516 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); | 492 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); |
| 517 } | 493 } |
| 518 | 494 |
| 519 for (frame_number = 0; frame_number < num_frames; ++frame_number) { | 495 for (frame_number = 0; frame_number < num_frames; ++frame_number) { |
| 520 ++num_frames_per_update_[TemporalLayerIndexForFrame(frame_number)]; | 496 const int tl_idx = TemporalLayerIndexForFrame(frame_number); |
| 497 ++num_frames_per_update_[tl_idx]; |
| 521 ++num_frames_total_; | 498 ++num_frames_total_; |
| 522 UpdateRateControlMetrics(frame_number); | 499 UpdateRateControlMetrics(frame_number); |
| 523 } | 500 } |
| 524 } else { | 501 } else { |
| 525 // In online mode, we calculate the metrics for a given frame right after | 502 // In online mode, we calculate the metrics for a given frame right after |
| 526 // it has been sent for encoding. | 503 // it has been sent for encoding. |
| 527 | 504 |
| 528 if (config_.hw_codec) { | 505 if (config_.hw_codec) { |
| 529 LOG(LS_WARNING) << "HW codecs should mostly be run in batch mode, " | 506 LOG(LS_WARNING) << "HW codecs should mostly be run in batch mode, " |
| 530 "since they may be pipelining."; | 507 "since they may be pipelining."; |
| 531 } | 508 } |
| 532 | 509 |
| 533 while (frame_number < num_frames) { | 510 while (frame_number < num_frames) { |
| 534 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); | 511 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); |
| 535 VerifyQpParser(frame_number); | 512 VerifyQpParser(frame_number); |
| 536 ++num_frames_per_update_[TemporalLayerIndexForFrame(frame_number)]; | 513 const int tl_idx = TemporalLayerIndexForFrame(frame_number); |
| 514 ++num_frames_per_update_[tl_idx]; |
| 537 ++num_frames_total_; | 515 ++num_frames_total_; |
| 538 UpdateRateControlMetrics(frame_number); | 516 UpdateRateControlMetrics(frame_number); |
| 539 | 517 |
| 540 ++frame_number; | 518 ++frame_number; |
| 541 | 519 |
| 542 // If we hit another/next update, verify stats for current state and | 520 // If we hit another/next update, verify stats for current state and |
| 543 // update layers and codec with new rates. | 521 // update layers and codec with new rates. |
| 544 if (frame_number == | 522 if (frame_number == |
| 545 rate_profile.frame_index_rate_update[update_index + 1]) { | 523 rate_profile.frame_index_rate_update[update_index + 1]) { |
| 546 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); | 524 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 560 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); | 538 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); |
| 561 } | 539 } |
| 562 | 540 |
| 563 // Verify rate control metrics for all frames (if in batch mode), or for all | 541 // Verify rate control metrics for all frames (if in batch mode), or for all |
| 564 // frames since the last rate update (if not in batch mode). | 542 // frames since the last rate update (if not in batch mode). |
| 565 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); | 543 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); |
| 566 EXPECT_EQ(num_frames, frame_number); | 544 EXPECT_EQ(num_frames, frame_number); |
| 567 EXPECT_EQ(num_frames + 1, static_cast<int>(stats_.stats_.size())); | 545 EXPECT_EQ(num_frames + 1, static_cast<int>(stats_.stats_.size())); |
| 568 | 546 |
| 569 // Release encoder and decoder to make sure they have finished processing. | 547 // Release encoder and decoder to make sure they have finished processing. |
| 570 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release()); | 548 processor_->Release(); |
| 571 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release()); | 549 DestroyEncoderAndDecoder(); |
| 572 | 550 |
| 573 // Close the analysis files before we use them for SSIM/PSNR calculations. | 551 // Close the analysis files before we use them for SSIM/PSNR calculations. |
| 574 analysis_frame_reader_->Close(); | 552 analysis_frame_reader_->Close(); |
| 575 analysis_frame_writer_->Close(); | 553 analysis_frame_writer_->Close(); |
| 576 | 554 |
| 577 // Close visualization files. | 555 // Close visualization files. |
| 578 if (encoded_frame_writer_) { | 556 if (encoded_frame_writer_) { |
| 579 EXPECT_TRUE(encoded_frame_writer_->Close()); | 557 EXPECT_TRUE(encoded_frame_writer_->Close()); |
| 580 } | 558 } |
| 581 if (decoded_frame_writer_) { | 559 if (decoded_frame_writer_) { |
| 582 decoded_frame_writer_->Close(); | 560 decoded_frame_writer_->Close(); |
| 583 } | 561 } |
| 584 | 562 |
| 585 // TODO(marpan): Should compute these quality metrics per SetRates update. | 563 // TODO(marpan): Should compute these quality metrics per SetRates update. |
| 586 test::QualityMetricsResult psnr_result, ssim_result; | 564 QualityMetricsResult psnr_result, ssim_result; |
| 587 EXPECT_EQ(0, test::I420MetricsFromFiles(config_.input_filename.c_str(), | 565 EXPECT_EQ(0, I420MetricsFromFiles(config_.input_filename.c_str(), |
| 588 config_.output_filename.c_str(), | 566 config_.output_filename.c_str(), |
| 589 config_.codec_settings.width, | 567 config_.codec_settings.width, |
| 590 config_.codec_settings.height, | 568 config_.codec_settings.height, |
| 591 &psnr_result, &ssim_result)); | 569 &psnr_result, &ssim_result)); |
| 592 VerifyQuality(psnr_result, ssim_result, quality_thresholds); | 570 VerifyQuality(psnr_result, ssim_result, quality_thresholds); |
| 593 stats_.PrintSummary(); | 571 stats_.PrintSummary(); |
| 594 printf("PSNR avg: %f, min: %f\nSSIM avg: %f, min: %f\n", | 572 printf("PSNR avg: %f, min: %f\nSSIM avg: %f, min: %f\n", |
| 595 psnr_result.average, psnr_result.min, ssim_result.average, | 573 psnr_result.average, psnr_result.min, ssim_result.average, |
| 596 ssim_result.min); | 574 ssim_result.min); |
| 597 printf("\n"); | 575 printf("\n"); |
| 598 | 576 |
| 599 // Remove analysis file. | 577 // Remove analysis file. |
| 600 if (remove(config_.output_filename.c_str()) < 0) { | 578 if (remove(config_.output_filename.c_str()) < 0) { |
| 601 fprintf(stderr, "Failed to remove temporary file!\n"); | 579 fprintf(stderr, "Failed to remove temporary file!\n"); |
| 602 } | 580 } |
| 603 } | 581 } |
| 604 | 582 |
| 605 static void SetProcessParams(test::TestConfig* config, | 583 static void SetProcessParams(TestConfig* config, |
| 606 bool hw_codec, | 584 bool hw_codec, |
| 607 bool use_single_core, | 585 bool use_single_core, |
| 608 float packet_loss_probability, | 586 float packet_loss_probability, |
| 609 int key_frame_interval, | 587 int key_frame_interval, |
| 610 std::string filename, | 588 std::string filename, |
| 611 bool verbose_logging, | 589 bool verbose_logging, |
| 612 bool batch_mode) { | 590 bool batch_mode) { |
| 613 // Configure input filename. | 591 // Configure input filename. |
| 614 config->filename = filename; | 592 config->filename = filename; |
| 615 config->input_filename = test::ResourcePath(filename, "yuv"); | 593 config->input_filename = ResourcePath(filename, "yuv"); |
| 616 // Generate an output filename in a safe way. | 594 // Generate an output filename in a safe way. |
| 617 config->output_filename = test::TempFilename( | 595 config->output_filename = |
| 618 test::OutputPath(), "videoprocessor_integrationtest"); | 596 TempFilename(OutputPath(), "videoprocessor_integrationtest"); |
| 619 config->hw_codec = hw_codec; | 597 config->hw_codec = hw_codec; |
| 620 config->use_single_core = use_single_core; | 598 config->use_single_core = use_single_core; |
| 621 config->keyframe_interval = key_frame_interval; | 599 config->keyframe_interval = key_frame_interval; |
| 622 config->networking_config.packet_loss_probability = packet_loss_probability; | 600 config->networking_config.packet_loss_probability = packet_loss_probability; |
| 623 config->verbose = verbose_logging; | 601 config->verbose = verbose_logging; |
| 624 config->batch_mode = batch_mode; | 602 config->batch_mode = batch_mode; |
| 625 } | 603 } |
| 626 | 604 |
| 627 static void SetCodecSettings(test::TestConfig* config, | 605 static void SetCodecSettings(TestConfig* config, |
| 628 VideoCodecType codec_type, | 606 VideoCodecType codec_type, |
| 629 int num_temporal_layers, | 607 int num_temporal_layers, |
| 630 bool error_concealment_on, | 608 bool error_concealment_on, |
| 631 bool denoising_on, | 609 bool denoising_on, |
| 632 bool frame_dropper_on, | 610 bool frame_dropper_on, |
| 633 bool spatial_resize_on, | 611 bool spatial_resize_on, |
| 634 bool resilience_on, | 612 bool resilience_on, |
| 635 int width, | 613 int width, |
| 636 int height) { | 614 int height) { |
| 637 VideoCodingModule::Codec(codec_type, &config->codec_settings); | 615 VideoCodingModule::Codec(codec_type, &config->codec_settings); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 700 max_encoding_rate_mismatch; | 678 max_encoding_rate_mismatch; |
| 701 rc_thresholds[update_index].max_time_hit_target = max_time_hit_target; | 679 rc_thresholds[update_index].max_time_hit_target = max_time_hit_target; |
| 702 rc_thresholds[update_index].num_spatial_resizes = num_spatial_resizes; | 680 rc_thresholds[update_index].num_spatial_resizes = num_spatial_resizes; |
| 703 rc_thresholds[update_index].num_key_frames = num_key_frames; | 681 rc_thresholds[update_index].num_key_frames = num_key_frames; |
| 704 } | 682 } |
| 705 | 683 |
| 706 // Config. | 684 // Config. |
| 707 TestConfig config_; | 685 TestConfig config_; |
| 708 | 686 |
| 709 // Codecs. | 687 // Codecs. |
| 710 std::unique_ptr<VideoEncoder> encoder_; | 688 std::unique_ptr<cricket::WebRtcVideoEncoderFactory> encoder_factory_; |
| 711 std::unique_ptr<cricket::WebRtcVideoEncoderFactory> external_encoder_factory_; | 689 VideoEncoder* encoder_; |
| 712 std::unique_ptr<VideoDecoder> decoder_; | 690 std::unique_ptr<cricket::WebRtcVideoDecoderFactory> decoder_factory_; |
| 713 std::unique_ptr<cricket::WebRtcVideoDecoderFactory> external_decoder_factory_; | 691 VideoDecoder* decoder_; |
| 714 | 692 |
| 715 // Helper objects. | 693 // Helper objects. |
| 716 std::unique_ptr<test::FrameReader> analysis_frame_reader_; | 694 std::unique_ptr<FrameReader> analysis_frame_reader_; |
| 717 std::unique_ptr<test::FrameWriter> analysis_frame_writer_; | 695 std::unique_ptr<FrameWriter> analysis_frame_writer_; |
| 718 test::PacketReader packet_reader_; | |
| 719 std::unique_ptr<test::PacketManipulator> packet_manipulator_; | |
| 720 test::Stats stats_; | |
| 721 // Must be destroyed before |encoder_| and |decoder_|. | |
| 722 std::unique_ptr<test::VideoProcessor> processor_; | |
| 723 | |
| 724 // Visualization objects. | |
| 725 std::unique_ptr<IvfFileWriter> encoded_frame_writer_; | 696 std::unique_ptr<IvfFileWriter> encoded_frame_writer_; |
| 726 std::unique_ptr<test::FrameWriter> decoded_frame_writer_; | 697 std::unique_ptr<FrameWriter> decoded_frame_writer_; |
| 698 PacketReader packet_reader_; |
| 699 std::unique_ptr<PacketManipulator> packet_manipulator_; |
| 700 Stats stats_; |
| 701 std::unique_ptr<VideoProcessor> processor_; |
| 727 | 702 |
| 728 // Quantities defined/updated for every encoder rate update. | 703 // Quantities defined/updated for every encoder rate update. |
| 729 int num_frames_per_update_[kMaxNumTemporalLayers]; | 704 int num_frames_per_update_[kMaxNumTemporalLayers]; |
| 730 float sum_frame_size_mismatch_[kMaxNumTemporalLayers]; | 705 float sum_frame_size_mismatch_[kMaxNumTemporalLayers]; |
| 731 float sum_encoded_frame_size_[kMaxNumTemporalLayers]; | 706 float sum_encoded_frame_size_[kMaxNumTemporalLayers]; |
| 732 float encoding_bitrate_[kMaxNumTemporalLayers]; | 707 float encoding_bitrate_[kMaxNumTemporalLayers]; |
| 733 float per_frame_bandwidth_[kMaxNumTemporalLayers]; | 708 float per_frame_bandwidth_[kMaxNumTemporalLayers]; |
| 734 float bit_rate_layer_[kMaxNumTemporalLayers]; | 709 float bit_rate_layer_[kMaxNumTemporalLayers]; |
| 735 float frame_rate_layer_[kMaxNumTemporalLayers]; | 710 float frame_rate_layer_[kMaxNumTemporalLayers]; |
| 736 int num_frames_total_; | 711 int num_frames_total_; |
| 737 float sum_encoded_frame_size_total_; | 712 float sum_encoded_frame_size_total_; |
| 738 float encoding_bitrate_total_; | 713 float encoding_bitrate_total_; |
| 739 float perc_encoding_rate_mismatch_; | 714 float perc_encoding_rate_mismatch_; |
| 740 int num_frames_to_hit_target_; | 715 int num_frames_to_hit_target_; |
| 741 bool encoding_rate_within_target_; | 716 bool encoding_rate_within_target_; |
| 742 int bit_rate_; | 717 int bit_rate_; |
| 743 int frame_rate_; | 718 int frame_rate_; |
| 744 float target_size_key_frame_initial_; | 719 float target_size_key_frame_initial_; |
| 745 float target_size_key_frame_; | 720 float target_size_key_frame_; |
| 746 float sum_key_frame_size_mismatch_; | 721 float sum_key_frame_size_mismatch_; |
| 747 int num_key_frames_; | 722 int num_key_frames_; |
| 748 int start_frame_rate_; | |
| 749 | |
| 750 // Codec and network settings. | |
| 751 int num_temporal_layers_; | |
| 752 }; | 723 }; |
| 753 | 724 |
| 754 } // namespace test | 725 } // namespace test |
| 755 } // namespace webrtc | 726 } // namespace webrtc |
| 756 | 727 |
| 757 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES
T_H_ | 728 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES
T_H_ |
| OLD | NEW |