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 | |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 15 | #include <algorithm> // min_element, max_element |
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 { |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 22 | namespace { |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 23 | bool LessForEncodeTime(const FrameStatistic& s1, const FrameStatistic& s2) { |
philipel | cce46fc | 2015-12-21 03:04:49 -0800 | [diff] [blame] | 24 | return s1.encode_time_in_us < s2.encode_time_in_us; |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 25 | } |
| 26 | |
| 27 | bool LessForDecodeTime(const FrameStatistic& s1, const FrameStatistic& s2) { |
philipel | cce46fc | 2015-12-21 03:04:49 -0800 | [diff] [blame] | 28 | return s1.decode_time_in_us < s2.decode_time_in_us; |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 29 | } |
| 30 | |
| 31 | bool LessForEncodedSize(const FrameStatistic& s1, const FrameStatistic& s2) { |
philipel | cce46fc | 2015-12-21 03:04:49 -0800 | [diff] [blame] | 32 | return s1.encoded_frame_length_in_bytes < s2.encoded_frame_length_in_bytes; |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 33 | } |
| 34 | |
| 35 | bool LessForBitRate(const FrameStatistic& s1, const FrameStatistic& s2) { |
philipel | cce46fc | 2015-12-21 03:04:49 -0800 | [diff] [blame] | 36 | return s1.bit_rate_in_kbps < s2.bit_rate_in_kbps; |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 37 | } |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 38 | } // namespace |
| 39 | |
| 40 | Stats::Stats() {} |
| 41 | |
| 42 | Stats::~Stats() {} |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 43 | |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 44 | FrameStatistic& Stats::NewFrame(int frame_number) { |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 45 | RTC_DCHECK_GE(frame_number, 0); |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 46 | FrameStatistic stat; |
| 47 | stat.frame_number = frame_number; |
| 48 | stats_.push_back(stat); |
| 49 | return stats_[frame_number]; |
| 50 | } |
| 51 | |
| 52 | void Stats::PrintSummary() { |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 53 | if (stats_.empty()) { |
kjellander@webrtc.org | 5b97b12 | 2011-12-08 07:42:18 +0000 | [diff] [blame] | 54 | printf("No frame statistics have been logged yet.\n"); |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 55 | return; |
| 56 | } |
| 57 | |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 58 | // Calculate min, max, average and total encoding time. |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 59 | int total_encoding_time_in_us = 0; |
| 60 | int total_decoding_time_in_us = 0; |
asapersson | abc0080 | 2017-02-23 01:33:04 -0800 | [diff] [blame] | 61 | int total_qp = 0; |
| 62 | int total_qp_count = 0; |
pkasting@chromium.org | 4591fbd | 2014-11-20 22:28:14 +0000 | [diff] [blame] | 63 | size_t total_encoded_frames_lengths = 0; |
| 64 | size_t total_encoded_key_frames_lengths = 0; |
| 65 | size_t total_encoded_nonkey_frames_lengths = 0; |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 66 | size_t num_keyframes = 0; |
| 67 | size_t num_nonkeyframes = 0; |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 68 | |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 69 | for (const FrameStatistic& stat : stats_) { |
| 70 | total_encoding_time_in_us += stat.encode_time_in_us; |
| 71 | total_decoding_time_in_us += stat.decode_time_in_us; |
| 72 | total_encoded_frames_lengths += stat.encoded_frame_length_in_bytes; |
| 73 | if (stat.frame_type == webrtc::kVideoFrameKey) { |
| 74 | total_encoded_key_frames_lengths += stat.encoded_frame_length_in_bytes; |
| 75 | ++num_keyframes; |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 76 | } else { |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 77 | total_encoded_nonkey_frames_lengths += stat.encoded_frame_length_in_bytes; |
| 78 | ++num_nonkeyframes; |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 79 | } |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 80 | if (stat.qp >= 0) { |
| 81 | total_qp += stat.qp; |
asapersson | abc0080 | 2017-02-23 01:33:04 -0800 | [diff] [blame] | 82 | ++total_qp_count; |
| 83 | } |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 84 | } |
| 85 | |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 86 | // Encoding stats. |
kjellander@webrtc.org | 5b97b12 | 2011-12-08 07:42:18 +0000 | [diff] [blame] | 87 | printf("Encoding time:\n"); |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 88 | FrameStatisticsIterator frame; |
philipel | cce46fc | 2015-12-21 03:04:49 -0800 | [diff] [blame] | 89 | frame = std::min_element(stats_.begin(), stats_.end(), LessForEncodeTime); |
| 90 | printf(" Min : %7d us (frame %d)\n", frame->encode_time_in_us, |
| 91 | frame->frame_number); |
philipel | cce46fc | 2015-12-21 03:04:49 -0800 | [diff] [blame] | 92 | frame = std::max_element(stats_.begin(), stats_.end(), LessForEncodeTime); |
| 93 | printf(" Max : %7d us (frame %d)\n", frame->encode_time_in_us, |
| 94 | frame->frame_number); |
kjellander@webrtc.org | 5b97b12 | 2011-12-08 07:42:18 +0000 | [diff] [blame] | 95 | printf(" Average : %7d us\n", |
kjellander@webrtc.org | 7de6e10 | 2011-12-08 08:39:13 +0000 | [diff] [blame] | 96 | static_cast<int>(total_encoding_time_in_us / stats_.size())); |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 97 | |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 98 | // Decoding stats. |
kjellander@webrtc.org | 5b97b12 | 2011-12-08 07:42:18 +0000 | [diff] [blame] | 99 | printf("Decoding time:\n"); |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 100 | // Only consider successfully decoded frames (packet loss may cause failures). |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 101 | std::vector<FrameStatistic> decoded_frames; |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 102 | for (const FrameStatistic& stat : stats_) { |
| 103 | if (stat.decoding_successful) { |
| 104 | decoded_frames.push_back(stat); |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 105 | } |
| 106 | } |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 107 | if (decoded_frames.empty()) { |
kjellander@webrtc.org | 5b97b12 | 2011-12-08 07:42:18 +0000 | [diff] [blame] | 108 | printf("No successfully decoded frames exist in this statistics.\n"); |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 109 | } else { |
philipel | cce46fc | 2015-12-21 03:04:49 -0800 | [diff] [blame] | 110 | frame = std::min_element(decoded_frames.begin(), decoded_frames.end(), |
| 111 | LessForDecodeTime); |
| 112 | printf(" Min : %7d us (frame %d)\n", frame->decode_time_in_us, |
| 113 | frame->frame_number); |
philipel | cce46fc | 2015-12-21 03:04:49 -0800 | [diff] [blame] | 114 | frame = std::max_element(decoded_frames.begin(), decoded_frames.end(), |
| 115 | LessForDecodeTime); |
| 116 | printf(" Max : %7d us (frame %d)\n", frame->decode_time_in_us, |
| 117 | frame->frame_number); |
kjellander@webrtc.org | 5b97b12 | 2011-12-08 07:42:18 +0000 | [diff] [blame] | 118 | printf(" Average : %7d us\n", |
kjellander@webrtc.org | 7de6e10 | 2011-12-08 08:39:13 +0000 | [diff] [blame] | 119 | static_cast<int>(total_decoding_time_in_us / decoded_frames.size())); |
kjellander@webrtc.org | 5b97b12 | 2011-12-08 07:42:18 +0000 | [diff] [blame] | 120 | printf(" Failures: %d frames failed to decode.\n", |
kjellander@webrtc.org | 7de6e10 | 2011-12-08 08:39:13 +0000 | [diff] [blame] | 121 | static_cast<int>(stats_.size() - decoded_frames.size())); |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 122 | } |
| 123 | |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 124 | // Frame size stats. |
kjellander@webrtc.org | 5b97b12 | 2011-12-08 07:42:18 +0000 | [diff] [blame] | 125 | printf("Frame sizes:\n"); |
philipel | cce46fc | 2015-12-21 03:04:49 -0800 | [diff] [blame] | 126 | frame = std::min_element(stats_.begin(), stats_.end(), LessForEncodedSize); |
pkasting@chromium.org | 4591fbd | 2014-11-20 22:28:14 +0000 | [diff] [blame] | 127 | printf(" Min : %7" PRIuS " bytes (frame %d)\n", |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 128 | frame->encoded_frame_length_in_bytes, frame->frame_number); |
philipel | cce46fc | 2015-12-21 03:04:49 -0800 | [diff] [blame] | 129 | frame = std::max_element(stats_.begin(), stats_.end(), LessForEncodedSize); |
pkasting@chromium.org | 4591fbd | 2014-11-20 22:28:14 +0000 | [diff] [blame] | 130 | printf(" Max : %7" PRIuS " bytes (frame %d)\n", |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 131 | frame->encoded_frame_length_in_bytes, frame->frame_number); |
pkasting@chromium.org | 4591fbd | 2014-11-20 22:28:14 +0000 | [diff] [blame] | 132 | printf(" Average : %7" PRIuS " bytes\n", |
| 133 | total_encoded_frames_lengths / stats_.size()); |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 134 | if (num_keyframes > 0) { |
pkasting@chromium.org | 4591fbd | 2014-11-20 22:28:14 +0000 | [diff] [blame] | 135 | printf(" Average key frame size : %7" PRIuS " bytes (%" PRIuS |
| 136 | " keyframes)\n", |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 137 | total_encoded_key_frames_lengths / num_keyframes, num_keyframes); |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 138 | } |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 139 | if (num_nonkeyframes > 0) { |
pkasting@chromium.org | 4591fbd | 2014-11-20 22:28:14 +0000 | [diff] [blame] | 140 | printf(" Average non-key frame size: %7" PRIuS " bytes (%" PRIuS |
| 141 | " frames)\n", |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 142 | total_encoded_nonkey_frames_lengths / num_nonkeyframes, |
| 143 | num_nonkeyframes); |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 144 | } |
| 145 | |
asapersson | 68b91d7 | 2017-06-04 23:43:41 -0700 | [diff] [blame] | 146 | // Bitrate stats. |
brandtr | bea36fd | 2017-08-07 03:36:54 -0700 | [diff] [blame] | 147 | printf("Bitrates:\n"); |
philipel | cce46fc | 2015-12-21 03:04:49 -0800 | [diff] [blame] | 148 | frame = std::min_element(stats_.begin(), stats_.end(), LessForBitRate); |
brandtr | bea36fd | 2017-08-07 03:36:54 -0700 | [diff] [blame] | 149 | printf(" Min bitrate: %7d kbps (frame %d)\n", frame->bit_rate_in_kbps, |
philipel | cce46fc | 2015-12-21 03:04:49 -0800 | [diff] [blame] | 150 | frame->frame_number); |
philipel | cce46fc | 2015-12-21 03:04:49 -0800 | [diff] [blame] | 151 | frame = std::max_element(stats_.begin(), stats_.end(), LessForBitRate); |
brandtr | bea36fd | 2017-08-07 03:36:54 -0700 | [diff] [blame] | 152 | printf(" Max bitrate: %7d kbps (frame %d)\n", frame->bit_rate_in_kbps, |
philipel | cce46fc | 2015-12-21 03:04:49 -0800 | [diff] [blame] | 153 | frame->frame_number); |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 154 | |
kjellander@webrtc.org | 5b97b12 | 2011-12-08 07:42:18 +0000 | [diff] [blame] | 155 | printf("\n"); |
philipel | cce46fc | 2015-12-21 03:04:49 -0800 | [diff] [blame] | 156 | printf("Total encoding time : %7d ms.\n", total_encoding_time_in_us / 1000); |
| 157 | printf("Total decoding time : %7d ms.\n", total_decoding_time_in_us / 1000); |
kjellander@webrtc.org | 5b97b12 | 2011-12-08 07:42:18 +0000 | [diff] [blame] | 158 | printf("Total processing time: %7d ms.\n", |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 159 | (total_encoding_time_in_us + total_decoding_time_in_us) / 1000); |
brandtr | bea36fd | 2017-08-07 03:36:54 -0700 | [diff] [blame] | 160 | |
| 161 | int avg_qp = (total_qp_count > 0) ? (total_qp / total_qp_count) : -1; |
| 162 | printf("Average QP: %d\n", avg_qp); |
kjellander@webrtc.org | 35a1756 | 2011-10-06 06:44:54 +0000 | [diff] [blame] | 163 | } |
| 164 | |
| 165 | } // namespace test |
| 166 | } // namespace webrtc |