| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 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 #include "webrtc/video/video_quality_test.h" | 10 #include "webrtc/video/video_quality_test.h" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 #include "webrtc/call/call.h" | 26 #include "webrtc/call/call.h" |
| 27 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" | 27 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" |
| 28 #include "webrtc/logging/rtc_event_log/rtc_event_log.h" | 28 #include "webrtc/logging/rtc_event_log/rtc_event_log.h" |
| 29 #include "webrtc/modules/audio_mixer/audio_mixer_impl.h" | 29 #include "webrtc/modules/audio_mixer/audio_mixer_impl.h" |
| 30 #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" | 30 #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" |
| 31 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" | 31 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" |
| 32 #include "webrtc/modules/video_coding/codecs/h264/include/h264.h" | 32 #include "webrtc/modules/video_coding/codecs/h264/include/h264.h" |
| 33 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" | 33 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" |
| 34 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h" | 34 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h" |
| 35 #include "webrtc/system_wrappers/include/cpu_info.h" | 35 #include "webrtc/system_wrappers/include/cpu_info.h" |
| 36 #include "webrtc/system_wrappers/include/field_trial.h" |
| 36 #include "webrtc/test/gtest.h" | 37 #include "webrtc/test/gtest.h" |
| 37 #include "webrtc/test/layer_filtering_transport.h" | 38 #include "webrtc/test/layer_filtering_transport.h" |
| 38 #include "webrtc/test/run_loop.h" | 39 #include "webrtc/test/run_loop.h" |
| 39 #include "webrtc/test/statistics.h" | 40 #include "webrtc/test/statistics.h" |
| 40 #include "webrtc/test/testsupport/fileutils.h" | 41 #include "webrtc/test/testsupport/fileutils.h" |
| 41 #include "webrtc/test/vcm_capturer.h" | 42 #include "webrtc/test/vcm_capturer.h" |
| 42 #include "webrtc/test/video_renderer.h" | 43 #include "webrtc/test/video_renderer.h" |
| 43 #include "webrtc/voice_engine/include/voe_base.h" | 44 #include "webrtc/voice_engine/include/voe_base.h" |
| 44 | 45 |
| 45 namespace { | 46 namespace { |
| 46 | 47 |
| 47 constexpr int kSendStatsPollingIntervalMs = 1000; | 48 constexpr int kSendStatsPollingIntervalMs = 1000; |
| 48 constexpr int kPayloadTypeH264 = 122; | 49 constexpr int kPayloadTypeH264 = 122; |
| 49 constexpr int kPayloadTypeVP8 = 123; | 50 constexpr int kPayloadTypeVP8 = 123; |
| 50 constexpr int kPayloadTypeVP9 = 124; | 51 constexpr int kPayloadTypeVP9 = 124; |
| 51 constexpr size_t kMaxComparisons = 10; | 52 constexpr size_t kMaxComparisons = 10; |
| 52 constexpr char kSyncGroup[] = "av_sync"; | 53 constexpr char kSyncGroup[] = "av_sync"; |
| 53 constexpr int kOpusMinBitrateBps = 6000; | 54 constexpr int kOpusMinBitrateBps = 6000; |
| 54 constexpr int kOpusBitrateFbBps = 32000; | 55 constexpr int kOpusBitrateFbBps = 32000; |
| 56 constexpr int kFramesSentInQuickTest = 1; |
| 55 | 57 |
| 56 struct VoiceEngineState { | 58 struct VoiceEngineState { |
| 57 VoiceEngineState() | 59 VoiceEngineState() |
| 58 : voice_engine(nullptr), | 60 : voice_engine(nullptr), |
| 59 base(nullptr), | 61 base(nullptr), |
| 60 send_channel_id(-1), | 62 send_channel_id(-1), |
| 61 receive_channel_id(-1) {} | 63 receive_channel_id(-1) {} |
| 62 | 64 |
| 63 webrtc::VoiceEngine* voice_engine; | 65 webrtc::VoiceEngine* voice_engine; |
| 64 webrtc::VoEBase* base; | 66 webrtc::VoEBase* base; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 VideoAnalyzer(test::LayerFilteringTransport* transport, | 131 VideoAnalyzer(test::LayerFilteringTransport* transport, |
| 130 const std::string& test_label, | 132 const std::string& test_label, |
| 131 double avg_psnr_threshold, | 133 double avg_psnr_threshold, |
| 132 double avg_ssim_threshold, | 134 double avg_ssim_threshold, |
| 133 int duration_frames, | 135 int duration_frames, |
| 134 FILE* graph_data_output_file, | 136 FILE* graph_data_output_file, |
| 135 const std::string& graph_title, | 137 const std::string& graph_title, |
| 136 uint32_t ssrc_to_analyze, | 138 uint32_t ssrc_to_analyze, |
| 137 uint32_t rtx_ssrc_to_analyze, | 139 uint32_t rtx_ssrc_to_analyze, |
| 138 uint32_t selected_width, | 140 uint32_t selected_width, |
| 139 uint32_t selected_height) | 141 uint32_t selected_height, |
| 142 bool is_quick_test_enabled) |
| 140 : transport_(transport), | 143 : transport_(transport), |
| 141 receiver_(nullptr), | 144 receiver_(nullptr), |
| 142 send_stream_(nullptr), | 145 send_stream_(nullptr), |
| 143 receive_stream_(nullptr), | 146 receive_stream_(nullptr), |
| 144 captured_frame_forwarder_(this), | 147 captured_frame_forwarder_(this), |
| 145 test_label_(test_label), | 148 test_label_(test_label), |
| 146 graph_data_output_file_(graph_data_output_file), | 149 graph_data_output_file_(graph_data_output_file), |
| 147 graph_title_(graph_title), | 150 graph_title_(graph_title), |
| 148 ssrc_to_analyze_(ssrc_to_analyze), | 151 ssrc_to_analyze_(ssrc_to_analyze), |
| 149 rtx_ssrc_to_analyze_(rtx_ssrc_to_analyze), | 152 rtx_ssrc_to_analyze_(rtx_ssrc_to_analyze), |
| 150 selected_width_(selected_width), | 153 selected_width_(selected_width), |
| 151 selected_height_(selected_height), | 154 selected_height_(selected_height), |
| 152 pre_encode_proxy_(this), | 155 pre_encode_proxy_(this), |
| 153 encode_timing_proxy_(this), | 156 encode_timing_proxy_(this), |
| 154 frames_to_process_(duration_frames), | 157 frames_to_process_(duration_frames), |
| 155 frames_recorded_(0), | 158 frames_recorded_(0), |
| 156 frames_processed_(0), | 159 frames_processed_(0), |
| 157 dropped_frames_(0), | 160 dropped_frames_(0), |
| 158 dropped_frames_before_first_encode_(0), | 161 dropped_frames_before_first_encode_(0), |
| 159 dropped_frames_before_rendering_(0), | 162 dropped_frames_before_rendering_(0), |
| 160 last_render_time_(0), | 163 last_render_time_(0), |
| 161 rtp_timestamp_delta_(0), | 164 rtp_timestamp_delta_(0), |
| 162 avg_psnr_threshold_(avg_psnr_threshold), | 165 avg_psnr_threshold_(avg_psnr_threshold), |
| 163 avg_ssim_threshold_(avg_ssim_threshold), | 166 avg_ssim_threshold_(avg_ssim_threshold), |
| 167 is_quick_test_enabled_(is_quick_test_enabled), |
| 164 stats_polling_thread_(&PollStatsThread, this, "StatsPoller"), | 168 stats_polling_thread_(&PollStatsThread, this, "StatsPoller"), |
| 165 comparison_available_event_(false, false), | 169 comparison_available_event_(false, false), |
| 166 done_(true, false) { | 170 done_(true, false) { |
| 167 // Create thread pool for CPU-expensive PSNR/SSIM calculations. | 171 // Create thread pool for CPU-expensive PSNR/SSIM calculations. |
| 168 | 172 |
| 169 // Try to use about as many threads as cores, but leave kMinCoresLeft alone, | 173 // Try to use about as many threads as cores, but leave kMinCoresLeft alone, |
| 170 // so that we don't accidentally starve "real" worker threads (codec etc). | 174 // so that we don't accidentally starve "real" worker threads (codec etc). |
| 171 // Also, don't allocate more than kMaxComparisonThreads, even if there are | 175 // Also, don't allocate more than kMaxComparisonThreads, even if there are |
| 172 // spare cores. | 176 // spare cores. |
| 173 | 177 |
| (...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 676 PrintResult("decode_time", decode_time_ms_, " ms"); | 680 PrintResult("decode_time", decode_time_ms_, " ms"); |
| 677 PrintResult("decode_time_max", decode_time_max_ms_, " ms"); | 681 PrintResult("decode_time_max", decode_time_max_ms_, " ms"); |
| 678 } | 682 } |
| 679 | 683 |
| 680 printf("RESULT dropped_frames: %s = %d frames\n", test_label_.c_str(), | 684 printf("RESULT dropped_frames: %s = %d frames\n", test_label_.c_str(), |
| 681 dropped_frames_); | 685 dropped_frames_); |
| 682 printf("RESULT dropped_frames_before_first_encode: %s = %d frames\n", | 686 printf("RESULT dropped_frames_before_first_encode: %s = %d frames\n", |
| 683 test_label_.c_str(), dropped_frames_before_first_encode_); | 687 test_label_.c_str(), dropped_frames_before_first_encode_); |
| 684 printf("RESULT dropped_frames_before_rendering: %s = %d frames\n", | 688 printf("RESULT dropped_frames_before_rendering: %s = %d frames\n", |
| 685 test_label_.c_str(), dropped_frames_before_rendering_); | 689 test_label_.c_str(), dropped_frames_before_rendering_); |
| 686 | 690 // Disable quality check for quick test, as quality checks may fail |
| 687 EXPECT_GT(psnr_.Mean(), avg_psnr_threshold_); | 691 // because too few samples were collected. |
| 688 EXPECT_GT(ssim_.Mean(), avg_ssim_threshold_); | 692 if (!is_quick_test_enabled_) { |
| 693 EXPECT_GT(psnr_.Mean(), avg_psnr_threshold_); |
| 694 EXPECT_GT(ssim_.Mean(), avg_ssim_threshold_); |
| 695 } |
| 689 } | 696 } |
| 690 | 697 |
| 691 void PerformFrameComparison(const FrameComparison& comparison) { | 698 void PerformFrameComparison(const FrameComparison& comparison) { |
| 692 // Perform expensive psnr and ssim calculations while not holding lock. | 699 // Perform expensive psnr and ssim calculations while not holding lock. |
| 693 double psnr = -1.0; | 700 double psnr = -1.0; |
| 694 double ssim = -1.0; | 701 double ssim = -1.0; |
| 695 if (comparison.reference) { | 702 if (comparison.reference) { |
| 696 psnr = I420PSNR(&*comparison.reference, &*comparison.render); | 703 psnr = I420PSNR(&*comparison.reference, &*comparison.render); |
| 697 ssim = I420SSIM(&*comparison.reference, &*comparison.render); | 704 ssim = I420SSIM(&*comparison.reference, &*comparison.render); |
| 698 } | 705 } |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 883 std::deque<VideoFrame> frames_ GUARDED_BY(crit_); | 890 std::deque<VideoFrame> frames_ GUARDED_BY(crit_); |
| 884 rtc::Optional<VideoFrame> last_rendered_frame_ GUARDED_BY(crit_); | 891 rtc::Optional<VideoFrame> last_rendered_frame_ GUARDED_BY(crit_); |
| 885 rtc::TimestampWrapAroundHandler wrap_handler_ GUARDED_BY(crit_); | 892 rtc::TimestampWrapAroundHandler wrap_handler_ GUARDED_BY(crit_); |
| 886 std::map<int64_t, int64_t> send_times_ GUARDED_BY(crit_); | 893 std::map<int64_t, int64_t> send_times_ GUARDED_BY(crit_); |
| 887 std::map<int64_t, int64_t> recv_times_ GUARDED_BY(crit_); | 894 std::map<int64_t, int64_t> recv_times_ GUARDED_BY(crit_); |
| 888 std::map<int64_t, size_t> encoded_frame_sizes_ GUARDED_BY(crit_); | 895 std::map<int64_t, size_t> encoded_frame_sizes_ GUARDED_BY(crit_); |
| 889 rtc::Optional<uint32_t> first_encoded_timestamp_ GUARDED_BY(crit_); | 896 rtc::Optional<uint32_t> first_encoded_timestamp_ GUARDED_BY(crit_); |
| 890 rtc::Optional<uint32_t> first_sent_timestamp_ GUARDED_BY(crit_); | 897 rtc::Optional<uint32_t> first_sent_timestamp_ GUARDED_BY(crit_); |
| 891 const double avg_psnr_threshold_; | 898 const double avg_psnr_threshold_; |
| 892 const double avg_ssim_threshold_; | 899 const double avg_ssim_threshold_; |
| 900 bool is_quick_test_enabled_; |
| 893 | 901 |
| 894 rtc::CriticalSection comparison_lock_; | 902 rtc::CriticalSection comparison_lock_; |
| 895 std::vector<rtc::PlatformThread*> comparison_thread_pool_; | 903 std::vector<rtc::PlatformThread*> comparison_thread_pool_; |
| 896 rtc::PlatformThread stats_polling_thread_; | 904 rtc::PlatformThread stats_polling_thread_; |
| 897 rtc::Event comparison_available_event_; | 905 rtc::Event comparison_available_event_; |
| 898 std::deque<FrameComparison> comparisons_ GUARDED_BY(comparison_lock_); | 906 std::deque<FrameComparison> comparisons_ GUARDED_BY(comparison_lock_); |
| 899 rtc::Event done_; | 907 rtc::Event done_; |
| 900 }; | 908 }; |
| 901 | 909 |
| 902 VideoQualityTest::VideoQualityTest() | 910 VideoQualityTest::VideoQualityTest() |
| (...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1332 selected_stream.height != params_.video.height || | 1340 selected_stream.height != params_.video.height || |
| 1333 (!params_.ss.spatial_layers.empty() && | 1341 (!params_.ss.spatial_layers.empty() && |
| 1334 params_.ss.spatial_layers[selected_sl].scaling_factor_num != | 1342 params_.ss.spatial_layers[selected_sl].scaling_factor_num != |
| 1335 params_.ss.spatial_layers[selected_sl].scaling_factor_den); | 1343 params_.ss.spatial_layers[selected_sl].scaling_factor_den); |
| 1336 if (disable_quality_check) { | 1344 if (disable_quality_check) { |
| 1337 fprintf(stderr, | 1345 fprintf(stderr, |
| 1338 "Warning: Calculating PSNR and SSIM for downsized resolution " | 1346 "Warning: Calculating PSNR and SSIM for downsized resolution " |
| 1339 "not implemented yet! Skipping PSNR and SSIM calculations!\n"); | 1347 "not implemented yet! Skipping PSNR and SSIM calculations!\n"); |
| 1340 } | 1348 } |
| 1341 | 1349 |
| 1350 bool is_quick_test_enabled = |
| 1351 field_trial::FindFullName("WebRTC-QuickPerfTest") == "Enabled"; |
| 1342 VideoAnalyzer analyzer( | 1352 VideoAnalyzer analyzer( |
| 1343 &send_transport, params_.analyzer.test_label, | 1353 &send_transport, params_.analyzer.test_label, |
| 1344 disable_quality_check ? -1.1 : params_.analyzer.avg_psnr_threshold, | 1354 disable_quality_check ? -1.1 : params_.analyzer.avg_psnr_threshold, |
| 1345 disable_quality_check ? -1.1 : params_.analyzer.avg_ssim_threshold, | 1355 disable_quality_check ? -1.1 : params_.analyzer.avg_ssim_threshold, |
| 1346 params_.analyzer.test_durations_secs * params_.video.fps, | 1356 is_quick_test_enabled |
| 1357 ? kFramesSentInQuickTest |
| 1358 : params_.analyzer.test_durations_secs * params_.video.fps, |
| 1347 graph_data_output_file, graph_title, | 1359 graph_data_output_file, graph_title, |
| 1348 kVideoSendSsrcs[params_.ss.selected_stream], | 1360 kVideoSendSsrcs[params_.ss.selected_stream], |
| 1349 kSendRtxSsrcs[params_.ss.selected_stream], | 1361 kSendRtxSsrcs[params_.ss.selected_stream], |
| 1350 static_cast<uint32_t>(selected_stream.width), | 1362 static_cast<uint32_t>(selected_stream.width), |
| 1351 static_cast<uint32_t>(selected_stream.height)); | 1363 static_cast<uint32_t>(selected_stream.height), is_quick_test_enabled); |
| 1352 | |
| 1353 analyzer.SetReceiver(receiver_call_->Receiver()); | 1364 analyzer.SetReceiver(receiver_call_->Receiver()); |
| 1354 send_transport.SetReceiver(&analyzer); | 1365 send_transport.SetReceiver(&analyzer); |
| 1355 recv_transport.SetReceiver(sender_call_->Receiver()); | 1366 recv_transport.SetReceiver(sender_call_->Receiver()); |
| 1356 | 1367 |
| 1357 SetupVideo(&analyzer, &recv_transport); | 1368 SetupVideo(&analyzer, &recv_transport); |
| 1358 video_receive_configs_[params_.ss.selected_stream].renderer = &analyzer; | 1369 video_receive_configs_[params_.ss.selected_stream].renderer = &analyzer; |
| 1359 video_send_config_.pre_encode_callback = analyzer.pre_encode_proxy(); | 1370 video_send_config_.pre_encode_callback = analyzer.pre_encode_proxy(); |
| 1360 for (auto& config : video_receive_configs_) | 1371 for (auto& config : video_receive_configs_) |
| 1361 config.pre_decode_callback = &analyzer; | 1372 config.pre_decode_callback = &analyzer; |
| 1362 RTC_DCHECK(!video_send_config_.post_encode_callback); | 1373 RTC_DCHECK(!video_send_config_.post_encode_callback); |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1597 std::ostringstream str; | 1608 std::ostringstream str; |
| 1598 str << receive_logs_++; | 1609 str << receive_logs_++; |
| 1599 std::string path = | 1610 std::string path = |
| 1600 params_.video.encoded_frame_base_path + "." + str.str() + ".recv.ivf"; | 1611 params_.video.encoded_frame_base_path + "." + str.str() + ".recv.ivf"; |
| 1601 stream->EnableEncodedFrameRecording(rtc::CreatePlatformFile(path), | 1612 stream->EnableEncodedFrameRecording(rtc::CreatePlatformFile(path), |
| 1602 10000000); | 1613 10000000); |
| 1603 } | 1614 } |
| 1604 } | 1615 } |
| 1605 | 1616 |
| 1606 } // namespace webrtc | 1617 } // namespace webrtc |
| OLD | NEW |