Index: webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.h |
diff --git a/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.h b/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.h |
index ceaf7cef94b3288d765d0fb16fe52e777d2ab570..68fe68e7108764e391730c86c88ec841569866b1 100644 |
--- a/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.h |
+++ b/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.h |
@@ -53,6 +53,9 @@ namespace test { |
// and/or frame rate) for the current tests. |
const int kMaxNumRateUpdates = 3; |
+// Maximum number of temporal layers to use in tests. |
+const int kMaxNumTemporalLayers = 3; |
+ |
const int kPercTargetvsActualMismatch = 20; |
const int kBaseKeyFrameInterval = 3000; |
@@ -157,16 +160,15 @@ class VideoProcessorIntegrationTest : public testing::Test { |
} |
virtual ~VideoProcessorIntegrationTest() = default; |
- void SetUpCodecConfig(const CodecParams& process, |
- const VisualizationParams* visualization_params) { |
- if (process.hw_codec) { |
+ void CreateEncoderAndDecoder(bool hw_codec, VideoCodecType codec_type) { |
+ if (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 |
// allocated them. For the particular case of the Android |
// MediaCodecVideo{En,De}coderFactory's, however, it turns out that it is |
// fine for the std::unique_ptr to destroy the owned codec directly. |
- switch (process.codec_type) { |
+ switch (codec_type) { |
case kVideoCodecH264: |
encoder_.reset(external_encoder_factory_->CreateVideoEncoder( |
cricket::VideoCodec(cricket::kH264CodecName))); |
@@ -190,7 +192,7 @@ class VideoProcessorIntegrationTest : public testing::Test { |
break; |
} |
#elif defined(WEBRTC_IOS) |
- ASSERT_EQ(kVideoCodecH264, process.codec_type) |
+ ASSERT_EQ(kVideoCodecH264, codec_type) |
<< "iOS HW codecs only support H264."; |
encoder_.reset(new H264VideoToolboxEncoder( |
cricket::VideoCodec(cricket::kH264CodecName))); |
@@ -201,29 +203,33 @@ class VideoProcessorIntegrationTest : public testing::Test { |
#endif // WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED |
RTC_CHECK(encoder_) << "HW encoder not successfully created."; |
RTC_CHECK(decoder_) << "HW decoder not successfully created."; |
- } else { |
- // SW codecs. |
- switch (process.codec_type) { |
- case kVideoCodecH264: |
- encoder_.reset(H264Encoder::Create( |
- cricket::VideoCodec(cricket::kH264CodecName))); |
- decoder_.reset(H264Decoder::Create()); |
- break; |
- case kVideoCodecVP8: |
- encoder_.reset(VP8Encoder::Create()); |
- decoder_.reset(VP8Decoder::Create()); |
- break; |
- case kVideoCodecVP9: |
- encoder_.reset(VP9Encoder::Create()); |
- decoder_.reset(VP9Decoder::Create()); |
- break; |
- default: |
- RTC_NOTREACHED(); |
- break; |
- } |
+ return; |
} |
- VideoCodingModule::Codec(process.codec_type, &codec_settings_); |
+ // SW codecs. |
+ switch (codec_type) { |
+ case kVideoCodecH264: |
+ encoder_.reset( |
+ H264Encoder::Create(cricket::VideoCodec(cricket::kH264CodecName))); |
+ decoder_.reset(H264Decoder::Create()); |
+ break; |
+ case kVideoCodecVP8: |
+ encoder_.reset(VP8Encoder::Create()); |
+ decoder_.reset(VP8Decoder::Create()); |
+ break; |
+ case kVideoCodecVP9: |
+ encoder_.reset(VP9Encoder::Create()); |
+ decoder_.reset(VP9Decoder::Create()); |
+ break; |
+ default: |
+ RTC_NOTREACHED(); |
+ break; |
+ } |
+ } |
+ |
+ void SetUpCodecConfig(const CodecParams& process, |
+ const VisualizationParams* visualization_params) { |
+ CreateEncoderAndDecoder(process.hw_codec, process.codec_type); |
// Configure input filename. |
config_.input_filename = test::ResourcePath(process.filename, "yuv"); |
@@ -232,6 +238,7 @@ class VideoProcessorIntegrationTest : public testing::Test { |
// Generate an output filename in a safe way. |
config_.output_filename = test::TempFilename( |
test::OutputPath(), "videoprocessor_integrationtest"); |
+ |
config_.frame_length_in_bytes = |
CalcBufferSize(kI420, process.width, process.height); |
config_.verbose = process.verbose_logging; |
@@ -242,6 +249,7 @@ class VideoProcessorIntegrationTest : public testing::Test { |
packet_loss_probability_; |
// Configure codec settings. |
+ VideoCodingModule::Codec(process.codec_type, &codec_settings_); |
config_.codec_settings = &codec_settings_; |
config_.codec_settings->startBitrate = start_bitrate_; |
config_.codec_settings->width = process.width; |
@@ -400,13 +408,7 @@ class VideoProcessorIntegrationTest : public testing::Test { |
// Verify expected behavior of rate control and print out data. |
void VerifyRateControlMetrics(int update_index, |
- int max_key_frame_size_mismatch, |
- int max_delta_frame_size_mismatch, |
- int max_encoding_rate_mismatch, |
- int max_time_hit_target, |
- int max_num_dropped_frames, |
- int num_spatial_resizes, |
- int num_key_frames) { |
+ const RateControlThresholds& rc_expected) { |
int num_dropped_frames = processor_->NumberDroppedFrames(); |
int num_resize_actions = processor_->NumberSpatialResizes(); |
printf( |
@@ -420,7 +422,8 @@ class VideoProcessorIntegrationTest : public testing::Test { |
" Number of dropped frames: %d, \n" |
" Number of spatial resizes: %d, \n", |
num_frames_to_hit_target_, num_dropped_frames, num_resize_actions); |
- EXPECT_LE(perc_encoding_rate_mismatch_, max_encoding_rate_mismatch); |
+ EXPECT_LE(perc_encoding_rate_mismatch_, |
+ rc_expected.max_encoding_rate_mismatch); |
if (num_key_frames_ > 0) { |
int perc_key_frame_size_mismatch = |
100 * sum_key_frame_size_mismatch_ / num_key_frames_; |
@@ -428,7 +431,8 @@ class VideoProcessorIntegrationTest : public testing::Test { |
" Number of Key frames: %d \n" |
" Key frame rate mismatch: %d \n", |
num_key_frames_, perc_key_frame_size_mismatch); |
- EXPECT_LE(perc_key_frame_size_mismatch, max_key_frame_size_mismatch); |
+ EXPECT_LE(perc_key_frame_size_mismatch, |
+ rc_expected.max_key_frame_size_mismatch); |
} |
printf("\n"); |
printf("Rates statistics for Layer data \n"); |
@@ -450,14 +454,16 @@ class VideoProcessorIntegrationTest : public testing::Test { |
bit_rate_layer_[i], frame_rate_layer_[i], per_frame_bandwidth_[i], |
encoding_bitrate_[i], perc_frame_size_mismatch, |
perc_encoding_rate_mismatch, num_frames_per_update_[i]); |
- EXPECT_LE(perc_frame_size_mismatch, max_delta_frame_size_mismatch); |
- EXPECT_LE(perc_encoding_rate_mismatch, max_encoding_rate_mismatch); |
+ EXPECT_LE(perc_frame_size_mismatch, |
+ rc_expected.max_delta_frame_size_mismatch); |
+ EXPECT_LE(perc_encoding_rate_mismatch, |
+ rc_expected.max_encoding_rate_mismatch); |
} |
printf("\n"); |
- EXPECT_LE(num_frames_to_hit_target_, max_time_hit_target); |
- EXPECT_LE(num_dropped_frames, max_num_dropped_frames); |
- EXPECT_EQ(num_resize_actions, num_spatial_resizes); |
- EXPECT_EQ(num_key_frames_, num_key_frames); |
+ EXPECT_LE(num_frames_to_hit_target_, rc_expected.max_time_hit_target); |
+ EXPECT_LE(num_dropped_frames, rc_expected.max_num_dropped_frames); |
+ EXPECT_EQ(rc_expected.num_spatial_resizes, num_resize_actions); |
+ EXPECT_EQ(rc_expected.num_key_frames, num_key_frames_); |
} |
void VerifyQuality(const test::QualityMetricsResult& psnr_result, |
@@ -470,36 +476,40 @@ class VideoProcessorIntegrationTest : public testing::Test { |
} |
// Layer index corresponding to frame number, for up to 3 layers. |
- void LayerIndexForFrame(int frame_number) { |
- if (num_temporal_layers_ == 1) { |
- layer_ = 0; |
- } else if (num_temporal_layers_ == 2) { |
- // layer 0: 0 2 4 ... |
- // layer 1: 1 3 |
- if (frame_number % 2 == 0) { |
- layer_ = 0; |
- } else { |
- layer_ = 1; |
- } |
- } else if (num_temporal_layers_ == 3) { |
- // layer 0: 0 4 8 ... |
- // layer 1: 2 6 |
- // layer 2: 1 3 5 7 |
- if (frame_number % 4 == 0) { |
- layer_ = 0; |
- } else if ((frame_number + 2) % 4 == 0) { |
- layer_ = 1; |
- } else if ((frame_number + 1) % 2 == 0) { |
- layer_ = 2; |
- } |
- } else { |
- RTC_NOTREACHED() << "Max 3 layers are supported."; |
+ int LayerIndexForFrame(int frame_number) { |
+ int layer = -1; |
+ switch (num_temporal_layers_) { |
+ case 1: |
+ layer = 0; |
+ break; |
+ case 2: |
+ // layer 0: 0 2 4 ... |
+ // layer 1: 1 3 |
+ layer = (frame_number % 2 == 0) ? 0 : 1; |
+ break; |
+ case 3: |
+ // layer 0: 0 4 8 ... |
+ // layer 1: 2 6 |
+ // layer 2: 1 3 5 7 |
+ if (frame_number % 4 == 0) { |
+ layer = 0; |
+ } else if ((frame_number + 2) % 4 == 0) { |
+ layer = 1; |
+ } else if ((frame_number + 1) % 2 == 0) { |
+ layer = 2; |
+ } |
+ break; |
+ default: |
+ RTC_NOTREACHED(); |
+ break; |
} |
+ |
+ return layer; |
} |
// Set the bitrate and frame rate per layer, for up to 3 layers. |
void SetLayerRates() { |
- RTC_DCHECK_LE(num_temporal_layers_, 3); |
+ RTC_DCHECK_LE(num_temporal_layers_, kMaxNumTemporalLayers); |
for (int i = 0; i < num_temporal_layers_; i++) { |
float bit_rate_ratio = |
kVp8LayerRateAlloction[num_temporal_layers_ - 1][i]; |
@@ -550,7 +560,7 @@ class VideoProcessorIntegrationTest : public testing::Test { |
while (processor_->ProcessFrame(frame_number) && |
frame_number < num_frames) { |
// Get the layer index for the frame |frame_number|. |
- LayerIndexForFrame(frame_number); |
+ layer_ = LayerIndexForFrame(frame_number); |
// Get the frame_type. |
frame_type = processor_->EncodedFrameType(); |
// Counter for whole sequence run. |
@@ -563,15 +573,7 @@ class VideoProcessorIntegrationTest : public testing::Test { |
// update layers and codec with new rates. |
if (frame_number == |
rate_profile.frame_index_rate_update[update_index + 1]) { |
- VerifyRateControlMetrics( |
- update_index, |
- rc_thresholds[update_index].max_key_frame_size_mismatch, |
- rc_thresholds[update_index].max_delta_frame_size_mismatch, |
- rc_thresholds[update_index].max_encoding_rate_mismatch, |
- rc_thresholds[update_index].max_time_hit_target, |
- rc_thresholds[update_index].max_num_dropped_frames, |
- rc_thresholds[update_index].num_spatial_resizes, |
- rc_thresholds[update_index].num_key_frames); |
+ VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); |
// Update layer rates and the codec with new rates. |
++update_index; |
bit_rate_ = rate_profile.target_bit_rate[update_index]; |
@@ -582,14 +584,7 @@ class VideoProcessorIntegrationTest : public testing::Test { |
processor_->SetRates(bit_rate_, frame_rate_); |
} |
} |
- VerifyRateControlMetrics( |
- update_index, rc_thresholds[update_index].max_key_frame_size_mismatch, |
- rc_thresholds[update_index].max_delta_frame_size_mismatch, |
- rc_thresholds[update_index].max_encoding_rate_mismatch, |
- rc_thresholds[update_index].max_time_hit_target, |
- rc_thresholds[update_index].max_num_dropped_frames, |
- rc_thresholds[update_index].num_spatial_resizes, |
- rc_thresholds[update_index].num_key_frames); |
+ VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); |
EXPECT_EQ(num_frames, frame_number); |
EXPECT_EQ(num_frames + 1, static_cast<int>(stats_.stats_.size())); |
@@ -622,8 +617,8 @@ class VideoProcessorIntegrationTest : public testing::Test { |
printf("PSNR avg: %f, min: %f\nSSIM avg: %f, min: %f\n", |
psnr_result.average, psnr_result.min, ssim_result.average, |
ssim_result.min); |
- stats_.PrintSummary(); |
VerifyQuality(psnr_result, ssim_result, quality_thresholds); |
+ stats_.PrintSummary(); |
// Remove analysis file. |
if (remove(config_.output_filename.c_str()) < 0) { |
@@ -746,14 +741,13 @@ class VideoProcessorIntegrationTest : public testing::Test { |
std::unique_ptr<test::FrameWriter> decoded_frame_writer_; |
// Quantities defined/updated for every encoder rate update. |
- // Some quantities defined per temporal layer (at most 3 layers in this test). |
- int num_frames_per_update_[3]; |
- float sum_frame_size_mismatch_[3]; |
- float sum_encoded_frame_size_[3]; |
- float encoding_bitrate_[3]; |
- float per_frame_bandwidth_[3]; |
- float bit_rate_layer_[3]; |
- float frame_rate_layer_[3]; |
+ int num_frames_per_update_[kMaxNumTemporalLayers]; |
+ float sum_frame_size_mismatch_[kMaxNumTemporalLayers]; |
+ float sum_encoded_frame_size_[kMaxNumTemporalLayers]; |
+ float encoding_bitrate_[kMaxNumTemporalLayers]; |
+ float per_frame_bandwidth_[kMaxNumTemporalLayers]; |
+ float bit_rate_layer_[kMaxNumTemporalLayers]; |
+ float frame_rate_layer_[kMaxNumTemporalLayers]; |
int num_frames_total_; |
float sum_encoded_frame_size_total_; |
float encoding_bitrate_total_; |