OLD | NEW |
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 | 20 |
21 #if defined(WEBRTC_ANDROID) | 21 #if defined(WEBRTC_ANDROID) |
22 #include "webrtc/modules/video_coding/codecs/test/android_test_initializer.h" | 22 #include "webrtc/modules/video_coding/codecs/test/android_test_initializer.h" |
23 #include "webrtc/sdk/android/src/jni/androidmediadecoder_jni.h" | 23 #include "webrtc/sdk/android/src/jni/androidmediadecoder_jni.h" |
24 #include "webrtc/sdk/android/src/jni/androidmediaencoder_jni.h" | 24 #include "webrtc/sdk/android/src/jni/androidmediaencoder_jni.h" |
25 #elif defined(WEBRTC_IOS) | 25 #elif defined(WEBRTC_IOS) |
26 #include "webrtc/modules/video_coding/codecs/test/objc_codec_h264_test.h" | 26 #include "webrtc/modules/video_coding/codecs/test/objc_codec_h264_test.h" |
27 #endif | 27 #endif |
28 | 28 |
| 29 #include "webrtc/media/engine/internaldecoderfactory.h" |
| 30 #include "webrtc/media/engine/internalencoderfactory.h" |
29 #include "webrtc/media/engine/webrtcvideodecoderfactory.h" | 31 #include "webrtc/media/engine/webrtcvideodecoderfactory.h" |
30 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" | 32 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" |
31 #include "webrtc/modules/video_coding/codecs/h264/include/h264.h" | |
32 #include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h" | 33 #include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h" |
33 #include "webrtc/modules/video_coding/codecs/test/videoprocessor.h" | 34 #include "webrtc/modules/video_coding/codecs/test/videoprocessor.h" |
34 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" | |
35 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" | 35 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" |
36 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h" | |
37 #include "webrtc/modules/video_coding/include/video_codec_interface.h" | 36 #include "webrtc/modules/video_coding/include/video_codec_interface.h" |
38 #include "webrtc/modules/video_coding/include/video_coding.h" | 37 #include "webrtc/modules/video_coding/include/video_coding.h" |
39 #include "webrtc/modules/video_coding/utility/ivf_file_writer.h" | 38 #include "webrtc/modules/video_coding/utility/ivf_file_writer.h" |
40 #include "webrtc/rtc_base/checks.h" | 39 #include "webrtc/rtc_base/checks.h" |
41 #include "webrtc/rtc_base/file.h" | 40 #include "webrtc/rtc_base/file.h" |
42 #include "webrtc/rtc_base/logging.h" | 41 #include "webrtc/rtc_base/logging.h" |
43 #include "webrtc/rtc_base/ptr_util.h" | 42 #include "webrtc/rtc_base/ptr_util.h" |
44 #include "webrtc/test/gtest.h" | 43 #include "webrtc/test/gtest.h" |
45 #include "webrtc/test/testsupport/fileutils.h" | 44 #include "webrtc/test/testsupport/fileutils.h" |
46 #include "webrtc/test/testsupport/frame_reader.h" | 45 #include "webrtc/test/testsupport/frame_reader.h" |
47 #include "webrtc/test/testsupport/frame_writer.h" | 46 #include "webrtc/test/testsupport/frame_writer.h" |
48 #include "webrtc/test/testsupport/metrics/video_metrics.h" | 47 #include "webrtc/test/testsupport/metrics/video_metrics.h" |
49 #include "webrtc/test/testsupport/packet_reader.h" | 48 #include "webrtc/test/testsupport/packet_reader.h" |
50 #include "webrtc/typedefs.h" | 49 #include "webrtc/typedefs.h" |
51 | 50 |
52 namespace webrtc { | 51 namespace webrtc { |
53 namespace test { | 52 namespace test { |
54 // Maximum number of rate updates (i.e., calls to encoder to change bitrate | 53 |
55 // and/or frame rate) for the current tests. | |
56 const int kMaxNumRateUpdates = 3; | 54 const int kMaxNumRateUpdates = 3; |
57 | |
58 // Maximum number of temporal layers to use in tests. | |
59 const int kMaxNumTemporalLayers = 3; | 55 const int kMaxNumTemporalLayers = 3; |
60 | 56 |
61 const int kPercTargetvsActualMismatch = 20; | 57 const int kPercTargetvsActualMismatch = 20; |
62 const int kBaseKeyFrameInterval = 3000; | 58 const int kBaseKeyFrameInterval = 3000; |
63 | 59 |
| 60 // Parameters from VP8 wrapper, which control target size of key frames. |
| 61 const float kInitialBufferSize = 0.5f; |
| 62 const float kOptimalBufferSize = 0.6f; |
| 63 const float kScaleKeyFrameSize = 0.5f; |
| 64 |
64 // Thresholds for the quality metrics. Defaults are maximally minimal. | 65 // Thresholds for the quality metrics. Defaults are maximally minimal. |
65 struct QualityThresholds { | 66 struct QualityThresholds { |
66 QualityThresholds() {} | 67 QualityThresholds() {} |
67 QualityThresholds(double min_avg_psnr, | 68 QualityThresholds(double min_avg_psnr, |
68 double min_min_psnr, | 69 double min_min_psnr, |
69 double min_avg_ssim, | 70 double min_avg_ssim, |
70 double min_min_ssim) | 71 double min_min_ssim) |
71 : min_avg_psnr(min_avg_psnr), | 72 : min_avg_psnr(min_avg_psnr), |
72 min_min_psnr(min_min_psnr), | 73 min_min_psnr(min_min_psnr), |
73 min_avg_ssim(min_avg_ssim), | 74 min_avg_ssim(min_avg_ssim), |
(...skipping 28 matching lines...) Expand all Loading... |
102 int num_spatial_resizes; // Set to -1 to disable check. | 103 int num_spatial_resizes; // Set to -1 to disable check. |
103 int num_key_frames; // Set to -1 to disable check. | 104 int num_key_frames; // Set to -1 to disable check. |
104 }; | 105 }; |
105 | 106 |
106 // Should video files be saved persistently to disk for post-run visualization? | 107 // Should video files be saved persistently to disk for post-run visualization? |
107 struct VisualizationParams { | 108 struct VisualizationParams { |
108 bool save_encoded_ivf; | 109 bool save_encoded_ivf; |
109 bool save_decoded_y4m; | 110 bool save_decoded_y4m; |
110 }; | 111 }; |
111 | 112 |
112 #if !defined(WEBRTC_IOS) | |
113 const int kNumFramesShort = 100; | |
114 #endif | |
115 const int kNumFramesLong = 299; | |
116 | |
117 // Parameters from VP8 wrapper, which control target size of key frames. | |
118 const float kInitialBufferSize = 0.5f; | |
119 const float kOptimalBufferSize = 0.6f; | |
120 const float kScaleKeyFrameSize = 0.5f; | |
121 | |
122 // Integration test for video processor. Encodes+decodes a clip and | 113 // Integration test for video processor. Encodes+decodes a clip and |
123 // writes it to the output directory. After completion, quality metrics | 114 // writes it to the output directory. After completion, quality metrics |
124 // (PSNR and SSIM) and rate control metrics are computed and compared to given | 115 // (PSNR and SSIM) and rate control metrics are computed and compared to given |
125 // thresholds, to verify that the quality and encoder response is acceptable. | 116 // thresholds, to verify that the quality and encoder response is acceptable. |
126 // The rate control tests allow us to verify the behavior for changing bit rate, | 117 // The rate control tests allow us to verify the behavior for changing bit rate, |
127 // changing frame rate, frame dropping/spatial resize, and temporal layers. | 118 // changing frame rate, frame dropping/spatial resize, and temporal layers. |
128 // The thresholds for the rate control metrics are set to be fairly | 119 // The thresholds for the rate control metrics are set to be fairly |
129 // conservative, so failure should only happen when some significant regression | 120 // conservative, so failure should only happen when some significant regression |
130 // or breakdown occurs. | 121 // or breakdown occurs. |
131 class VideoProcessorIntegrationTest : public testing::Test { | 122 class VideoProcessorIntegrationTest : public testing::Test { |
132 protected: | 123 protected: |
133 VideoProcessorIntegrationTest() { | 124 VideoProcessorIntegrationTest() { |
134 #if defined(WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED) && \ | 125 #if defined(WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED) && \ |
135 defined(WEBRTC_ANDROID) | 126 defined(WEBRTC_ANDROID) |
136 InitializeAndroidObjects(); | 127 InitializeAndroidObjects(); |
137 | |
138 external_encoder_factory_.reset( | |
139 new webrtc_jni::MediaCodecVideoEncoderFactory()); | |
140 external_decoder_factory_.reset( | |
141 new webrtc_jni::MediaCodecVideoDecoderFactory()); | |
142 #endif | 128 #endif |
143 } | 129 } |
144 virtual ~VideoProcessorIntegrationTest() = default; | 130 ~VideoProcessorIntegrationTest() override = default; |
145 | 131 |
146 void CreateEncoderAndDecoder() { | 132 void CreateEncoderAndDecoder() { |
147 if (config_.hw_codec) { | 133 if (config_.hw_codec) { |
148 #if defined(WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED) | 134 #if defined(WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED) |
149 #if defined(WEBRTC_ANDROID) | 135 #if defined(WEBRTC_ANDROID) |
150 // In general, external codecs should be destroyed by the factories that | 136 encoder_factory_.reset(new webrtc_jni::MediaCodecVideoEncoderFactory()); |
151 // allocated them. For the particular case of the Android | 137 decoder_factory_.reset(new webrtc_jni::MediaCodecVideoDecoderFactory()); |
152 // MediaCodecVideo{En,De}coderFactory's, however, it turns out that it is | |
153 // fine for the std::unique_ptr to destroy the owned codec directly. | |
154 switch (config_.codec_settings.codecType) { | |
155 case kVideoCodecH264: | |
156 encoder_.reset(external_encoder_factory_->CreateVideoEncoder( | |
157 cricket::VideoCodec(cricket::kH264CodecName))); | |
158 decoder_.reset( | |
159 external_decoder_factory_->CreateVideoDecoder(kVideoCodecH264)); | |
160 break; | |
161 case kVideoCodecVP8: | |
162 encoder_.reset(external_encoder_factory_->CreateVideoEncoder( | |
163 cricket::VideoCodec(cricket::kVp8CodecName))); | |
164 decoder_.reset( | |
165 external_decoder_factory_->CreateVideoDecoder(kVideoCodecVP8)); | |
166 break; | |
167 case kVideoCodecVP9: | |
168 encoder_.reset(external_encoder_factory_->CreateVideoEncoder( | |
169 cricket::VideoCodec(cricket::kVp9CodecName))); | |
170 decoder_.reset( | |
171 external_decoder_factory_->CreateVideoDecoder(kVideoCodecVP9)); | |
172 break; | |
173 default: | |
174 RTC_NOTREACHED(); | |
175 break; | |
176 } | |
177 #elif defined(WEBRTC_IOS) | 138 #elif defined(WEBRTC_IOS) |
178 ASSERT_EQ(kVideoCodecH264, config_.codec_settings.codecType) | 139 EXPECT_EQ(kVideoCodecH264, config_.codec_settings.codecType) |
179 << "iOS HW codecs only support H264."; | 140 << "iOS HW codecs only support H264."; |
180 std::unique_ptr<cricket::WebRtcVideoEncoderFactory> encoder_factory = | 141 encoder_factory_ = CreateObjCEncoderFactory(); |
181 CreateObjCEncoderFactory(); | 142 decoder_factory_ = CreateObjCDecoderFactory(); |
182 std::unique_ptr<cricket::WebRtcVideoDecoderFactory> decoder_factory = | |
183 CreateObjCDecoderFactory(); | |
184 cricket::VideoCodec codecInfo = encoder_factory->supported_codecs().at(0); | |
185 encoder_.reset(encoder_factory->CreateVideoEncoder(codecInfo)); | |
186 decoder_.reset(decoder_factory->CreateVideoDecoder(kVideoCodecH264)); | |
187 #else | 143 #else |
188 RTC_NOTREACHED() << "Only support HW codecs on Android and iOS."; | 144 RTC_NOTREACHED() << "Only support HW codecs on Android and iOS."; |
189 #endif | 145 #endif |
190 #endif // WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED | 146 #endif // WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED |
191 RTC_CHECK(encoder_) << "HW encoder not successfully created."; | 147 } else { |
192 RTC_CHECK(decoder_) << "HW decoder not successfully created."; | 148 // SW codecs. |
193 return; | 149 encoder_factory_.reset(new cricket::InternalEncoderFactory()); |
| 150 decoder_factory_.reset(new cricket::InternalDecoderFactory()); |
194 } | 151 } |
195 | 152 |
196 // SW codecs. | |
197 switch (config_.codec_settings.codecType) { | 153 switch (config_.codec_settings.codecType) { |
198 case kVideoCodecH264: | |
199 encoder_.reset( | |
200 H264Encoder::Create(cricket::VideoCodec(cricket::kH264CodecName))); | |
201 decoder_.reset(H264Decoder::Create()); | |
202 break; | |
203 case kVideoCodecVP8: | 154 case kVideoCodecVP8: |
204 encoder_.reset(VP8Encoder::Create()); | 155 encoder_ = encoder_factory_->CreateVideoEncoder( |
205 decoder_.reset(VP8Decoder::Create()); | 156 cricket::VideoCodec(cricket::kVp8CodecName)); |
| 157 decoder_ = decoder_factory_->CreateVideoDecoder(kVideoCodecVP8); |
206 break; | 158 break; |
207 case kVideoCodecVP9: | 159 case kVideoCodecVP9: |
208 encoder_.reset(VP9Encoder::Create()); | 160 encoder_ = encoder_factory_->CreateVideoEncoder( |
209 decoder_.reset(VP9Decoder::Create()); | 161 cricket::VideoCodec(cricket::kVp9CodecName)); |
| 162 decoder_ = decoder_factory_->CreateVideoDecoder(kVideoCodecVP9); |
| 163 break; |
| 164 case kVideoCodecH264: |
| 165 // TODO(brandtr): Generalize so that we support multiple profiles here. |
| 166 encoder_ = encoder_factory_->CreateVideoEncoder( |
| 167 cricket::VideoCodec(cricket::kH264CodecName)); |
| 168 decoder_ = decoder_factory_->CreateVideoDecoder(kVideoCodecH264); |
210 break; | 169 break; |
211 default: | 170 default: |
212 RTC_NOTREACHED(); | 171 RTC_NOTREACHED(); |
213 break; | 172 break; |
214 } | 173 } |
| 174 |
| 175 RTC_CHECK(encoder_) << "Encoder not successfully created."; |
| 176 RTC_CHECK(decoder_) << "Decoder not successfully created."; |
215 } | 177 } |
216 | 178 |
217 void SetUpObjects(const VisualizationParams* visualization_params) { | 179 void DestroyEncoderAndDecoder() { |
| 180 encoder_factory_->DestroyVideoEncoder(encoder_); |
| 181 decoder_factory_->DestroyVideoDecoder(decoder_); |
| 182 } |
| 183 |
| 184 void SetUpObjects(const VisualizationParams* visualization_params, |
| 185 const int initial_bitrate_kbps, |
| 186 const int initial_framerate_fps) { |
218 CreateEncoderAndDecoder(); | 187 CreateEncoderAndDecoder(); |
219 | 188 |
220 // Create file objects for quality analysis. | 189 // Create file objects for quality analysis. |
221 analysis_frame_reader_.reset(new test::YuvFrameReaderImpl( | 190 analysis_frame_reader_.reset(new YuvFrameReaderImpl( |
222 config_.input_filename, config_.codec_settings.width, | 191 config_.input_filename, config_.codec_settings.width, |
223 config_.codec_settings.height)); | 192 config_.codec_settings.height)); |
224 analysis_frame_writer_.reset(new test::YuvFrameWriterImpl( | 193 analysis_frame_writer_.reset(new YuvFrameWriterImpl( |
225 config_.output_filename, config_.codec_settings.width, | 194 config_.output_filename, config_.codec_settings.width, |
226 config_.codec_settings.height)); | 195 config_.codec_settings.height)); |
227 RTC_CHECK(analysis_frame_reader_->Init()); | 196 RTC_CHECK(analysis_frame_reader_->Init()); |
228 RTC_CHECK(analysis_frame_writer_->Init()); | 197 RTC_CHECK(analysis_frame_writer_->Init()); |
229 | 198 |
230 if (visualization_params) { | 199 if (visualization_params) { |
| 200 const std::string codec_name = |
| 201 CodecTypeToPayloadName(config_.codec_settings.codecType) |
| 202 .value_or("unknown"); |
| 203 const std::string implementation_type = config_.hw_codec ? "hw" : "sw"; |
231 // clang-format off | 204 // clang-format off |
232 const std::string output_filename_base = | 205 const std::string output_filename_base = |
233 test::OutputPath() + config_.filename + | 206 OutputPath() + config_.filename + "-" + |
234 "_cd-" + CodecTypeToPayloadName( | 207 codec_name + "-" + implementation_type + "-" + |
235 config_.codec_settings.codecType).value_or("") + | 208 std::to_string(initial_bitrate_kbps); |
236 "_hw-" + std::to_string(config_.hw_codec) + | |
237 "_br-" + std::to_string( | |
238 static_cast<int>(config_.codec_settings.startBitrate)); | |
239 // clang-format on | 209 // clang-format on |
240 if (visualization_params->save_encoded_ivf) { | 210 if (visualization_params->save_encoded_ivf) { |
241 rtc::File post_encode_file = | 211 rtc::File post_encode_file = |
242 rtc::File::Create(output_filename_base + "_encoded.ivf"); | 212 rtc::File::Create(output_filename_base + "_encoded.ivf"); |
243 encoded_frame_writer_ = | 213 encoded_frame_writer_ = |
244 IvfFileWriter::Wrap(std::move(post_encode_file), 0); | 214 IvfFileWriter::Wrap(std::move(post_encode_file), 0); |
245 } | 215 } |
246 if (visualization_params->save_decoded_y4m) { | 216 if (visualization_params->save_decoded_y4m) { |
247 decoded_frame_writer_.reset(new test::Y4mFrameWriterImpl( | 217 decoded_frame_writer_.reset(new Y4mFrameWriterImpl( |
248 output_filename_base + "_decoded.y4m", config_.codec_settings.width, | 218 output_filename_base + "_decoded.y4m", config_.codec_settings.width, |
249 config_.codec_settings.height, start_frame_rate_)); | 219 config_.codec_settings.height, initial_framerate_fps)); |
250 RTC_CHECK(decoded_frame_writer_->Init()); | 220 RTC_CHECK(decoded_frame_writer_->Init()); |
251 } | 221 } |
252 } | 222 } |
253 | 223 |
254 packet_manipulator_.reset(new test::PacketManipulatorImpl( | 224 packet_manipulator_.reset(new PacketManipulatorImpl( |
255 &packet_reader_, config_.networking_config, config_.verbose)); | 225 &packet_reader_, config_.networking_config, config_.verbose)); |
256 processor_ = rtc::MakeUnique<VideoProcessor>( | 226 processor_ = rtc::MakeUnique<VideoProcessor>( |
257 encoder_.get(), decoder_.get(), analysis_frame_reader_.get(), | 227 encoder_, decoder_, analysis_frame_reader_.get(), |
258 analysis_frame_writer_.get(), packet_manipulator_.get(), config_, | 228 analysis_frame_writer_.get(), packet_manipulator_.get(), config_, |
259 &stats_, encoded_frame_writer_.get(), decoded_frame_writer_.get()); | 229 &stats_, encoded_frame_writer_.get(), decoded_frame_writer_.get()); |
260 processor_->Init(); | 230 processor_->Init(); |
261 } | 231 } |
262 | 232 |
263 // Reset quantities after each encoder update, update the target per-frame | 233 // Reset quantities after each encoder update, update the target per-frame |
264 // bandwidth. | 234 // bandwidth. |
265 void ResetRateControlMetrics(int num_frames_to_hit_target) { | 235 void ResetRateControlMetrics(int num_frames_to_hit_target) { |
266 for (int i = 0; i < num_temporal_layers_; i++) { | 236 const int num_temporal_layers = |
| 237 NumberOfTemporalLayers(config_.codec_settings); |
| 238 for (int i = 0; i < num_temporal_layers; i++) { |
267 num_frames_per_update_[i] = 0; | 239 num_frames_per_update_[i] = 0; |
268 sum_frame_size_mismatch_[i] = 0.0f; | 240 sum_frame_size_mismatch_[i] = 0.0f; |
269 sum_encoded_frame_size_[i] = 0.0f; | 241 sum_encoded_frame_size_[i] = 0.0f; |
270 encoding_bitrate_[i] = 0.0f; | 242 encoding_bitrate_[i] = 0.0f; |
271 // Update layer per-frame-bandwidth. | 243 // Update layer per-frame-bandwidth. |
272 per_frame_bandwidth_[i] = static_cast<float>(bit_rate_layer_[i]) / | 244 per_frame_bandwidth_[i] = static_cast<float>(bit_rate_layer_[i]) / |
273 static_cast<float>(frame_rate_layer_[i]); | 245 static_cast<float>(frame_rate_layer_[i]); |
274 } | 246 } |
275 // Set maximum size of key frames, following setting in the VP8 wrapper. | 247 // Set maximum size of key frames, following setting in the VP8 wrapper. |
276 float max_key_size = kScaleKeyFrameSize * kOptimalBufferSize * frame_rate_; | 248 float max_key_size = kScaleKeyFrameSize * kOptimalBufferSize * frame_rate_; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 if (num_key_frames_ > 0) { | 326 if (num_key_frames_ > 0) { |
355 int perc_key_frame_size_mismatch = | 327 int perc_key_frame_size_mismatch = |
356 100 * sum_key_frame_size_mismatch_ / num_key_frames_; | 328 100 * sum_key_frame_size_mismatch_ / num_key_frames_; |
357 printf( | 329 printf( |
358 " # key frames : %d\n" | 330 " # key frames : %d\n" |
359 " Key frame rate mismatch: %d\n", | 331 " Key frame rate mismatch: %d\n", |
360 num_key_frames_, perc_key_frame_size_mismatch); | 332 num_key_frames_, perc_key_frame_size_mismatch); |
361 EXPECT_LE(perc_key_frame_size_mismatch, | 333 EXPECT_LE(perc_key_frame_size_mismatch, |
362 rc_expected.max_key_frame_size_mismatch); | 334 rc_expected.max_key_frame_size_mismatch); |
363 } | 335 } |
364 for (int i = 0; i < num_temporal_layers_; i++) { | 336 const int num_temporal_layers = |
| 337 NumberOfTemporalLayers(config_.codec_settings); |
| 338 for (int i = 0; i < num_temporal_layers; i++) { |
365 printf(" Temporal layer #%d:\n", i); | 339 printf(" Temporal layer #%d:\n", i); |
366 int perc_frame_size_mismatch = | 340 int perc_frame_size_mismatch = |
367 100 * sum_frame_size_mismatch_[i] / num_frames_per_update_[i]; | 341 100 * sum_frame_size_mismatch_[i] / num_frames_per_update_[i]; |
368 int perc_encoding_rate_mismatch = | 342 int perc_encoding_rate_mismatch = |
369 100 * fabs(encoding_bitrate_[i] - bit_rate_layer_[i]) / | 343 100 * fabs(encoding_bitrate_[i] - bit_rate_layer_[i]) / |
370 bit_rate_layer_[i]; | 344 bit_rate_layer_[i]; |
371 printf( | 345 printf( |
372 " Target layer bitrate : %f\n" | 346 " Target layer bitrate : %f\n" |
373 " Layer frame rate : %f\n" | 347 " Layer frame rate : %f\n" |
374 " Layer per frame bandwidth : %f\n" | 348 " Layer per frame bandwidth : %f\n" |
(...skipping 13 matching lines...) Expand all Loading... |
388 EXPECT_LE(num_frames_to_hit_target_, rc_expected.max_time_hit_target); | 362 EXPECT_LE(num_frames_to_hit_target_, rc_expected.max_time_hit_target); |
389 EXPECT_LE(num_dropped_frames, rc_expected.max_num_dropped_frames); | 363 EXPECT_LE(num_dropped_frames, rc_expected.max_num_dropped_frames); |
390 if (rc_expected.num_spatial_resizes >= 0) { | 364 if (rc_expected.num_spatial_resizes >= 0) { |
391 EXPECT_EQ(rc_expected.num_spatial_resizes, num_resize_actions); | 365 EXPECT_EQ(rc_expected.num_spatial_resizes, num_resize_actions); |
392 } | 366 } |
393 if (rc_expected.num_key_frames >= 0) { | 367 if (rc_expected.num_key_frames >= 0) { |
394 EXPECT_EQ(rc_expected.num_key_frames, num_key_frames_); | 368 EXPECT_EQ(rc_expected.num_key_frames, num_key_frames_); |
395 } | 369 } |
396 } | 370 } |
397 | 371 |
398 void VerifyQuality(const test::QualityMetricsResult& psnr_result, | 372 void VerifyQuality(const QualityMetricsResult& psnr_result, |
399 const test::QualityMetricsResult& ssim_result, | 373 const QualityMetricsResult& ssim_result, |
400 const QualityThresholds& quality_thresholds) { | 374 const QualityThresholds& quality_thresholds) { |
401 EXPECT_GT(psnr_result.average, quality_thresholds.min_avg_psnr); | 375 EXPECT_GT(psnr_result.average, quality_thresholds.min_avg_psnr); |
402 EXPECT_GT(psnr_result.min, quality_thresholds.min_min_psnr); | 376 EXPECT_GT(psnr_result.min, quality_thresholds.min_min_psnr); |
403 EXPECT_GT(ssim_result.average, quality_thresholds.min_avg_ssim); | 377 EXPECT_GT(ssim_result.average, quality_thresholds.min_avg_ssim); |
404 EXPECT_GT(ssim_result.min, quality_thresholds.min_min_ssim); | 378 EXPECT_GT(ssim_result.min, quality_thresholds.min_min_ssim); |
405 } | 379 } |
406 | 380 |
407 void VerifyQpParser(int frame_number) { | 381 void VerifyQpParser(int frame_number) { |
408 if (!config_.hw_codec && | 382 if (!config_.hw_codec && |
409 (config_.codec_settings.codecType == kVideoCodecVP8 || | 383 (config_.codec_settings.codecType == kVideoCodecVP8 || |
410 config_.codec_settings.codecType == kVideoCodecVP9)) { | 384 config_.codec_settings.codecType == kVideoCodecVP9)) { |
411 EXPECT_EQ(processor_->GetQpFromEncoder(frame_number), | 385 EXPECT_EQ(processor_->GetQpFromEncoder(frame_number), |
412 processor_->GetQpFromBitstream(frame_number)); | 386 processor_->GetQpFromBitstream(frame_number)); |
413 } | 387 } |
414 } | 388 } |
415 | 389 |
416 int NumberOfTemporalLayers(const VideoCodec& codec_settings) { | 390 int NumberOfTemporalLayers(const VideoCodec& codec_settings) { |
417 if (codec_settings.codecType == kVideoCodecVP8) { | 391 if (codec_settings.codecType == kVideoCodecVP8) { |
418 return codec_settings.VP8().numberOfTemporalLayers; | 392 return codec_settings.VP8().numberOfTemporalLayers; |
419 } else if (codec_settings.codecType == kVideoCodecVP9) { | 393 } else if (codec_settings.codecType == kVideoCodecVP9) { |
420 return codec_settings.VP9().numberOfTemporalLayers; | 394 return codec_settings.VP9().numberOfTemporalLayers; |
421 } else { | 395 } else { |
422 return 1; | 396 return 1; |
423 } | 397 } |
424 } | 398 } |
425 | 399 |
426 // Temporal layer index corresponding to frame number, for up to 3 layers. | 400 // Temporal layer index corresponding to frame number, for up to 3 layers. |
427 int TemporalLayerIndexForFrame(int frame_number) { | 401 int TemporalLayerIndexForFrame(int frame_number) { |
| 402 const int num_temporal_layers = |
| 403 NumberOfTemporalLayers(config_.codec_settings); |
428 int tl_idx = -1; | 404 int tl_idx = -1; |
429 switch (num_temporal_layers_) { | 405 switch (num_temporal_layers) { |
430 case 1: | 406 case 1: |
431 tl_idx = 0; | 407 tl_idx = 0; |
432 break; | 408 break; |
433 case 2: | 409 case 2: |
434 // temporal layer 0: 0 2 4 ... | 410 // temporal layer 0: 0 2 4 ... |
435 // temporal layer 1: 1 3 | 411 // temporal layer 1: 1 3 |
436 tl_idx = (frame_number % 2 == 0) ? 0 : 1; | 412 tl_idx = (frame_number % 2 == 0) ? 0 : 1; |
437 break; | 413 break; |
438 case 3: | 414 case 3: |
439 // temporal layer 0: 0 4 8 ... | 415 // temporal layer 0: 0 4 8 ... |
440 // temporal layer 1: 2 6 | 416 // temporal layer 1: 2 6 |
441 // temporal layer 2: 1 3 5 7 | 417 // temporal layer 2: 1 3 5 7 |
442 if (frame_number % 4 == 0) { | 418 if (frame_number % 4 == 0) { |
443 tl_idx = 0; | 419 tl_idx = 0; |
444 } else if ((frame_number + 2) % 4 == 0) { | 420 } else if ((frame_number + 2) % 4 == 0) { |
445 tl_idx = 1; | 421 tl_idx = 1; |
446 } else if ((frame_number + 1) % 2 == 0) { | 422 } else if ((frame_number + 1) % 2 == 0) { |
447 tl_idx = 2; | 423 tl_idx = 2; |
448 } | 424 } |
449 break; | 425 break; |
450 default: | 426 default: |
451 RTC_NOTREACHED(); | 427 RTC_NOTREACHED(); |
452 break; | 428 break; |
453 } | 429 } |
454 return tl_idx; | 430 return tl_idx; |
455 } | 431 } |
456 | 432 |
457 // Set the bit rate and frame rate per temporal layer, for up to 3 layers. | 433 // Set the bit rate and frame rate per temporal layer, for up to 3 layers. |
458 void SetTemporalLayerRates() { | 434 void SetTemporalLayerRates() { |
459 RTC_DCHECK_LE(num_temporal_layers_, kMaxNumTemporalLayers); | 435 const int num_temporal_layers = |
460 for (int i = 0; i < num_temporal_layers_; i++) { | 436 NumberOfTemporalLayers(config_.codec_settings); |
461 float bit_rate_ratio = | 437 RTC_DCHECK_LE(num_temporal_layers, kMaxNumTemporalLayers); |
462 kVp8LayerRateAlloction[num_temporal_layers_ - 1][i]; | 438 for (int i = 0; i < num_temporal_layers; i++) { |
| 439 float bit_rate_ratio = kVp8LayerRateAlloction[num_temporal_layers - 1][i]; |
463 if (i > 0) { | 440 if (i > 0) { |
464 float bit_rate_delta_ratio = | 441 float bit_rate_delta_ratio = |
465 kVp8LayerRateAlloction[num_temporal_layers_ - 1][i] - | 442 kVp8LayerRateAlloction[num_temporal_layers - 1][i] - |
466 kVp8LayerRateAlloction[num_temporal_layers_ - 1][i - 1]; | 443 kVp8LayerRateAlloction[num_temporal_layers - 1][i - 1]; |
467 bit_rate_layer_[i] = bit_rate_ * bit_rate_delta_ratio; | 444 bit_rate_layer_[i] = bit_rate_ * bit_rate_delta_ratio; |
468 } else { | 445 } else { |
469 bit_rate_layer_[i] = bit_rate_ * bit_rate_ratio; | 446 bit_rate_layer_[i] = bit_rate_ * bit_rate_ratio; |
470 } | 447 } |
471 frame_rate_layer_[i] = | 448 frame_rate_layer_[i] = |
472 frame_rate_ / static_cast<float>(1 << (num_temporal_layers_ - 1)); | 449 frame_rate_ / static_cast<float>(1 << (num_temporal_layers - 1)); |
473 } | 450 } |
474 if (num_temporal_layers_ == 3) { | 451 if (num_temporal_layers == 3) { |
475 frame_rate_layer_[2] = frame_rate_ / 2.0f; | 452 frame_rate_layer_[2] = frame_rate_ / 2.0f; |
476 } | 453 } |
477 } | 454 } |
478 | 455 |
479 // Processes all frames in the clip and verifies the result. | 456 // Processes all frames in the clip and verifies the result. |
480 // TODO(brandtr): Change the second last argument to be a | 457 // TODO(brandtr): Change the second last argument to be a |
481 // const std::vector<RateControlThresholds>&, so we can ensure that the user | 458 // const std::vector<RateControlThresholds>&, so we can ensure that the user |
482 // does not expect us to do mid-clip rate updates when we are not able to, | 459 // does not expect us to do mid-clip rate updates when we are not able to, |
483 // e.g., when we are operating in batch mode. | 460 // e.g., when we are operating in batch mode. |
484 void ProcessFramesAndVerify(const QualityThresholds& quality_thresholds, | 461 void ProcessFramesAndVerify(const QualityThresholds& quality_thresholds, |
485 const RateProfile& rate_profile, | 462 const RateProfile& rate_profile, |
486 RateControlThresholds* rc_thresholds, | 463 RateControlThresholds* rc_thresholds, |
487 const VisualizationParams* visualization_params) { | 464 const VisualizationParams* visualization_params) { |
488 // Codec/config settings. | |
489 num_temporal_layers_ = NumberOfTemporalLayers(config_.codec_settings); | |
490 config_.codec_settings.startBitrate = rate_profile.target_bit_rate[0]; | 465 config_.codec_settings.startBitrate = rate_profile.target_bit_rate[0]; |
491 start_frame_rate_ = rate_profile.input_frame_rate[0]; | 466 SetUpObjects(visualization_params, rate_profile.target_bit_rate[0], |
492 SetUpObjects(visualization_params); | 467 rate_profile.input_frame_rate[0]); |
493 // Update the temporal layers and the codec with the initial rates. | 468 |
| 469 // Set initial rates. |
494 bit_rate_ = rate_profile.target_bit_rate[0]; | 470 bit_rate_ = rate_profile.target_bit_rate[0]; |
495 frame_rate_ = rate_profile.input_frame_rate[0]; | 471 frame_rate_ = rate_profile.input_frame_rate[0]; |
496 SetTemporalLayerRates(); | 472 SetTemporalLayerRates(); |
497 // Set the initial target size for key frame. | 473 // Set the initial target size for key frame. |
498 target_size_key_frame_initial_ = | 474 target_size_key_frame_initial_ = |
499 0.5 * kInitialBufferSize * bit_rate_layer_[0]; | 475 0.5 * kInitialBufferSize * bit_rate_layer_[0]; |
500 processor_->SetRates(bit_rate_, frame_rate_); | 476 processor_->SetRates(bit_rate_, frame_rate_); |
501 | 477 |
502 // Process each frame, up to |num_frames|. | 478 // Process each frame, up to |num_frames|. |
503 int frame_number = 0; | 479 int frame_number = 0; |
504 int update_index = 0; | 480 int update_index = 0; |
505 int num_frames = rate_profile.num_frames; | 481 int num_frames = rate_profile.num_frames; |
506 ResetRateControlMetrics( | 482 ResetRateControlMetrics( |
507 rate_profile.frame_index_rate_update[update_index + 1]); | 483 rate_profile.frame_index_rate_update[update_index + 1]); |
508 | 484 |
509 if (config_.batch_mode) { | 485 if (config_.batch_mode) { |
510 // In batch mode, we calculate the metrics for all frames after all frames | 486 // In batch mode, we calculate the metrics for all frames after all frames |
511 // have been sent for encoding. | 487 // have been sent for encoding. |
512 | 488 |
513 // TODO(brandtr): Refactor "frame number accounting" so we don't have to | 489 // TODO(brandtr): Refactor "frame number accounting" so we don't have to |
514 // call ProcessFrame num_frames+1 times here. | 490 // call ProcessFrame num_frames+1 times here. |
515 for (frame_number = 0; frame_number <= num_frames; ++frame_number) { | 491 for (frame_number = 0; frame_number <= num_frames; ++frame_number) { |
516 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); | 492 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); |
517 } | 493 } |
518 | 494 |
519 for (frame_number = 0; frame_number < num_frames; ++frame_number) { | 495 for (frame_number = 0; frame_number < num_frames; ++frame_number) { |
520 ++num_frames_per_update_[TemporalLayerIndexForFrame(frame_number)]; | 496 const int tl_idx = TemporalLayerIndexForFrame(frame_number); |
| 497 ++num_frames_per_update_[tl_idx]; |
521 ++num_frames_total_; | 498 ++num_frames_total_; |
522 UpdateRateControlMetrics(frame_number); | 499 UpdateRateControlMetrics(frame_number); |
523 } | 500 } |
524 } else { | 501 } else { |
525 // In online mode, we calculate the metrics for a given frame right after | 502 // In online mode, we calculate the metrics for a given frame right after |
526 // it has been sent for encoding. | 503 // it has been sent for encoding. |
527 | 504 |
528 if (config_.hw_codec) { | 505 if (config_.hw_codec) { |
529 LOG(LS_WARNING) << "HW codecs should mostly be run in batch mode, " | 506 LOG(LS_WARNING) << "HW codecs should mostly be run in batch mode, " |
530 "since they may be pipelining."; | 507 "since they may be pipelining."; |
531 } | 508 } |
532 | 509 |
533 while (frame_number < num_frames) { | 510 while (frame_number < num_frames) { |
534 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); | 511 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); |
535 VerifyQpParser(frame_number); | 512 VerifyQpParser(frame_number); |
536 ++num_frames_per_update_[TemporalLayerIndexForFrame(frame_number)]; | 513 const int tl_idx = TemporalLayerIndexForFrame(frame_number); |
| 514 ++num_frames_per_update_[tl_idx]; |
537 ++num_frames_total_; | 515 ++num_frames_total_; |
538 UpdateRateControlMetrics(frame_number); | 516 UpdateRateControlMetrics(frame_number); |
539 | 517 |
540 ++frame_number; | 518 ++frame_number; |
541 | 519 |
542 // If we hit another/next update, verify stats for current state and | 520 // If we hit another/next update, verify stats for current state and |
543 // update layers and codec with new rates. | 521 // update layers and codec with new rates. |
544 if (frame_number == | 522 if (frame_number == |
545 rate_profile.frame_index_rate_update[update_index + 1]) { | 523 rate_profile.frame_index_rate_update[update_index + 1]) { |
546 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); | 524 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); |
(...skipping 13 matching lines...) Expand all Loading... |
560 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); | 538 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); |
561 } | 539 } |
562 | 540 |
563 // Verify rate control metrics for all frames (if in batch mode), or for all | 541 // Verify rate control metrics for all frames (if in batch mode), or for all |
564 // frames since the last rate update (if not in batch mode). | 542 // frames since the last rate update (if not in batch mode). |
565 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); | 543 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); |
566 EXPECT_EQ(num_frames, frame_number); | 544 EXPECT_EQ(num_frames, frame_number); |
567 EXPECT_EQ(num_frames + 1, static_cast<int>(stats_.stats_.size())); | 545 EXPECT_EQ(num_frames + 1, static_cast<int>(stats_.stats_.size())); |
568 | 546 |
569 // Release encoder and decoder to make sure they have finished processing. | 547 // Release encoder and decoder to make sure they have finished processing. |
570 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release()); | 548 processor_->Release(); |
571 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release()); | 549 DestroyEncoderAndDecoder(); |
572 | 550 |
573 // Close the analysis files before we use them for SSIM/PSNR calculations. | 551 // Close the analysis files before we use them for SSIM/PSNR calculations. |
574 analysis_frame_reader_->Close(); | 552 analysis_frame_reader_->Close(); |
575 analysis_frame_writer_->Close(); | 553 analysis_frame_writer_->Close(); |
576 | 554 |
577 // Close visualization files. | 555 // Close visualization files. |
578 if (encoded_frame_writer_) { | 556 if (encoded_frame_writer_) { |
579 EXPECT_TRUE(encoded_frame_writer_->Close()); | 557 EXPECT_TRUE(encoded_frame_writer_->Close()); |
580 } | 558 } |
581 if (decoded_frame_writer_) { | 559 if (decoded_frame_writer_) { |
582 decoded_frame_writer_->Close(); | 560 decoded_frame_writer_->Close(); |
583 } | 561 } |
584 | 562 |
585 // TODO(marpan): Should compute these quality metrics per SetRates update. | 563 // TODO(marpan): Should compute these quality metrics per SetRates update. |
586 test::QualityMetricsResult psnr_result, ssim_result; | 564 QualityMetricsResult psnr_result, ssim_result; |
587 EXPECT_EQ(0, test::I420MetricsFromFiles(config_.input_filename.c_str(), | 565 EXPECT_EQ(0, I420MetricsFromFiles(config_.input_filename.c_str(), |
588 config_.output_filename.c_str(), | 566 config_.output_filename.c_str(), |
589 config_.codec_settings.width, | 567 config_.codec_settings.width, |
590 config_.codec_settings.height, | 568 config_.codec_settings.height, |
591 &psnr_result, &ssim_result)); | 569 &psnr_result, &ssim_result)); |
592 VerifyQuality(psnr_result, ssim_result, quality_thresholds); | 570 VerifyQuality(psnr_result, ssim_result, quality_thresholds); |
593 stats_.PrintSummary(); | 571 stats_.PrintSummary(); |
594 printf("PSNR avg: %f, min: %f\nSSIM avg: %f, min: %f\n", | 572 printf("PSNR avg: %f, min: %f\nSSIM avg: %f, min: %f\n", |
595 psnr_result.average, psnr_result.min, ssim_result.average, | 573 psnr_result.average, psnr_result.min, ssim_result.average, |
596 ssim_result.min); | 574 ssim_result.min); |
597 printf("\n"); | 575 printf("\n"); |
598 | 576 |
599 // Remove analysis file. | 577 // Remove analysis file. |
600 if (remove(config_.output_filename.c_str()) < 0) { | 578 if (remove(config_.output_filename.c_str()) < 0) { |
601 fprintf(stderr, "Failed to remove temporary file!\n"); | 579 fprintf(stderr, "Failed to remove temporary file!\n"); |
602 } | 580 } |
603 } | 581 } |
604 | 582 |
605 static void SetProcessParams(test::TestConfig* config, | 583 static void SetProcessParams(TestConfig* config, |
606 bool hw_codec, | 584 bool hw_codec, |
607 bool use_single_core, | 585 bool use_single_core, |
608 float packet_loss_probability, | 586 float packet_loss_probability, |
609 int key_frame_interval, | 587 int key_frame_interval, |
610 std::string filename, | 588 std::string filename, |
611 bool verbose_logging, | 589 bool verbose_logging, |
612 bool batch_mode) { | 590 bool batch_mode) { |
613 // Configure input filename. | 591 // Configure input filename. |
614 config->filename = filename; | 592 config->filename = filename; |
615 config->input_filename = test::ResourcePath(filename, "yuv"); | 593 config->input_filename = ResourcePath(filename, "yuv"); |
616 // Generate an output filename in a safe way. | 594 // Generate an output filename in a safe way. |
617 config->output_filename = test::TempFilename( | 595 config->output_filename = |
618 test::OutputPath(), "videoprocessor_integrationtest"); | 596 TempFilename(OutputPath(), "videoprocessor_integrationtest"); |
619 config->hw_codec = hw_codec; | 597 config->hw_codec = hw_codec; |
620 config->use_single_core = use_single_core; | 598 config->use_single_core = use_single_core; |
621 config->keyframe_interval = key_frame_interval; | 599 config->keyframe_interval = key_frame_interval; |
622 config->networking_config.packet_loss_probability = packet_loss_probability; | 600 config->networking_config.packet_loss_probability = packet_loss_probability; |
623 config->verbose = verbose_logging; | 601 config->verbose = verbose_logging; |
624 config->batch_mode = batch_mode; | 602 config->batch_mode = batch_mode; |
625 } | 603 } |
626 | 604 |
627 static void SetCodecSettings(test::TestConfig* config, | 605 static void SetCodecSettings(TestConfig* config, |
628 VideoCodecType codec_type, | 606 VideoCodecType codec_type, |
629 int num_temporal_layers, | 607 int num_temporal_layers, |
630 bool error_concealment_on, | 608 bool error_concealment_on, |
631 bool denoising_on, | 609 bool denoising_on, |
632 bool frame_dropper_on, | 610 bool frame_dropper_on, |
633 bool spatial_resize_on, | 611 bool spatial_resize_on, |
634 bool resilience_on, | 612 bool resilience_on, |
635 int width, | 613 int width, |
636 int height) { | 614 int height) { |
637 VideoCodingModule::Codec(codec_type, &config->codec_settings); | 615 VideoCodingModule::Codec(codec_type, &config->codec_settings); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
700 max_encoding_rate_mismatch; | 678 max_encoding_rate_mismatch; |
701 rc_thresholds[update_index].max_time_hit_target = max_time_hit_target; | 679 rc_thresholds[update_index].max_time_hit_target = max_time_hit_target; |
702 rc_thresholds[update_index].num_spatial_resizes = num_spatial_resizes; | 680 rc_thresholds[update_index].num_spatial_resizes = num_spatial_resizes; |
703 rc_thresholds[update_index].num_key_frames = num_key_frames; | 681 rc_thresholds[update_index].num_key_frames = num_key_frames; |
704 } | 682 } |
705 | 683 |
706 // Config. | 684 // Config. |
707 TestConfig config_; | 685 TestConfig config_; |
708 | 686 |
709 // Codecs. | 687 // Codecs. |
710 std::unique_ptr<VideoEncoder> encoder_; | 688 std::unique_ptr<cricket::WebRtcVideoEncoderFactory> encoder_factory_; |
711 std::unique_ptr<cricket::WebRtcVideoEncoderFactory> external_encoder_factory_; | 689 VideoEncoder* encoder_; |
712 std::unique_ptr<VideoDecoder> decoder_; | 690 std::unique_ptr<cricket::WebRtcVideoDecoderFactory> decoder_factory_; |
713 std::unique_ptr<cricket::WebRtcVideoDecoderFactory> external_decoder_factory_; | 691 VideoDecoder* decoder_; |
714 | 692 |
715 // Helper objects. | 693 // Helper objects. |
716 std::unique_ptr<test::FrameReader> analysis_frame_reader_; | 694 std::unique_ptr<FrameReader> analysis_frame_reader_; |
717 std::unique_ptr<test::FrameWriter> analysis_frame_writer_; | 695 std::unique_ptr<FrameWriter> analysis_frame_writer_; |
718 test::PacketReader packet_reader_; | |
719 std::unique_ptr<test::PacketManipulator> packet_manipulator_; | |
720 test::Stats stats_; | |
721 // Must be destroyed before |encoder_| and |decoder_|. | |
722 std::unique_ptr<test::VideoProcessor> processor_; | |
723 | |
724 // Visualization objects. | |
725 std::unique_ptr<IvfFileWriter> encoded_frame_writer_; | 696 std::unique_ptr<IvfFileWriter> encoded_frame_writer_; |
726 std::unique_ptr<test::FrameWriter> decoded_frame_writer_; | 697 std::unique_ptr<FrameWriter> decoded_frame_writer_; |
| 698 PacketReader packet_reader_; |
| 699 std::unique_ptr<PacketManipulator> packet_manipulator_; |
| 700 Stats stats_; |
| 701 std::unique_ptr<VideoProcessor> processor_; |
727 | 702 |
728 // Quantities defined/updated for every encoder rate update. | 703 // Quantities defined/updated for every encoder rate update. |
729 int num_frames_per_update_[kMaxNumTemporalLayers]; | 704 int num_frames_per_update_[kMaxNumTemporalLayers]; |
730 float sum_frame_size_mismatch_[kMaxNumTemporalLayers]; | 705 float sum_frame_size_mismatch_[kMaxNumTemporalLayers]; |
731 float sum_encoded_frame_size_[kMaxNumTemporalLayers]; | 706 float sum_encoded_frame_size_[kMaxNumTemporalLayers]; |
732 float encoding_bitrate_[kMaxNumTemporalLayers]; | 707 float encoding_bitrate_[kMaxNumTemporalLayers]; |
733 float per_frame_bandwidth_[kMaxNumTemporalLayers]; | 708 float per_frame_bandwidth_[kMaxNumTemporalLayers]; |
734 float bit_rate_layer_[kMaxNumTemporalLayers]; | 709 float bit_rate_layer_[kMaxNumTemporalLayers]; |
735 float frame_rate_layer_[kMaxNumTemporalLayers]; | 710 float frame_rate_layer_[kMaxNumTemporalLayers]; |
736 int num_frames_total_; | 711 int num_frames_total_; |
737 float sum_encoded_frame_size_total_; | 712 float sum_encoded_frame_size_total_; |
738 float encoding_bitrate_total_; | 713 float encoding_bitrate_total_; |
739 float perc_encoding_rate_mismatch_; | 714 float perc_encoding_rate_mismatch_; |
740 int num_frames_to_hit_target_; | 715 int num_frames_to_hit_target_; |
741 bool encoding_rate_within_target_; | 716 bool encoding_rate_within_target_; |
742 int bit_rate_; | 717 int bit_rate_; |
743 int frame_rate_; | 718 int frame_rate_; |
744 float target_size_key_frame_initial_; | 719 float target_size_key_frame_initial_; |
745 float target_size_key_frame_; | 720 float target_size_key_frame_; |
746 float sum_key_frame_size_mismatch_; | 721 float sum_key_frame_size_mismatch_; |
747 int num_key_frames_; | 722 int num_key_frames_; |
748 int start_frame_rate_; | |
749 | |
750 // Codec and network settings. | |
751 int num_temporal_layers_; | |
752 }; | 723 }; |
753 | 724 |
754 } // namespace test | 725 } // namespace test |
755 } // namespace webrtc | 726 } // namespace webrtc |
756 | 727 |
757 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES
T_H_ | 728 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES
T_H_ |
OLD | NEW |