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