blob: 649c0d549a80735fbdbf689b7adcfcf58608a58e [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
kjellander@webrtc.org35a17562011-10-06 06:44:54 +000015#include <algorithm> // min_element, max_element
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 {
asapersson68b91d72017-06-04 23:43:41 -070022namespace {
kjellander@webrtc.org35a17562011-10-06 06:44:54 +000023bool LessForEncodeTime(const FrameStatistic& s1, const FrameStatistic& s2) {
philipelcce46fc2015-12-21 03:04:49 -080024 return s1.encode_time_in_us < s2.encode_time_in_us;
kjellander@webrtc.org35a17562011-10-06 06:44:54 +000025}
26
27bool LessForDecodeTime(const FrameStatistic& s1, const FrameStatistic& s2) {
philipelcce46fc2015-12-21 03:04:49 -080028 return s1.decode_time_in_us < s2.decode_time_in_us;
kjellander@webrtc.org35a17562011-10-06 06:44:54 +000029}
30
31bool LessForEncodedSize(const FrameStatistic& s1, const FrameStatistic& s2) {
philipelcce46fc2015-12-21 03:04:49 -080032 return s1.encoded_frame_length_in_bytes < s2.encoded_frame_length_in_bytes;
kjellander@webrtc.org35a17562011-10-06 06:44:54 +000033}
34
35bool LessForBitRate(const FrameStatistic& s1, const FrameStatistic& s2) {
philipelcce46fc2015-12-21 03:04:49 -080036 return s1.bit_rate_in_kbps < s2.bit_rate_in_kbps;
kjellander@webrtc.org35a17562011-10-06 06:44:54 +000037}
asapersson68b91d72017-06-04 23:43:41 -070038} // namespace
39
40Stats::Stats() {}
41
42Stats::~Stats() {}
kjellander@webrtc.org35a17562011-10-06 06:44:54 +000043
kjellander@webrtc.org35a17562011-10-06 06:44:54 +000044FrameStatistic& Stats::NewFrame(int frame_number) {
asapersson68b91d72017-06-04 23:43:41 -070045 RTC_DCHECK_GE(frame_number, 0);
kjellander@webrtc.org35a17562011-10-06 06:44:54 +000046 FrameStatistic stat;
47 stat.frame_number = frame_number;
48 stats_.push_back(stat);
49 return stats_[frame_number];
50}
51
52void Stats::PrintSummary() {
asapersson68b91d72017-06-04 23:43:41 -070053 if (stats_.empty()) {
kjellander@webrtc.org5b97b122011-12-08 07:42:18 +000054 printf("No frame statistics have been logged yet.\n");
kjellander@webrtc.org35a17562011-10-06 06:44:54 +000055 return;
56 }
57
asapersson68b91d72017-06-04 23:43:41 -070058 // Calculate min, max, average and total encoding time.
kjellander@webrtc.org35a17562011-10-06 06:44:54 +000059 int total_encoding_time_in_us = 0;
60 int total_decoding_time_in_us = 0;
asaperssonabc00802017-02-23 01:33:04 -080061 int total_qp = 0;
62 int total_qp_count = 0;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000063 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;
asapersson68b91d72017-06-04 23:43:41 -070066 size_t num_keyframes = 0;
67 size_t num_nonkeyframes = 0;
kjellander@webrtc.org35a17562011-10-06 06:44:54 +000068
asapersson68b91d72017-06-04 23:43:41 -070069 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.org35a17562011-10-06 06:44:54 +000076 } else {
asapersson68b91d72017-06-04 23:43:41 -070077 total_encoded_nonkey_frames_lengths += stat.encoded_frame_length_in_bytes;
78 ++num_nonkeyframes;
kjellander@webrtc.org35a17562011-10-06 06:44:54 +000079 }
asapersson68b91d72017-06-04 23:43:41 -070080 if (stat.qp >= 0) {
81 total_qp += stat.qp;
asaperssonabc00802017-02-23 01:33:04 -080082 ++total_qp_count;
83 }
kjellander@webrtc.org35a17562011-10-06 06:44:54 +000084 }
85
asapersson68b91d72017-06-04 23:43:41 -070086 // Encoding stats.
kjellander@webrtc.org5b97b122011-12-08 07:42:18 +000087 printf("Encoding time:\n");
asapersson68b91d72017-06-04 23:43:41 -070088 FrameStatisticsIterator frame;
philipelcce46fc2015-12-21 03:04:49 -080089 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);
philipelcce46fc2015-12-21 03:04:49 -080092 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.org5b97b122011-12-08 07:42:18 +000095 printf(" Average : %7d us\n",
kjellander@webrtc.org7de6e102011-12-08 08:39:13 +000096 static_cast<int>(total_encoding_time_in_us / stats_.size()));
kjellander@webrtc.org35a17562011-10-06 06:44:54 +000097
asapersson68b91d72017-06-04 23:43:41 -070098 // Decoding stats.
kjellander@webrtc.org5b97b122011-12-08 07:42:18 +000099 printf("Decoding time:\n");
asapersson68b91d72017-06-04 23:43:41 -0700100 // Only consider successfully decoded frames (packet loss may cause failures).
kjellander@webrtc.org35a17562011-10-06 06:44:54 +0000101 std::vector<FrameStatistic> decoded_frames;
asapersson68b91d72017-06-04 23:43:41 -0700102 for (const FrameStatistic& stat : stats_) {
103 if (stat.decoding_successful) {
104 decoded_frames.push_back(stat);
kjellander@webrtc.org35a17562011-10-06 06:44:54 +0000105 }
106 }
asapersson68b91d72017-06-04 23:43:41 -0700107 if (decoded_frames.empty()) {
kjellander@webrtc.org5b97b122011-12-08 07:42:18 +0000108 printf("No successfully decoded frames exist in this statistics.\n");
kjellander@webrtc.org35a17562011-10-06 06:44:54 +0000109 } else {
philipelcce46fc2015-12-21 03:04:49 -0800110 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);
philipelcce46fc2015-12-21 03:04:49 -0800114 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.org5b97b122011-12-08 07:42:18 +0000118 printf(" Average : %7d us\n",
kjellander@webrtc.org7de6e102011-12-08 08:39:13 +0000119 static_cast<int>(total_decoding_time_in_us / decoded_frames.size()));
kjellander@webrtc.org5b97b122011-12-08 07:42:18 +0000120 printf(" Failures: %d frames failed to decode.\n",
kjellander@webrtc.org7de6e102011-12-08 08:39:13 +0000121 static_cast<int>(stats_.size() - decoded_frames.size()));
kjellander@webrtc.org35a17562011-10-06 06:44:54 +0000122 }
123
asapersson68b91d72017-06-04 23:43:41 -0700124 // Frame size stats.
kjellander@webrtc.org5b97b122011-12-08 07:42:18 +0000125 printf("Frame sizes:\n");
philipelcce46fc2015-12-21 03:04:49 -0800126 frame = std::min_element(stats_.begin(), stats_.end(), LessForEncodedSize);
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000127 printf(" Min : %7" PRIuS " bytes (frame %d)\n",
kjellander@webrtc.org35a17562011-10-06 06:44:54 +0000128 frame->encoded_frame_length_in_bytes, frame->frame_number);
philipelcce46fc2015-12-21 03:04:49 -0800129 frame = std::max_element(stats_.begin(), stats_.end(), LessForEncodedSize);
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000130 printf(" Max : %7" PRIuS " bytes (frame %d)\n",
kjellander@webrtc.org35a17562011-10-06 06:44:54 +0000131 frame->encoded_frame_length_in_bytes, frame->frame_number);
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000132 printf(" Average : %7" PRIuS " bytes\n",
133 total_encoded_frames_lengths / stats_.size());
asapersson68b91d72017-06-04 23:43:41 -0700134 if (num_keyframes > 0) {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000135 printf(" Average key frame size : %7" PRIuS " bytes (%" PRIuS
136 " keyframes)\n",
asapersson68b91d72017-06-04 23:43:41 -0700137 total_encoded_key_frames_lengths / num_keyframes, num_keyframes);
kjellander@webrtc.org35a17562011-10-06 06:44:54 +0000138 }
asapersson68b91d72017-06-04 23:43:41 -0700139 if (num_nonkeyframes > 0) {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000140 printf(" Average non-key frame size: %7" PRIuS " bytes (%" PRIuS
141 " frames)\n",
asapersson68b91d72017-06-04 23:43:41 -0700142 total_encoded_nonkey_frames_lengths / num_nonkeyframes,
143 num_nonkeyframes);
kjellander@webrtc.org35a17562011-10-06 06:44:54 +0000144 }
145
asapersson68b91d72017-06-04 23:43:41 -0700146 // Bitrate stats.
brandtrbea36fd2017-08-07 03:36:54 -0700147 printf("Bitrates:\n");
philipelcce46fc2015-12-21 03:04:49 -0800148 frame = std::min_element(stats_.begin(), stats_.end(), LessForBitRate);
brandtrbea36fd2017-08-07 03:36:54 -0700149 printf(" Min bitrate: %7d kbps (frame %d)\n", frame->bit_rate_in_kbps,
philipelcce46fc2015-12-21 03:04:49 -0800150 frame->frame_number);
philipelcce46fc2015-12-21 03:04:49 -0800151 frame = std::max_element(stats_.begin(), stats_.end(), LessForBitRate);
brandtrbea36fd2017-08-07 03:36:54 -0700152 printf(" Max bitrate: %7d kbps (frame %d)\n", frame->bit_rate_in_kbps,
philipelcce46fc2015-12-21 03:04:49 -0800153 frame->frame_number);
kjellander@webrtc.org35a17562011-10-06 06:44:54 +0000154
kjellander@webrtc.org5b97b122011-12-08 07:42:18 +0000155 printf("\n");
philipelcce46fc2015-12-21 03:04:49 -0800156 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.org5b97b122011-12-08 07:42:18 +0000158 printf("Total processing time: %7d ms.\n",
kjellander@webrtc.org35a17562011-10-06 06:44:54 +0000159 (total_encoding_time_in_us + total_decoding_time_in_us) / 1000);
brandtrbea36fd2017-08-07 03:36:54 -0700160
161 int avg_qp = (total_qp_count > 0) ? (total_qp / total_qp_count) : -1;
162 printf("Average QP: %d\n", avg_qp);
kjellander@webrtc.org35a17562011-10-06 06:44:54 +0000163}
164
165} // namespace test
166} // namespace webrtc