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

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

Issue 2999113002: Run VideoProcessor on task queue in VideoProcessorIntegrationTest. (Closed)
Patch Set: Created 3 years, 4 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) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTEST_H _ 11 #ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTEST_H _
12 #define WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTEST_H _ 12 #define WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTEST_H _
13 13
14 #include <math.h> 14 #include <math.h>
15 15
16 #include <limits> 16 #include <limits>
17 #include <memory> 17 #include <memory>
18 #include <string> 18 #include <string>
19 #include <utility> 19 #include <utility>
20 #include <vector>
20 21
21 #if defined(WEBRTC_ANDROID) 22 #if defined(WEBRTC_ANDROID)
22 #include "webrtc/modules/video_coding/codecs/test/android_test_initializer.h" 23 #include "webrtc/modules/video_coding/codecs/test/android_test_initializer.h"
23 #include "webrtc/sdk/android/src/jni/androidmediadecoder_jni.h" 24 #include "webrtc/sdk/android/src/jni/androidmediadecoder_jni.h"
24 #include "webrtc/sdk/android/src/jni/androidmediaencoder_jni.h" 25 #include "webrtc/sdk/android/src/jni/androidmediaencoder_jni.h"
25 #elif defined(WEBRTC_IOS) 26 #elif defined(WEBRTC_IOS)
26 #include "webrtc/modules/video_coding/codecs/test/objc_codec_h264_test.h" 27 #include "webrtc/modules/video_coding/codecs/test/objc_codec_h264_test.h"
27 #endif 28 #endif
28 29
29 #include "webrtc/media/engine/internaldecoderfactory.h" 30 #include "webrtc/media/engine/internaldecoderfactory.h"
30 #include "webrtc/media/engine/internalencoderfactory.h" 31 #include "webrtc/media/engine/internalencoderfactory.h"
31 #include "webrtc/media/engine/webrtcvideodecoderfactory.h" 32 #include "webrtc/media/engine/webrtcvideodecoderfactory.h"
32 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" 33 #include "webrtc/media/engine/webrtcvideoencoderfactory.h"
33 #include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h" 34 #include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h"
34 #include "webrtc/modules/video_coding/codecs/test/videoprocessor.h" 35 #include "webrtc/modules/video_coding/codecs/test/videoprocessor.h"
35 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" 36 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h"
36 #include "webrtc/modules/video_coding/include/video_codec_interface.h" 37 #include "webrtc/modules/video_coding/include/video_codec_interface.h"
37 #include "webrtc/modules/video_coding/include/video_coding.h" 38 #include "webrtc/modules/video_coding/include/video_coding.h"
38 #include "webrtc/modules/video_coding/utility/ivf_file_writer.h" 39 #include "webrtc/modules/video_coding/utility/ivf_file_writer.h"
39 #include "webrtc/rtc_base/checks.h" 40 #include "webrtc/rtc_base/checks.h"
41 #include "webrtc/rtc_base/event.h"
40 #include "webrtc/rtc_base/file.h" 42 #include "webrtc/rtc_base/file.h"
41 #include "webrtc/rtc_base/logging.h" 43 #include "webrtc/rtc_base/logging.h"
42 #include "webrtc/rtc_base/ptr_util.h" 44 #include "webrtc/rtc_base/ptr_util.h"
45 #include "webrtc/system_wrappers/include/sleep.h"
43 #include "webrtc/test/gtest.h" 46 #include "webrtc/test/gtest.h"
44 #include "webrtc/test/testsupport/fileutils.h" 47 #include "webrtc/test/testsupport/fileutils.h"
45 #include "webrtc/test/testsupport/frame_reader.h" 48 #include "webrtc/test/testsupport/frame_reader.h"
46 #include "webrtc/test/testsupport/frame_writer.h" 49 #include "webrtc/test/testsupport/frame_writer.h"
47 #include "webrtc/test/testsupport/metrics/video_metrics.h" 50 #include "webrtc/test/testsupport/metrics/video_metrics.h"
48 #include "webrtc/test/testsupport/packet_reader.h" 51 #include "webrtc/test/testsupport/packet_reader.h"
49 #include "webrtc/test/video_codec_settings.h" 52 #include "webrtc/test/video_codec_settings.h"
50 #include "webrtc/typedefs.h" 53 #include "webrtc/typedefs.h"
51 54
52 namespace webrtc { 55 namespace webrtc {
53 namespace test { 56 namespace test {
54 57
55 const int kMaxNumRateUpdates = 3; 58 const int kMaxNumRateUpdates = 3;
56 const int kMaxNumTemporalLayers = 3; 59 const int kMaxNumTemporalLayers = 3;
57 60
58 const int kPercTargetvsActualMismatch = 20; 61 const int kPercTargetvsActualMismatch = 20;
59 const int kBaseKeyFrameInterval = 3000; 62 const int kBaseKeyFrameInterval = 3000;
60 63
61 // Parameters from VP8 wrapper, which control target size of key frames. 64 // Parameters from VP8 wrapper, which control target size of key frames.
62 const float kInitialBufferSize = 0.5f; 65 const float kInitialBufferSize = 0.5f;
63 const float kOptimalBufferSize = 0.6f; 66 const float kOptimalBufferSize = 0.6f;
64 const float kScaleKeyFrameSize = 0.5f; 67 const float kScaleKeyFrameSize = 0.5f;
65 68
66 // Thresholds for the quality metrics. Defaults are maximally minimal. 69 // Thresholds for the quality metrics. Defaults are maximally minimal.
67 struct QualityThresholds { 70 struct QualityThresholds {
68 QualityThresholds() {}
69 QualityThresholds(double min_avg_psnr, 71 QualityThresholds(double min_avg_psnr,
70 double min_min_psnr, 72 double min_min_psnr,
71 double min_avg_ssim, 73 double min_avg_ssim,
72 double min_min_ssim) 74 double min_min_ssim)
73 : min_avg_psnr(min_avg_psnr), 75 : min_avg_psnr(min_avg_psnr),
74 min_min_psnr(min_min_psnr), 76 min_min_psnr(min_min_psnr),
75 min_avg_ssim(min_avg_ssim), 77 min_avg_ssim(min_avg_ssim),
76 min_min_ssim(min_min_ssim) {} 78 min_min_ssim(min_min_ssim) {}
77 double min_avg_psnr = std::numeric_limits<double>::min(); 79 double min_avg_psnr;
78 double min_min_psnr = std::numeric_limits<double>::min(); 80 double min_min_psnr;
79 double min_avg_ssim = 0.0; 81 double min_avg_ssim;
80 double min_min_ssim = 0.0; 82 double min_min_ssim;
81 }; 83 };
82 84
83 // The sequence of bit rate and frame rate changes for the encoder, the frame 85 // The sequence of bit rate and frame rate changes for the encoder, the frame
84 // number where the changes are made, and the total number of frames for the 86 // number where the changes are made, and the total number of frames for the
85 // test. 87 // test.
86 struct RateProfile { 88 struct RateProfile {
87 int target_bit_rate[kMaxNumRateUpdates]; 89 int target_bit_rate[kMaxNumRateUpdates];
88 int input_frame_rate[kMaxNumRateUpdates]; 90 int input_frame_rate[kMaxNumRateUpdates];
89 int frame_index_rate_update[kMaxNumRateUpdates + 1]; 91 int frame_index_rate_update[kMaxNumRateUpdates + 1];
90 int num_frames; 92 int num_frames;
91 }; 93 };
92 94
93 // Thresholds for the rate control metrics. The rate mismatch thresholds are 95 // Thresholds for the rate control metrics. The rate mismatch thresholds are
94 // defined as percentages. |max_time_hit_target| is defined as number of frames, 96 // defined as percentages. |max_time_hit_target| is defined as number of frames,
95 // after a rate update is made to the encoder, for the encoder to reach within 97 // after a rate update is made to the encoder, for the encoder to reach within
96 // |kPercTargetvsActualMismatch| of new target rate. The thresholds are defined 98 // |kPercTargetvsActualMismatch| of new target rate. The thresholds are defined
97 // for each rate update sequence. 99 // for each rate update sequence.
98 struct RateControlThresholds { 100 struct RateControlThresholds {
99 int max_num_dropped_frames; 101 int max_num_dropped_frames;
100 int max_key_frame_size_mismatch; 102 int max_key_frame_size_mismatch;
101 int max_delta_frame_size_mismatch; 103 int max_delta_frame_size_mismatch;
102 int max_encoding_rate_mismatch; 104 int max_encoding_rate_mismatch;
103 int max_time_hit_target; 105 int max_time_hit_target;
104 int num_spatial_resizes; // Set to -1 to disable check. 106 int num_spatial_resizes;
105 int num_key_frames; // Set to -1 to disable check. 107 int num_key_frames;
106 }; 108 };
107 109
108 // Should video files be saved persistently to disk for post-run visualization? 110 // Should video files be saved persistently to disk for post-run visualization?
109 struct VisualizationParams { 111 struct VisualizationParams {
110 bool save_encoded_ivf; 112 bool save_encoded_ivf;
111 bool save_decoded_y4m; 113 bool save_decoded_y4m;
112 }; 114 };
113 115
114 // Integration test for video processor. Encodes+decodes a clip and 116 // Integration test for video processor. Encodes+decodes a clip and
115 // writes it to the output directory. After completion, quality metrics 117 // writes it to the output directory. After completion, quality metrics
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 // TODO(brandtr): Generalize so that we support multiple profiles here. 168 // TODO(brandtr): Generalize so that we support multiple profiles here.
167 encoder_ = encoder_factory_->CreateVideoEncoder( 169 encoder_ = encoder_factory_->CreateVideoEncoder(
168 cricket::VideoCodec(cricket::kH264CodecName)); 170 cricket::VideoCodec(cricket::kH264CodecName));
169 decoder_ = decoder_factory_->CreateVideoDecoder(kVideoCodecH264); 171 decoder_ = decoder_factory_->CreateVideoDecoder(kVideoCodecH264);
170 break; 172 break;
171 default: 173 default:
172 RTC_NOTREACHED(); 174 RTC_NOTREACHED();
173 break; 175 break;
174 } 176 }
175 177
176 RTC_CHECK(encoder_) << "Encoder not successfully created."; 178 EXPECT_TRUE(encoder_) << "Encoder not successfully created.";
177 RTC_CHECK(decoder_) << "Decoder not successfully created."; 179 EXPECT_TRUE(decoder_) << "Decoder not successfully created.";
178 } 180 }
179 181
180 void DestroyEncoderAndDecoder() { 182 void DestroyEncoderAndDecoder() {
181 encoder_factory_->DestroyVideoEncoder(encoder_); 183 encoder_factory_->DestroyVideoEncoder(encoder_);
182 decoder_factory_->DestroyVideoDecoder(decoder_); 184 decoder_factory_->DestroyVideoDecoder(decoder_);
183 } 185 }
184 186
185 void SetUpObjects(const VisualizationParams* visualization_params, 187 void SetUpAndInitObjects(rtc::TaskQueue* task_queue,
186 const int initial_bitrate_kbps, 188 const int initial_bitrate_kbps,
187 const int initial_framerate_fps) { 189 const int initial_framerate_fps,
190 const VisualizationParams* visualization_params) {
188 CreateEncoderAndDecoder(); 191 CreateEncoderAndDecoder();
189 192
190 // Create file objects for quality analysis. 193 // Create file objects for quality analysis.
191 analysis_frame_reader_.reset(new YuvFrameReaderImpl( 194 analysis_frame_reader_.reset(new YuvFrameReaderImpl(
192 config_.input_filename, config_.codec_settings.width, 195 config_.input_filename, config_.codec_settings.width,
193 config_.codec_settings.height)); 196 config_.codec_settings.height));
194 analysis_frame_writer_.reset(new YuvFrameWriterImpl( 197 analysis_frame_writer_.reset(new YuvFrameWriterImpl(
195 config_.output_filename, config_.codec_settings.width, 198 config_.output_filename, config_.codec_settings.width,
196 config_.codec_settings.height)); 199 config_.codec_settings.height));
197 RTC_CHECK(analysis_frame_reader_->Init()); 200 EXPECT_TRUE(analysis_frame_reader_->Init());
198 RTC_CHECK(analysis_frame_writer_->Init()); 201 EXPECT_TRUE(analysis_frame_writer_->Init());
199 202
200 if (visualization_params) { 203 if (visualization_params) {
201 const std::string codec_name = 204 const std::string codec_name =
202 CodecTypeToPayloadName(config_.codec_settings.codecType) 205 CodecTypeToPayloadName(config_.codec_settings.codecType)
203 .value_or("unknown"); 206 .value_or("unknown");
204 const std::string implementation_type = config_.hw_codec ? "hw" : "sw"; 207 const std::string implementation_type = config_.hw_codec ? "hw" : "sw";
205 // clang-format off 208 // clang-format off
206 const std::string output_filename_base = 209 const std::string output_filename_base =
207 OutputPath() + config_.filename + "-" + 210 OutputPath() + config_.filename + "-" +
208 codec_name + "-" + implementation_type + "-" + 211 codec_name + "-" + implementation_type + "-" +
209 std::to_string(initial_bitrate_kbps); 212 std::to_string(initial_bitrate_kbps);
210 // clang-format on 213 // clang-format on
211 if (visualization_params->save_encoded_ivf) { 214 if (visualization_params->save_encoded_ivf) {
212 rtc::File post_encode_file = 215 rtc::File post_encode_file =
213 rtc::File::Create(output_filename_base + "_encoded.ivf"); 216 rtc::File::Create(output_filename_base + ".ivf");
214 encoded_frame_writer_ = 217 encoded_frame_writer_ =
215 IvfFileWriter::Wrap(std::move(post_encode_file), 0); 218 IvfFileWriter::Wrap(std::move(post_encode_file), 0);
216 } 219 }
217 if (visualization_params->save_decoded_y4m) { 220 if (visualization_params->save_decoded_y4m) {
218 decoded_frame_writer_.reset(new Y4mFrameWriterImpl( 221 decoded_frame_writer_.reset(new Y4mFrameWriterImpl(
219 output_filename_base + "_decoded.y4m", config_.codec_settings.width, 222 output_filename_base + ".y4m", config_.codec_settings.width,
220 config_.codec_settings.height, initial_framerate_fps)); 223 config_.codec_settings.height, initial_framerate_fps));
221 RTC_CHECK(decoded_frame_writer_->Init()); 224 EXPECT_TRUE(decoded_frame_writer_->Init());
222 } 225 }
223 } 226 }
224 227
225 packet_manipulator_.reset(new PacketManipulatorImpl( 228 packet_manipulator_.reset(new PacketManipulatorImpl(
226 &packet_reader_, config_.networking_config, config_.verbose)); 229 &packet_reader_, config_.networking_config, config_.verbose));
227 processor_ = rtc::MakeUnique<VideoProcessor>( 230
228 encoder_, decoder_, analysis_frame_reader_.get(), 231 config_.codec_settings.startBitrate = initial_bitrate_kbps;
229 analysis_frame_writer_.get(), packet_manipulator_.get(), config_, 232
230 &stats_, encoded_frame_writer_.get(), decoded_frame_writer_.get()); 233 rtc::Event sync_event(false, false);
231 processor_->Init(); 234 task_queue->PostTask([this, &sync_event]() {
235 processor_ = rtc::MakeUnique<VideoProcessor>(
236 encoder_, decoder_, analysis_frame_reader_.get(),
237 analysis_frame_writer_.get(), packet_manipulator_.get(), config_,
238 &stats_, encoded_frame_writer_.get(), decoded_frame_writer_.get());
239 processor_->Init();
240 sync_event.Set();
241 });
242 sync_event.Wait(rtc::Event::kForever);
243 }
244
245 void ReleaseAndCloseObjects(rtc::TaskQueue* task_queue) {
246 rtc::Event sync_event(false, false);
247 task_queue->PostTask([this, &sync_event]() {
248 processor_->Release();
249 sync_event.Set();
250 });
251 sync_event.Wait(rtc::Event::kForever);
252
253 // The VideoProcessor must be ::Release()'d before we destroy the codecs.
254 DestroyEncoderAndDecoder();
255
256 // Close the analysis files before we use them for SSIM/PSNR calculations.
257 analysis_frame_reader_->Close();
258 analysis_frame_writer_->Close();
259
260 // Close visualization files.
261 if (encoded_frame_writer_) {
262 EXPECT_TRUE(encoded_frame_writer_->Close());
263 }
264 if (decoded_frame_writer_) {
265 decoded_frame_writer_->Close();
266 }
232 } 267 }
233 268
234 // Reset quantities after each encoder update, update the target per-frame 269 // Reset quantities after each encoder update, update the target per-frame
235 // bandwidth. 270 // bandwidth.
236 void ResetRateControlMetrics(int num_frames_to_hit_target) { 271 void ResetRateControlMetrics(int num_frames_to_hit_target) {
237 const int num_temporal_layers = 272 const int num_temporal_layers =
238 NumberOfTemporalLayers(config_.codec_settings); 273 NumberOfTemporalLayers(config_.codec_settings);
239 for (int i = 0; i < num_temporal_layers; i++) { 274 for (int i = 0; i < num_temporal_layers; i++) {
240 num_frames_per_update_[i] = 0; 275 num_frames_per_update_[i] = 0;
241 sum_frame_size_mismatch_[i] = 0.0f; 276 sum_frame_size_mismatch_[i] = 0.0f;
242 sum_encoded_frame_size_[i] = 0.0f; 277 sum_encoded_frame_size_[i] = 0.0f;
243 encoding_bitrate_[i] = 0.0f; 278 encoding_bitrate_[i] = 0.0f;
244 // Update layer per-frame-bandwidth. 279 // Update layer per-frame-bandwidth.
245 per_frame_bandwidth_[i] = static_cast<float>(bit_rate_layer_[i]) / 280 per_frame_bandwidth_[i] = static_cast<float>(bitrate_layer_[i]) /
246 static_cast<float>(frame_rate_layer_[i]); 281 static_cast<float>(framerate_layer_[i]);
247 } 282 }
248 // Set maximum size of key frames, following setting in the VP8 wrapper. 283 // Set maximum size of key frames, following setting in the VP8 wrapper.
249 float max_key_size = kScaleKeyFrameSize * kOptimalBufferSize * frame_rate_; 284 float max_key_size = kScaleKeyFrameSize * kOptimalBufferSize * framerate_;
250 // We don't know exact target size of the key frames (except for first one), 285 // We don't know exact target size of the key frames (except for first one),
251 // but the minimum in libvpx is ~|3 * per_frame_bandwidth| and maximum is 286 // but the minimum in libvpx is ~|3 * per_frame_bandwidth| and maximum is
252 // set by |max_key_size_ * per_frame_bandwidth|. Take middle point/average 287 // set by |max_key_size_ * per_frame_bandwidth|. Take middle point/average
253 // as reference for mismatch. Note key frames always correspond to base 288 // as reference for mismatch. Note key frames always correspond to base
254 // layer frame in this test. 289 // layer frame in this test.
255 target_size_key_frame_ = 0.5 * (3 + max_key_size) * per_frame_bandwidth_[0]; 290 target_size_key_frame_ = 0.5 * (3 + max_key_size) * per_frame_bandwidth_[0];
256 num_frames_total_ = 0; 291 num_frames_total_ = 0;
257 sum_encoded_frame_size_total_ = 0.0f; 292 sum_encoded_frame_size_total_ = 0.0f;
258 encoding_bitrate_total_ = 0.0f; 293 encoding_bitrate_total_ = 0.0f;
259 perc_encoding_rate_mismatch_ = 0.0f; 294 perc_encoding_rate_mismatch_ = 0.0f;
260 num_frames_to_hit_target_ = num_frames_to_hit_target; 295 num_frames_to_hit_target_ = num_frames_to_hit_target;
261 encoding_rate_within_target_ = false; 296 encoding_rate_within_target_ = false;
262 sum_key_frame_size_mismatch_ = 0.0; 297 sum_key_frame_size_mismatch_ = 0.0;
263 num_key_frames_ = 0; 298 num_key_frames_ = 0;
264 } 299 }
265 300
266 // For every encoded frame, update the rate control metrics. 301 // For every encoded frame, update the rate control metrics.
267 void UpdateRateControlMetrics(int frame_number) { 302 void UpdateRateControlMetrics(int frame_number) {
268 RTC_CHECK_GE(frame_number, 0); 303 RTC_CHECK_GE(frame_number, 0);
269 int tl_idx = TemporalLayerIndexForFrame(frame_number); 304 int tl_idx = TemporalLayerIndexForFrame(frame_number);
270 FrameType frame_type = processor_->EncodedFrameType(frame_number); 305 FrameType frame_type = stats_.stats_[frame_number].frame_type;
271 float encoded_size_kbits = 306 float encoded_size_kbits =
272 processor_->EncodedFrameSize(frame_number) * 8.0f / 1000.0f; 307 stats_.stats_[frame_number].encoded_frame_length_in_bytes * 8.0f /
308 1000.0f;
273 309
274 // Update layer data. 310 // Update layer data.
275 // Update rate mismatch relative to per-frame bandwidth for delta frames. 311 // Update rate mismatch relative to per-frame bandwidth for delta frames.
276 if (frame_type == kVideoFrameDelta) { 312 if (frame_type == kVideoFrameDelta) {
277 // TODO(marpan): Should we count dropped (zero size) frames in mismatch? 313 // TODO(marpan): Should we count dropped (zero size) frames in mismatch?
278 sum_frame_size_mismatch_[tl_idx] += 314 sum_frame_size_mismatch_[tl_idx] +=
279 fabs(encoded_size_kbits - per_frame_bandwidth_[tl_idx]) / 315 fabs(encoded_size_kbits - per_frame_bandwidth_[tl_idx]) /
280 per_frame_bandwidth_[tl_idx]; 316 per_frame_bandwidth_[tl_idx];
281 } else { 317 } else {
282 float target_size = (frame_number == 0) ? target_size_key_frame_initial_ 318 float target_size = (frame_number == 0) ? target_size_key_frame_initial_
283 : target_size_key_frame_; 319 : target_size_key_frame_;
284 sum_key_frame_size_mismatch_ += 320 sum_key_frame_size_mismatch_ +=
285 fabs(encoded_size_kbits - target_size) / target_size; 321 fabs(encoded_size_kbits - target_size) / target_size;
286 num_key_frames_ += 1; 322 num_key_frames_ += 1;
287 } 323 }
288 sum_encoded_frame_size_[tl_idx] += encoded_size_kbits; 324 sum_encoded_frame_size_[tl_idx] += encoded_size_kbits;
289 // Encoding bit rate per temporal layer: from the start of the update/run 325 // Encoding bit rate per temporal layer: from the start of the update/run
290 // to the current frame. 326 // to the current frame.
291 encoding_bitrate_[tl_idx] = sum_encoded_frame_size_[tl_idx] * 327 encoding_bitrate_[tl_idx] = sum_encoded_frame_size_[tl_idx] *
292 frame_rate_layer_[tl_idx] / 328 framerate_layer_[tl_idx] /
293 num_frames_per_update_[tl_idx]; 329 num_frames_per_update_[tl_idx];
294 // Total encoding rate: from the start of the update/run to current frame. 330 // Total encoding rate: from the start of the update/run to current frame.
295 sum_encoded_frame_size_total_ += encoded_size_kbits; 331 sum_encoded_frame_size_total_ += encoded_size_kbits;
296 encoding_bitrate_total_ = 332 encoding_bitrate_total_ =
297 sum_encoded_frame_size_total_ * frame_rate_ / num_frames_total_; 333 sum_encoded_frame_size_total_ * framerate_ / num_frames_total_;
298 perc_encoding_rate_mismatch_ = 334 perc_encoding_rate_mismatch_ =
299 100 * fabs(encoding_bitrate_total_ - bit_rate_) / bit_rate_; 335 100 * fabs(encoding_bitrate_total_ - bitrate_kbps_) / bitrate_kbps_;
300 if (perc_encoding_rate_mismatch_ < kPercTargetvsActualMismatch && 336 if (perc_encoding_rate_mismatch_ < kPercTargetvsActualMismatch &&
301 !encoding_rate_within_target_) { 337 !encoding_rate_within_target_) {
302 num_frames_to_hit_target_ = num_frames_total_; 338 num_frames_to_hit_target_ = num_frames_total_;
303 encoding_rate_within_target_ = true; 339 encoding_rate_within_target_ = true;
304 } 340 }
305 } 341 }
306 342
307 // Verify expected behavior of rate control and print out data. 343 // Verify expected behavior of rate control and print out data.
308 void VerifyRateControlMetrics(int update_index, 344 void PrintAndMaybeVerifyRateControlMetrics(
309 const RateControlThresholds& rc_expected) { 345 int rate_update_index,
310 int num_dropped_frames = processor_->NumberDroppedFrames(); 346 const std::vector<RateControlThresholds>* rc_thresholds,
311 int num_resize_actions = processor_->NumberSpatialResizes(); 347 const std::vector<int>& num_dropped_frames,
348 const std::vector<int>& num_resize_actions) {
349 const RateControlThresholds* rc_threshold = nullptr;
350 if (rc_thresholds) {
351 rc_threshold = &(*rc_thresholds)[rate_update_index];
352
353 EXPECT_LE(perc_encoding_rate_mismatch_,
354 rc_threshold->max_encoding_rate_mismatch);
355 }
356
312 printf( 357 printf(
313 "Rate update #%d:\n" 358 "Rate update #%d:\n"
314 " Target bitrate : %d\n" 359 " Target bitrate : %d\n"
315 " Encoded bitrate : %f\n" 360 " Encoded bitrate : %f\n"
316 " Frame rate : %d\n", 361 " Frame rate : %d\n",
317 update_index, bit_rate_, encoding_bitrate_total_, frame_rate_); 362 rate_update_index, bitrate_kbps_, encoding_bitrate_total_, framerate_);
318 printf( 363 printf(
319 " # processed frames : %d\n" 364 " # processed frames : %d\n"
320 " # frames to convergence: %d\n" 365 " # frames to convergence: %d\n"
321 " # dropped frames : %d\n" 366 " # dropped frames : %d\n"
322 " # spatial resizes : %d\n", 367 " # spatial resizes : %d\n",
323 num_frames_total_, num_frames_to_hit_target_, num_dropped_frames, 368 num_frames_total_, num_frames_to_hit_target_,
324 num_resize_actions); 369 num_dropped_frames[rate_update_index],
325 EXPECT_LE(perc_encoding_rate_mismatch_, 370 num_resize_actions[rate_update_index]);
326 rc_expected.max_encoding_rate_mismatch); 371
327 if (num_key_frames_ > 0) { 372 if (num_key_frames_ > 0) {
328 int perc_key_frame_size_mismatch = 373 int perc_key_frame_size_mismatch =
329 100 * sum_key_frame_size_mismatch_ / num_key_frames_; 374 100 * sum_key_frame_size_mismatch_ / num_key_frames_;
330 printf( 375 printf(
331 " # key frames : %d\n" 376 " # key frames : %d\n"
332 " Key frame rate mismatch: %d\n", 377 " Key frame rate mismatch: %d\n",
333 num_key_frames_, perc_key_frame_size_mismatch); 378 num_key_frames_, perc_key_frame_size_mismatch);
334 EXPECT_LE(perc_key_frame_size_mismatch, 379 if (rc_threshold) {
335 rc_expected.max_key_frame_size_mismatch); 380 EXPECT_LE(perc_key_frame_size_mismatch,
381 rc_threshold->max_key_frame_size_mismatch);
382 }
336 } 383 }
384
337 const int num_temporal_layers = 385 const int num_temporal_layers =
338 NumberOfTemporalLayers(config_.codec_settings); 386 NumberOfTemporalLayers(config_.codec_settings);
339 for (int i = 0; i < num_temporal_layers; i++) { 387 for (int i = 0; i < num_temporal_layers; i++) {
340 printf(" Temporal layer #%d:\n", i); 388 printf(" Temporal layer #%d:\n", i);
341 int perc_frame_size_mismatch = 389 int perc_frame_size_mismatch =
342 100 * sum_frame_size_mismatch_[i] / num_frames_per_update_[i]; 390 100 * sum_frame_size_mismatch_[i] / num_frames_per_update_[i];
343 int perc_encoding_rate_mismatch = 391 int perc_encoding_rate_mismatch =
344 100 * fabs(encoding_bitrate_[i] - bit_rate_layer_[i]) / 392 100 * fabs(encoding_bitrate_[i] - bitrate_layer_[i]) /
345 bit_rate_layer_[i]; 393 bitrate_layer_[i];
346 printf( 394 printf(
347 " Target layer bitrate : %f\n" 395 " Target layer bitrate : %f\n"
348 " Layer frame rate : %f\n" 396 " Layer frame rate : %f\n"
349 " Layer per frame bandwidth : %f\n" 397 " Layer per frame bandwidth : %f\n"
350 " Layer encoding bitrate : %f\n" 398 " Layer encoding bitrate : %f\n"
351 " Layer percent frame size mismatch : %d\n" 399 " Layer percent frame size mismatch : %d\n"
352 " Layer percent encoding rate mismatch: %d\n" 400 " Layer percent encoding rate mismatch: %d\n"
353 " # frame processed per layer : %d\n", 401 " # frames processed per layer : %d\n",
354 bit_rate_layer_[i], frame_rate_layer_[i], per_frame_bandwidth_[i], 402 bitrate_layer_[i], framerate_layer_[i], per_frame_bandwidth_[i],
355 encoding_bitrate_[i], perc_frame_size_mismatch, 403 encoding_bitrate_[i], perc_frame_size_mismatch,
356 perc_encoding_rate_mismatch, num_frames_per_update_[i]); 404 perc_encoding_rate_mismatch, num_frames_per_update_[i]);
357 EXPECT_LE(perc_frame_size_mismatch, 405 if (rc_threshold) {
358 rc_expected.max_delta_frame_size_mismatch); 406 EXPECT_LE(perc_frame_size_mismatch,
359 EXPECT_LE(perc_encoding_rate_mismatch, 407 rc_threshold->max_delta_frame_size_mismatch);
360 rc_expected.max_encoding_rate_mismatch); 408 EXPECT_LE(perc_encoding_rate_mismatch,
409 rc_threshold->max_encoding_rate_mismatch);
410 }
361 } 411 }
362 printf("\n"); 412 printf("\n");
363 EXPECT_LE(num_frames_to_hit_target_, rc_expected.max_time_hit_target); 413
364 EXPECT_LE(num_dropped_frames, rc_expected.max_num_dropped_frames); 414 if (rc_threshold) {
365 if (rc_expected.num_spatial_resizes >= 0) { 415 EXPECT_LE(num_frames_to_hit_target_, rc_threshold->max_time_hit_target);
366 EXPECT_EQ(rc_expected.num_spatial_resizes, num_resize_actions); 416 EXPECT_LE(num_dropped_frames[rate_update_index],
367 } 417 rc_threshold->max_num_dropped_frames);
368 if (rc_expected.num_key_frames >= 0) { 418 EXPECT_EQ(rc_threshold->num_spatial_resizes,
369 EXPECT_EQ(rc_expected.num_key_frames, num_key_frames_); 419 num_resize_actions[rate_update_index]);
420 EXPECT_EQ(rc_threshold->num_key_frames, num_key_frames_);
370 } 421 }
371 } 422 }
372 423
373 void VerifyQuality(const QualityMetricsResult& psnr_result, 424 static void VerifyQuality(const QualityMetricsResult& psnr_result,
374 const QualityMetricsResult& ssim_result, 425 const QualityMetricsResult& ssim_result,
375 const QualityThresholds& quality_thresholds) { 426 const QualityThresholds& quality_thresholds) {
376 EXPECT_GT(psnr_result.average, quality_thresholds.min_avg_psnr); 427 EXPECT_GT(psnr_result.average, quality_thresholds.min_avg_psnr);
377 EXPECT_GT(psnr_result.min, quality_thresholds.min_min_psnr); 428 EXPECT_GT(psnr_result.min, quality_thresholds.min_min_psnr);
378 EXPECT_GT(ssim_result.average, quality_thresholds.min_avg_ssim); 429 EXPECT_GT(ssim_result.average, quality_thresholds.min_avg_ssim);
379 EXPECT_GT(ssim_result.min, quality_thresholds.min_min_ssim); 430 EXPECT_GT(ssim_result.min, quality_thresholds.min_min_ssim);
380 } 431 }
381 432
382 void VerifyQpParser(int frame_number) { 433 static int NumberOfTemporalLayers(const VideoCodec& codec_settings) {
383 if (!config_.hw_codec &&
384 (config_.codec_settings.codecType == kVideoCodecVP8 ||
385 config_.codec_settings.codecType == kVideoCodecVP9)) {
386 EXPECT_EQ(processor_->GetQpFromEncoder(frame_number),
387 processor_->GetQpFromBitstream(frame_number));
388 }
389 }
390
391 int NumberOfTemporalLayers(const VideoCodec& codec_settings) {
392 if (codec_settings.codecType == kVideoCodecVP8) { 434 if (codec_settings.codecType == kVideoCodecVP8) {
393 return codec_settings.VP8().numberOfTemporalLayers; 435 return codec_settings.VP8().numberOfTemporalLayers;
394 } else if (codec_settings.codecType == kVideoCodecVP9) { 436 } else if (codec_settings.codecType == kVideoCodecVP9) {
395 return codec_settings.VP9().numberOfTemporalLayers; 437 return codec_settings.VP9().numberOfTemporalLayers;
396 } else { 438 } else {
397 return 1; 439 return 1;
398 } 440 }
399 } 441 }
400 442
401 // Temporal layer index corresponding to frame number, for up to 3 layers. 443 // Temporal layer index corresponding to frame number, for up to 3 layers.
(...skipping 22 matching lines...) Expand all
424 tl_idx = 2; 466 tl_idx = 2;
425 } 467 }
426 break; 468 break;
427 default: 469 default:
428 RTC_NOTREACHED(); 470 RTC_NOTREACHED();
429 break; 471 break;
430 } 472 }
431 return tl_idx; 473 return tl_idx;
432 } 474 }
433 475
434 // Set the bit rate and frame rate per temporal layer, for up to 3 layers. 476 void UpdateRates(int rate_update_index, const RateProfile& rate_profile) {
435 void SetTemporalLayerRates() { 477 bitrate_kbps_ = rate_profile.target_bit_rate[rate_update_index];
478 framerate_ = rate_profile.input_frame_rate[rate_update_index];
479
436 const int num_temporal_layers = 480 const int num_temporal_layers =
437 NumberOfTemporalLayers(config_.codec_settings); 481 NumberOfTemporalLayers(config_.codec_settings);
438 RTC_DCHECK_LE(num_temporal_layers, kMaxNumTemporalLayers); 482 RTC_DCHECK_LE(num_temporal_layers, kMaxNumTemporalLayers);
439 for (int i = 0; i < num_temporal_layers; i++) { 483 for (int i = 0; i < num_temporal_layers; i++) {
440 float bit_rate_ratio = kVp8LayerRateAlloction[num_temporal_layers - 1][i]; 484 float bit_rate_ratio = kVp8LayerRateAlloction[num_temporal_layers - 1][i];
441 if (i > 0) { 485 if (i > 0) {
442 float bit_rate_delta_ratio = 486 float bit_rate_delta_ratio =
443 kVp8LayerRateAlloction[num_temporal_layers - 1][i] - 487 kVp8LayerRateAlloction[num_temporal_layers - 1][i] -
444 kVp8LayerRateAlloction[num_temporal_layers - 1][i - 1]; 488 kVp8LayerRateAlloction[num_temporal_layers - 1][i - 1];
445 bit_rate_layer_[i] = bit_rate_ * bit_rate_delta_ratio; 489 bitrate_layer_[i] = bitrate_kbps_ * bit_rate_delta_ratio;
446 } else { 490 } else {
447 bit_rate_layer_[i] = bit_rate_ * bit_rate_ratio; 491 bitrate_layer_[i] = bitrate_kbps_ * bit_rate_ratio;
448 } 492 }
449 frame_rate_layer_[i] = 493 framerate_layer_[i] =
450 frame_rate_ / static_cast<float>(1 << (num_temporal_layers - 1)); 494 framerate_ / static_cast<float>(1 << (num_temporal_layers - 1));
451 } 495 }
452 if (num_temporal_layers == 3) { 496 if (num_temporal_layers == 3) {
453 frame_rate_layer_[2] = frame_rate_ / 2.0f; 497 framerate_layer_[2] = framerate_ / 2.0f;
454 } 498 }
455 } 499 }
456 500
457 // Processes all frames in the clip and verifies the result. 501 // Processes all frames in the clip and verifies the result.
458 // TODO(brandtr): Change the second last argument to be a 502 void ProcessFramesAndMaybeVerify(
459 // const std::vector<RateControlThresholds>&, so we can ensure that the user 503 const RateProfile& rate_profile,
460 // does not expect us to do mid-clip rate updates when we are not able to, 504 const std::vector<RateControlThresholds>* rc_thresholds,
461 // e.g., when we are operating in batch mode. 505 const QualityThresholds* quality_thresholds,
462 void ProcessFramesAndVerify(const QualityThresholds& quality_thresholds, 506 const VisualizationParams* visualization_params) {
463 const RateProfile& rate_profile, 507 // The Android HW codec needs to be run on a task queue, so we simply always
464 RateControlThresholds* rc_thresholds, 508 // run the test on a task queue.
465 const VisualizationParams* visualization_params) { 509 rtc::TaskQueue task_queue("VidProc TQ");
466 config_.codec_settings.startBitrate = rate_profile.target_bit_rate[0]; 510
467 SetUpObjects(visualization_params, rate_profile.target_bit_rate[0], 511 SetUpAndInitObjects(&task_queue, rate_profile.target_bit_rate[0],
468 rate_profile.input_frame_rate[0]); 512 rate_profile.input_frame_rate[0], visualization_params);
469 513
470 // Set initial rates. 514 // Set initial rates.
471 bit_rate_ = rate_profile.target_bit_rate[0]; 515 int rate_update_index = 0;
472 frame_rate_ = rate_profile.input_frame_rate[0]; 516 task_queue.PostTask([this, &rate_profile, rate_update_index] {
473 SetTemporalLayerRates(); 517 processor_->SetRates(rate_profile.target_bit_rate[rate_update_index],
474 // Set the initial target size for key frame. 518 rate_profile.input_frame_rate[rate_update_index]);
475 target_size_key_frame_initial_ = 519 });
476 0.5 * kInitialBufferSize * bit_rate_layer_[0];
477 processor_->SetRates(bit_rate_, frame_rate_);
478 520
479 // Process each frame, up to |num_frames|. 521 // Process all frames.
480 int frame_number = 0; 522 int frame_number = 0;
481 int update_index = 0; 523 const int num_frames = rate_profile.num_frames;
482 int num_frames = rate_profile.num_frames; 524 while (frame_number < num_frames) {
483 ResetRateControlMetrics( 525 // In order to not overwhelm the OpenMAX buffers in the Android
484 rate_profile.frame_index_rate_update[update_index + 1]); 526 // MediaCodec API, we roughly pace the frames here. The downside
485 527 // of this is that the encode run will be done in real-time.
486 if (config_.batch_mode) { 528 // TODO(brandtr): Investigate if this is needed on iOS.
487 // In batch mode, we calculate the metrics for all frames after all frames 529 if (config_.hw_codec) {
488 // have been sent for encoding. 530 SleepMs(rtc::kNumMillisecsPerSec /
489 531 rate_profile.input_frame_rate[rate_update_index]);
490 // TODO(brandtr): Refactor "frame number accounting" so we don't have to
491 // call ProcessFrame num_frames+1 times here.
492 for (frame_number = 0; frame_number <= num_frames; ++frame_number) {
493 EXPECT_TRUE(processor_->ProcessFrame(frame_number));
494 } 532 }
495 533
496 for (frame_number = 0; frame_number < num_frames; ++frame_number) { 534 task_queue.PostTask(
497 const int tl_idx = TemporalLayerIndexForFrame(frame_number); 535 [this, frame_number] { processor_->ProcessFrame(frame_number); });
498 ++num_frames_per_update_[tl_idx]; 536 ++frame_number;
499 ++num_frames_total_; 537
500 UpdateRateControlMetrics(frame_number); 538 if (frame_number ==
539 rate_profile.frame_index_rate_update[rate_update_index + 1]) {
540 ++rate_update_index;
541
542 task_queue.PostTask([this, &rate_profile, rate_update_index] {
543 processor_->SetRates(
544 rate_profile.target_bit_rate[rate_update_index],
545 rate_profile.input_frame_rate[rate_update_index]);
546 });
501 } 547 }
502 } else {
503 // In online mode, we calculate the metrics for a given frame right after
504 // it has been sent for encoding.
505
506 if (config_.hw_codec) {
507 LOG(LS_WARNING) << "HW codecs should mostly be run in batch mode, "
508 "since they may be pipelining.";
509 }
510
511 while (frame_number < num_frames) {
512 EXPECT_TRUE(processor_->ProcessFrame(frame_number));
513 VerifyQpParser(frame_number);
514 const int tl_idx = TemporalLayerIndexForFrame(frame_number);
515 ++num_frames_per_update_[tl_idx];
516 ++num_frames_total_;
517 UpdateRateControlMetrics(frame_number);
518
519 ++frame_number;
520
521 // If we hit another/next update, verify stats for current state and
522 // update layers and codec with new rates.
523 if (frame_number ==
524 rate_profile.frame_index_rate_update[update_index + 1]) {
525 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]);
526
527 // Update layer rates and the codec with new rates.
528 ++update_index;
529 bit_rate_ = rate_profile.target_bit_rate[update_index];
530 frame_rate_ = rate_profile.input_frame_rate[update_index];
531 SetTemporalLayerRates();
532 ResetRateControlMetrics(
533 rate_profile.frame_index_rate_update[update_index + 1]);
534 processor_->SetRates(bit_rate_, frame_rate_);
535 }
536 }
537 // TODO(brandtr): Refactor "frame number accounting" so we don't have to
538 // call ProcessFrame one extra time here.
539 EXPECT_TRUE(processor_->ProcessFrame(frame_number));
540 } 548 }
541 549
542 // Verify rate control metrics for all frames (if in batch mode), or for all 550 // TODO(brandtr): Verify the assumption that HW codecs never
543 // frames since the last rate update (if not in batch mode). 551 // drop frames internally.
544 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); 552 if (config_.hw_codec) {
545 EXPECT_EQ(num_frames, frame_number); 553 // Ensure that all the frames have been encoded and decoded.
546 EXPECT_EQ(num_frames + 1, static_cast<int>(stats_.stats_.size())); 554 rtc::Event sync_event(false, false);
555 int num_frames_decoded = -1;
556 int wait_count = 0;
557 while (num_frames_decoded < num_frames && wait_count++ < 10) {
558 sync_event.Reset();
559 task_queue.PostTask([this, &num_frames_decoded, &sync_event]() {
560 num_frames_decoded = processor_->NumFramesDecoded();
561 sync_event.Set();
562 });
563 sync_event.Wait(rtc::Event::kForever);
547 564
548 // Release encoder and decoder to make sure they have finished processing. 565 SleepMs(1000);
549 processor_->Release(); 566 }
550 DestroyEncoderAndDecoder(); 567 EXPECT_LT(wait_count, 10) << "Lost frames in the VideoProcessor.";
551
552 // Close the analysis files before we use them for SSIM/PSNR calculations.
553 analysis_frame_reader_->Close();
554 analysis_frame_writer_->Close();
555
556 // Close visualization files.
557 if (encoded_frame_writer_) {
558 EXPECT_TRUE(encoded_frame_writer_->Close());
559 }
560 if (decoded_frame_writer_) {
561 decoded_frame_writer_->Close();
562 } 568 }
563 569
570 ReleaseAndCloseObjects(&task_queue);
571
572 // Verify QP parsing.
573 if (!config_.hw_codec &&
574 (config_.codec_settings.codecType == kVideoCodecVP8 ||
575 config_.codec_settings.codecType == kVideoCodecVP9)) {
576 for (int frame_number = 0; frame_number < num_frames; ++frame_number) {
577 task_queue.PostTask([this, frame_number] {
578 EXPECT_EQ(processor_->GetQpFromEncoder(frame_number),
579 processor_->GetQpFromBitstream(frame_number));
580 });
581 }
582 }
583
584 // Calculate and print rate control statistics.
585 rate_update_index = 0;
586 frame_number = 0;
587 UpdateRates(rate_update_index, rate_profile);
588 ResetRateControlMetrics(
589 rate_profile.frame_index_rate_update[rate_update_index + 1]);
590 target_size_key_frame_initial_ =
591 0.5 * kInitialBufferSize * bitrate_layer_[0];
592 std::vector<int> num_dropped_frames;
593 std::vector<int> num_resize_actions;
594 rtc::Event sync_event(false, false);
595 task_queue.PostTask(
596 [this, &num_dropped_frames, &num_resize_actions, &sync_event]() {
597 num_dropped_frames = processor_->NumberDroppedFramesPerRateUpdate();
598 num_resize_actions = processor_->NumberSpatialResizesPerRateUpdate();
599 sync_event.Set();
600 });
601 sync_event.Wait(rtc::Event::kForever);
602 while (frame_number < num_frames) {
603 const int tl_idx = TemporalLayerIndexForFrame(frame_number);
604 ++num_frames_per_update_[tl_idx];
605 ++num_frames_total_;
606 UpdateRateControlMetrics(frame_number);
607
608 ++frame_number;
609
610 if (frame_number ==
611 rate_profile.frame_index_rate_update[rate_update_index + 1]) {
612 PrintAndMaybeVerifyRateControlMetrics(rate_update_index, rc_thresholds,
613 num_dropped_frames,
614 num_resize_actions);
615 ++rate_update_index;
616 UpdateRates(rate_update_index, rate_profile);
617 ResetRateControlMetrics(
618 rate_profile.frame_index_rate_update[rate_update_index + 1]);
619 }
620 }
621 PrintAndMaybeVerifyRateControlMetrics(rate_update_index, rc_thresholds,
622 num_dropped_frames,
623 num_resize_actions);
624
625 // Calculate and print other statistics.
626 EXPECT_EQ(num_frames, static_cast<int>(stats_.stats_.size()));
627 stats_.PrintSummary();
628
629 // Calculate and print image quality statistics.
564 // TODO(marpan): Should compute these quality metrics per SetRates update. 630 // TODO(marpan): Should compute these quality metrics per SetRates update.
565 QualityMetricsResult psnr_result, ssim_result; 631 QualityMetricsResult psnr_result, ssim_result;
566 EXPECT_EQ(0, I420MetricsFromFiles(config_.input_filename.c_str(), 632 EXPECT_EQ(0, I420MetricsFromFiles(config_.input_filename.c_str(),
567 config_.output_filename.c_str(), 633 config_.output_filename.c_str(),
568 config_.codec_settings.width, 634 config_.codec_settings.width,
569 config_.codec_settings.height, 635 config_.codec_settings.height,
570 &psnr_result, &ssim_result)); 636 &psnr_result, &ssim_result));
571 VerifyQuality(psnr_result, ssim_result, quality_thresholds); 637 if (quality_thresholds) {
572 stats_.PrintSummary(); 638 VerifyQuality(psnr_result, ssim_result, *quality_thresholds);
639 }
573 printf("PSNR avg: %f, min: %f\nSSIM avg: %f, min: %f\n", 640 printf("PSNR avg: %f, min: %f\nSSIM avg: %f, min: %f\n",
574 psnr_result.average, psnr_result.min, ssim_result.average, 641 psnr_result.average, psnr_result.min, ssim_result.average,
575 ssim_result.min); 642 ssim_result.min);
576 printf("\n"); 643 printf("\n");
577 644
578 // Remove analysis file. 645 // Remove analysis file.
579 if (remove(config_.output_filename.c_str()) < 0) { 646 if (remove(config_.output_filename.c_str()) < 0) {
580 fprintf(stderr, "Failed to remove temporary file!\n"); 647 fprintf(stderr, "Failed to remove temporary file!\n");
581 } 648 }
582 } 649 }
583 650
584 static void SetTestConfig(TestConfig* config, 651 static void SetTestConfig(TestConfig* config,
585 bool hw_codec, 652 bool hw_codec,
586 bool use_single_core, 653 bool use_single_core,
587 float packet_loss_probability, 654 float packet_loss_probability,
588 std::string filename, 655 std::string filename,
589 bool verbose_logging, 656 bool verbose_logging) {
590 bool batch_mode) {
591 config->filename = filename; 657 config->filename = filename;
592 config->input_filename = ResourcePath(filename, "yuv"); 658 config->input_filename = ResourcePath(filename, "yuv");
593 // Generate an output filename in a safe way. 659 // Generate an output filename in a safe way.
594 config->output_filename = 660 config->output_filename =
595 TempFilename(OutputPath(), "videoprocessor_integrationtest"); 661 TempFilename(OutputPath(), "videoprocessor_integrationtest");
596 config->networking_config.packet_loss_probability = packet_loss_probability; 662 config->networking_config.packet_loss_probability = packet_loss_probability;
597 config->use_single_core = use_single_core; 663 config->use_single_core = use_single_core;
598 config->verbose = verbose_logging; 664 config->verbose = verbose_logging;
599 config->hw_codec = hw_codec; 665 config->hw_codec = hw_codec;
600 config->batch_mode = batch_mode;
601 } 666 }
602 667
603 static void SetCodecSettings(TestConfig* config, 668 static void SetCodecSettings(TestConfig* config,
604 VideoCodecType codec_type, 669 VideoCodecType codec_type,
605 int num_temporal_layers, 670 int num_temporal_layers,
606 bool error_concealment_on, 671 bool error_concealment_on,
607 bool denoising_on, 672 bool denoising_on,
608 bool frame_dropper_on, 673 bool frame_dropper_on,
609 bool spatial_resize_on, 674 bool spatial_resize_on,
610 bool resilience_on, 675 bool resilience_on,
(...skipping 30 matching lines...) Expand all
641 default: 706 default:
642 RTC_NOTREACHED(); 707 RTC_NOTREACHED();
643 break; 708 break;
644 } 709 }
645 710
646 config->frame_length_in_bytes = 711 config->frame_length_in_bytes =
647 CalcBufferSize(VideoType::kI420, width, height); 712 CalcBufferSize(VideoType::kI420, width, height);
648 } 713 }
649 714
650 static void SetRateProfile(RateProfile* rate_profile, 715 static void SetRateProfile(RateProfile* rate_profile,
651 int update_index, 716 int rate_update_index,
652 int bit_rate, 717 int bit_rate_kbps,
653 int frame_rate, 718 int frame_rate_fps,
654 int frame_index_rate_update) { 719 int frame_index_rate_update) {
655 rate_profile->target_bit_rate[update_index] = bit_rate; 720 rate_profile->target_bit_rate[rate_update_index] = bit_rate_kbps;
656 rate_profile->input_frame_rate[update_index] = frame_rate; 721 rate_profile->input_frame_rate[rate_update_index] = frame_rate_fps;
657 rate_profile->frame_index_rate_update[update_index] = 722 rate_profile->frame_index_rate_update[rate_update_index] =
658 frame_index_rate_update; 723 frame_index_rate_update;
659 } 724 }
660 725
661 static void SetRateControlThresholds(RateControlThresholds* rc_thresholds, 726 static void AddRateControlThresholds(
662 int update_index, 727 int max_num_dropped_frames,
663 int max_num_dropped_frames, 728 int max_key_frame_size_mismatch,
664 int max_key_frame_size_mismatch, 729 int max_delta_frame_size_mismatch,
665 int max_delta_frame_size_mismatch, 730 int max_encoding_rate_mismatch,
666 int max_encoding_rate_mismatch, 731 int max_time_hit_target,
667 int max_time_hit_target, 732 int num_spatial_resizes,
668 int num_spatial_resizes, 733 int num_key_frames,
669 int num_key_frames) { 734 std::vector<RateControlThresholds>* rc_thresholds) {
670 rc_thresholds[update_index].max_num_dropped_frames = max_num_dropped_frames; 735 RTC_DCHECK(rc_thresholds);
671 rc_thresholds[update_index].max_key_frame_size_mismatch = 736
672 max_key_frame_size_mismatch; 737 rc_thresholds->emplace_back();
673 rc_thresholds[update_index].max_delta_frame_size_mismatch = 738 RateControlThresholds* rc_threshold = &rc_thresholds->back();
674 max_delta_frame_size_mismatch; 739 rc_threshold->max_num_dropped_frames = max_num_dropped_frames;
675 rc_thresholds[update_index].max_encoding_rate_mismatch = 740 rc_threshold->max_key_frame_size_mismatch = max_key_frame_size_mismatch;
676 max_encoding_rate_mismatch; 741 rc_threshold->max_delta_frame_size_mismatch = max_delta_frame_size_mismatch;
677 rc_thresholds[update_index].max_time_hit_target = max_time_hit_target; 742 rc_threshold->max_encoding_rate_mismatch = max_encoding_rate_mismatch;
678 rc_thresholds[update_index].num_spatial_resizes = num_spatial_resizes; 743 rc_threshold->max_time_hit_target = max_time_hit_target;
679 rc_thresholds[update_index].num_key_frames = num_key_frames; 744 rc_threshold->num_spatial_resizes = num_spatial_resizes;
745 rc_threshold->num_key_frames = num_key_frames;
680 } 746 }
681 747
682 // Config. 748 // Config.
683 TestConfig config_; 749 TestConfig config_;
684 750
685 // Codecs. 751 // Codecs.
686 std::unique_ptr<cricket::WebRtcVideoEncoderFactory> encoder_factory_; 752 std::unique_ptr<cricket::WebRtcVideoEncoderFactory> encoder_factory_;
687 VideoEncoder* encoder_; 753 VideoEncoder* encoder_;
688 std::unique_ptr<cricket::WebRtcVideoDecoderFactory> decoder_factory_; 754 std::unique_ptr<cricket::WebRtcVideoDecoderFactory> decoder_factory_;
689 VideoDecoder* decoder_; 755 VideoDecoder* decoder_;
690 756
691 // Helper objects. 757 // Helper objects.
692 std::unique_ptr<FrameReader> analysis_frame_reader_; 758 std::unique_ptr<FrameReader> analysis_frame_reader_;
693 std::unique_ptr<FrameWriter> analysis_frame_writer_; 759 std::unique_ptr<FrameWriter> analysis_frame_writer_;
694 std::unique_ptr<IvfFileWriter> encoded_frame_writer_; 760 std::unique_ptr<IvfFileWriter> encoded_frame_writer_;
695 std::unique_ptr<FrameWriter> decoded_frame_writer_; 761 std::unique_ptr<FrameWriter> decoded_frame_writer_;
696 PacketReader packet_reader_; 762 PacketReader packet_reader_;
697 std::unique_ptr<PacketManipulator> packet_manipulator_; 763 std::unique_ptr<PacketManipulator> packet_manipulator_;
698 Stats stats_; 764 Stats stats_;
699 std::unique_ptr<VideoProcessor> processor_; 765 std::unique_ptr<VideoProcessor> processor_;
700 766
701 // Quantities defined/updated for every encoder rate update. 767 // Quantities defined/updated for every encoder rate update.
702 int num_frames_per_update_[kMaxNumTemporalLayers]; 768 int num_frames_per_update_[kMaxNumTemporalLayers];
703 float sum_frame_size_mismatch_[kMaxNumTemporalLayers]; 769 float sum_frame_size_mismatch_[kMaxNumTemporalLayers];
704 float sum_encoded_frame_size_[kMaxNumTemporalLayers]; 770 float sum_encoded_frame_size_[kMaxNumTemporalLayers];
705 float encoding_bitrate_[kMaxNumTemporalLayers]; 771 float encoding_bitrate_[kMaxNumTemporalLayers];
706 float per_frame_bandwidth_[kMaxNumTemporalLayers]; 772 float per_frame_bandwidth_[kMaxNumTemporalLayers];
707 float bit_rate_layer_[kMaxNumTemporalLayers]; 773 float bitrate_layer_[kMaxNumTemporalLayers];
708 float frame_rate_layer_[kMaxNumTemporalLayers]; 774 float framerate_layer_[kMaxNumTemporalLayers];
709 int num_frames_total_; 775 int num_frames_total_;
710 float sum_encoded_frame_size_total_; 776 float sum_encoded_frame_size_total_;
711 float encoding_bitrate_total_; 777 float encoding_bitrate_total_;
712 float perc_encoding_rate_mismatch_; 778 float perc_encoding_rate_mismatch_;
713 int num_frames_to_hit_target_; 779 int num_frames_to_hit_target_;
714 bool encoding_rate_within_target_; 780 bool encoding_rate_within_target_;
715 int bit_rate_; 781 int bitrate_kbps_;
716 int frame_rate_; 782 int framerate_;
717 float target_size_key_frame_initial_; 783 float target_size_key_frame_initial_;
718 float target_size_key_frame_; 784 float target_size_key_frame_;
719 float sum_key_frame_size_mismatch_; 785 float sum_key_frame_size_mismatch_;
720 int num_key_frames_; 786 int num_key_frames_;
721 }; 787 };
722 788
723 } // namespace test 789 } // namespace test
724 } // namespace webrtc 790 } // namespace webrtc
725 791
726 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES T_H_ 792 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES T_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698