aboutsummaryrefslogtreecommitdiff
path: root/tests/c2_e2e_test/jni/common.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/c2_e2e_test/jni/common.cpp')
-rw-r--r--tests/c2_e2e_test/jni/common.cpp192
1 files changed, 192 insertions, 0 deletions
diff --git a/tests/c2_e2e_test/jni/common.cpp b/tests/c2_e2e_test/jni/common.cpp
new file mode 100644
index 0000000..5372f24
--- /dev/null
+++ b/tests/c2_e2e_test/jni/common.cpp
@@ -0,0 +1,192 @@
+// Copyright 2018 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// #define LOG_NDEBUG 0
+#define LOG_TAG "Common"
+
+#include "common.h"
+
+#include <strings.h>
+#include <time.h>
+
+#include <algorithm>
+#include <cmath>
+#include <numeric>
+#include <sstream>
+
+#include <utils/Log.h>
+
+namespace android {
+
+InputFile::InputFile(std::string file_path) {
+ file_ = std::ifstream(file_path);
+}
+
+InputFile::InputFile(std::string file_path, std::ios_base::openmode openmode) {
+ file_ = std::ifstream(file_path, openmode);
+}
+
+bool InputFile::IsValid() const {
+ return file_.is_open();
+}
+
+size_t InputFile::GetLength() {
+ int current_pos = file_.tellg();
+
+ file_.seekg(0, file_.end);
+ size_t ret = file_.tellg();
+
+ file_.seekg(current_pos, file_.beg);
+ return ret;
+}
+
+void InputFile::Rewind() {
+ file_.clear();
+ file_.seekg(0);
+}
+
+InputFileStream::InputFileStream(std::string file_path)
+ : InputFile(file_path, std::ifstream::binary) {}
+
+size_t InputFileStream::Read(char* buffer, size_t size) {
+ file_.read(buffer, size);
+ if (file_.fail()) return -1;
+
+ return file_.gcount();
+}
+
+InputFileASCII::InputFileASCII(std::string file_path) : InputFile(file_path) {}
+
+bool InputFileASCII::ReadLine(std::string* line) {
+ std::string read_line;
+ while (std::getline(file_, read_line)) {
+ if (read_line.empty()) // be careful: an empty line might be read
+ continue; // even if none exist.
+ *line = read_line;
+ return true;
+ }
+ return false; // no more lines
+}
+
+bool FPSCalculator::RecordFrameTimeDiff() {
+ int64_t now_us = GetNowUs();
+ if (last_frame_time_us_ != 0) {
+ int64_t frame_diff_us = now_us - last_frame_time_us_;
+ if (frame_diff_us <= 0) return false;
+ frame_time_diffs_us_.push_back(static_cast<double>(frame_diff_us));
+ }
+ last_frame_time_us_ = now_us;
+ return true;
+}
+
+// Reference: (https://cs.corp.google.com/android/cts/common/device-side/util/
+// src/com/android/compatibility/common/util/MediaPerfUtils.java)
+// addPerformanceStatsToLog
+double FPSCalculator::CalculateFPS() const {
+ std::vector<double> moving_avgs = MovingAvgOverSum();
+ std::sort(moving_avgs.begin(), moving_avgs.end());
+
+ int index = static_cast<int>(std::round(kRegardedPercentile * (moving_avgs.size() - 1) / 100));
+ ALOGV("Frame decode time stats (us): { min=%.4f, regarded=%.4f, "
+ "max=%.4f}, window=%.0f",
+ moving_avgs[0], moving_avgs[index], moving_avgs[moving_avgs.size() - 1],
+ kMovingAvgWindowUs);
+
+ return 1E6 / moving_avgs[index];
+}
+
+// Reference: (https://cs.corp.google.com/android/cts/common/device-side/util/
+// src/com/android/compatibility/common/util/MediaUtils.java)
+// movingAverageOverSum
+std::vector<double> FPSCalculator::MovingAvgOverSum() const {
+ std::vector<double> moving_avgs;
+
+ double sum = std::accumulate(frame_time_diffs_us_.begin(), frame_time_diffs_us_.end(), 0.0);
+ int data_size = static_cast<int>(frame_time_diffs_us_.size());
+ double avg = sum / data_size;
+ if (kMovingAvgWindowUs >= sum) {
+ moving_avgs.push_back(avg);
+ return moving_avgs;
+ }
+
+ int samples = static_cast<int>(std::ceil((sum - kMovingAvgWindowUs) / avg));
+ double cumulative_sum = 0;
+ int num = 0;
+ int bi = 0;
+ int ei = 0;
+ double space = kMovingAvgWindowUs;
+ double foot = 0;
+
+ int ix = 0;
+ while (ix < samples) {
+ while (ei < data_size && frame_time_diffs_us_[ei] <= space) {
+ space -= frame_time_diffs_us_[ei];
+ cumulative_sum += frame_time_diffs_us_[ei];
+ num++;
+ ei++;
+ }
+
+ if (num > 0) {
+ moving_avgs.push_back(cumulative_sum / num);
+ } else if (bi > 0 && foot > space) {
+ moving_avgs.push_back(frame_time_diffs_us_[bi - 1]);
+ } else if (ei == data_size) {
+ break;
+ } else {
+ moving_avgs.push_back(frame_time_diffs_us_[ei]);
+ }
+
+ ix++;
+ foot -= avg;
+ space += avg;
+
+ while (bi < ei && foot < 0) {
+ foot += frame_time_diffs_us_[bi];
+ cumulative_sum -= frame_time_diffs_us_[bi];
+ num--;
+ bi++;
+ }
+ }
+ return moving_avgs;
+}
+
+VideoCodecType VideoCodecProfileToType(VideoCodecProfile profile) {
+ if (profile >= H264PROFILE_MIN && profile <= H264PROFILE_MAX) return VideoCodecType::H264;
+ if (profile >= VP8PROFILE_MIN && profile <= VP8PROFILE_MAX) return VideoCodecType::VP8;
+ if (profile >= VP9PROFILE_MIN && profile <= VP9PROFILE_MAX) return VideoCodecType::VP9;
+ return VideoCodecType::UNKNOWN;
+}
+
+std::vector<std::string> SplitString(const std::string& src, char delim) {
+ std::stringstream ss(src);
+ std::string item;
+ std::vector<std::string> ret;
+ while (std::getline(ss, item, delim)) {
+ ret.push_back(item);
+ }
+ return ret;
+}
+
+int64_t GetNowUs() {
+ struct timespec t;
+ t.tv_sec = t.tv_nsec = 0;
+ clock_gettime(CLOCK_MONOTONIC, &t);
+ int64_t nsecs = static_cast<int64_t>(t.tv_sec) * 1000000000LL + t.tv_nsec;
+ return nsecs / 1000ll;
+}
+
+const char* GetMimeType(VideoCodecType type) {
+ switch (type) {
+ case VideoCodecType::H264:
+ return "video/avc";
+ case VideoCodecType::VP8:
+ return "video/x-vnd.on2.vp8";
+ case VideoCodecType::VP9:
+ return "video/x-vnd.on2.vp9";
+ default: // unknown type
+ return nullptr;
+ }
+}
+
+} // namespace android