blob: b2950ae35da328412b3b290ce4a5bbc45bd53c23 [file] [log] [blame]
kjellander@webrtc.org35a17562011-10-06 06:44:54 +00001/*
leozwang@webrtc.orgdb2de5b2012-03-05 19:53:24 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
kjellander@webrtc.org35a17562011-10-06 06:44:54 +00003 *
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.org5b97b122011-12-08 07:42:18 +000010
pbos@webrtc.orga4407322013-07-16 12:32:05 +000011#include "webrtc/modules/video_coding/codecs/test/stats.h"
kjellander@webrtc.org35a17562011-10-06 06:44:54 +000012
pbos@webrtc.org12dc1a32013-08-05 16:22:53 +000013#include <stdio.h>
14
brandtr8935d972017-09-06 01:53:22 -070015#include <algorithm>
kjellander@webrtc.org35a17562011-10-06 06:44:54 +000016
Edward Lemurc20978e2017-07-06 19:44:34 +020017#include "webrtc/rtc_base/checks.h"
18#include "webrtc/rtc_base/format_macros.h"
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000019
kjellander@webrtc.org35a17562011-10-06 06:44:54 +000020namespace webrtc {
21namespace test {
brandtr8935d972017-09-06 01:53:22 -070022
asapersson68b91d72017-06-04 23:43:41 -070023namespace {
brandtr8935d972017-09-06 01:53:22 -070024
kjellander@webrtc.org35a17562011-10-06 06:44:54 +000025bool LessForEncodeTime(const FrameStatistic& s1, const FrameStatistic& s2) {
brandtr8935d972017-09-06 01:53:22 -070026 RTC_DCHECK_NE(s1.frame_number, s2.frame_number);
27 return s1.encode_time_us < s2.encode_time_us;
kjellander@webrtc.org35a17562011-10-06 06:44:54 +000028}
29
30bool LessForDecodeTime(const FrameStatistic& s1, const FrameStatistic& s2) {
brandtr8935d972017-09-06 01:53:22 -070031 RTC_DCHECK_NE(s1.frame_number, s2.frame_number);
32 return s1.decode_time_us < s2.decode_time_us;
kjellander@webrtc.org35a17562011-10-06 06:44:54 +000033}
34
35bool LessForEncodedSize(const FrameStatistic& s1, const FrameStatistic& s2) {
brandtr8935d972017-09-06 01:53:22 -070036 RTC_DCHECK_NE(s1.frame_number, s2.frame_number);
37 return s1.encoded_frame_size_bytes < s2.encoded_frame_size_bytes;
kjellander@webrtc.org35a17562011-10-06 06:44:54 +000038}
39
40bool LessForBitRate(const FrameStatistic& s1, const FrameStatistic& s2) {
brandtr8935d972017-09-06 01:53:22 -070041 RTC_DCHECK_NE(s1.frame_number, s2.frame_number);
42 return s1.bitrate_kbps < s2.bitrate_kbps;
kjellander@webrtc.org35a17562011-10-06 06:44:54 +000043}
brandtr8935d972017-09-06 01:53:22 -070044
asapersson68b91d72017-06-04 23:43:41 -070045} // namespace
46
brandtr8935d972017-09-06 01:53:22 -070047FrameStatistic* 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.org35a17562011-10-06 06:44:54 +000051}
52
brandtr8935d972017-09-06 01:53:22 -070053FrameStatistic* 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
59size_t Stats::size() const {
60 return stats_.size();
61}
62
63void Stats::PrintSummary() const {
asapersson68b91d72017-06-04 23:43:41 -070064 if (stats_.empty()) {
kjellander@webrtc.org5b97b122011-12-08 07:42:18 +000065 printf("No frame statistics have been logged yet.\n");
kjellander@webrtc.org35a17562011-10-06 06:44:54 +000066 return;
67 }
68
asapersson68b91d72017-06-04 23:43:41 -070069 // Calculate min, max, average and total encoding time.
brandtr8935d972017-09-06 01:53:22 -070070 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.org35a17562011-10-06 06:44:54 +000077
asapersson68b91d72017-06-04 23:43:41 -070078 for (const FrameStatistic& stat : stats_) {
brandtr8935d972017-09-06 01:53:22 -070079 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;
asapersson68b91d72017-06-04 23:43:41 -070082 if (stat.frame_type == webrtc::kVideoFrameKey) {
brandtr8935d972017-09-06 01:53:22 -070083 total_encoded_key_frame_size_bytes += stat.encoded_frame_size_bytes;
84 ++num_key_frames;
kjellander@webrtc.org35a17562011-10-06 06:44:54 +000085 } else {
brandtr8935d972017-09-06 01:53:22 -070086 total_encoded_delta_frame_size_bytes += stat.encoded_frame_size_bytes;
87 ++num_delta_frames;
asaperssonabc00802017-02-23 01:33:04 -080088 }
kjellander@webrtc.org35a17562011-10-06 06:44:54 +000089 }
90
asapersson68b91d72017-06-04 23:43:41 -070091 // Encoding stats.
kjellander@webrtc.org5b97b122011-12-08 07:42:18 +000092 printf("Encoding time:\n");
brandtr8935d972017-09-06 01:53:22 -070093 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.org5b97b122011-12-08 07:42:18 +0000100 printf(" Average : %7d us\n",
brandtr8935d972017-09-06 01:53:22 -0700101 static_cast<int>(total_encoding_time_us / stats_.size()));
kjellander@webrtc.org35a17562011-10-06 06:44:54 +0000102
asapersson68b91d72017-06-04 23:43:41 -0700103 // Decoding stats.
kjellander@webrtc.org5b97b122011-12-08 07:42:18 +0000104 printf("Decoding time:\n");
asapersson68b91d72017-06-04 23:43:41 -0700105 // Only consider successfully decoded frames (packet loss may cause failures).
kjellander@webrtc.org35a17562011-10-06 06:44:54 +0000106 std::vector<FrameStatistic> decoded_frames;
asapersson68b91d72017-06-04 23:43:41 -0700107 for (const FrameStatistic& stat : stats_) {
108 if (stat.decoding_successful) {
109 decoded_frames.push_back(stat);
kjellander@webrtc.org35a17562011-10-06 06:44:54 +0000110 }
111 }
asapersson68b91d72017-06-04 23:43:41 -0700112 if (decoded_frames.empty()) {
kjellander@webrtc.org5b97b122011-12-08 07:42:18 +0000113 printf("No successfully decoded frames exist in this statistics.\n");
kjellander@webrtc.org35a17562011-10-06 06:44:54 +0000114 } else {
brandtr8935d972017-09-06 01:53:22 -0700115 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.org5b97b122011-12-08 07:42:18 +0000123 printf(" Average : %7d us\n",
brandtr8935d972017-09-06 01:53:22 -0700124 static_cast<int>(total_decoding_time_us / decoded_frames.size()));
kjellander@webrtc.org5b97b122011-12-08 07:42:18 +0000125 printf(" Failures: %d frames failed to decode.\n",
kjellander@webrtc.org7de6e102011-12-08 08:39:13 +0000126 static_cast<int>(stats_.size() - decoded_frames.size()));
kjellander@webrtc.org35a17562011-10-06 06:44:54 +0000127 }
128
asapersson68b91d72017-06-04 23:43:41 -0700129 // Frame size stats.
kjellander@webrtc.org5b97b122011-12-08 07:42:18 +0000130 printf("Frame sizes:\n");
brandtr8935d972017-09-06 01:53:22 -0700131 frame_it = std::min_element(stats_.begin(), stats_.end(), LessForEncodedSize);
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000132 printf(" Min : %7" PRIuS " bytes (frame %d)\n",
brandtr8935d972017-09-06 01:53:22 -0700133 frame_it->encoded_frame_size_bytes, frame_it->frame_number);
134 frame_it = std::max_element(stats_.begin(), stats_.end(), LessForEncodedSize);
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000135 printf(" Max : %7" PRIuS " bytes (frame %d)\n",
brandtr8935d972017-09-06 01:53:22 -0700136 frame_it->encoded_frame_size_bytes, frame_it->frame_number);
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000137 printf(" Average : %7" PRIuS " bytes\n",
brandtr8935d972017-09-06 01:53:22 -0700138 total_encoded_frame_size_bytes / stats_.size());
139 if (num_key_frames > 0) {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000140 printf(" Average key frame size : %7" PRIuS " bytes (%" PRIuS
141 " keyframes)\n",
brandtr8935d972017-09-06 01:53:22 -0700142 total_encoded_key_frame_size_bytes / num_key_frames, num_key_frames);
kjellander@webrtc.org35a17562011-10-06 06:44:54 +0000143 }
brandtr8935d972017-09-06 01:53:22 -0700144 if (num_delta_frames > 0) {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000145 printf(" Average non-key frame size: %7" PRIuS " bytes (%" PRIuS
146 " frames)\n",
brandtr8935d972017-09-06 01:53:22 -0700147 total_encoded_delta_frame_size_bytes / num_delta_frames,
148 num_delta_frames);
kjellander@webrtc.org35a17562011-10-06 06:44:54 +0000149 }
150
asapersson68b91d72017-06-04 23:43:41 -0700151 // Bitrate stats.
brandtrbea36fd2017-08-07 03:36:54 -0700152 printf("Bitrates:\n");
brandtr8935d972017-09-06 01:53:22 -0700153 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.org35a17562011-10-06 06:44:54 +0000159
kjellander@webrtc.org5b97b122011-12-08 07:42:18 +0000160 printf("\n");
brandtr8935d972017-09-06 01:53:22 -0700161 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.org5b97b122011-12-08 07:42:18 +0000163 printf("Total processing time: %7d ms.\n",
brandtr8935d972017-09-06 01:53:22 -0700164 (total_encoding_time_us + total_decoding_time_us) / 1000);
brandtrbea36fd2017-08-07 03:36:54 -0700165
brandtr8935d972017-09-06 01:53:22 -0700166 // 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 }
brandtrbea36fd2017-08-07 03:36:54 -0700175 int avg_qp = (total_qp_count > 0) ? (total_qp / total_qp_count) : -1;
176 printf("Average QP: %d\n", avg_qp);
kjellander@webrtc.org35a17562011-10-06 06:44:54 +0000177}
178
179} // namespace test
180} // namespace webrtc