Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Side by Side Diff: webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc

Issue 3008913002: Split up VideoProcessorIntegrationTest files. (Closed)
Patch Set: asapersson comments 1. Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest .h" 11 #include "webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest .h"
12 12
13 #include <vector> 13 #include <utility>
14
15 #if defined(WEBRTC_ANDROID)
16 #include "webrtc/modules/video_coding/codecs/test/android_test_initializer.h"
17 #include "webrtc/sdk/android/src/jni/androidmediadecoder_jni.h"
18 #include "webrtc/sdk/android/src/jni/androidmediaencoder_jni.h"
19 #elif defined(WEBRTC_IOS)
20 #include "webrtc/modules/video_coding/codecs/test/objc_codec_h264_test.h"
21 #endif
22
23 #include "webrtc/media/engine/internaldecoderfactory.h"
24 #include "webrtc/media/engine/internalencoderfactory.h"
25 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h"
26 #include "webrtc/modules/video_coding/include/video_codec_interface.h"
27 #include "webrtc/modules/video_coding/include/video_coding.h"
28 #include "webrtc/rtc_base/checks.h"
29 #include "webrtc/rtc_base/event.h"
30 #include "webrtc/rtc_base/file.h"
31 #include "webrtc/rtc_base/logging.h"
32 #include "webrtc/rtc_base/ptr_util.h"
33 #include "webrtc/system_wrappers/include/sleep.h"
34 #include "webrtc/test/testsupport/fileutils.h"
35 #include "webrtc/test/testsupport/metrics/video_metrics.h"
36 #include "webrtc/test/video_codec_settings.h"
14 37
15 namespace webrtc { 38 namespace webrtc {
16 namespace test { 39 namespace test {
17 40
18 namespace { 41 namespace {
19 42
20 // Test settings. 43 const int kPercTargetvsActualMismatch = 20;
21 // Only allow encoder/decoder to use single core, for predictability. 44 const int kBaseKeyFrameInterval = 3000;
22 const bool kUseSingleCore = true; 45
23 const bool kVerboseLogging = false; 46 // Parameters from VP8 wrapper, which control target size of key frames.
24 const bool kHwCodec = false; 47 const float kInitialBufferSize = 0.5f;
25 48 const float kOptimalBufferSize = 0.6f;
26 // Codec settings. 49 const float kScaleKeyFrameSize = 0.5f;
27 const bool kResilienceOn = true; 50
28 51 void VerifyQuality(const QualityMetricsResult& psnr_result,
29 // Default sequence is foreman (CIF): may be better to use VGA for resize test. 52 const QualityMetricsResult& ssim_result,
30 const int kCifWidth = 352; 53 const QualityThresholds& quality_thresholds) {
31 const int kCifHeight = 288; 54 EXPECT_GT(psnr_result.average, quality_thresholds.min_avg_psnr);
32 const char kForemanCif[] = "foreman_cif"; 55 EXPECT_GT(psnr_result.min, quality_thresholds.min_min_psnr);
33 #if !defined(WEBRTC_IOS) 56 EXPECT_GT(ssim_result.average, quality_thresholds.min_avg_ssim);
34 const int kNumFramesShort = 100; 57 EXPECT_GT(ssim_result.min, quality_thresholds.min_min_ssim);
58 }
59
60 int NumberOfTemporalLayers(const VideoCodec& codec_settings) {
61 if (codec_settings.codecType == kVideoCodecVP8) {
62 return codec_settings.VP8().numberOfTemporalLayers;
63 } else if (codec_settings.codecType == kVideoCodecVP9) {
64 return codec_settings.VP9().numberOfTemporalLayers;
65 } else {
66 return 1;
67 }
68 }
69
70 } // namespace
71
72 VideoProcessorIntegrationTest::VideoProcessorIntegrationTest() {
73 #if defined(WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED) && \
74 defined(WEBRTC_ANDROID)
75 InitializeAndroidObjects();
35 #endif 76 #endif
36 const int kNumFramesLong = 300; 77 }
37 78
38 const std::nullptr_t kNoVisualizationParams = nullptr; 79 VideoProcessorIntegrationTest::~VideoProcessorIntegrationTest() = default;
39 80
40 } // namespace 81 void VideoProcessorIntegrationTest::SetTestConfig(TestConfig* config,
41 82 bool hw_codec,
42 #if defined(WEBRTC_USE_H264) 83 bool use_single_core,
43 84 float packet_loss_probability,
44 // H264: Run with no packet loss and fixed bitrate. Quality should be very high. 85 std::string filename,
45 // Note(hbos): The PacketManipulatorImpl code used to simulate packet loss in 86 bool verbose_logging) {
46 // these unittests appears to drop "packets" in a way that is not compatible 87 config->filename = filename;
47 // with H264. Therefore ProcessXPercentPacketLossH264, X != 0, unittests have 88 config->input_filename = ResourcePath(filename, "yuv");
48 // not been added. 89 // Generate an output filename in a safe way.
49 TEST_F(VideoProcessorIntegrationTest, Process0PercentPacketLossH264) { 90 config->output_filename =
50 SetTestConfig(&config_, kHwCodec, kUseSingleCore, 0.0f, kForemanCif, 91 TempFilename(OutputPath(), "videoprocessor_integrationtest");
51 kVerboseLogging); 92 config->networking_config.packet_loss_probability = packet_loss_probability;
52 SetCodecSettings(&config_, kVideoCodecH264, 1, false, false, true, false, 93 config->use_single_core = use_single_core;
53 kResilienceOn, kCifWidth, kCifHeight); 94 config->verbose = verbose_logging;
54 95 config->hw_codec = hw_codec;
55 RateProfile rate_profile; 96 }
56 SetRateProfile(&rate_profile, 0, 500, 30, 0); 97
57 rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1; 98 void VideoProcessorIntegrationTest::SetCodecSettings(TestConfig* config,
58 rate_profile.num_frames = kNumFramesShort; 99 VideoCodecType codec_type,
59 100 int num_temporal_layers,
60 std::vector<RateControlThresholds> rc_thresholds; 101 bool error_concealment_on,
61 AddRateControlThresholds(2, 60, 20, 10, 20, 0, 1, &rc_thresholds); 102 bool denoising_on,
62 103 bool frame_dropper_on,
63 QualityThresholds quality_thresholds(35.0, 25.0, 0.93, 0.70); 104 bool spatial_resize_on,
64 105 bool resilience_on,
65 ProcessFramesAndMaybeVerify(rate_profile, &rc_thresholds, &quality_thresholds, 106 int width,
66 kNoVisualizationParams); 107 int height) {
67 } 108 webrtc::test::CodecSettings(codec_type, &config->codec_settings);
68 109 config->codec_settings.width = width;
69 #endif // defined(WEBRTC_USE_H264) 110 config->codec_settings.height = height;
70 111 switch (config->codec_settings.codecType) {
71 // Fails on iOS. See webrtc:4755. 112 case kVideoCodecVP8:
72 #if !defined(WEBRTC_IOS) 113 config->codec_settings.VP8()->resilience =
73 114 resilience_on ? kResilientStream : kResilienceOff;
74 #if !defined(RTC_DISABLE_VP9) 115 config->codec_settings.VP8()->numberOfTemporalLayers =
75 // VP9: Run with no packet loss and fixed bitrate. Quality should be very high. 116 num_temporal_layers;
76 // One key frame (first frame only) in sequence. 117 config->codec_settings.VP8()->denoisingOn = denoising_on;
77 TEST_F(VideoProcessorIntegrationTest, Process0PercentPacketLossVP9) { 118 config->codec_settings.VP8()->errorConcealmentOn = error_concealment_on;
78 SetTestConfig(&config_, kHwCodec, kUseSingleCore, 0.0f, kForemanCif, 119 config->codec_settings.VP8()->automaticResizeOn = spatial_resize_on;
79 kVerboseLogging); 120 config->codec_settings.VP8()->frameDroppingOn = frame_dropper_on;
80 SetCodecSettings(&config_, kVideoCodecVP9, 1, false, false, true, false, 121 config->codec_settings.VP8()->keyFrameInterval = kBaseKeyFrameInterval;
81 kResilienceOn, kCifWidth, kCifHeight); 122 break;
82 123 case kVideoCodecVP9:
83 RateProfile rate_profile; 124 config->codec_settings.VP9()->resilienceOn = resilience_on;
84 SetRateProfile(&rate_profile, 0, 500, 30, 0); 125 config->codec_settings.VP9()->numberOfTemporalLayers =
85 rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1; 126 num_temporal_layers;
86 rate_profile.num_frames = kNumFramesShort; 127 config->codec_settings.VP9()->denoisingOn = denoising_on;
87 128 config->codec_settings.VP9()->frameDroppingOn = frame_dropper_on;
88 std::vector<RateControlThresholds> rc_thresholds; 129 config->codec_settings.VP9()->keyFrameInterval = kBaseKeyFrameInterval;
89 AddRateControlThresholds(0, 40, 20, 10, 20, 0, 1, &rc_thresholds); 130 config->codec_settings.VP9()->automaticResizeOn = spatial_resize_on;
90 131 break;
91 QualityThresholds quality_thresholds(37.0, 36.0, 0.93, 0.92); 132 case kVideoCodecH264:
92 133 config->codec_settings.H264()->frameDroppingOn = frame_dropper_on;
93 ProcessFramesAndMaybeVerify(rate_profile, &rc_thresholds, &quality_thresholds, 134 config->codec_settings.H264()->keyFrameInterval = kBaseKeyFrameInterval;
94 kNoVisualizationParams); 135 break;
95 } 136 default:
96 137 RTC_NOTREACHED();
97 // VP9: Run with 5% packet loss and fixed bitrate. Quality should be a bit 138 break;
98 // lower. One key frame (first frame only) in sequence. 139 }
99 TEST_F(VideoProcessorIntegrationTest, Process5PercentPacketLossVP9) { 140
100 SetTestConfig(&config_, kHwCodec, kUseSingleCore, 0.05f, kForemanCif, 141 config->frame_length_in_bytes =
101 kVerboseLogging); 142 CalcBufferSize(VideoType::kI420, width, height);
102 SetCodecSettings(&config_, kVideoCodecVP9, 1, false, false, true, false, 143 }
103 kResilienceOn, kCifWidth, kCifHeight); 144
104 145 void VideoProcessorIntegrationTest::SetRateProfile(
105 RateProfile rate_profile; 146 RateProfile* rate_profile,
106 SetRateProfile(&rate_profile, 0, 500, 30, 0); 147 int rate_update_index,
107 rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1; 148 int bitrate_kbps,
108 rate_profile.num_frames = kNumFramesShort; 149 int framerate_fps,
109 150 int frame_index_rate_update) {
110 std::vector<RateControlThresholds> rc_thresholds; 151 rate_profile->target_bit_rate[rate_update_index] = bitrate_kbps;
111 AddRateControlThresholds(0, 40, 20, 10, 20, 0, 1, &rc_thresholds); 152 rate_profile->input_frame_rate[rate_update_index] = framerate_fps;
112 153 rate_profile->frame_index_rate_update[rate_update_index] =
113 QualityThresholds quality_thresholds(17.0, 14.0, 0.45, 0.36); 154 frame_index_rate_update;
114 155 }
115 ProcessFramesAndMaybeVerify(rate_profile, &rc_thresholds, &quality_thresholds, 156
116 kNoVisualizationParams); 157 void VideoProcessorIntegrationTest::AddRateControlThresholds(
117 } 158 int max_num_dropped_frames,
118 159 int max_key_frame_size_mismatch,
119 // VP9: Run with no packet loss, with varying bitrate (3 rate updates): 160 int max_delta_frame_size_mismatch,
120 // low to high to medium. Check that quality and encoder response to the new 161 int max_encoding_rate_mismatch,
121 // target rate/per-frame bandwidth (for each rate update) is within limits. 162 int max_time_hit_target,
122 // One key frame (first frame only) in sequence. 163 int num_spatial_resizes,
123 TEST_F(VideoProcessorIntegrationTest, ProcessNoLossChangeBitRateVP9) { 164 int num_key_frames,
124 SetTestConfig(&config_, kHwCodec, kUseSingleCore, 0.0f, kForemanCif, 165 std::vector<RateControlThresholds>* rc_thresholds) {
125 kVerboseLogging); 166 RTC_DCHECK(rc_thresholds);
126 SetCodecSettings(&config_, kVideoCodecVP9, 1, false, false, true, false, 167
127 kResilienceOn, kCifWidth, kCifHeight); 168 rc_thresholds->emplace_back();
128 169 RateControlThresholds* rc_threshold = &rc_thresholds->back();
129 RateProfile rate_profile; 170 rc_threshold->max_num_dropped_frames = max_num_dropped_frames;
130 SetRateProfile(&rate_profile, 0, 200, 30, 0); 171 rc_threshold->max_key_frame_size_mismatch = max_key_frame_size_mismatch;
131 SetRateProfile(&rate_profile, 1, 700, 30, 100); 172 rc_threshold->max_delta_frame_size_mismatch = max_delta_frame_size_mismatch;
132 SetRateProfile(&rate_profile, 2, 500, 30, 200); 173 rc_threshold->max_encoding_rate_mismatch = max_encoding_rate_mismatch;
133 rate_profile.frame_index_rate_update[3] = kNumFramesLong + 1; 174 rc_threshold->max_time_hit_target = max_time_hit_target;
134 rate_profile.num_frames = kNumFramesLong; 175 rc_threshold->num_spatial_resizes = num_spatial_resizes;
135 176 rc_threshold->num_key_frames = num_key_frames;
136 std::vector<RateControlThresholds> rc_thresholds; 177 }
137 AddRateControlThresholds(0, 30, 20, 20, 35, 0, 1, &rc_thresholds); 178
138 AddRateControlThresholds(2, 0, 20, 20, 60, 0, 0, &rc_thresholds); 179 // Processes all frames in the clip and verifies the result.
139 AddRateControlThresholds(0, 0, 25, 20, 40, 0, 0, &rc_thresholds); 180 void VideoProcessorIntegrationTest::ProcessFramesAndMaybeVerify(
140 181 const RateProfile& rate_profile,
141 QualityThresholds quality_thresholds(35.5, 30.0, 0.90, 0.85); 182 const std::vector<RateControlThresholds>* rc_thresholds,
142 183 const QualityThresholds* quality_thresholds,
143 ProcessFramesAndMaybeVerify(rate_profile, &rc_thresholds, &quality_thresholds, 184 const VisualizationParams* visualization_params) {
144 kNoVisualizationParams); 185 // The Android HW codec needs to be run on a task queue, so we simply always
145 } 186 // run the test on a task queue.
146 187 rtc::TaskQueue task_queue("VidProc TQ");
147 // VP9: Run with no packet loss, with an update (decrease) in frame rate. 188 rtc::Event sync_event(false, false);
148 // Lower frame rate means higher per-frame-bandwidth, so easier to encode. 189
149 // At the low bitrate in this test, this means better rate control after the 190 SetUpAndInitObjects(&task_queue, rate_profile.target_bit_rate[0],
150 // update(s) to lower frame rate. So expect less frame drops, and max values 191 rate_profile.input_frame_rate[0], visualization_params);
151 // for the rate control metrics can be lower. One key frame (first frame only). 192
152 // Note: quality after update should be higher but we currently compute quality 193 // Set initial rates.
153 // metrics averaged over whole sequence run. 194 int rate_update_index = 0;
154 TEST_F(VideoProcessorIntegrationTest, 195 task_queue.PostTask([this, &rate_profile, rate_update_index] {
155 ProcessNoLossChangeFrameRateFrameDropVP9) { 196 processor_->SetRates(rate_profile.target_bit_rate[rate_update_index],
156 SetTestConfig(&config_, kHwCodec, kUseSingleCore, 0.0f, kForemanCif, 197 rate_profile.input_frame_rate[rate_update_index]);
157 kVerboseLogging); 198 });
158 SetCodecSettings(&config_, kVideoCodecVP9, 1, false, false, true, false, 199
159 kResilienceOn, kCifWidth, kCifHeight); 200 // Process all frames.
160 201 int frame_number = 0;
161 RateProfile rate_profile; 202 const int num_frames = rate_profile.num_frames;
162 SetRateProfile(&rate_profile, 0, 100, 24, 0); 203 RTC_DCHECK_GE(num_frames, 1);
163 SetRateProfile(&rate_profile, 1, 100, 15, 100); 204 while (frame_number < num_frames) {
164 SetRateProfile(&rate_profile, 2, 100, 10, 200); 205 // In order to not overwhelm the OpenMAX buffers in the Android
165 rate_profile.frame_index_rate_update[3] = kNumFramesLong + 1; 206 // MediaCodec API, we roughly pace the frames here. The downside
166 rate_profile.num_frames = kNumFramesLong; 207 // of this is that the encode run will be done in real-time.
167 208 // TODO(brandtr): Investigate if this is needed on iOS.
168 std::vector<RateControlThresholds> rc_thresholds; 209 if (config_.hw_codec) {
169 AddRateControlThresholds(45, 50, 95, 15, 45, 0, 1, &rc_thresholds); 210 SleepMs(rtc::kNumMillisecsPerSec /
170 AddRateControlThresholds(20, 0, 50, 10, 30, 0, 0, &rc_thresholds); 211 rate_profile.input_frame_rate[rate_update_index]);
171 AddRateControlThresholds(5, 0, 30, 5, 25, 0, 0, &rc_thresholds); 212 }
172 213
173 QualityThresholds quality_thresholds(31.5, 18.0, 0.80, 0.43); 214 task_queue.PostTask(
174 215 [this, frame_number] { processor_->ProcessFrame(frame_number); });
175 ProcessFramesAndMaybeVerify(rate_profile, &rc_thresholds, &quality_thresholds, 216 ++frame_number;
176 kNoVisualizationParams); 217
177 } 218 if (frame_number ==
178 219 rate_profile.frame_index_rate_update[rate_update_index + 1]) {
179 // VP9: Run with no packet loss and denoiser on. One key frame (first frame). 220 ++rate_update_index;
180 TEST_F(VideoProcessorIntegrationTest, ProcessNoLossDenoiserOnVP9) { 221
181 SetTestConfig(&config_, kHwCodec, kUseSingleCore, 0.0f, kForemanCif, 222 task_queue.PostTask([this, &rate_profile, rate_update_index] {
182 kVerboseLogging); 223 processor_->SetRates(rate_profile.target_bit_rate[rate_update_index],
183 SetCodecSettings(&config_, kVideoCodecVP9, 1, false, true, true, false, 224 rate_profile.input_frame_rate[rate_update_index]);
184 kResilienceOn, kCifWidth, kCifHeight); 225 });
185 226 }
186 RateProfile rate_profile; 227 }
187 SetRateProfile(&rate_profile, 0, 500, 30, 0); 228
188 rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1; 229 // Give the VideoProcessor pipeline some time to process the last frame,
189 rate_profile.num_frames = kNumFramesShort; 230 // and then release the codecs.
190 231 if (config_.hw_codec) {
191 std::vector<RateControlThresholds> rc_thresholds; 232 SleepMs(1 * rtc::kNumMillisecsPerSec);
192 AddRateControlThresholds(0, 40, 20, 10, 20, 0, 1, &rc_thresholds); 233 }
193 234 ReleaseAndCloseObjects(&task_queue);
194 QualityThresholds quality_thresholds(36.8, 35.8, 0.92, 0.91); 235
195 236 // Calculate and print rate control statistics.
196 ProcessFramesAndMaybeVerify(rate_profile, &rc_thresholds, &quality_thresholds, 237 rate_update_index = 0;
197 kNoVisualizationParams); 238 frame_number = 0;
198 } 239 ResetRateControlMetrics(rate_update_index, rate_profile);
199 240 std::vector<int> num_dropped_frames;
200 // Run with no packet loss, at low bitrate. 241 std::vector<int> num_resize_actions;
201 // spatial_resize is on, for this low bitrate expect one resize in sequence. 242 sync_event.Reset();
202 // Resize happens on delta frame. Expect only one key frame (first frame). 243 task_queue.PostTask(
203 TEST_F(VideoProcessorIntegrationTest, 244 [this, &num_dropped_frames, &num_resize_actions, &sync_event]() {
204 DISABLED_ProcessNoLossSpatialResizeFrameDropVP9) { 245 num_dropped_frames = processor_->NumberDroppedFramesPerRateUpdate();
205 SetTestConfig(&config_, kHwCodec, kUseSingleCore, 0.0f, kForemanCif, 246 num_resize_actions = processor_->NumberSpatialResizesPerRateUpdate();
206 kVerboseLogging); 247 sync_event.Set();
207 SetCodecSettings(&config_, kVideoCodecVP9, 1, false, false, true, true, 248 });
208 kResilienceOn, kCifWidth, kCifHeight); 249 sync_event.Wait(rtc::Event::kForever);
209 250 while (frame_number < num_frames) {
210 RateProfile rate_profile; 251 UpdateRateControlMetrics(frame_number);
211 SetRateProfile(&rate_profile, 0, 50, 30, 0); 252
212 rate_profile.frame_index_rate_update[1] = kNumFramesLong + 1; 253 ++frame_number;
213 rate_profile.num_frames = kNumFramesLong; 254
214 255 if (frame_number ==
215 std::vector<RateControlThresholds> rc_thresholds; 256 rate_profile.frame_index_rate_update[rate_update_index + 1]) {
216 AddRateControlThresholds(228, 70, 160, 15, 80, 1, 1, &rc_thresholds); 257 PrintAndMaybeVerifyRateControlMetrics(rate_update_index, rc_thresholds,
217 258 num_dropped_frames,
218 QualityThresholds quality_thresholds(24.0, 13.0, 0.65, 0.37); 259 num_resize_actions);
219 260 ++rate_update_index;
220 ProcessFramesAndMaybeVerify(rate_profile, &rc_thresholds, &quality_thresholds, 261 ResetRateControlMetrics(rate_update_index, rate_profile);
221 kNoVisualizationParams); 262 }
222 } 263 }
223 264 PrintAndMaybeVerifyRateControlMetrics(rate_update_index, rc_thresholds,
224 // TODO(marpan): Add temporal layer test for VP9, once changes are in 265 num_dropped_frames, num_resize_actions);
225 // vp9 wrapper for this. 266
226 267 // Calculate and print other statistics.
227 #endif // !defined(RTC_DISABLE_VP9) 268 EXPECT_EQ(num_frames, static_cast<int>(stats_.stats_.size()));
228 269 stats_.PrintSummary();
229 // VP8: Run with no packet loss and fixed bitrate. Quality should be very high. 270
230 // One key frame (first frame only) in sequence. Setting |key_frame_interval| 271 // Calculate and print image quality statistics.
231 // to -1 below means no periodic key frames in test. 272 // TODO(marpan): Should compute these quality metrics per SetRates update.
232 TEST_F(VideoProcessorIntegrationTest, ProcessZeroPacketLoss) { 273 QualityMetricsResult psnr_result, ssim_result;
233 SetTestConfig(&config_, kHwCodec, kUseSingleCore, 0.0f, kForemanCif, 274 EXPECT_EQ(0, I420MetricsFromFiles(config_.input_filename.c_str(),
234 kVerboseLogging); 275 config_.output_filename.c_str(),
235 SetCodecSettings(&config_, kVideoCodecVP8, 1, false, true, true, false, 276 config_.codec_settings.width,
236 kResilienceOn, kCifWidth, kCifHeight); 277 config_.codec_settings.height, &psnr_result,
237 278 &ssim_result));
238 RateProfile rate_profile; 279 if (quality_thresholds) {
239 SetRateProfile(&rate_profile, 0, 500, 30, 0); 280 VerifyQuality(psnr_result, ssim_result, *quality_thresholds);
240 rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1; 281 }
241 rate_profile.num_frames = kNumFramesShort; 282 printf("PSNR avg: %f, min: %f\nSSIM avg: %f, min: %f\n", psnr_result.average,
242 283 psnr_result.min, ssim_result.average, ssim_result.min);
243 std::vector<RateControlThresholds> rc_thresholds; 284 printf("\n");
244 AddRateControlThresholds(0, 40, 20, 10, 15, 0, 1, &rc_thresholds); 285
245 286 // Remove analysis file.
246 QualityThresholds quality_thresholds(34.95, 33.0, 0.90, 0.89); 287 if (remove(config_.output_filename.c_str()) < 0) {
247 288 fprintf(stderr, "Failed to remove temporary file!\n");
248 ProcessFramesAndMaybeVerify(rate_profile, &rc_thresholds, &quality_thresholds, 289 }
249 kNoVisualizationParams); 290 }
250 } 291
251 292 void VideoProcessorIntegrationTest::CreateEncoderAndDecoder() {
252 // VP8: Run with 5% packet loss and fixed bitrate. Quality should be a bit 293 if (config_.hw_codec) {
253 // lower. One key frame (first frame only) in sequence. 294 #if defined(WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED)
254 TEST_F(VideoProcessorIntegrationTest, Process5PercentPacketLoss) { 295 #if defined(WEBRTC_ANDROID)
255 SetTestConfig(&config_, kHwCodec, kUseSingleCore, 0.05f, kForemanCif, 296 encoder_factory_.reset(new jni::MediaCodecVideoEncoderFactory());
256 kVerboseLogging); 297 decoder_factory_.reset(new jni::MediaCodecVideoDecoderFactory());
257 SetCodecSettings(&config_, kVideoCodecVP8, 1, false, true, true, false, 298 #elif defined(WEBRTC_IOS)
258 kResilienceOn, kCifWidth, kCifHeight); 299 EXPECT_EQ(kVideoCodecH264, config_.codec_settings.codecType)
259 300 << "iOS HW codecs only support H264.";
260 RateProfile rate_profile; 301 encoder_factory_ = CreateObjCEncoderFactory();
261 SetRateProfile(&rate_profile, 0, 500, 30, 0); 302 decoder_factory_ = CreateObjCDecoderFactory();
262 rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1;
263 rate_profile.num_frames = kNumFramesShort;
264
265 std::vector<RateControlThresholds> rc_thresholds;
266 AddRateControlThresholds(0, 40, 20, 10, 15, 0, 1, &rc_thresholds);
267
268 QualityThresholds quality_thresholds(20.0, 16.0, 0.60, 0.40);
269
270 ProcessFramesAndMaybeVerify(rate_profile, &rc_thresholds, &quality_thresholds,
271 kNoVisualizationParams);
272 }
273
274 // VP8: Run with 10% packet loss and fixed bitrate. Quality should be lower.
275 // One key frame (first frame only) in sequence.
276 TEST_F(VideoProcessorIntegrationTest, Process10PercentPacketLoss) {
277 SetTestConfig(&config_, kHwCodec, kUseSingleCore, 0.1f, kForemanCif,
278 kVerboseLogging);
279 SetCodecSettings(&config_, kVideoCodecVP8, 1, false, true, true, false,
280 kResilienceOn, kCifWidth, kCifHeight);
281
282 RateProfile rate_profile;
283 SetRateProfile(&rate_profile, 0, 500, 30, 0);
284 rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1;
285 rate_profile.num_frames = kNumFramesShort;
286
287 std::vector<RateControlThresholds> rc_thresholds;
288 AddRateControlThresholds(0, 40, 20, 10, 15, 0, 1, &rc_thresholds);
289
290 QualityThresholds quality_thresholds(19.0, 16.0, 0.50, 0.35);
291
292 ProcessFramesAndMaybeVerify(rate_profile, &rc_thresholds, &quality_thresholds,
293 kNoVisualizationParams);
294 }
295
296 #endif // !defined(WEBRTC_IOS)
297
298 // The tests below are currently disabled for Android. For ARM, the encoder
299 // uses |cpu_speed| = 12, as opposed to default |cpu_speed| <= 6 for x86,
300 // which leads to significantly different quality. The quality and rate control
301 // settings in the tests below are defined for encoder speed setting
302 // |cpu_speed| <= ~6. A number of settings would need to be significantly
303 // modified for the |cpu_speed| = 12 case. For now, keep the tests below
304 // disabled on Android. Some quality parameter in the above test has been
305 // adjusted to also pass for |cpu_speed| <= 12.
306
307 // VP8: Run with no packet loss, with varying bitrate (3 rate updates):
308 // low to high to medium. Check that quality and encoder response to the new
309 // target rate/per-frame bandwidth (for each rate update) is within limits.
310 // One key frame (first frame only) in sequence.
311 // Too slow to finish before timeout on iOS. See webrtc:4755.
312 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
313 #define MAYBE_ProcessNoLossChangeBitRateVP8 \
314 DISABLED_ProcessNoLossChangeBitRateVP8
315 #else 303 #else
316 #define MAYBE_ProcessNoLossChangeBitRateVP8 ProcessNoLossChangeBitRateVP8 304 RTC_NOTREACHED() << "Only support HW codecs on Android and iOS.";
317 #endif 305 #endif
318 TEST_F(VideoProcessorIntegrationTest, MAYBE_ProcessNoLossChangeBitRateVP8) { 306 #endif // WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED
319 SetTestConfig(&config_, kHwCodec, kUseSingleCore, 0.0f, kForemanCif, 307 } else {
320 kVerboseLogging); 308 // SW codecs.
321 SetCodecSettings(&config_, kVideoCodecVP8, 1, false, true, true, false, 309 encoder_factory_.reset(new cricket::InternalEncoderFactory());
322 kResilienceOn, kCifWidth, kCifHeight); 310 decoder_factory_.reset(new cricket::InternalDecoderFactory());
323 311 }
324 RateProfile rate_profile; 312
325 SetRateProfile(&rate_profile, 0, 200, 30, 0); 313 switch (config_.codec_settings.codecType) {
326 SetRateProfile(&rate_profile, 1, 800, 30, 100); 314 case kVideoCodecVP8:
327 SetRateProfile(&rate_profile, 2, 500, 30, 200); 315 encoder_ = encoder_factory_->CreateVideoEncoder(
328 rate_profile.frame_index_rate_update[3] = kNumFramesLong + 1; 316 cricket::VideoCodec(cricket::kVp8CodecName));
329 rate_profile.num_frames = kNumFramesLong; 317 decoder_ = decoder_factory_->CreateVideoDecoder(kVideoCodecVP8);
330 318 break;
331 std::vector<RateControlThresholds> rc_thresholds; 319 case kVideoCodecVP9:
332 AddRateControlThresholds(0, 45, 20, 10, 15, 0, 1, &rc_thresholds); 320 encoder_ = encoder_factory_->CreateVideoEncoder(
333 AddRateControlThresholds(0, 0, 25, 20, 10, 0, 0, &rc_thresholds); 321 cricket::VideoCodec(cricket::kVp9CodecName));
334 AddRateControlThresholds(0, 0, 25, 15, 10, 0, 0, &rc_thresholds); 322 decoder_ = decoder_factory_->CreateVideoDecoder(kVideoCodecVP9);
335 323 break;
336 QualityThresholds quality_thresholds(34.0, 32.0, 0.85, 0.80); 324 case kVideoCodecH264:
337 325 // TODO(brandtr): Generalize so that we support multiple profiles here.
338 ProcessFramesAndMaybeVerify(rate_profile, &rc_thresholds, &quality_thresholds, 326 encoder_ = encoder_factory_->CreateVideoEncoder(
339 kNoVisualizationParams); 327 cricket::VideoCodec(cricket::kH264CodecName));
340 } 328 decoder_ = decoder_factory_->CreateVideoDecoder(kVideoCodecH264);
341 329 break;
342 // VP8: Run with no packet loss, with an update (decrease) in frame rate. 330 default:
343 // Lower frame rate means higher per-frame-bandwidth, so easier to encode. 331 RTC_NOTREACHED();
344 // At the bitrate in this test, this means better rate control after the 332 break;
345 // update(s) to lower frame rate. So expect less frame drops, and max values 333 }
346 // for the rate control metrics can be lower. One key frame (first frame only). 334
347 // Note: quality after update should be higher but we currently compute quality 335 EXPECT_TRUE(encoder_) << "Encoder not successfully created.";
348 // metrics averaged over whole sequence run. 336 EXPECT_TRUE(decoder_) << "Decoder not successfully created.";
349 // Too slow to finish before timeout on iOS. See webrtc:4755. 337 }
350 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) 338
351 #define MAYBE_ProcessNoLossChangeFrameRateFrameDropVP8 \ 339 void VideoProcessorIntegrationTest::DestroyEncoderAndDecoder() {
352 DISABLED_ProcessNoLossChangeFrameRateFrameDropVP8 340 encoder_factory_->DestroyVideoEncoder(encoder_);
353 #else 341 decoder_factory_->DestroyVideoDecoder(decoder_);
354 #define MAYBE_ProcessNoLossChangeFrameRateFrameDropVP8 \ 342 }
355 ProcessNoLossChangeFrameRateFrameDropVP8 343
356 #endif 344 void VideoProcessorIntegrationTest::SetUpAndInitObjects(
357 TEST_F(VideoProcessorIntegrationTest, 345 rtc::TaskQueue* task_queue,
358 MAYBE_ProcessNoLossChangeFrameRateFrameDropVP8) { 346 const int initial_bitrate_kbps,
359 SetTestConfig(&config_, kHwCodec, kUseSingleCore, 0.0f, kForemanCif, 347 const int initial_framerate_fps,
360 kVerboseLogging); 348 const VisualizationParams* visualization_params) {
361 SetCodecSettings(&config_, kVideoCodecVP8, 1, false, true, true, false, 349 CreateEncoderAndDecoder();
362 kResilienceOn, kCifWidth, kCifHeight); 350
363 351 // Create file objects for quality analysis.
364 RateProfile rate_profile; 352 analysis_frame_reader_.reset(new YuvFrameReaderImpl(
365 SetRateProfile(&rate_profile, 0, 80, 24, 0); 353 config_.input_filename, config_.codec_settings.width,
366 SetRateProfile(&rate_profile, 1, 80, 15, 100); 354 config_.codec_settings.height));
367 SetRateProfile(&rate_profile, 2, 80, 10, 200); 355 analysis_frame_writer_.reset(new YuvFrameWriterImpl(
368 rate_profile.frame_index_rate_update[3] = kNumFramesLong + 1; 356 config_.output_filename, config_.codec_settings.width,
369 rate_profile.num_frames = kNumFramesLong; 357 config_.codec_settings.height));
370 358 EXPECT_TRUE(analysis_frame_reader_->Init());
371 std::vector<RateControlThresholds> rc_thresholds; 359 EXPECT_TRUE(analysis_frame_writer_->Init());
372 AddRateControlThresholds(40, 20, 75, 15, 60, 0, 1, &rc_thresholds); 360
373 AddRateControlThresholds(10, 0, 25, 10, 35, 0, 0, &rc_thresholds); 361 if (visualization_params) {
374 AddRateControlThresholds(0, 0, 20, 10, 15, 0, 0, &rc_thresholds); 362 const std::string codec_name =
375 363 CodecTypeToPayloadString(config_.codec_settings.codecType);
376 QualityThresholds quality_thresholds(31.0, 22.0, 0.80, 0.65); 364 const std::string implementation_type = config_.hw_codec ? "hw" : "sw";
377 365 // clang-format off
378 ProcessFramesAndMaybeVerify(rate_profile, &rc_thresholds, &quality_thresholds, 366 const std::string output_filename_base =
379 kNoVisualizationParams); 367 OutputPath() + config_.filename + "-" +
380 } 368 codec_name + "-" + implementation_type + "-" +
381 369 std::to_string(initial_bitrate_kbps);
382 // VP8: Run with no packet loss, with 3 temporal layers, with a rate update in 370 // clang-format on
383 // the middle of the sequence. The max values for the frame size mismatch and 371 if (visualization_params->save_encoded_ivf) {
384 // encoding rate mismatch are applied to each layer. 372 rtc::File post_encode_file =
385 // No dropped frames in this test, and internal spatial resizer is off. 373 rtc::File::Create(output_filename_base + ".ivf");
386 // One key frame (first frame only) in sequence, so no spatial resizing. 374 encoded_frame_writer_ =
387 // Too slow to finish before timeout on iOS. See webrtc:4755. 375 IvfFileWriter::Wrap(std::move(post_encode_file), 0);
388 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) 376 }
389 #define MAYBE_ProcessNoLossTemporalLayersVP8 \ 377 if (visualization_params->save_decoded_y4m) {
390 DISABLED_ProcessNoLossTemporalLayersVP8 378 decoded_frame_writer_.reset(new Y4mFrameWriterImpl(
391 #else 379 output_filename_base + ".y4m", config_.codec_settings.width,
392 #define MAYBE_ProcessNoLossTemporalLayersVP8 ProcessNoLossTemporalLayersVP8 380 config_.codec_settings.height, initial_framerate_fps));
393 #endif 381 EXPECT_TRUE(decoded_frame_writer_->Init());
394 TEST_F(VideoProcessorIntegrationTest, MAYBE_ProcessNoLossTemporalLayersVP8) { 382 }
395 SetTestConfig(&config_, kHwCodec, kUseSingleCore, 0.0f, kForemanCif, 383 }
396 kVerboseLogging); 384
397 SetCodecSettings(&config_, kVideoCodecVP8, 3, false, true, true, false, 385 packet_manipulator_.reset(new PacketManipulatorImpl(
398 kResilienceOn, kCifWidth, kCifHeight); 386 &packet_reader_, config_.networking_config, config_.verbose));
399 387
400 RateProfile rate_profile; 388 config_.codec_settings.minBitrate = 0;
401 SetRateProfile(&rate_profile, 0, 200, 30, 0); 389 config_.codec_settings.startBitrate = initial_bitrate_kbps;
402 SetRateProfile(&rate_profile, 1, 400, 30, 150); 390 config_.codec_settings.maxFramerate = initial_framerate_fps;
403 rate_profile.frame_index_rate_update[2] = kNumFramesLong + 1; 391
404 rate_profile.num_frames = kNumFramesLong; 392 rtc::Event sync_event(false, false);
405 393 task_queue->PostTask([this, &sync_event]() {
406 std::vector<RateControlThresholds> rc_thresholds; 394 processor_ = rtc::MakeUnique<VideoProcessor>(
407 AddRateControlThresholds(0, 20, 30, 10, 10, 0, 1, &rc_thresholds); 395 encoder_, decoder_, analysis_frame_reader_.get(),
408 AddRateControlThresholds(0, 0, 30, 15, 10, 0, 0, &rc_thresholds); 396 analysis_frame_writer_.get(), packet_manipulator_.get(), config_,
409 397 &stats_, encoded_frame_writer_.get(), decoded_frame_writer_.get());
410 QualityThresholds quality_thresholds(32.5, 30.0, 0.85, 0.80); 398 processor_->Init();
411 399 sync_event.Set();
412 ProcessFramesAndMaybeVerify(rate_profile, &rc_thresholds, &quality_thresholds, 400 });
413 kNoVisualizationParams); 401 sync_event.Wait(rtc::Event::kForever);
414 } 402 }
403
404 void VideoProcessorIntegrationTest::ReleaseAndCloseObjects(
405 rtc::TaskQueue* task_queue) {
406 rtc::Event sync_event(false, false);
407 task_queue->PostTask([this, &sync_event]() {
408 processor_->Release();
409 sync_event.Set();
410 });
411 sync_event.Wait(rtc::Event::kForever);
412
413 // The VideoProcessor must be ::Release()'d before we destroy the codecs.
414 DestroyEncoderAndDecoder();
415
416 // Close the analysis files before we use them for SSIM/PSNR calculations.
417 analysis_frame_reader_->Close();
418 analysis_frame_writer_->Close();
419
420 // Close visualization files.
421 if (encoded_frame_writer_) {
422 EXPECT_TRUE(encoded_frame_writer_->Close());
423 }
424 if (decoded_frame_writer_) {
425 decoded_frame_writer_->Close();
426 }
427 }
428
429 // For every encoded frame, update the rate control metrics.
430 void VideoProcessorIntegrationTest::UpdateRateControlMetrics(int frame_number) {
431 RTC_CHECK_GE(frame_number, 0);
432
433 const int tl_idx = TemporalLayerIndexForFrame(frame_number);
434 ++num_frames_per_update_[tl_idx];
435 ++num_frames_total_;
436
437 FrameType frame_type = stats_.stats_[frame_number].frame_type;
438 float encoded_size_kbits =
439 stats_.stats_[frame_number].encoded_frame_length_in_bytes * 8.0f /
440 1000.0f;
441
442 // Update layer data.
443 // Update rate mismatch relative to per-frame bandwidth for delta frames.
444 if (frame_type == kVideoFrameDelta) {
445 // TODO(marpan): Should we count dropped (zero size) frames in mismatch?
446 sum_frame_size_mismatch_[tl_idx] +=
447 fabs(encoded_size_kbits - per_frame_bandwidth_[tl_idx]) /
448 per_frame_bandwidth_[tl_idx];
449 } else {
450 float target_size = (frame_number == 0) ? target_size_key_frame_initial_
451 : target_size_key_frame_;
452 sum_key_frame_size_mismatch_ +=
453 fabs(encoded_size_kbits - target_size) / target_size;
454 num_key_frames_ += 1;
455 }
456 sum_encoded_frame_size_[tl_idx] += encoded_size_kbits;
457 // Encoding bit rate per temporal layer: from the start of the update/run
458 // to the current frame.
459 encoding_bitrate_[tl_idx] = sum_encoded_frame_size_[tl_idx] *
460 framerate_layer_[tl_idx] /
461 num_frames_per_update_[tl_idx];
462 // Total encoding rate: from the start of the update/run to current frame.
463 sum_encoded_frame_size_total_ += encoded_size_kbits;
464 encoding_bitrate_total_ =
465 sum_encoded_frame_size_total_ * framerate_ / num_frames_total_;
466 perc_encoding_rate_mismatch_ =
467 100 * fabs(encoding_bitrate_total_ - bitrate_kbps_) / bitrate_kbps_;
468 if (perc_encoding_rate_mismatch_ < kPercTargetvsActualMismatch &&
469 !encoding_rate_within_target_) {
470 num_frames_to_hit_target_ = num_frames_total_;
471 encoding_rate_within_target_ = true;
472 }
473 }
474
475 // Verify expected behavior of rate control and print out data.
476 void VideoProcessorIntegrationTest::PrintAndMaybeVerifyRateControlMetrics(
477 int rate_update_index,
478 const std::vector<RateControlThresholds>* rc_thresholds,
479 const std::vector<int>& num_dropped_frames,
480 const std::vector<int>& num_resize_actions) {
481 printf(
482 "Rate update #%d:\n"
483 " Target bitrate : %d\n"
484 " Encoded bitrate : %f\n"
485 " Frame rate : %d\n",
486 rate_update_index, bitrate_kbps_, encoding_bitrate_total_, framerate_);
487 printf(
488 " # processed frames : %d\n"
489 " # frames to convergence: %d\n"
490 " # dropped frames : %d\n"
491 " # spatial resizes : %d\n",
492 num_frames_total_, num_frames_to_hit_target_,
493 num_dropped_frames[rate_update_index],
494 num_resize_actions[rate_update_index]);
495
496 const RateControlThresholds* rc_threshold = nullptr;
497 if (rc_thresholds) {
498 rc_threshold = &(*rc_thresholds)[rate_update_index];
499
500 EXPECT_LE(perc_encoding_rate_mismatch_,
501 rc_threshold->max_encoding_rate_mismatch);
502 }
503 if (num_key_frames_ > 0) {
504 int perc_key_frame_size_mismatch =
505 100 * sum_key_frame_size_mismatch_ / num_key_frames_;
506 printf(
507 " # key frames : %d\n"
508 " Key frame rate mismatch: %d\n",
509 num_key_frames_, perc_key_frame_size_mismatch);
510 if (rc_threshold) {
511 EXPECT_LE(perc_key_frame_size_mismatch,
512 rc_threshold->max_key_frame_size_mismatch);
513 }
514 }
515
516 const int num_temporal_layers =
517 NumberOfTemporalLayers(config_.codec_settings);
518 for (int i = 0; i < num_temporal_layers; i++) {
519 int perc_frame_size_mismatch =
520 100 * sum_frame_size_mismatch_[i] / num_frames_per_update_[i];
521 int perc_encoding_rate_mismatch =
522 100 * fabs(encoding_bitrate_[i] - bitrate_layer_[i]) /
523 bitrate_layer_[i];
524 printf(
525 " Temporal layer #%d:\n"
526 " Target layer bitrate : %f\n"
527 " Layer frame rate : %f\n"
528 " Layer per frame bandwidth : %f\n"
529 " Layer encoding bitrate : %f\n"
530 " Layer percent frame size mismatch : %d\n"
531 " Layer percent encoding rate mismatch: %d\n"
532 " # frames processed per layer : %d\n",
533 i, bitrate_layer_[i], framerate_layer_[i], per_frame_bandwidth_[i],
534 encoding_bitrate_[i], perc_frame_size_mismatch,
535 perc_encoding_rate_mismatch, num_frames_per_update_[i]);
536 if (rc_threshold) {
537 EXPECT_LE(perc_frame_size_mismatch,
538 rc_threshold->max_delta_frame_size_mismatch);
539 EXPECT_LE(perc_encoding_rate_mismatch,
540 rc_threshold->max_encoding_rate_mismatch);
541 }
542 }
543 printf("\n");
544
545 if (rc_threshold) {
546 EXPECT_LE(num_frames_to_hit_target_, rc_threshold->max_time_hit_target);
547 EXPECT_LE(num_dropped_frames[rate_update_index],
548 rc_threshold->max_num_dropped_frames);
549 EXPECT_EQ(rc_threshold->num_spatial_resizes,
550 num_resize_actions[rate_update_index]);
551 EXPECT_EQ(rc_threshold->num_key_frames, num_key_frames_);
552 }
553 }
554
555 // Temporal layer index corresponding to frame number, for up to 3 layers.
556 int VideoProcessorIntegrationTest::TemporalLayerIndexForFrame(
557 int frame_number) const {
558 const int num_temporal_layers =
559 NumberOfTemporalLayers(config_.codec_settings);
560 int tl_idx = -1;
561 switch (num_temporal_layers) {
562 case 1:
563 tl_idx = 0;
564 break;
565 case 2:
566 // temporal layer 0: 0 2 4 ...
567 // temporal layer 1: 1 3
568 tl_idx = (frame_number % 2 == 0) ? 0 : 1;
569 break;
570 case 3:
571 // temporal layer 0: 0 4 8 ...
572 // temporal layer 1: 2 6
573 // temporal layer 2: 1 3 5 7
574 if (frame_number % 4 == 0) {
575 tl_idx = 0;
576 } else if ((frame_number + 2) % 4 == 0) {
577 tl_idx = 1;
578 } else if ((frame_number + 1) % 2 == 0) {
579 tl_idx = 2;
580 }
581 break;
582 default:
583 RTC_NOTREACHED();
584 break;
585 }
586 return tl_idx;
587 }
588
589 // Reset quantities before each encoder rate update.
590 void VideoProcessorIntegrationTest::ResetRateControlMetrics(
591 int rate_update_index,
592 const RateProfile& rate_profile) {
593 // Set new rates.
594 bitrate_kbps_ = rate_profile.target_bit_rate[rate_update_index];
595 framerate_ = rate_profile.input_frame_rate[rate_update_index];
596 const int num_temporal_layers =
597 NumberOfTemporalLayers(config_.codec_settings);
598 RTC_DCHECK_LE(num_temporal_layers, kMaxNumTemporalLayers);
599 for (int i = 0; i < num_temporal_layers; i++) {
600 float bit_rate_ratio = kVp8LayerRateAlloction[num_temporal_layers - 1][i];
601 if (i > 0) {
602 float bit_rate_delta_ratio =
603 kVp8LayerRateAlloction[num_temporal_layers - 1][i] -
604 kVp8LayerRateAlloction[num_temporal_layers - 1][i - 1];
605 bitrate_layer_[i] = bitrate_kbps_ * bit_rate_delta_ratio;
606 } else {
607 bitrate_layer_[i] = bitrate_kbps_ * bit_rate_ratio;
608 }
609 framerate_layer_[i] =
610 framerate_ / static_cast<float>(1 << (num_temporal_layers - 1));
611 }
612 if (num_temporal_layers == 3) {
613 framerate_layer_[2] = framerate_ / 2.0f;
614 }
615 if (rate_update_index == 0) {
616 target_size_key_frame_initial_ =
617 0.5 * kInitialBufferSize * bitrate_layer_[0];
618 }
619
620 // Reset rate control metrics.
621 for (int i = 0; i < num_temporal_layers; i++) {
622 num_frames_per_update_[i] = 0;
623 sum_frame_size_mismatch_[i] = 0.0f;
624 sum_encoded_frame_size_[i] = 0.0f;
625 encoding_bitrate_[i] = 0.0f;
626 // Update layer per-frame-bandwidth.
627 per_frame_bandwidth_[i] = static_cast<float>(bitrate_layer_[i]) /
628 static_cast<float>(framerate_layer_[i]);
629 }
630 // Set maximum size of key frames, following setting in the VP8 wrapper.
631 float max_key_size = kScaleKeyFrameSize * kOptimalBufferSize * framerate_;
632 // We don't know exact target size of the key frames (except for first one),
633 // but the minimum in libvpx is ~|3 * per_frame_bandwidth| and maximum is
634 // set by |max_key_size_ * per_frame_bandwidth|. Take middle point/average
635 // as reference for mismatch. Note key frames always correspond to base
636 // layer frame in this test.
637 target_size_key_frame_ = 0.5 * (3 + max_key_size) * per_frame_bandwidth_[0];
638 num_frames_total_ = 0;
639 sum_encoded_frame_size_total_ = 0.0f;
640 encoding_bitrate_total_ = 0.0f;
641 perc_encoding_rate_mismatch_ = 0.0f;
642 num_frames_to_hit_target_ =
643 rate_profile.frame_index_rate_update[rate_update_index + 1];
644 encoding_rate_within_target_ = false;
645 sum_key_frame_size_mismatch_ = 0.0;
646 num_key_frames_ = 0;
647 }
648
415 } // namespace test 649 } // namespace test
416 } // namespace webrtc 650 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698