Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / video_coding / codecs / test / videoprocessor_integrationtest.cc
1 /*
2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3  *
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
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10
11 #include <math.h>
12
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 #include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h"
16 #include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h"
17 #include "webrtc/modules/video_coding/codecs/test/videoprocessor.h"
18 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
19 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h"
20 #include "webrtc/modules/video_coding/main/interface/video_coding.h"
21 #include "webrtc/test/testsupport/fileutils.h"
22 #include "webrtc/test/testsupport/frame_reader.h"
23 #include "webrtc/test/testsupport/frame_writer.h"
24 #include "webrtc/test/testsupport/gtest_disable.h"
25 #include "webrtc/test/testsupport/metrics/video_metrics.h"
26 #include "webrtc/test/testsupport/packet_reader.h"
27 #include "webrtc/typedefs.h"
28
29 namespace webrtc {
30
31 // Maximum number of rate updates (i.e., calls to encoder to change bitrate
32 // and/or frame rate) for the current tests.
33 const int kMaxNumRateUpdates = 3;
34
35 const int kPercTargetvsActualMismatch = 20;
36 const int kBaseKeyFrameInterval = 3000;
37
38 // Codec and network settings.
39 struct CodecConfigPars {
40   float packet_loss;
41   int num_temporal_layers;
42   int key_frame_interval;
43   bool error_concealment_on;
44   bool denoising_on;
45   bool frame_dropper_on;
46   bool spatial_resize_on;
47 };
48
49 // Quality metrics.
50 struct QualityMetrics {
51   double minimum_avg_psnr;
52   double minimum_min_psnr;
53   double minimum_avg_ssim;
54   double minimum_min_ssim;
55 };
56
57 // The sequence of bitrate and frame rate changes for the encoder, the frame
58 // number where the changes are made, and the total number of frames for the
59 // test.
60 struct RateProfile {
61   int target_bit_rate[kMaxNumRateUpdates];
62   int input_frame_rate[kMaxNumRateUpdates];
63   int frame_index_rate_update[kMaxNumRateUpdates + 1];
64   int num_frames;
65 };
66
67 // Metrics for the rate control. The rate mismatch metrics are defined as
68 // percentages.|max_time_hit_target| is defined as number of frames, after a
69 // rate update is made to the encoder, for the encoder to reach within
70 // |kPercTargetvsActualMismatch| of new target rate. The metrics are defined for
71 // each rate update sequence.
72 struct RateControlMetrics {
73   int max_num_dropped_frames;
74   int max_key_frame_size_mismatch;
75   int max_delta_frame_size_mismatch;
76   int max_encoding_rate_mismatch;
77   int max_time_hit_target;
78   int num_spatial_resizes;
79 };
80
81
82 // Sequence used is foreman (CIF): may be better to use VGA for resize test.
83 const int kCIFWidth = 352;
84 const int kCIFHeight = 288;
85 const int kNbrFramesShort = 100;  // Some tests are run for shorter sequence.
86 const int kNbrFramesLong = 299;
87
88 // Parameters from VP8 wrapper, which control target size of key frames.
89 const float kInitialBufferSize = 0.5f;
90 const float kOptimalBufferSize = 0.6f;
91 const float kScaleKeyFrameSize = 0.5f;
92
93 // Integration test for video processor. Encodes+decodes a clip and
94 // writes it to the output directory. After completion, quality metrics
95 // (PSNR and SSIM) and rate control metrics are computed to verify that the
96 // quality and encoder response is acceptable. The rate control tests allow us
97 // to verify the behavior for changing bitrate, changing frame rate, frame
98 // dropping/spatial resize, and temporal layers. The limits for the rate
99 // control metrics are set to be fairly conservative, so failure should only
100 // happen when some significant regression or breakdown occurs.
101 class VideoProcessorIntegrationTest: public testing::Test {
102  protected:
103   VideoEncoder* encoder_;
104   VideoDecoder* decoder_;
105   webrtc::test::FrameReader* frame_reader_;
106   webrtc::test::FrameWriter* frame_writer_;
107   webrtc::test::PacketReader packet_reader_;
108   webrtc::test::PacketManipulator* packet_manipulator_;
109   webrtc::test::Stats stats_;
110   webrtc::test::TestConfig config_;
111   VideoCodec codec_settings_;
112   webrtc::test::VideoProcessor* processor_;
113
114   // Quantities defined/updated for every encoder rate update.
115   // Some quantities defined per temporal layer (at most 3 layers in this test).
116   int num_frames_per_update_[3];
117   float sum_frame_size_mismatch_[3];
118   float sum_encoded_frame_size_[3];
119   float encoding_bitrate_[3];
120   float per_frame_bandwidth_[3];
121   float bit_rate_layer_[3];
122   float frame_rate_layer_[3];
123   int num_frames_total_;
124   float sum_encoded_frame_size_total_;
125   float encoding_bitrate_total_;
126   float perc_encoding_rate_mismatch_;
127   int num_frames_to_hit_target_;
128   bool encoding_rate_within_target_;
129   int bit_rate_;
130   int frame_rate_;
131   int layer_;
132   float target_size_key_frame_initial_;
133   float target_size_key_frame_;
134   float sum_key_frame_size_mismatch_;
135   int num_key_frames_;
136   float start_bitrate_;
137
138   // Codec and network settings.
139   float packet_loss_;
140   int num_temporal_layers_;
141   int key_frame_interval_;
142   bool error_concealment_on_;
143   bool denoising_on_;
144   bool frame_dropper_on_;
145   bool spatial_resize_on_;
146
147
148   VideoProcessorIntegrationTest() {}
149   virtual ~VideoProcessorIntegrationTest() {}
150
151   void SetUpCodecConfig() {
152     encoder_ = VP8Encoder::Create();
153     decoder_ = VP8Decoder::Create();
154
155     // CIF is currently used for all tests below.
156     // Setup the TestConfig struct for processing of a clip in CIF resolution.
157     config_.input_filename =
158         webrtc::test::ResourcePath("foreman_cif", "yuv");
159
160     // Generate an output filename in a safe way.
161     config_.output_filename = webrtc::test::TempFilename(
162         webrtc::test::OutputPath(), "videoprocessor_integrationtest");
163     config_.frame_length_in_bytes = CalcBufferSize(kI420,
164                                                    kCIFWidth, kCIFHeight);
165     config_.verbose = false;
166     // Only allow encoder/decoder to use single core, for predictability.
167     config_.use_single_core = true;
168     // Key frame interval and packet loss are set for each test.
169     config_.keyframe_interval = key_frame_interval_;
170     config_.networking_config.packet_loss_probability = packet_loss_;
171
172     // Get a codec configuration struct and configure it.
173     VideoCodingModule::Codec(kVideoCodecVP8, &codec_settings_);
174     config_.codec_settings = &codec_settings_;
175     config_.codec_settings->startBitrate = start_bitrate_;
176     config_.codec_settings->width = kCIFWidth;
177     config_.codec_settings->height = kCIFHeight;
178     // These features may be set depending on the test.
179     config_.codec_settings->codecSpecific.VP8.errorConcealmentOn =
180         error_concealment_on_;
181     config_.codec_settings->codecSpecific.VP8.denoisingOn =
182         denoising_on_;
183     config_.codec_settings->codecSpecific.VP8.numberOfTemporalLayers =
184         num_temporal_layers_;
185     config_.codec_settings->codecSpecific.VP8.frameDroppingOn =
186         frame_dropper_on_;
187     config_.codec_settings->codecSpecific.VP8.automaticResizeOn =
188         spatial_resize_on_;
189     config_.codec_settings->codecSpecific.VP8.keyFrameInterval =
190         kBaseKeyFrameInterval;
191
192     frame_reader_ =
193         new webrtc::test::FrameReaderImpl(config_.input_filename,
194                                           config_.frame_length_in_bytes);
195     frame_writer_ =
196         new webrtc::test::FrameWriterImpl(config_.output_filename,
197                                           config_.frame_length_in_bytes);
198     ASSERT_TRUE(frame_reader_->Init());
199     ASSERT_TRUE(frame_writer_->Init());
200
201     packet_manipulator_ = new webrtc::test::PacketManipulatorImpl(
202         &packet_reader_, config_.networking_config, config_.verbose);
203     processor_ = new webrtc::test::VideoProcessorImpl(encoder_, decoder_,
204                                                       frame_reader_,
205                                                       frame_writer_,
206                                                       packet_manipulator_,
207                                                       config_, &stats_);
208     ASSERT_TRUE(processor_->Init());
209   }
210
211   // Reset quantities after each encoder update, update the target
212   // per-frame bandwidth.
213   void ResetRateControlMetrics(int num_frames) {
214     for (int i = 0; i < num_temporal_layers_; i++) {
215       num_frames_per_update_[i] = 0;
216       sum_frame_size_mismatch_[i] = 0.0f;
217       sum_encoded_frame_size_[i] = 0.0f;
218       encoding_bitrate_[i] = 0.0f;
219       // Update layer per-frame-bandwidth.
220       per_frame_bandwidth_[i] = static_cast<float>(bit_rate_layer_[i]) /
221              static_cast<float>(frame_rate_layer_[i]);
222     }
223     // Set maximum size of key frames, following setting in the VP8 wrapper.
224     float max_key_size = kScaleKeyFrameSize * kOptimalBufferSize * frame_rate_;
225     // We don't know exact target size of the key frames (except for first one),
226     // but the minimum in libvpx is ~|3 * per_frame_bandwidth| and maximum is
227     // set by |max_key_size_  * per_frame_bandwidth|. Take middle point/average
228     // as reference for mismatch. Note key frames always correspond to base
229     // layer frame in this test.
230     target_size_key_frame_ = 0.5 * (3 + max_key_size) * per_frame_bandwidth_[0];
231     num_frames_total_ = 0;
232     sum_encoded_frame_size_total_ = 0.0f;
233     encoding_bitrate_total_ = 0.0f;
234     perc_encoding_rate_mismatch_ = 0.0f;
235     num_frames_to_hit_target_ = num_frames;
236     encoding_rate_within_target_ = false;
237     sum_key_frame_size_mismatch_ = 0.0;
238     num_key_frames_ = 0;
239   }
240
241   // For every encoded frame, update the rate control metrics.
242   void UpdateRateControlMetrics(int frame_num, VideoFrameType frame_type) {
243     int encoded_frame_size = processor_->EncodedFrameSize();
244     float encoded_size_kbits = encoded_frame_size * 8.0f / 1000.0f;
245     // Update layer data.
246     // Update rate mismatch relative to per-frame bandwidth for delta frames.
247     if (frame_type == kDeltaFrame) {
248       // TODO(marpan): Should we count dropped (zero size) frames in mismatch?
249       sum_frame_size_mismatch_[layer_] += fabs(encoded_size_kbits -
250                                                per_frame_bandwidth_[layer_]) /
251                                                per_frame_bandwidth_[layer_];
252     } else {
253       float target_size = (frame_num == 1) ? target_size_key_frame_initial_ :
254           target_size_key_frame_;
255       sum_key_frame_size_mismatch_ += fabs(encoded_size_kbits - target_size) /
256           target_size;
257       num_key_frames_ += 1;
258     }
259     sum_encoded_frame_size_[layer_] += encoded_size_kbits;
260     // Encoding bitrate per layer: from the start of the update/run to the
261     // current frame.
262     encoding_bitrate_[layer_] = sum_encoded_frame_size_[layer_] *
263         frame_rate_layer_[layer_] /
264         num_frames_per_update_[layer_];
265     // Total encoding rate: from the start of the update/run to current frame.
266     sum_encoded_frame_size_total_ += encoded_size_kbits;
267     encoding_bitrate_total_ = sum_encoded_frame_size_total_ * frame_rate_ /
268         num_frames_total_;
269     perc_encoding_rate_mismatch_ =  100 * fabs(encoding_bitrate_total_ -
270                                                bit_rate_) / bit_rate_;
271     if (perc_encoding_rate_mismatch_ < kPercTargetvsActualMismatch &&
272         !encoding_rate_within_target_) {
273       num_frames_to_hit_target_ = num_frames_total_;
274       encoding_rate_within_target_ = true;
275     }
276   }
277
278   // Verify expected behavior of rate control and print out data.
279   void VerifyRateControl(int update_index,
280                          int max_key_frame_size_mismatch,
281                          int max_delta_frame_size_mismatch,
282                          int max_encoding_rate_mismatch,
283                          int max_time_hit_target,
284                          int max_num_dropped_frames,
285                          int num_spatial_resizes) {
286     int num_dropped_frames = processor_->NumberDroppedFrames();
287     int num_resize_actions = processor_->NumberSpatialResizes();
288     printf("For update #: %d,\n "
289         " Target Bitrate: %d,\n"
290         " Encoding bitrate: %f,\n"
291         " Frame rate: %d \n",
292         update_index, bit_rate_, encoding_bitrate_total_, frame_rate_);
293     printf(" Number of frames to approach target rate = %d, \n"
294            " Number of dropped frames = %d, \n"
295            " Number of spatial resizes = %d, \n",
296            num_frames_to_hit_target_, num_dropped_frames, num_resize_actions);
297     EXPECT_LE(perc_encoding_rate_mismatch_, max_encoding_rate_mismatch);
298     if (num_key_frames_ > 0) {
299       int perc_key_frame_size_mismatch = 100 * sum_key_frame_size_mismatch_ /
300               num_key_frames_;
301       printf(" Number of Key frames: %d \n"
302              " Key frame rate mismatch: %d \n",
303              num_key_frames_, perc_key_frame_size_mismatch);
304       EXPECT_LE(perc_key_frame_size_mismatch, max_key_frame_size_mismatch);
305     }
306     printf("\n");
307     printf("Rates statistics for Layer data \n");
308     for (int i = 0; i < num_temporal_layers_ ; i++) {
309       printf("Layer #%d \n", i);
310       int perc_frame_size_mismatch = 100 * sum_frame_size_mismatch_[i] /
311         num_frames_per_update_[i];
312       int perc_encoding_rate_mismatch = 100 * fabs(encoding_bitrate_[i] -
313                                                    bit_rate_layer_[i]) /
314                                                    bit_rate_layer_[i];
315       printf(" Target Layer Bit rate: %f \n"
316           " Layer frame rate: %f, \n"
317           " Layer per frame bandwidth: %f, \n"
318           " Layer Encoding bit rate: %f, \n"
319           " Layer Percent frame size mismatch: %d,  \n"
320           " Layer Percent encoding rate mismatch = %d, \n"
321           " Number of frame processed per layer = %d \n",
322           bit_rate_layer_[i], frame_rate_layer_[i], per_frame_bandwidth_[i],
323           encoding_bitrate_[i], perc_frame_size_mismatch,
324           perc_encoding_rate_mismatch, num_frames_per_update_[i]);
325       EXPECT_LE(perc_frame_size_mismatch, max_delta_frame_size_mismatch);
326       EXPECT_LE(perc_encoding_rate_mismatch, max_encoding_rate_mismatch);
327     }
328     printf("\n");
329     EXPECT_LE(num_frames_to_hit_target_, max_time_hit_target);
330     EXPECT_LE(num_dropped_frames, max_num_dropped_frames);
331     EXPECT_EQ(num_resize_actions, num_spatial_resizes);
332   }
333
334   // Layer index corresponding to frame number, for up to 3 layers.
335   void LayerIndexForFrame(int frame_number) {
336     if (num_temporal_layers_ == 1) {
337       layer_ = 0;
338     } else if (num_temporal_layers_ == 2) {
339         // layer 0:  0     2     4 ...
340         // layer 1:     1     3
341         if (frame_number % 2 == 0) {
342           layer_ = 0;
343         } else {
344           layer_ = 1;
345         }
346     } else if (num_temporal_layers_ == 3) {
347       // layer 0:  0            4            8 ...
348       // layer 1:        2            6
349       // layer 2:     1      3     5      7
350       if (frame_number % 4 == 0) {
351         layer_ = 0;
352       } else if ((frame_number + 2) % 4 == 0) {
353         layer_ = 1;
354       } else if ((frame_number + 1) % 2 == 0) {
355         layer_ = 2;
356       }
357     } else {
358       assert(false);  // Only up to 3 layers.
359     }
360   }
361
362   // Set the bitrate and frame rate per layer, for up to 3 layers.
363   void SetLayerRates() {
364     assert(num_temporal_layers_<= 3);
365     for (int i = 0; i < num_temporal_layers_; i++) {
366       float bit_rate_ratio =
367           kVp8LayerRateAlloction[num_temporal_layers_ - 1][i];
368       if (i > 0) {
369         float bit_rate_delta_ratio = kVp8LayerRateAlloction
370             [num_temporal_layers_ - 1][i] -
371             kVp8LayerRateAlloction[num_temporal_layers_ - 1][i - 1];
372         bit_rate_layer_[i] = bit_rate_ * bit_rate_delta_ratio;
373       } else {
374         bit_rate_layer_[i] = bit_rate_ * bit_rate_ratio;
375       }
376       frame_rate_layer_[i] = frame_rate_ / static_cast<float>(
377           1 << (num_temporal_layers_ - 1));
378     }
379     if (num_temporal_layers_ == 3) {
380       frame_rate_layer_[2] = frame_rate_ / 2.0f;
381     }
382   }
383
384   VideoFrameType FrameType(int frame_number) {
385     if (frame_number == 0 || ((frame_number) % key_frame_interval_ == 0 &&
386         key_frame_interval_ > 0)) {
387       return kKeyFrame;
388     } else {
389       return kDeltaFrame;
390     }
391   }
392
393   void TearDown() {
394     delete processor_;
395     delete packet_manipulator_;
396     delete frame_writer_;
397     delete frame_reader_;
398     delete decoder_;
399     delete encoder_;
400   }
401
402   // Processes all frames in the clip and verifies the result.
403   void ProcessFramesAndVerify(QualityMetrics quality_metrics,
404                               RateProfile rate_profile,
405                               CodecConfigPars process,
406                               RateControlMetrics* rc_metrics) {
407     // Codec/config settings.
408     start_bitrate_ = rate_profile.target_bit_rate[0];
409     packet_loss_ = process.packet_loss;
410     key_frame_interval_ = process.key_frame_interval;
411     num_temporal_layers_ = process.num_temporal_layers;
412     error_concealment_on_ = process.error_concealment_on;
413     denoising_on_ = process.denoising_on;
414     frame_dropper_on_ = process.frame_dropper_on;
415     spatial_resize_on_ = process.spatial_resize_on;
416     SetUpCodecConfig();
417     // Update the layers and the codec with the initial rates.
418     bit_rate_ =  rate_profile.target_bit_rate[0];
419     frame_rate_ = rate_profile.input_frame_rate[0];
420     SetLayerRates();
421     // Set the initial target size for key frame.
422     target_size_key_frame_initial_ = 0.5 * kInitialBufferSize *
423         bit_rate_layer_[0];
424     processor_->SetRates(bit_rate_, frame_rate_);
425     // Process each frame, up to |num_frames|.
426     int num_frames = rate_profile.num_frames;
427     int update_index = 0;
428     ResetRateControlMetrics(
429         rate_profile.frame_index_rate_update[update_index + 1]);
430     int frame_number = 0;
431     VideoFrameType frame_type = kDeltaFrame;
432     while (processor_->ProcessFrame(frame_number) &&
433         frame_number < num_frames) {
434       // Get the layer index for the frame |frame_number|.
435       LayerIndexForFrame(frame_number);
436       frame_type = FrameType(frame_number);
437       // Counter for whole sequence run.
438       ++frame_number;
439       // Counters for each rate update.
440       ++num_frames_per_update_[layer_];
441       ++num_frames_total_;
442       UpdateRateControlMetrics(frame_number, frame_type);
443       // If we hit another/next update, verify stats for current state and
444       // update layers and codec with new rates.
445       if (frame_number ==
446           rate_profile.frame_index_rate_update[update_index + 1]) {
447         VerifyRateControl(
448             update_index,
449             rc_metrics[update_index].max_key_frame_size_mismatch,
450             rc_metrics[update_index].max_delta_frame_size_mismatch,
451             rc_metrics[update_index].max_encoding_rate_mismatch,
452             rc_metrics[update_index].max_time_hit_target,
453             rc_metrics[update_index].max_num_dropped_frames,
454             rc_metrics[update_index].num_spatial_resizes);
455         // Update layer rates and the codec with new rates.
456         ++update_index;
457         bit_rate_ =  rate_profile.target_bit_rate[update_index];
458         frame_rate_ = rate_profile.input_frame_rate[update_index];
459         SetLayerRates();
460         ResetRateControlMetrics(rate_profile.
461                                 frame_index_rate_update[update_index + 1]);
462         processor_->SetRates(bit_rate_, frame_rate_);
463       }
464     }
465     VerifyRateControl(
466         update_index,
467         rc_metrics[update_index].max_key_frame_size_mismatch,
468         rc_metrics[update_index].max_delta_frame_size_mismatch,
469         rc_metrics[update_index].max_encoding_rate_mismatch,
470         rc_metrics[update_index].max_time_hit_target,
471         rc_metrics[update_index].max_num_dropped_frames,
472         rc_metrics[update_index].num_spatial_resizes);
473     EXPECT_EQ(num_frames, frame_number);
474     EXPECT_EQ(num_frames + 1, static_cast<int>(stats_.stats_.size()));
475
476     // Release encoder and decoder to make sure they have finished processing:
477     EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());
478     EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release());
479     // Close the files before we start using them for SSIM/PSNR calculations.
480     frame_reader_->Close();
481     frame_writer_->Close();
482
483     // TODO(marpan): should compute these quality metrics per SetRates update.
484     webrtc::test::QualityMetricsResult psnr_result, ssim_result;
485     EXPECT_EQ(0, webrtc::test::I420MetricsFromFiles(
486         config_.input_filename.c_str(),
487         config_.output_filename.c_str(),
488         config_.codec_settings->width,
489         config_.codec_settings->height,
490         &psnr_result,
491         &ssim_result));
492     printf("PSNR avg: %f, min: %f    SSIM avg: %f, min: %f\n",
493            psnr_result.average, psnr_result.min,
494            ssim_result.average, ssim_result.min);
495     stats_.PrintSummary();
496     EXPECT_GT(psnr_result.average, quality_metrics.minimum_avg_psnr);
497     EXPECT_GT(psnr_result.min, quality_metrics.minimum_min_psnr);
498     EXPECT_GT(ssim_result.average, quality_metrics.minimum_avg_ssim);
499     EXPECT_GT(ssim_result.min, quality_metrics.minimum_min_ssim);
500     if (!remove(config_.output_filename.c_str())) {
501       fprintf(stderr, "Failed to remove temporary file!");
502     }
503   }
504 };
505
506 void SetRateProfilePars(RateProfile* rate_profile,
507                         int update_index,
508                         int bit_rate,
509                         int frame_rate,
510                         int frame_index_rate_update) {
511   rate_profile->target_bit_rate[update_index] = bit_rate;
512   rate_profile->input_frame_rate[update_index] = frame_rate;
513   rate_profile->frame_index_rate_update[update_index] = frame_index_rate_update;
514 }
515
516 void SetCodecParameters(CodecConfigPars* process_settings,
517                         float packet_loss,
518                         int key_frame_interval,
519                         int num_temporal_layers,
520                         bool error_concealment_on,
521                         bool denoising_on,
522                         bool frame_dropper_on,
523                         bool spatial_resize_on) {
524   process_settings->packet_loss = packet_loss;
525   process_settings->key_frame_interval =  key_frame_interval;
526   process_settings->num_temporal_layers = num_temporal_layers,
527   process_settings->error_concealment_on = error_concealment_on;
528   process_settings->denoising_on = denoising_on;
529   process_settings->frame_dropper_on = frame_dropper_on;
530   process_settings->spatial_resize_on = spatial_resize_on;
531 }
532
533 void SetQualityMetrics(QualityMetrics* quality_metrics,
534                        double minimum_avg_psnr,
535                        double minimum_min_psnr,
536                        double minimum_avg_ssim,
537                        double minimum_min_ssim) {
538   quality_metrics->minimum_avg_psnr = minimum_avg_psnr;
539   quality_metrics->minimum_min_psnr = minimum_min_psnr;
540   quality_metrics->minimum_avg_ssim = minimum_avg_ssim;
541   quality_metrics->minimum_min_ssim = minimum_min_ssim;
542 }
543
544 void SetRateControlMetrics(RateControlMetrics* rc_metrics,
545                            int update_index,
546                            int max_num_dropped_frames,
547                            int max_key_frame_size_mismatch,
548                            int max_delta_frame_size_mismatch,
549                            int max_encoding_rate_mismatch,
550                            int max_time_hit_target,
551                            int num_spatial_resizes) {
552   rc_metrics[update_index].max_num_dropped_frames = max_num_dropped_frames;
553   rc_metrics[update_index].max_key_frame_size_mismatch =
554       max_key_frame_size_mismatch;
555   rc_metrics[update_index].max_delta_frame_size_mismatch =
556       max_delta_frame_size_mismatch;
557   rc_metrics[update_index].max_encoding_rate_mismatch =
558       max_encoding_rate_mismatch;
559   rc_metrics[update_index].max_time_hit_target = max_time_hit_target;
560   rc_metrics[update_index].num_spatial_resizes = num_spatial_resizes;
561 }
562
563 // Run with no packet loss and fixed bitrate. Quality should be very high.
564 // One key frame (first frame only) in sequence. Setting |key_frame_interval|
565 // to -1 below means no periodic key frames in test.
566 TEST_F(VideoProcessorIntegrationTest, ProcessZeroPacketLoss) {
567   // Bitrate and frame rate profile.
568   RateProfile rate_profile;
569   SetRateProfilePars(&rate_profile, 0, 500, 30, 0);
570   rate_profile.frame_index_rate_update[1] = kNbrFramesShort + 1;
571   rate_profile.num_frames = kNbrFramesShort;
572   // Codec/network settings.
573   CodecConfigPars process_settings;
574   SetCodecParameters(&process_settings, 0.0f, -1, 1, false, true, true, false);
575   // Metrics for expected quality.
576   QualityMetrics quality_metrics;
577   SetQualityMetrics(&quality_metrics, 34.95, 33.0, 0.90, 0.89);
578   // Metrics for rate control.
579   RateControlMetrics rc_metrics[1];
580   SetRateControlMetrics(rc_metrics, 0, 0, 40, 20, 10, 15, 0);
581   ProcessFramesAndVerify(quality_metrics,
582                          rate_profile,
583                          process_settings,
584                          rc_metrics);
585 }
586
587 // Run with 5% packet loss and fixed bitrate. Quality should be a bit lower.
588 // One key frame (first frame only) in sequence.
589 TEST_F(VideoProcessorIntegrationTest, Process5PercentPacketLoss) {
590   // Bitrate and frame rate profile.
591   RateProfile rate_profile;
592   SetRateProfilePars(&rate_profile, 0, 500, 30, 0);
593   rate_profile.frame_index_rate_update[1] = kNbrFramesShort + 1;
594   rate_profile.num_frames = kNbrFramesShort;
595   // Codec/network settings.
596   CodecConfigPars process_settings;
597   SetCodecParameters(&process_settings, 0.05f, -1, 1, false, true, true, false);
598   // Metrics for expected quality.
599   QualityMetrics quality_metrics;
600   SetQualityMetrics(&quality_metrics, 20.0, 16.0, 0.60, 0.40);
601   // Metrics for rate control.
602   RateControlMetrics rc_metrics[1];
603   SetRateControlMetrics(rc_metrics, 0, 0, 40, 20, 10, 15, 0);
604   ProcessFramesAndVerify(quality_metrics,
605                          rate_profile,
606                          process_settings,
607                          rc_metrics);
608 }
609
610 // Run with 10% packet loss and fixed bitrate. Quality should be even lower.
611 // One key frame (first frame only) in sequence.
612 TEST_F(VideoProcessorIntegrationTest, Process10PercentPacketLoss) {
613   // Bitrate and frame rate profile.
614   RateProfile rate_profile;
615   SetRateProfilePars(&rate_profile, 0, 500, 30, 0);
616   rate_profile.frame_index_rate_update[1] = kNbrFramesShort + 1;
617   rate_profile.num_frames = kNbrFramesShort;
618   // Codec/network settings.
619   CodecConfigPars process_settings;
620   SetCodecParameters(&process_settings, 0.1f, -1, 1, false, true, true, false);
621   // Metrics for expected quality.
622   QualityMetrics quality_metrics;
623   SetQualityMetrics(&quality_metrics, 19.0, 16.0, 0.50, 0.35);
624   // Metrics for rate control.
625   RateControlMetrics rc_metrics[1];
626   SetRateControlMetrics(rc_metrics, 0, 0, 40, 20, 10, 15, 0);
627   ProcessFramesAndVerify(quality_metrics,
628                          rate_profile,
629                          process_settings,
630                          rc_metrics);
631 }
632
633 // The tests below are currently disabled for Android. For ARM, the encoder
634 // uses |cpu_speed| = 12, as opposed to default |cpu_speed| <= 6 for x86,
635 // which leads to significantly different quality. The quality and rate control
636 // settings in the tests below are defined for encoder speed setting
637 // |cpu_speed| <= ~6. A number of settings would need to be significantly
638 // modified for the |cpu_speed| = 12 case. For now, keep the tests below
639 // disabled on Android. Some quality parameter in the above test has been
640 // adjusted to also pass for |cpu_speed| <= 12.
641
642 // Run with no packet loss, with varying bitrate (3 rate updates):
643 // low to high to medium. Check that quality and encoder response to the new
644 // target rate/per-frame bandwidth (for each rate update) is within limits.
645 // One key frame (first frame only) in sequence.
646 TEST_F(VideoProcessorIntegrationTest,
647        DISABLED_ON_ANDROID(ProcessNoLossChangeBitRate)) {
648   // Bitrate and frame rate profile.
649   RateProfile rate_profile;
650   SetRateProfilePars(&rate_profile, 0, 200, 30, 0);
651   SetRateProfilePars(&rate_profile, 1, 800, 30, 100);
652   SetRateProfilePars(&rate_profile, 2, 500, 30, 200);
653   rate_profile.frame_index_rate_update[3] = kNbrFramesLong + 1;
654   rate_profile.num_frames = kNbrFramesLong;
655   // Codec/network settings.
656   CodecConfigPars process_settings;
657   SetCodecParameters(&process_settings, 0.0f, -1, 1, false, true, true, false);
658   // Metrics for expected quality.
659   QualityMetrics quality_metrics;
660   SetQualityMetrics(&quality_metrics, 34.0, 32.0, 0.85, 0.80);
661   // Metrics for rate control.
662   RateControlMetrics rc_metrics[3];
663   SetRateControlMetrics(rc_metrics, 0, 0, 45, 20, 10, 15, 0);
664   SetRateControlMetrics(rc_metrics, 1, 0, 0, 25, 20, 10, 0);
665   SetRateControlMetrics(rc_metrics, 2, 0, 0, 25, 15, 10, 0);
666   ProcessFramesAndVerify(quality_metrics,
667                          rate_profile,
668                          process_settings,
669                          rc_metrics);
670 }
671
672 // Run with no packet loss, with an update (decrease) in frame rate.
673 // Lower frame rate means higher per-frame-bandwidth, so easier to encode.
674 // At the bitrate in this test, this means better rate control after the
675 // update(s) to lower frame rate. So expect less frame drops, and max values
676 // for the rate control metrics can be lower. One key frame (first frame only).
677 // Note: quality after update should be higher but we currently compute quality
678 // metrics avergaed over whole sequence run.
679 TEST_F(VideoProcessorIntegrationTest,
680        DISABLED_ON_ANDROID(ProcessNoLossChangeFrameRateFrameDrop)) {
681   config_.networking_config.packet_loss_probability = 0;
682   // Bitrate and frame rate profile.
683   RateProfile rate_profile;
684   SetRateProfilePars(&rate_profile, 0, 80, 24, 0);
685   SetRateProfilePars(&rate_profile, 1, 80, 15, 100);
686   SetRateProfilePars(&rate_profile, 2, 80, 10, 200);
687   rate_profile.frame_index_rate_update[3] = kNbrFramesLong + 1;
688   rate_profile.num_frames = kNbrFramesLong;
689   // Codec/network settings.
690   CodecConfigPars process_settings;
691   SetCodecParameters(&process_settings, 0.0f, -1, 1, false, true, true, false);
692   // Metrics for expected quality.
693   QualityMetrics quality_metrics;
694   SetQualityMetrics(&quality_metrics, 31.0, 22.0, 0.80, 0.65);
695   // Metrics for rate control.
696   RateControlMetrics rc_metrics[3];
697   SetRateControlMetrics(rc_metrics, 0, 40, 20, 75, 15, 60, 0);
698   SetRateControlMetrics(rc_metrics, 1, 10, 0, 25, 10, 35, 0);
699   SetRateControlMetrics(rc_metrics, 2, 0, 0, 20, 10, 15, 0);
700   ProcessFramesAndVerify(quality_metrics,
701                          rate_profile,
702                          process_settings,
703                          rc_metrics);
704 }
705
706 // Run with no packet loss, at low bitrate. During this time we should've
707 // resized once.
708 TEST_F(VideoProcessorIntegrationTest,
709        DISABLED_ON_ANDROID(ProcessNoLossSpatialResizeFrameDrop)) {
710   config_.networking_config.packet_loss_probability = 0;
711   // Bitrate and frame rate profile.
712   RateProfile rate_profile;
713   SetRateProfilePars(&rate_profile, 0, 50, 30, 0);
714   rate_profile.frame_index_rate_update[1] = kNbrFramesLong + 1;
715   rate_profile.num_frames = kNbrFramesLong;
716   // Codec/network settings.
717   CodecConfigPars process_settings;
718   SetCodecParameters(
719       &process_settings, 0.0f, kNbrFramesLong, 1, false, true, true, true);
720   // Metrics for expected quality.
721   QualityMetrics quality_metrics;
722   SetQualityMetrics(&quality_metrics, 25.0, 15.0, 0.70, 0.40);
723   // Metrics for rate control.
724   RateControlMetrics rc_metrics[1];
725   SetRateControlMetrics(rc_metrics, 0, 160, 60, 120, 20, 70, 1);
726   ProcessFramesAndVerify(quality_metrics,
727                          rate_profile,
728                          process_settings,
729                          rc_metrics);
730 }
731
732 // Run with no packet loss, with 3 temporal layers, with a rate update in the
733 // middle of the sequence. The max values for the frame size mismatch and
734 // encoding rate mismatch are applied to each layer.
735 // No dropped frames in this test, and internal spatial resizer is off.
736 // One key frame (first frame only) in sequence, so no spatial resizing.
737 TEST_F(VideoProcessorIntegrationTest,
738        DISABLED_ON_ANDROID(ProcessNoLossTemporalLayers)) {
739   config_.networking_config.packet_loss_probability = 0;
740   // Bitrate and frame rate profile.
741   RateProfile rate_profile;
742   SetRateProfilePars(&rate_profile, 0, 200, 30, 0);
743   SetRateProfilePars(&rate_profile, 1, 400, 30, 150);
744   rate_profile.frame_index_rate_update[2] = kNbrFramesLong + 1;
745   rate_profile.num_frames = kNbrFramesLong;
746   // Codec/network settings.
747   CodecConfigPars process_settings;
748   SetCodecParameters(&process_settings, 0.0f, -1, 3, false, true, true, false);
749   // Metrics for expected quality.
750   QualityMetrics quality_metrics;
751   SetQualityMetrics(&quality_metrics, 32.5, 30.0, 0.85, 0.80);
752   // Metrics for rate control.
753   RateControlMetrics rc_metrics[2];
754   SetRateControlMetrics(rc_metrics, 0, 0, 20, 30, 10, 10, 0);
755   SetRateControlMetrics(rc_metrics, 1, 0, 0, 30, 15, 10, 0);
756   ProcessFramesAndVerify(quality_metrics,
757                          rate_profile,
758                          process_settings,
759                          rc_metrics);
760 }
761 }  // namespace webrtc