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