| 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 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 // Maximum number of rate updates (i.e., calls to encoder to change bitrate | 54 // Maximum number of rate updates (i.e., calls to encoder to change bitrate |
| 55 // and/or frame rate) for the current tests. | 55 // and/or frame rate) for the current tests. |
| 56 const int kMaxNumRateUpdates = 3; | 56 const int kMaxNumRateUpdates = 3; |
| 57 | 57 |
| 58 // Maximum number of temporal layers to use in tests. | 58 // Maximum number of temporal layers to use in tests. |
| 59 const int kMaxNumTemporalLayers = 3; | 59 const int kMaxNumTemporalLayers = 3; |
| 60 | 60 |
| 61 const int kPercTargetvsActualMismatch = 20; | 61 const int kPercTargetvsActualMismatch = 20; |
| 62 const int kBaseKeyFrameInterval = 3000; | 62 const int kBaseKeyFrameInterval = 3000; |
| 63 | 63 |
| 64 // Process and network settings. | |
| 65 struct ProcessParams { | |
| 66 ProcessParams(bool hw_codec, | |
| 67 bool use_single_core, | |
| 68 float packet_loss_probability, | |
| 69 int key_frame_interval, | |
| 70 std::string filename, | |
| 71 bool verbose_logging, | |
| 72 bool batch_mode) | |
| 73 : hw_codec(hw_codec), | |
| 74 use_single_core(use_single_core), | |
| 75 key_frame_interval(key_frame_interval), | |
| 76 packet_loss_probability(packet_loss_probability), | |
| 77 filename(filename), | |
| 78 verbose_logging(verbose_logging), | |
| 79 batch_mode(batch_mode) {} | |
| 80 | |
| 81 bool hw_codec; | |
| 82 bool use_single_core; | |
| 83 int key_frame_interval; | |
| 84 float packet_loss_probability; // [0.0, 1.0]. | |
| 85 std::string filename; | |
| 86 bool verbose_logging; | |
| 87 | |
| 88 // In batch mode, the VideoProcessor is fed all the frames for processing | |
| 89 // before any metrics are calculated. This is useful for pipelining HW codecs, | |
| 90 // for which some calculated metrics otherwise would be incorrect. The | |
| 91 // downside with batch mode is that mid-test rate allocation is not supported. | |
| 92 bool batch_mode; | |
| 93 }; | |
| 94 | |
| 95 // Thresholds for the quality metrics. Defaults are maximally minimal. | 64 // Thresholds for the quality metrics. Defaults are maximally minimal. |
| 96 struct QualityThresholds { | 65 struct QualityThresholds { |
| 66 QualityThresholds() {} |
| 67 QualityThresholds(double min_avg_psnr, |
| 68 double min_min_psnr, |
| 69 double min_avg_ssim, |
| 70 double min_min_ssim) |
| 71 : min_avg_psnr(min_avg_psnr), |
| 72 min_min_psnr(min_min_psnr), |
| 73 min_avg_ssim(min_avg_ssim), |
| 74 min_min_ssim(min_min_ssim) {} |
| 97 double min_avg_psnr = std::numeric_limits<double>::min(); | 75 double min_avg_psnr = std::numeric_limits<double>::min(); |
| 98 double min_min_psnr = std::numeric_limits<double>::min(); | 76 double min_min_psnr = std::numeric_limits<double>::min(); |
| 99 double min_avg_ssim = 0; | 77 double min_avg_ssim = 0.0; |
| 100 double min_min_ssim = 0; | 78 double min_min_ssim = 0.0; |
| 101 }; | 79 }; |
| 102 | 80 |
| 103 // The sequence of bit rate and frame rate changes for the encoder, the frame | 81 // The sequence of bit rate and frame rate changes for the encoder, the frame |
| 104 // number where the changes are made, and the total number of frames for the | 82 // number where the changes are made, and the total number of frames for the |
| 105 // test. | 83 // test. |
| 106 struct RateProfile { | 84 struct RateProfile { |
| 107 int target_bit_rate[kMaxNumRateUpdates]; | 85 int target_bit_rate[kMaxNumRateUpdates]; |
| 108 int input_frame_rate[kMaxNumRateUpdates]; | 86 int input_frame_rate[kMaxNumRateUpdates]; |
| 109 int frame_index_rate_update[kMaxNumRateUpdates + 1]; | 87 int frame_index_rate_update[kMaxNumRateUpdates + 1]; |
| 110 int num_frames; | 88 int num_frames; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 InitializeAndroidObjects(); | 137 InitializeAndroidObjects(); |
| 160 | 138 |
| 161 external_encoder_factory_.reset( | 139 external_encoder_factory_.reset( |
| 162 new webrtc_jni::MediaCodecVideoEncoderFactory()); | 140 new webrtc_jni::MediaCodecVideoEncoderFactory()); |
| 163 external_decoder_factory_.reset( | 141 external_decoder_factory_.reset( |
| 164 new webrtc_jni::MediaCodecVideoDecoderFactory()); | 142 new webrtc_jni::MediaCodecVideoDecoderFactory()); |
| 165 #endif | 143 #endif |
| 166 } | 144 } |
| 167 virtual ~VideoProcessorIntegrationTest() = default; | 145 virtual ~VideoProcessorIntegrationTest() = default; |
| 168 | 146 |
| 169 void CreateEncoderAndDecoder(bool hw_codec) { | 147 void CreateEncoderAndDecoder() { |
| 170 if (hw_codec) { | 148 if (config_.hw_codec) { |
| 171 #if defined(WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED) | 149 #if defined(WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED) |
| 172 #if defined(WEBRTC_ANDROID) | 150 #if defined(WEBRTC_ANDROID) |
| 173 // In general, external codecs should be destroyed by the factories that | 151 // In general, external codecs should be destroyed by the factories that |
| 174 // allocated them. For the particular case of the Android | 152 // allocated them. For the particular case of the Android |
| 175 // MediaCodecVideo{En,De}coderFactory's, however, it turns out that it is | 153 // MediaCodecVideo{En,De}coderFactory's, however, it turns out that it is |
| 176 // fine for the std::unique_ptr to destroy the owned codec directly. | 154 // fine for the std::unique_ptr to destroy the owned codec directly. |
| 177 switch (config_.codec_settings->codecType) { | 155 switch (config_.codec_settings->codecType) { |
| 178 case kVideoCodecH264: | 156 case kVideoCodecH264: |
| 179 encoder_.reset(external_encoder_factory_->CreateVideoEncoder( | 157 encoder_.reset(external_encoder_factory_->CreateVideoEncoder( |
| 180 cricket::VideoCodec(cricket::kH264CodecName))); | 158 cricket::VideoCodec(cricket::kH264CodecName))); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 case kVideoCodecVP9: | 204 case kVideoCodecVP9: |
| 227 encoder_.reset(VP9Encoder::Create()); | 205 encoder_.reset(VP9Encoder::Create()); |
| 228 decoder_.reset(VP9Decoder::Create()); | 206 decoder_.reset(VP9Decoder::Create()); |
| 229 break; | 207 break; |
| 230 default: | 208 default: |
| 231 RTC_NOTREACHED(); | 209 RTC_NOTREACHED(); |
| 232 break; | 210 break; |
| 233 } | 211 } |
| 234 } | 212 } |
| 235 | 213 |
| 236 void SetUpCodecConfig(const ProcessParams& process, | 214 void SetUpObjects(const VisualizationParams* visualization_params) { |
| 237 const VisualizationParams* visualization_params) { | 215 CreateEncoderAndDecoder(); |
| 238 CreateEncoderAndDecoder(process.hw_codec); | |
| 239 | |
| 240 // Configure input filename. | |
| 241 config_.input_filename = test::ResourcePath(process.filename, "yuv"); | |
| 242 if (process.verbose_logging) | |
| 243 printf("Filename: %s\n", process.filename.c_str()); | |
| 244 // Generate an output filename in a safe way. | |
| 245 config_.output_filename = test::TempFilename( | |
| 246 test::OutputPath(), "videoprocessor_integrationtest"); | |
| 247 | |
| 248 config_.frame_length_in_bytes = | |
| 249 CalcBufferSize(VideoType::kI420, config_.codec_settings->width, | |
| 250 config_.codec_settings->height); | |
| 251 config_.verbose = process.verbose_logging; | |
| 252 config_.use_single_core = process.use_single_core; | |
| 253 | |
| 254 // Key frame interval and packet loss are set for each test. | |
| 255 config_.keyframe_interval = process.key_frame_interval; | |
| 256 config_.networking_config.packet_loss_probability = | |
| 257 process.packet_loss_probability; | |
| 258 | 216 |
| 259 // Create file objects for quality analysis. | 217 // Create file objects for quality analysis. |
| 260 analysis_frame_reader_.reset(new test::YuvFrameReaderImpl( | 218 analysis_frame_reader_.reset(new test::YuvFrameReaderImpl( |
| 261 config_.input_filename, config_.codec_settings->width, | 219 config_.input_filename, config_.codec_settings->width, |
| 262 config_.codec_settings->height)); | 220 config_.codec_settings->height)); |
| 263 analysis_frame_writer_.reset(new test::YuvFrameWriterImpl( | 221 analysis_frame_writer_.reset(new test::YuvFrameWriterImpl( |
| 264 config_.output_filename, config_.codec_settings->width, | 222 config_.output_filename, config_.codec_settings->width, |
| 265 config_.codec_settings->height)); | 223 config_.codec_settings->height)); |
| 266 RTC_CHECK(analysis_frame_reader_->Init()); | 224 RTC_CHECK(analysis_frame_reader_->Init()); |
| 267 RTC_CHECK(analysis_frame_writer_->Init()); | 225 RTC_CHECK(analysis_frame_writer_->Init()); |
| 268 | 226 |
| 269 if (visualization_params) { | 227 if (visualization_params) { |
| 270 // clang-format off | 228 // clang-format off |
| 271 const std::string output_filename_base = | 229 const std::string output_filename_base = |
| 272 test::OutputPath() + process.filename + | 230 test::OutputPath() + config_.filename + |
| 273 "_cd-" + CodecTypeToPayloadName( | 231 "_cd-" + CodecTypeToPayloadName( |
| 274 config_.codec_settings->codecType).value_or("") + | 232 config_.codec_settings->codecType).value_or("") + |
| 275 "_hw-" + std::to_string(process.hw_codec) + | 233 "_hw-" + std::to_string(config_.hw_codec) + |
| 276 "_fr-" + std::to_string(start_frame_rate_) + | 234 "_fr-" + std::to_string(start_frame_rate_) + |
| 277 "_br-" + std::to_string( | 235 "_br-" + std::to_string( |
| 278 static_cast<int>(config_.codec_settings->startBitrate)); | 236 static_cast<int>(config_.codec_settings->startBitrate)); |
| 279 // clang-format on | 237 // clang-format on |
| 280 if (visualization_params->save_source_y4m) { | 238 if (visualization_params->save_source_y4m) { |
| 281 source_frame_writer_.reset(new test::Y4mFrameWriterImpl( | 239 source_frame_writer_.reset(new test::Y4mFrameWriterImpl( |
| 282 output_filename_base + "_source.y4m", config_.codec_settings->width, | 240 output_filename_base + "_source.y4m", config_.codec_settings->width, |
| 283 config_.codec_settings->height, start_frame_rate_)); | 241 config_.codec_settings->height, start_frame_rate_)); |
| 284 RTC_CHECK(source_frame_writer_->Init()); | 242 RTC_CHECK(source_frame_writer_->Init()); |
| 285 } | 243 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 301 packet_manipulator_.reset(new test::PacketManipulatorImpl( | 259 packet_manipulator_.reset(new test::PacketManipulatorImpl( |
| 302 &packet_reader_, config_.networking_config, config_.verbose)); | 260 &packet_reader_, config_.networking_config, config_.verbose)); |
| 303 processor_.reset(new test::VideoProcessorImpl( | 261 processor_.reset(new test::VideoProcessorImpl( |
| 304 encoder_.get(), decoder_.get(), analysis_frame_reader_.get(), | 262 encoder_.get(), decoder_.get(), analysis_frame_reader_.get(), |
| 305 analysis_frame_writer_.get(), packet_manipulator_.get(), config_, | 263 analysis_frame_writer_.get(), packet_manipulator_.get(), config_, |
| 306 &stats_, source_frame_writer_.get(), encoded_frame_writer_.get(), | 264 &stats_, source_frame_writer_.get(), encoded_frame_writer_.get(), |
| 307 decoded_frame_writer_.get())); | 265 decoded_frame_writer_.get())); |
| 308 processor_->Init(); | 266 processor_->Init(); |
| 309 } | 267 } |
| 310 | 268 |
| 311 // Reset quantities after each encoder update, update the target | 269 // Reset quantities after each encoder update, update the target per-frame |
| 312 // per-frame bandwidth. | 270 // bandwidth. |
| 313 void ResetRateControlMetrics(int num_frames_to_hit_target) { | 271 void ResetRateControlMetrics(int num_frames_to_hit_target) { |
| 314 for (int i = 0; i < num_temporal_layers_; i++) { | 272 for (int i = 0; i < num_temporal_layers_; i++) { |
| 315 num_frames_per_update_[i] = 0; | 273 num_frames_per_update_[i] = 0; |
| 316 sum_frame_size_mismatch_[i] = 0.0f; | 274 sum_frame_size_mismatch_[i] = 0.0f; |
| 317 sum_encoded_frame_size_[i] = 0.0f; | 275 sum_encoded_frame_size_[i] = 0.0f; |
| 318 encoding_bitrate_[i] = 0.0f; | 276 encoding_bitrate_[i] = 0.0f; |
| 319 // Update layer per-frame-bandwidth. | 277 // Update layer per-frame-bandwidth. |
| 320 per_frame_bandwidth_[i] = static_cast<float>(bit_rate_layer_[i]) / | 278 per_frame_bandwidth_[i] = static_cast<float>(bit_rate_layer_[i]) / |
| 321 static_cast<float>(frame_rate_layer_[i]); | 279 static_cast<float>(frame_rate_layer_[i]); |
| 322 } | 280 } |
| 323 // Set maximum size of key frames, following setting in the VP8 wrapper. | 281 // Set maximum size of key frames, following setting in the VP8 wrapper. |
| 324 float max_key_size = kScaleKeyFrameSize * kOptimalBufferSize * frame_rate_; | 282 float max_key_size = kScaleKeyFrameSize * kOptimalBufferSize * frame_rate_; |
| 325 // We don't know exact target size of the key frames (except for first one), | 283 // We don't know exact target size of the key frames (except for first one), |
| 326 // but the minimum in libvpx is ~|3 * per_frame_bandwidth| and maximum is | 284 // but the minimum in libvpx is ~|3 * per_frame_bandwidth| and maximum is |
| 327 // set by |max_key_size_ * per_frame_bandwidth|. Take middle point/average | 285 // set by |max_key_size_ * per_frame_bandwidth|. Take middle point/average |
| 328 // as reference for mismatch. Note key frames always correspond to base | 286 // as reference for mismatch. Note key frames always correspond to base |
| 329 // layer frame in this test. | 287 // layer frame in this test. |
| 330 target_size_key_frame_ = 0.5 * (3 + max_key_size) * per_frame_bandwidth_[0]; | 288 target_size_key_frame_ = 0.5 * (3 + max_key_size) * per_frame_bandwidth_[0]; |
| 331 num_frames_total_ = 0; | 289 num_frames_total_ = 0; |
| 332 sum_encoded_frame_size_total_ = 0.0f; | 290 sum_encoded_frame_size_total_ = 0.0f; |
| 333 encoding_bitrate_total_ = 0.0f; | 291 encoding_bitrate_total_ = 0.0f; |
| 334 perc_encoding_rate_mismatch_ = 0.0f; | 292 perc_encoding_rate_mismatch_ = 0.0f; |
| 335 num_frames_to_hit_target_ = num_frames_to_hit_target; | 293 num_frames_to_hit_target_ = num_frames_to_hit_target; |
| 336 encoding_rate_within_target_ = false; | 294 encoding_rate_within_target_ = false; |
| 337 sum_key_frame_size_mismatch_ = 0.0; | 295 sum_key_frame_size_mismatch_ = 0.0; |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 447 | 405 |
| 448 void VerifyQuality(const test::QualityMetricsResult& psnr_result, | 406 void VerifyQuality(const test::QualityMetricsResult& psnr_result, |
| 449 const test::QualityMetricsResult& ssim_result, | 407 const test::QualityMetricsResult& ssim_result, |
| 450 const QualityThresholds& quality_thresholds) { | 408 const QualityThresholds& quality_thresholds) { |
| 451 EXPECT_GT(psnr_result.average, quality_thresholds.min_avg_psnr); | 409 EXPECT_GT(psnr_result.average, quality_thresholds.min_avg_psnr); |
| 452 EXPECT_GT(psnr_result.min, quality_thresholds.min_min_psnr); | 410 EXPECT_GT(psnr_result.min, quality_thresholds.min_min_psnr); |
| 453 EXPECT_GT(ssim_result.average, quality_thresholds.min_avg_ssim); | 411 EXPECT_GT(ssim_result.average, quality_thresholds.min_avg_ssim); |
| 454 EXPECT_GT(ssim_result.min, quality_thresholds.min_min_ssim); | 412 EXPECT_GT(ssim_result.min, quality_thresholds.min_min_ssim); |
| 455 } | 413 } |
| 456 | 414 |
| 457 void VerifyQpParser(const ProcessParams& process, int frame_number) { | 415 void VerifyQpParser(int frame_number) { |
| 458 if (!process.hw_codec && | 416 if (!config_.hw_codec && |
| 459 (config_.codec_settings->codecType == kVideoCodecVP8 || | 417 (config_.codec_settings->codecType == kVideoCodecVP8 || |
| 460 config_.codec_settings->codecType == kVideoCodecVP9)) { | 418 config_.codec_settings->codecType == kVideoCodecVP9)) { |
| 461 EXPECT_EQ(processor_->GetQpFromEncoder(frame_number), | 419 EXPECT_EQ(processor_->GetQpFromEncoder(frame_number), |
| 462 processor_->GetQpFromBitstream(frame_number)); | 420 processor_->GetQpFromBitstream(frame_number)); |
| 463 } | 421 } |
| 464 } | 422 } |
| 465 | 423 |
| 466 int NumberOfTemporalLayers(const VideoCodec* codec_settings) { | 424 int NumberOfTemporalLayers(const VideoCodec* codec_settings) { |
| 467 if (codec_settings->codecType == kVideoCodecVP8) { | 425 if (codec_settings->codecType == kVideoCodecVP8) { |
| 468 return codec_settings->VP8().numberOfTemporalLayers; | 426 return codec_settings->VP8().numberOfTemporalLayers; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 if (num_temporal_layers_ == 3) { | 482 if (num_temporal_layers_ == 3) { |
| 525 frame_rate_layer_[2] = frame_rate_ / 2.0f; | 483 frame_rate_layer_[2] = frame_rate_ / 2.0f; |
| 526 } | 484 } |
| 527 } | 485 } |
| 528 | 486 |
| 529 // Processes all frames in the clip and verifies the result. | 487 // Processes all frames in the clip and verifies the result. |
| 530 // TODO(brandtr): Change the second last argument to be a | 488 // TODO(brandtr): Change the second last argument to be a |
| 531 // const std::vector<RateControlThresholds>&, so we can ensure that the user | 489 // const std::vector<RateControlThresholds>&, so we can ensure that the user |
| 532 // does not expect us to do mid-clip rate updates when we are not able to, | 490 // does not expect us to do mid-clip rate updates when we are not able to, |
| 533 // e.g., when we are operating in batch mode. | 491 // e.g., when we are operating in batch mode. |
| 534 void ProcessFramesAndVerify(QualityThresholds quality_thresholds, | 492 void ProcessFramesAndVerify(const QualityThresholds& quality_thresholds, |
| 535 RateProfile rate_profile, | 493 const RateProfile& rate_profile, |
| 536 ProcessParams process, | |
| 537 RateControlThresholds* rc_thresholds, | 494 RateControlThresholds* rc_thresholds, |
| 538 const VisualizationParams* visualization_params) { | 495 const VisualizationParams* visualization_params) { |
| 539 // Codec/config settings. | 496 // Codec/config settings. |
| 540 RTC_CHECK(config_.codec_settings); | 497 RTC_CHECK(config_.codec_settings); |
| 541 num_temporal_layers_ = NumberOfTemporalLayers(config_.codec_settings); | 498 num_temporal_layers_ = NumberOfTemporalLayers(config_.codec_settings); |
| 542 config_.codec_settings->startBitrate = rate_profile.target_bit_rate[0]; | 499 config_.codec_settings->startBitrate = rate_profile.target_bit_rate[0]; |
| 543 start_frame_rate_ = rate_profile.input_frame_rate[0]; | 500 start_frame_rate_ = rate_profile.input_frame_rate[0]; |
| 544 SetUpCodecConfig(process, visualization_params); | 501 SetUpObjects(visualization_params); |
| 545 // Update the temporal layers and the codec with the initial rates. | 502 // Update the temporal layers and the codec with the initial rates. |
| 546 bit_rate_ = rate_profile.target_bit_rate[0]; | 503 bit_rate_ = rate_profile.target_bit_rate[0]; |
| 547 frame_rate_ = rate_profile.input_frame_rate[0]; | 504 frame_rate_ = rate_profile.input_frame_rate[0]; |
| 548 SetTemporalLayerRates(); | 505 SetTemporalLayerRates(); |
| 549 // Set the initial target size for key frame. | 506 // Set the initial target size for key frame. |
| 550 target_size_key_frame_initial_ = | 507 target_size_key_frame_initial_ = |
| 551 0.5 * kInitialBufferSize * bit_rate_layer_[0]; | 508 0.5 * kInitialBufferSize * bit_rate_layer_[0]; |
| 552 processor_->SetRates(bit_rate_, frame_rate_); | 509 processor_->SetRates(bit_rate_, frame_rate_); |
| 553 | 510 |
| 554 // Process each frame, up to |num_frames|. | 511 // Process each frame, up to |num_frames|. |
| 555 int frame_number = 0; | 512 int frame_number = 0; |
| 556 int update_index = 0; | 513 int update_index = 0; |
| 557 int num_frames = rate_profile.num_frames; | 514 int num_frames = rate_profile.num_frames; |
| 558 ResetRateControlMetrics( | 515 ResetRateControlMetrics( |
| 559 rate_profile.frame_index_rate_update[update_index + 1]); | 516 rate_profile.frame_index_rate_update[update_index + 1]); |
| 560 | 517 |
| 561 if (process.batch_mode) { | 518 if (config_.batch_mode) { |
| 562 // In batch mode, we calculate the metrics for all frames after all frames | 519 // In batch mode, we calculate the metrics for all frames after all frames |
| 563 // have been sent for encoding. | 520 // have been sent for encoding. |
| 564 | 521 |
| 565 // TODO(brandtr): Refactor "frame number accounting" so we don't have to | 522 // TODO(brandtr): Refactor "frame number accounting" so we don't have to |
| 566 // call ProcessFrame num_frames+1 times here. | 523 // call ProcessFrame num_frames+1 times here. |
| 567 for (frame_number = 0; frame_number <= num_frames; ++frame_number) { | 524 for (frame_number = 0; frame_number <= num_frames; ++frame_number) { |
| 568 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); | 525 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); |
| 569 } | 526 } |
| 570 | 527 |
| 571 for (frame_number = 0; frame_number < num_frames; ++frame_number) { | 528 for (frame_number = 0; frame_number < num_frames; ++frame_number) { |
| 572 ++num_frames_per_update_[TemporalLayerIndexForFrame(frame_number)]; | 529 ++num_frames_per_update_[TemporalLayerIndexForFrame(frame_number)]; |
| 573 ++num_frames_total_; | 530 ++num_frames_total_; |
| 574 UpdateRateControlMetrics(frame_number); | 531 UpdateRateControlMetrics(frame_number); |
| 575 } | 532 } |
| 576 } else { | 533 } else { |
| 577 // In online mode, we calculate the metrics for a given frame right after | 534 // In online mode, we calculate the metrics for a given frame right after |
| 578 // it has been sent for encoding. | 535 // it has been sent for encoding. |
| 579 | 536 |
| 580 if (process.hw_codec) { | 537 if (config_.hw_codec) { |
| 581 LOG(LS_WARNING) << "HW codecs should mostly be run in batch mode, " | 538 LOG(LS_WARNING) << "HW codecs should mostly be run in batch mode, " |
| 582 "since they may be pipelining."; | 539 "since they may be pipelining."; |
| 583 } | 540 } |
| 584 | 541 |
| 585 while (frame_number < num_frames) { | 542 while (frame_number < num_frames) { |
| 586 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); | 543 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); |
| 587 VerifyQpParser(process, frame_number); | 544 VerifyQpParser(frame_number); |
| 588 ++num_frames_per_update_[TemporalLayerIndexForFrame(frame_number)]; | 545 ++num_frames_per_update_[TemporalLayerIndexForFrame(frame_number)]; |
| 589 ++num_frames_total_; | 546 ++num_frames_total_; |
| 590 UpdateRateControlMetrics(frame_number); | 547 UpdateRateControlMetrics(frame_number); |
| 591 | 548 |
| 592 ++frame_number; | 549 ++frame_number; |
| 593 | 550 |
| 594 // If we hit another/next update, verify stats for current state and | 551 // If we hit another/next update, verify stats for current state and |
| 595 // update layers and codec with new rates. | 552 // update layers and codec with new rates. |
| 596 if (frame_number == | 553 if (frame_number == |
| 597 rate_profile.frame_index_rate_update[update_index + 1]) { | 554 rate_profile.frame_index_rate_update[update_index + 1]) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 649 ssim_result.min); | 606 ssim_result.min); |
| 650 VerifyQuality(psnr_result, ssim_result, quality_thresholds); | 607 VerifyQuality(psnr_result, ssim_result, quality_thresholds); |
| 651 stats_.PrintSummary(); | 608 stats_.PrintSummary(); |
| 652 | 609 |
| 653 // Remove analysis file. | 610 // Remove analysis file. |
| 654 if (remove(config_.output_filename.c_str()) < 0) { | 611 if (remove(config_.output_filename.c_str()) < 0) { |
| 655 fprintf(stderr, "Failed to remove temporary file!\n"); | 612 fprintf(stderr, "Failed to remove temporary file!\n"); |
| 656 } | 613 } |
| 657 } | 614 } |
| 658 | 615 |
| 616 static void SetProcessParams(test::TestConfig* config, |
| 617 bool hw_codec, |
| 618 bool use_single_core, |
| 619 float packet_loss_probability, |
| 620 int key_frame_interval, |
| 621 std::string filename, |
| 622 bool verbose_logging, |
| 623 bool batch_mode) { |
| 624 // Configure input filename. |
| 625 config->filename = filename; |
| 626 config->input_filename = test::ResourcePath(filename, "yuv"); |
| 627 // Generate an output filename in a safe way. |
| 628 config->output_filename = test::TempFilename( |
| 629 test::OutputPath(), "videoprocessor_integrationtest"); |
| 630 config->hw_codec = hw_codec; |
| 631 config->use_single_core = use_single_core; |
| 632 config->keyframe_interval = key_frame_interval; |
| 633 config->networking_config.packet_loss_probability = packet_loss_probability; |
| 634 config->verbose = verbose_logging; |
| 635 config->batch_mode = batch_mode; |
| 636 } |
| 637 |
| 659 static void SetCodecSettings(test::TestConfig* config, | 638 static void SetCodecSettings(test::TestConfig* config, |
| 660 VideoCodec* codec_settings, | 639 VideoCodec* codec_settings, |
| 661 VideoCodecType codec_type, | 640 VideoCodecType codec_type, |
| 662 int num_temporal_layers, | 641 int num_temporal_layers, |
| 663 bool error_concealment_on, | 642 bool error_concealment_on, |
| 664 bool denoising_on, | 643 bool denoising_on, |
| 665 bool frame_dropper_on, | 644 bool frame_dropper_on, |
| 666 bool spatial_resize_on, | 645 bool spatial_resize_on, |
| 667 bool resilience_on, | 646 bool resilience_on, |
| 668 int width, | 647 int width, |
| (...skipping 26 matching lines...) Expand all Loading... |
| 695 num_temporal_layers; | 674 num_temporal_layers; |
| 696 config->codec_settings->VP9()->frameDroppingOn = frame_dropper_on; | 675 config->codec_settings->VP9()->frameDroppingOn = frame_dropper_on; |
| 697 config->codec_settings->VP9()->automaticResizeOn = spatial_resize_on; | 676 config->codec_settings->VP9()->automaticResizeOn = spatial_resize_on; |
| 698 config->codec_settings->VP9()->keyFrameInterval = kBaseKeyFrameInterval; | 677 config->codec_settings->VP9()->keyFrameInterval = kBaseKeyFrameInterval; |
| 699 config->codec_settings->VP9()->resilienceOn = resilience_on; | 678 config->codec_settings->VP9()->resilienceOn = resilience_on; |
| 700 break; | 679 break; |
| 701 default: | 680 default: |
| 702 RTC_NOTREACHED(); | 681 RTC_NOTREACHED(); |
| 703 break; | 682 break; |
| 704 } | 683 } |
| 705 } | |
| 706 | 684 |
| 707 static void SetQualityThresholds(QualityThresholds* quality_thresholds, | 685 config->frame_length_in_bytes = |
| 708 double min_avg_psnr, | 686 CalcBufferSize(VideoType::kI420, width, height); |
| 709 double min_min_psnr, | |
| 710 double min_avg_ssim, | |
| 711 double min_min_ssim) { | |
| 712 quality_thresholds->min_avg_psnr = min_avg_psnr; | |
| 713 quality_thresholds->min_min_psnr = min_min_psnr; | |
| 714 quality_thresholds->min_avg_ssim = min_avg_ssim; | |
| 715 quality_thresholds->min_min_ssim = min_min_ssim; | |
| 716 } | 687 } |
| 717 | 688 |
| 718 static void SetRateProfile(RateProfile* rate_profile, | 689 static void SetRateProfile(RateProfile* rate_profile, |
| 719 int update_index, | 690 int update_index, |
| 720 int bit_rate, | 691 int bit_rate, |
| 721 int frame_rate, | 692 int frame_rate, |
| 722 int frame_index_rate_update) { | 693 int frame_index_rate_update) { |
| 723 rate_profile->target_bit_rate[update_index] = bit_rate; | 694 rate_profile->target_bit_rate[update_index] = bit_rate; |
| 724 rate_profile->input_frame_rate[update_index] = frame_rate; | 695 rate_profile->input_frame_rate[update_index] = frame_rate; |
| 725 rate_profile->frame_index_rate_update[update_index] = | 696 rate_profile->frame_index_rate_update[update_index] = |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 792 int start_frame_rate_; | 763 int start_frame_rate_; |
| 793 | 764 |
| 794 // Codec and network settings. | 765 // Codec and network settings. |
| 795 int num_temporal_layers_; | 766 int num_temporal_layers_; |
| 796 }; | 767 }; |
| 797 | 768 |
| 798 } // namespace test | 769 } // namespace test |
| 799 } // namespace webrtc | 770 } // namespace webrtc |
| 800 | 771 |
| 801 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES
T_H_ | 772 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES
T_H_ |
| OLD | NEW |