/* * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include "webrtc/modules/video_coding/codecs/test/stats.h" #include #include #include // min_element, max_element #include "webrtc/base/format_macros.h" namespace webrtc { namespace test { FrameStatistic::FrameStatistic() : encoding_successful(false), decoding_successful(false), encode_return_code(0), decode_return_code(0), encode_time_in_us(0), decode_time_in_us(0), frame_number(0), packets_dropped(0), total_packets(0), bit_rate_in_kbps(0), encoded_frame_length_in_bytes(0), frame_type(kVideoFrameDelta) {} Stats::Stats() {} Stats::~Stats() {} bool LessForEncodeTime(const FrameStatistic& s1, const FrameStatistic& s2) { return s1.encode_time_in_us < s2.encode_time_in_us; } bool LessForDecodeTime(const FrameStatistic& s1, const FrameStatistic& s2) { return s1.decode_time_in_us < s2.decode_time_in_us; } bool LessForEncodedSize(const FrameStatistic& s1, const FrameStatistic& s2) { return s1.encoded_frame_length_in_bytes < s2.encoded_frame_length_in_bytes; } bool LessForBitRate(const FrameStatistic& s1, const FrameStatistic& s2) { return s1.bit_rate_in_kbps < s2.bit_rate_in_kbps; } FrameStatistic& Stats::NewFrame(int frame_number) { assert(frame_number >= 0); FrameStatistic stat; stat.frame_number = frame_number; stats_.push_back(stat); return stats_[frame_number]; } void Stats::PrintSummary() { printf("Processing summary:\n"); if (stats_.size() == 0) { printf("No frame statistics have been logged yet.\n"); return; } // Calculate min, max, average and total encoding time int total_encoding_time_in_us = 0; int total_decoding_time_in_us = 0; size_t total_encoded_frames_lengths = 0; size_t total_encoded_key_frames_lengths = 0; size_t total_encoded_nonkey_frames_lengths = 0; size_t nbr_keyframes = 0; size_t nbr_nonkeyframes = 0; for (FrameStatisticsIterator it = stats_.begin(); it != stats_.end(); ++it) { total_encoding_time_in_us += it->encode_time_in_us; total_decoding_time_in_us += it->decode_time_in_us; total_encoded_frames_lengths += it->encoded_frame_length_in_bytes; if (it->frame_type == webrtc::kVideoFrameKey) { total_encoded_key_frames_lengths += it->encoded_frame_length_in_bytes; nbr_keyframes++; } else { total_encoded_nonkey_frames_lengths += it->encoded_frame_length_in_bytes; nbr_nonkeyframes++; } } FrameStatisticsIterator frame; // ENCODING printf("Encoding time:\n"); frame = std::min_element(stats_.begin(), stats_.end(), LessForEncodeTime); printf(" Min : %7d us (frame %d)\n", frame->encode_time_in_us, frame->frame_number); frame = std::max_element(stats_.begin(), stats_.end(), LessForEncodeTime); printf(" Max : %7d us (frame %d)\n", frame->encode_time_in_us, frame->frame_number); printf(" Average : %7d us\n", static_cast(total_encoding_time_in_us / stats_.size())); // DECODING printf("Decoding time:\n"); // only consider frames that were successfully decoded (packet loss may cause // failures) std::vector decoded_frames; for (std::vector::iterator it = stats_.begin(); it != stats_.end(); ++it) { if (it->decoding_successful) { decoded_frames.push_back(*it); } } if (decoded_frames.size() == 0) { printf("No successfully decoded frames exist in this statistics.\n"); } else { frame = std::min_element(decoded_frames.begin(), decoded_frames.end(), LessForDecodeTime); printf(" Min : %7d us (frame %d)\n", frame->decode_time_in_us, frame->frame_number); frame = std::max_element(decoded_frames.begin(), decoded_frames.end(), LessForDecodeTime); printf(" Max : %7d us (frame %d)\n", frame->decode_time_in_us, frame->frame_number); printf(" Average : %7d us\n", static_cast(total_decoding_time_in_us / decoded_frames.size())); printf(" Failures: %d frames failed to decode.\n", static_cast(stats_.size() - decoded_frames.size())); } // SIZE printf("Frame sizes:\n"); frame = std::min_element(stats_.begin(), stats_.end(), LessForEncodedSize); printf(" Min : %7" PRIuS " bytes (frame %d)\n", frame->encoded_frame_length_in_bytes, frame->frame_number); frame = std::max_element(stats_.begin(), stats_.end(), LessForEncodedSize); printf(" Max : %7" PRIuS " bytes (frame %d)\n", frame->encoded_frame_length_in_bytes, frame->frame_number); printf(" Average : %7" PRIuS " bytes\n", total_encoded_frames_lengths / stats_.size()); if (nbr_keyframes > 0) { printf(" Average key frame size : %7" PRIuS " bytes (%" PRIuS " keyframes)\n", total_encoded_key_frames_lengths / nbr_keyframes, nbr_keyframes); } if (nbr_nonkeyframes > 0) { printf(" Average non-key frame size: %7" PRIuS " bytes (%" PRIuS " frames)\n", total_encoded_nonkey_frames_lengths / nbr_nonkeyframes, nbr_nonkeyframes); } // BIT RATE printf("Bit rates:\n"); frame = std::min_element(stats_.begin(), stats_.end(), LessForBitRate); printf(" Min bit rate: %7d kbps (frame %d)\n", frame->bit_rate_in_kbps, frame->frame_number); frame = std::max_element(stats_.begin(), stats_.end(), LessForBitRate); printf(" Max bit rate: %7d kbps (frame %d)\n", frame->bit_rate_in_kbps, frame->frame_number); printf("\n"); printf("Total encoding time : %7d ms.\n", total_encoding_time_in_us / 1000); printf("Total decoding time : %7d ms.\n", total_decoding_time_in_us / 1000); printf("Total processing time: %7d ms.\n", (total_encoding_time_in_us + total_decoding_time_in_us) / 1000); } } // namespace test } // namespace webrtc