kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 1 | /* |
leozwang@webrtc.org | db2de5b | 2012-03-05 19:53:24 +0000 | [diff] [blame] | 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license |
| 5 | * that can be found in the LICENSE file in the root of the source |
| 6 | * tree. An additional intellectual property rights grant can be found |
| 7 | * in the file PATENTS. All contributing project authors may |
| 8 | * be found in the AUTHORS file in the root of the source tree. |
| 9 | */ |
kjellander@webrtc.org | 5b97b12 | 2011-12-08 07:42:18 +0000 | [diff] [blame] | 10 | |
pbos@webrtc.org | a440732 | 2013-07-16 12:32:05 +0000 | [diff] [blame] | 11 | #include "webrtc/modules/video_coding/codecs/test/stats.h" |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 12 | |
pbos@webrtc.org | 12dc1a3 | 2013-08-05 16:22:53 +0000 | [diff] [blame] | 13 | #include <stdio.h> |
| 14 | |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 15 | #include <algorithm> |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 16 | |
Edward Lemur | c20978e | 2017-07-06 19:44:34 +0200 | [diff] [blame] | 17 | #include "webrtc/rtc_base/checks.h" |
| 18 | #include "webrtc/rtc_base/format_macros.h" |
pkasting@chromium.org | 4591fbd | 2014-11-20 22:28:14 +0000 | [diff] [blame] | 19 | |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 20 | namespace webrtc { |
| 21 | namespace test { |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 22 | |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 23 | namespace { |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 24 | |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 25 | bool LessForEncodeTime(const FrameStatistic& s1, const FrameStatistic& s2) { |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 26 | RTC_DCHECK_NE(s1.frame_number, s2.frame_number); |
| 27 | return s1.encode_time_us < s2.encode_time_us; |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 28 | } |
| 29 | |
| 30 | bool LessForDecodeTime(const FrameStatistic& s1, const FrameStatistic& s2) { |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 31 | RTC_DCHECK_NE(s1.frame_number, s2.frame_number); |
| 32 | return s1.decode_time_us < s2.decode_time_us; |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 33 | } |
| 34 | |
| 35 | bool LessForEncodedSize(const FrameStatistic& s1, const FrameStatistic& s2) { |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 36 | RTC_DCHECK_NE(s1.frame_number, s2.frame_number); |
| 37 | return s1.encoded_frame_size_bytes < s2.encoded_frame_size_bytes; |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 38 | } |
| 39 | |
| 40 | bool LessForBitRate(const FrameStatistic& s1, const FrameStatistic& s2) { |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 41 | RTC_DCHECK_NE(s1.frame_number, s2.frame_number); |
| 42 | return s1.bitrate_kbps < s2.bitrate_kbps; |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 43 | } |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 44 | |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 45 | } // namespace |
| 46 | |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 47 | FrameStatistic* Stats::AddFrame() { |
| 48 | // We don't expect more frames than what can be stored in an int. |
| 49 | stats_.emplace_back(static_cast<int>(stats_.size())); |
| 50 | return &stats_.back(); |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 51 | } |
| 52 | |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 53 | FrameStatistic* Stats::GetFrame(int frame_number) { |
| 54 | RTC_CHECK_GE(frame_number, 0); |
| 55 | RTC_CHECK_LT(frame_number, stats_.size()); |
| 56 | return &stats_[frame_number]; |
| 57 | } |
| 58 | |
| 59 | size_t Stats::size() const { |
| 60 | return stats_.size(); |
| 61 | } |
| 62 | |
| 63 | void Stats::PrintSummary() const { |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 64 | if (stats_.empty()) { |
kjellander@webrtc.org | 5b97b12 | 2011-12-08 07:42:18 +0000 | [diff] [blame] | 65 | printf("No frame statistics have been logged yet.\n"); |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 66 | return; |
| 67 | } |
| 68 | |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 69 | // Calculate min, max, average and total encoding time. |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 70 | int total_encoding_time_us = 0; |
| 71 | int total_decoding_time_us = 0; |
| 72 | size_t total_encoded_frame_size_bytes = 0; |
| 73 | size_t total_encoded_key_frame_size_bytes = 0; |
| 74 | size_t total_encoded_delta_frame_size_bytes = 0; |
| 75 | size_t num_key_frames = 0; |
| 76 | size_t num_delta_frames = 0; |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 77 | |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 78 | for (const FrameStatistic& stat : stats_) { |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 79 | total_encoding_time_us += stat.encode_time_us; |
| 80 | total_decoding_time_us += stat.decode_time_us; |
| 81 | total_encoded_frame_size_bytes += stat.encoded_frame_size_bytes; |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 82 | if (stat.frame_type == webrtc::kVideoFrameKey) { |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 83 | total_encoded_key_frame_size_bytes += stat.encoded_frame_size_bytes; |
| 84 | ++num_key_frames; |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 85 | } else { |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 86 | total_encoded_delta_frame_size_bytes += stat.encoded_frame_size_bytes; |
| 87 | ++num_delta_frames; |
asapersson | abc0080 | 2017-02-23 01:33:04 -0800 | [diff] [blame] | 88 | } |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 89 | } |
| 90 | |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 91 | // Encoding stats. |
kjellander@webrtc.org | 5b97b12 | 2011-12-08 07:42:18 +0000 | [diff] [blame] | 92 | printf("Encoding time:\n"); |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 93 | auto frame_it = |
| 94 | std::min_element(stats_.begin(), stats_.end(), LessForEncodeTime); |
| 95 | printf(" Min : %7d us (frame %d)\n", frame_it->encode_time_us, |
| 96 | frame_it->frame_number); |
| 97 | frame_it = std::max_element(stats_.begin(), stats_.end(), LessForEncodeTime); |
| 98 | printf(" Max : %7d us (frame %d)\n", frame_it->encode_time_us, |
| 99 | frame_it->frame_number); |
kjellander@webrtc.org | 5b97b12 | 2011-12-08 07:42:18 +0000 | [diff] [blame] | 100 | printf(" Average : %7d us\n", |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 101 | static_cast<int>(total_encoding_time_us / stats_.size())); |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 102 | |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 103 | // Decoding stats. |
kjellander@webrtc.org | 5b97b12 | 2011-12-08 07:42:18 +0000 | [diff] [blame] | 104 | printf("Decoding time:\n"); |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 105 | // Only consider successfully decoded frames (packet loss may cause failures). |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 106 | std::vector<FrameStatistic> decoded_frames; |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 107 | for (const FrameStatistic& stat : stats_) { |
| 108 | if (stat.decoding_successful) { |
| 109 | decoded_frames.push_back(stat); |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 110 | } |
| 111 | } |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 112 | if (decoded_frames.empty()) { |
kjellander@webrtc.org | 5b97b12 | 2011-12-08 07:42:18 +0000 | [diff] [blame] | 113 | printf("No successfully decoded frames exist in this statistics.\n"); |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 114 | } else { |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 115 | frame_it = std::min_element(decoded_frames.begin(), decoded_frames.end(), |
| 116 | LessForDecodeTime); |
| 117 | printf(" Min : %7d us (frame %d)\n", frame_it->decode_time_us, |
| 118 | frame_it->frame_number); |
| 119 | frame_it = std::max_element(decoded_frames.begin(), decoded_frames.end(), |
| 120 | LessForDecodeTime); |
| 121 | printf(" Max : %7d us (frame %d)\n", frame_it->decode_time_us, |
| 122 | frame_it->frame_number); |
kjellander@webrtc.org | 5b97b12 | 2011-12-08 07:42:18 +0000 | [diff] [blame] | 123 | printf(" Average : %7d us\n", |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 124 | static_cast<int>(total_decoding_time_us / decoded_frames.size())); |
kjellander@webrtc.org | 5b97b12 | 2011-12-08 07:42:18 +0000 | [diff] [blame] | 125 | printf(" Failures: %d frames failed to decode.\n", |
kjellander@webrtc.org | 7de6e10 | 2011-12-08 08:39:13 +0000 | [diff] [blame] | 126 | static_cast<int>(stats_.size() - decoded_frames.size())); |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 127 | } |
| 128 | |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 129 | // Frame size stats. |
kjellander@webrtc.org | 5b97b12 | 2011-12-08 07:42:18 +0000 | [diff] [blame] | 130 | printf("Frame sizes:\n"); |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 131 | frame_it = std::min_element(stats_.begin(), stats_.end(), LessForEncodedSize); |
pkasting@chromium.org | 4591fbd | 2014-11-20 22:28:14 +0000 | [diff] [blame] | 132 | printf(" Min : %7" PRIuS " bytes (frame %d)\n", |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 133 | frame_it->encoded_frame_size_bytes, frame_it->frame_number); |
| 134 | frame_it = std::max_element(stats_.begin(), stats_.end(), LessForEncodedSize); |
pkasting@chromium.org | 4591fbd | 2014-11-20 22:28:14 +0000 | [diff] [blame] | 135 | printf(" Max : %7" PRIuS " bytes (frame %d)\n", |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 136 | frame_it->encoded_frame_size_bytes, frame_it->frame_number); |
pkasting@chromium.org | 4591fbd | 2014-11-20 22:28:14 +0000 | [diff] [blame] | 137 | printf(" Average : %7" PRIuS " bytes\n", |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 138 | total_encoded_frame_size_bytes / stats_.size()); |
| 139 | if (num_key_frames > 0) { |
pkasting@chromium.org | 4591fbd | 2014-11-20 22:28:14 +0000 | [diff] [blame] | 140 | printf(" Average key frame size : %7" PRIuS " bytes (%" PRIuS |
| 141 | " keyframes)\n", |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 142 | total_encoded_key_frame_size_bytes / num_key_frames, num_key_frames); |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 143 | } |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 144 | if (num_delta_frames > 0) { |
pkasting@chromium.org | 4591fbd | 2014-11-20 22:28:14 +0000 | [diff] [blame] | 145 | printf(" Average non-key frame size: %7" PRIuS " bytes (%" PRIuS |
| 146 | " frames)\n", |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 147 | total_encoded_delta_frame_size_bytes / num_delta_frames, |
| 148 | num_delta_frames); |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 149 | } |
| 150 | |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 151 | // Bitrate stats. |
brandtr | bea36fd | 2017-08-07 03:36:54 -0700 | [diff] [blame] | 152 | printf("Bitrates:\n"); |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 153 | frame_it = std::min_element(stats_.begin(), stats_.end(), LessForBitRate); |
| 154 | printf(" Min bitrate: %7d kbps (frame %d)\n", frame_it->bitrate_kbps, |
| 155 | frame_it->frame_number); |
| 156 | frame_it = std::max_element(stats_.begin(), stats_.end(), LessForBitRate); |
| 157 | printf(" Max bitrate: %7d kbps (frame %d)\n", frame_it->bitrate_kbps, |
| 158 | frame_it->frame_number); |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 159 | |
kjellander@webrtc.org | 5b97b12 | 2011-12-08 07:42:18 +0000 | [diff] [blame] | 160 | printf("\n"); |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 161 | printf("Total encoding time : %7d ms.\n", total_encoding_time_us / 1000); |
| 162 | printf("Total decoding time : %7d ms.\n", total_decoding_time_us / 1000); |
kjellander@webrtc.org | 5b97b12 | 2011-12-08 07:42:18 +0000 | [diff] [blame] | 163 | printf("Total processing time: %7d ms.\n", |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 164 | (total_encoding_time_us + total_decoding_time_us) / 1000); |
brandtr | bea36fd | 2017-08-07 03:36:54 -0700 | [diff] [blame] | 165 | |
brandtr | 8935d97 | 2017-09-06 01:53:22 -0700 | [diff] [blame] | 166 | // QP stats. |
| 167 | int total_qp = 0; |
| 168 | int total_qp_count = 0; |
| 169 | for (const FrameStatistic& stat : stats_) { |
| 170 | if (stat.qp >= 0) { |
| 171 | total_qp += stat.qp; |
| 172 | ++total_qp_count; |
| 173 | } |
| 174 | } |
brandtr | bea36fd | 2017-08-07 03:36:54 -0700 | [diff] [blame] | 175 | int avg_qp = (total_qp_count > 0) ? (total_qp / total_qp_count) : -1; |
| 176 | printf("Average QP: %d\n", avg_qp); |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 177 | } |
| 178 | |
| 179 | } // namespace test |
| 180 | } // namespace webrtc |