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 #include "webrtc/modules/video_coding/codecs/test/stats.h" | 11 #include "webrtc/modules/video_coding/codecs/test/stats.h" |
12 | 12 |
13 #include <assert.h> | |
14 #include <stdio.h> | 13 #include <stdio.h> |
15 | 14 |
16 #include <algorithm> // min_element, max_element | 15 #include <algorithm> // min_element, max_element |
17 | 16 |
| 17 #include "webrtc/base/checks.h" |
18 #include "webrtc/base/format_macros.h" | 18 #include "webrtc/base/format_macros.h" |
19 | 19 |
20 namespace webrtc { | 20 namespace webrtc { |
21 namespace test { | 21 namespace test { |
22 | 22 namespace { |
23 FrameStatistic::FrameStatistic() | |
24 : encoding_successful(false), | |
25 decoding_successful(false), | |
26 encode_return_code(0), | |
27 decode_return_code(0), | |
28 encode_time_in_us(0), | |
29 decode_time_in_us(0), | |
30 qp(-1), | |
31 frame_number(0), | |
32 packets_dropped(0), | |
33 total_packets(0), | |
34 bit_rate_in_kbps(0), | |
35 encoded_frame_length_in_bytes(0), | |
36 frame_type(kVideoFrameDelta) {} | |
37 | |
38 Stats::Stats() {} | |
39 | |
40 Stats::~Stats() {} | |
41 | |
42 bool LessForEncodeTime(const FrameStatistic& s1, const FrameStatistic& s2) { | 23 bool LessForEncodeTime(const FrameStatistic& s1, const FrameStatistic& s2) { |
43 return s1.encode_time_in_us < s2.encode_time_in_us; | 24 return s1.encode_time_in_us < s2.encode_time_in_us; |
44 } | 25 } |
45 | 26 |
46 bool LessForDecodeTime(const FrameStatistic& s1, const FrameStatistic& s2) { | 27 bool LessForDecodeTime(const FrameStatistic& s1, const FrameStatistic& s2) { |
47 return s1.decode_time_in_us < s2.decode_time_in_us; | 28 return s1.decode_time_in_us < s2.decode_time_in_us; |
48 } | 29 } |
49 | 30 |
50 bool LessForEncodedSize(const FrameStatistic& s1, const FrameStatistic& s2) { | 31 bool LessForEncodedSize(const FrameStatistic& s1, const FrameStatistic& s2) { |
51 return s1.encoded_frame_length_in_bytes < s2.encoded_frame_length_in_bytes; | 32 return s1.encoded_frame_length_in_bytes < s2.encoded_frame_length_in_bytes; |
52 } | 33 } |
53 | 34 |
54 bool LessForBitRate(const FrameStatistic& s1, const FrameStatistic& s2) { | 35 bool LessForBitRate(const FrameStatistic& s1, const FrameStatistic& s2) { |
55 return s1.bit_rate_in_kbps < s2.bit_rate_in_kbps; | 36 return s1.bit_rate_in_kbps < s2.bit_rate_in_kbps; |
56 } | 37 } |
| 38 } // namespace |
| 39 |
| 40 Stats::Stats() {} |
| 41 |
| 42 Stats::~Stats() {} |
57 | 43 |
58 FrameStatistic& Stats::NewFrame(int frame_number) { | 44 FrameStatistic& Stats::NewFrame(int frame_number) { |
59 assert(frame_number >= 0); | 45 RTC_DCHECK_GE(frame_number, 0); |
60 FrameStatistic stat; | 46 FrameStatistic stat; |
61 stat.frame_number = frame_number; | 47 stat.frame_number = frame_number; |
62 stats_.push_back(stat); | 48 stats_.push_back(stat); |
63 return stats_[frame_number]; | 49 return stats_[frame_number]; |
64 } | 50 } |
65 | 51 |
66 void Stats::PrintSummary() { | 52 void Stats::PrintSummary() { |
67 printf("Processing summary:\n"); | 53 printf("Processing summary:\n"); |
68 if (stats_.size() == 0) { | 54 if (stats_.empty()) { |
69 printf("No frame statistics have been logged yet.\n"); | 55 printf("No frame statistics have been logged yet.\n"); |
70 return; | 56 return; |
71 } | 57 } |
72 | 58 |
73 // Calculate min, max, average and total encoding time | 59 // Calculate min, max, average and total encoding time. |
74 int total_encoding_time_in_us = 0; | 60 int total_encoding_time_in_us = 0; |
75 int total_decoding_time_in_us = 0; | 61 int total_decoding_time_in_us = 0; |
76 int total_qp = 0; | 62 int total_qp = 0; |
77 int total_qp_count = 0; | 63 int total_qp_count = 0; |
78 size_t total_encoded_frames_lengths = 0; | 64 size_t total_encoded_frames_lengths = 0; |
79 size_t total_encoded_key_frames_lengths = 0; | 65 size_t total_encoded_key_frames_lengths = 0; |
80 size_t total_encoded_nonkey_frames_lengths = 0; | 66 size_t total_encoded_nonkey_frames_lengths = 0; |
81 size_t nbr_keyframes = 0; | 67 size_t num_keyframes = 0; |
82 size_t nbr_nonkeyframes = 0; | 68 size_t num_nonkeyframes = 0; |
83 | 69 |
84 for (FrameStatisticsIterator it = stats_.begin(); it != stats_.end(); ++it) { | 70 for (const FrameStatistic& stat : stats_) { |
85 total_encoding_time_in_us += it->encode_time_in_us; | 71 total_encoding_time_in_us += stat.encode_time_in_us; |
86 total_decoding_time_in_us += it->decode_time_in_us; | 72 total_decoding_time_in_us += stat.decode_time_in_us; |
87 total_encoded_frames_lengths += it->encoded_frame_length_in_bytes; | 73 total_encoded_frames_lengths += stat.encoded_frame_length_in_bytes; |
88 if (it->frame_type == webrtc::kVideoFrameKey) { | 74 if (stat.frame_type == webrtc::kVideoFrameKey) { |
89 total_encoded_key_frames_lengths += it->encoded_frame_length_in_bytes; | 75 total_encoded_key_frames_lengths += stat.encoded_frame_length_in_bytes; |
90 nbr_keyframes++; | 76 ++num_keyframes; |
91 } else { | 77 } else { |
92 total_encoded_nonkey_frames_lengths += it->encoded_frame_length_in_bytes; | 78 total_encoded_nonkey_frames_lengths += stat.encoded_frame_length_in_bytes; |
93 nbr_nonkeyframes++; | 79 ++num_nonkeyframes; |
94 } | 80 } |
95 if (it->qp >= 0) { | 81 if (stat.qp >= 0) { |
96 total_qp += it->qp; | 82 total_qp += stat.qp; |
97 ++total_qp_count; | 83 ++total_qp_count; |
98 } | 84 } |
99 } | 85 } |
100 | 86 |
| 87 // Encoding stats. |
| 88 printf("Encoding time:\n"); |
101 FrameStatisticsIterator frame; | 89 FrameStatisticsIterator frame; |
102 | |
103 // ENCODING | |
104 printf("Encoding time:\n"); | |
105 frame = std::min_element(stats_.begin(), stats_.end(), LessForEncodeTime); | 90 frame = std::min_element(stats_.begin(), stats_.end(), LessForEncodeTime); |
106 printf(" Min : %7d us (frame %d)\n", frame->encode_time_in_us, | 91 printf(" Min : %7d us (frame %d)\n", frame->encode_time_in_us, |
107 frame->frame_number); | 92 frame->frame_number); |
108 | |
109 frame = std::max_element(stats_.begin(), stats_.end(), LessForEncodeTime); | 93 frame = std::max_element(stats_.begin(), stats_.end(), LessForEncodeTime); |
110 printf(" Max : %7d us (frame %d)\n", frame->encode_time_in_us, | 94 printf(" Max : %7d us (frame %d)\n", frame->encode_time_in_us, |
111 frame->frame_number); | 95 frame->frame_number); |
112 | |
113 printf(" Average : %7d us\n", | 96 printf(" Average : %7d us\n", |
114 static_cast<int>(total_encoding_time_in_us / stats_.size())); | 97 static_cast<int>(total_encoding_time_in_us / stats_.size())); |
115 | 98 |
116 // DECODING | 99 // Decoding stats. |
117 printf("Decoding time:\n"); | 100 printf("Decoding time:\n"); |
118 // only consider frames that were successfully decoded (packet loss may cause | 101 // Only consider successfully decoded frames (packet loss may cause failures). |
119 // failures) | |
120 std::vector<FrameStatistic> decoded_frames; | 102 std::vector<FrameStatistic> decoded_frames; |
121 for (std::vector<FrameStatistic>::iterator it = stats_.begin(); | 103 for (const FrameStatistic& stat : stats_) { |
122 it != stats_.end(); ++it) { | 104 if (stat.decoding_successful) { |
123 if (it->decoding_successful) { | 105 decoded_frames.push_back(stat); |
124 decoded_frames.push_back(*it); | |
125 } | 106 } |
126 } | 107 } |
127 if (decoded_frames.size() == 0) { | 108 if (decoded_frames.empty()) { |
128 printf("No successfully decoded frames exist in this statistics.\n"); | 109 printf("No successfully decoded frames exist in this statistics.\n"); |
129 } else { | 110 } else { |
130 frame = std::min_element(decoded_frames.begin(), decoded_frames.end(), | 111 frame = std::min_element(decoded_frames.begin(), decoded_frames.end(), |
131 LessForDecodeTime); | 112 LessForDecodeTime); |
132 printf(" Min : %7d us (frame %d)\n", frame->decode_time_in_us, | 113 printf(" Min : %7d us (frame %d)\n", frame->decode_time_in_us, |
133 frame->frame_number); | 114 frame->frame_number); |
134 | |
135 frame = std::max_element(decoded_frames.begin(), decoded_frames.end(), | 115 frame = std::max_element(decoded_frames.begin(), decoded_frames.end(), |
136 LessForDecodeTime); | 116 LessForDecodeTime); |
137 printf(" Max : %7d us (frame %d)\n", frame->decode_time_in_us, | 117 printf(" Max : %7d us (frame %d)\n", frame->decode_time_in_us, |
138 frame->frame_number); | 118 frame->frame_number); |
139 | |
140 printf(" Average : %7d us\n", | 119 printf(" Average : %7d us\n", |
141 static_cast<int>(total_decoding_time_in_us / decoded_frames.size())); | 120 static_cast<int>(total_decoding_time_in_us / decoded_frames.size())); |
142 printf(" Failures: %d frames failed to decode.\n", | 121 printf(" Failures: %d frames failed to decode.\n", |
143 static_cast<int>(stats_.size() - decoded_frames.size())); | 122 static_cast<int>(stats_.size() - decoded_frames.size())); |
144 } | 123 } |
145 | 124 |
146 // SIZE | 125 // Frame size stats. |
147 printf("Frame sizes:\n"); | 126 printf("Frame sizes:\n"); |
148 frame = std::min_element(stats_.begin(), stats_.end(), LessForEncodedSize); | 127 frame = std::min_element(stats_.begin(), stats_.end(), LessForEncodedSize); |
149 printf(" Min : %7" PRIuS " bytes (frame %d)\n", | 128 printf(" Min : %7" PRIuS " bytes (frame %d)\n", |
150 frame->encoded_frame_length_in_bytes, frame->frame_number); | 129 frame->encoded_frame_length_in_bytes, frame->frame_number); |
151 | |
152 frame = std::max_element(stats_.begin(), stats_.end(), LessForEncodedSize); | 130 frame = std::max_element(stats_.begin(), stats_.end(), LessForEncodedSize); |
153 printf(" Max : %7" PRIuS " bytes (frame %d)\n", | 131 printf(" Max : %7" PRIuS " bytes (frame %d)\n", |
154 frame->encoded_frame_length_in_bytes, frame->frame_number); | 132 frame->encoded_frame_length_in_bytes, frame->frame_number); |
155 | |
156 printf(" Average : %7" PRIuS " bytes\n", | 133 printf(" Average : %7" PRIuS " bytes\n", |
157 total_encoded_frames_lengths / stats_.size()); | 134 total_encoded_frames_lengths / stats_.size()); |
158 if (nbr_keyframes > 0) { | 135 if (num_keyframes > 0) { |
159 printf(" Average key frame size : %7" PRIuS " bytes (%" PRIuS | 136 printf(" Average key frame size : %7" PRIuS " bytes (%" PRIuS |
160 " keyframes)\n", | 137 " keyframes)\n", |
161 total_encoded_key_frames_lengths / nbr_keyframes, nbr_keyframes); | 138 total_encoded_key_frames_lengths / num_keyframes, num_keyframes); |
162 } | 139 } |
163 if (nbr_nonkeyframes > 0) { | 140 if (num_nonkeyframes > 0) { |
164 printf(" Average non-key frame size: %7" PRIuS " bytes (%" PRIuS | 141 printf(" Average non-key frame size: %7" PRIuS " bytes (%" PRIuS |
165 " frames)\n", | 142 " frames)\n", |
166 total_encoded_nonkey_frames_lengths / nbr_nonkeyframes, | 143 total_encoded_nonkey_frames_lengths / num_nonkeyframes, |
167 nbr_nonkeyframes); | 144 num_nonkeyframes); |
168 } | 145 } |
169 | 146 |
170 // BIT RATE | 147 // Bitrate stats. |
171 printf("Bit rates:\n"); | 148 printf("Bit rates:\n"); |
172 frame = std::min_element(stats_.begin(), stats_.end(), LessForBitRate); | 149 frame = std::min_element(stats_.begin(), stats_.end(), LessForBitRate); |
173 printf(" Min bit rate: %7d kbps (frame %d)\n", frame->bit_rate_in_kbps, | 150 printf(" Min bit rate: %7d kbps (frame %d)\n", frame->bit_rate_in_kbps, |
174 frame->frame_number); | 151 frame->frame_number); |
175 | |
176 frame = std::max_element(stats_.begin(), stats_.end(), LessForBitRate); | 152 frame = std::max_element(stats_.begin(), stats_.end(), LessForBitRate); |
177 printf(" Max bit rate: %7d kbps (frame %d)\n", frame->bit_rate_in_kbps, | 153 printf(" Max bit rate: %7d kbps (frame %d)\n", frame->bit_rate_in_kbps, |
178 frame->frame_number); | 154 frame->frame_number); |
179 | 155 |
180 int avg_qp = (total_qp_count > 0) ? (total_qp / total_qp_count) : -1; | 156 int avg_qp = (total_qp_count > 0) ? (total_qp / total_qp_count) : -1; |
181 printf("Average QP: %d\n", avg_qp); | 157 printf("Average QP: %d\n", avg_qp); |
182 | 158 |
183 printf("\n"); | 159 printf("\n"); |
184 printf("Total encoding time : %7d ms.\n", total_encoding_time_in_us / 1000); | 160 printf("Total encoding time : %7d ms.\n", total_encoding_time_in_us / 1000); |
185 printf("Total decoding time : %7d ms.\n", total_decoding_time_in_us / 1000); | 161 printf("Total decoding time : %7d ms.\n", total_decoding_time_in_us / 1000); |
186 printf("Total processing time: %7d ms.\n", | 162 printf("Total processing time: %7d ms.\n", |
187 (total_encoding_time_in_us + total_decoding_time_in_us) / 1000); | 163 (total_encoding_time_in_us + total_decoding_time_in_us) / 1000); |
188 } | 164 } |
189 | 165 |
190 } // namespace test | 166 } // namespace test |
191 } // namespace webrtc | 167 } // namespace webrtc |
OLD | NEW |