blob: 01898e335934a1ceed330f3e5e3728137a536e44 [file] [log] [blame]
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.camera.integration.core;
import androidx.annotation.IntRange;
final class FpsRecorder {
private static final double NANOS_IN_SECOND = 1_000_000_000;
private final long[] mTimestamps;
private int mIndex = 0;
private int mNumSamples = 0; // Number of samples used in calculation.
/**
* Creates an fps recorder that creates a running average of {@code bufferLength+1} samples.
*/
FpsRecorder(@IntRange(from = 1) int bufferLength) {
if (bufferLength < 1) {
throw new IllegalArgumentException("Invalid buffer length. Buffer must contain at "
+ "least 1 sample");
}
mTimestamps = new long[bufferLength];
}
/**
* Records the latest timestamp and returns the latest fps value or NaN if not enough samples
* have been recorded.
*/
double recordTimestamp(long timestampNs) {
// Find the duration between the oldest and newest timestamp
int nextIndex = (mIndex + 1) % mTimestamps.length;
long duration = timestampNs - mTimestamps[mIndex];
mTimestamps[mIndex] = timestampNs;
mIndex = nextIndex;
// The discarded sample is used in the calculation, so we use a maximum of bufferLength +
// 1 samples.
mNumSamples = Math.min(mNumSamples + 1, mTimestamps.length + 1);
if (mNumSamples == mTimestamps.length + 1) {
return (NANOS_IN_SECOND * mTimestamps.length) / duration;
}
// Return NaN if we don't have enough samples
return Double.NaN;
}
/**
* Ignores all previously recorded timestamps and calculates timestamps from new recorded
* timestamps.
*
* <p>{@link #recordTimestamp(long)} will return NaN until enough samples have been
* recorded.
*/
void reset() {
mNumSamples = 0;
mIndex = 0;
}
}