| /* |
| * 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 <assert.h> |
| #include <stdio.h> |
| |
| #include <algorithm> // 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(kDeltaFrame) {} |
| |
| 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::kKeyFrame) { |
| 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<int>(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<FrameStatistic> decoded_frames; |
| for (std::vector<FrameStatistic>::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<int>(total_decoding_time_in_us / decoded_frames.size())); |
| printf(" Failures: %d frames failed to decode.\n", |
| static_cast<int>(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 |