You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
5.3 KiB
139 lines
5.3 KiB
/*
|
|
* Copyright 2018 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.
|
|
*/
|
|
|
|
//#define LOG_NDEBUG 0
|
|
#define LOG_TAG "audio_utils_timestampverifier_tests"
|
|
|
|
#include <audio_utils/TimestampVerifier.h>
|
|
|
|
#include <stdio.h>
|
|
#include <gtest/gtest.h>
|
|
|
|
// Ensure that all TimestampVerifier mutators are really constexpr and free from
|
|
// nasty system calls (in case called from a SCHED_FIFO thread).
|
|
static constexpr auto makeVerifier(
|
|
size_t N, uint32_t sampleRate, size_t errors, size_t discontinuities) {
|
|
android::TimestampVerifier<int64_t, int64_t> tv;
|
|
|
|
int64_t f = 0;
|
|
int64_t t = 0;
|
|
for (size_t i = 0; i < N; ++i) {
|
|
tv.add(f, t, sampleRate);
|
|
f += sampleRate;
|
|
t += (int64_t)1e9;
|
|
}
|
|
for (size_t i = 0; i < discontinuities; ++i) {
|
|
tv.discontinuity(tv.DISCONTINUITY_MODE_CONTINUOUS);
|
|
}
|
|
for (size_t i = 0; i < errors; ++i) {
|
|
tv.error();
|
|
}
|
|
return tv;
|
|
}
|
|
|
|
TEST(TimestampVerifier, sanity)
|
|
{
|
|
constexpr android::TimestampVerifier<int64_t, int64_t> tv;
|
|
|
|
// The timestamp verifier must be embeddable in a memcpy structure just like pod.
|
|
// We use is_trivially_copyable and is_trivially_destructible for this test.
|
|
static_assert(std::is_trivially_copyable<decltype(tv)>::value,
|
|
"TimestampVerifier must be trivially copyable");
|
|
static_assert(std::is_trivially_destructible<decltype(tv)>::value,
|
|
"TimestampVerifier must be trivially destructible");
|
|
|
|
constexpr android::audio_utils::Statistics<double> s = tv.getJitterMs();
|
|
|
|
EXPECT_EQ(std::numeric_limits<double>::infinity(), s.getMin());
|
|
EXPECT_EQ(-std::numeric_limits<double>::infinity(), s.getMax());
|
|
|
|
constexpr int64_t frames[] { 0, 48000 };
|
|
constexpr int64_t timeNs[] { 0, 1000000000 };
|
|
constexpr android::TimestampVerifier<int64_t, int64_t> tv2(frames, timeNs, 48000);
|
|
EXPECT_EQ(0., tv2.getJitterMs().getMax());
|
|
EXPECT_EQ(0., tv2.getJitterMs().getMin());
|
|
EXPECT_EQ(0., tv2.getJitterMs().getMean());
|
|
EXPECT_EQ(1, tv2.getJitterMs().getN());
|
|
|
|
// We should get a perfect straight line estimate as there is no noise.
|
|
double a, b, r2;
|
|
tv2.estimateSampleRate(a, b, r2);
|
|
EXPECT_EQ(0., a);
|
|
EXPECT_EQ(48000., b);
|
|
EXPECT_NEAR(1., r2, std::numeric_limits<double>::epsilon());
|
|
|
|
constexpr android::TimestampVerifier<int64_t, int64_t> tv3 =
|
|
makeVerifier(8 /* N */, 48000 /* sampleRate */, 10 /* errors */, 10 /* disc */);
|
|
EXPECT_EQ(8, tv3.getN());
|
|
EXPECT_EQ(10, tv3.getErrors());
|
|
EXPECT_EQ(1, tv3.getDiscontinuities()); // consecutive discontinuities read as 1.
|
|
EXPECT_EQ(0., tv3.getJitterMs().getMax());
|
|
EXPECT_EQ(0., tv3.getJitterMs().getMin());
|
|
EXPECT_EQ(0., tv3.getJitterMs().getMean());
|
|
|
|
constexpr auto first = tv3.getFirstTimestamp();
|
|
constexpr auto last = tv3.getLastTimestamp();
|
|
|
|
EXPECT_EQ(0, first.mFrames);
|
|
EXPECT_EQ(0, first.mTimeNs);
|
|
EXPECT_EQ(48000 * (8 - 1), last.mFrames);
|
|
EXPECT_EQ((int64_t)1e9 * (8 - 1), last.mTimeNs);
|
|
EXPECT_EQ((uint32_t)48000, tv3.getSampleRate());
|
|
EXPECT_EQ(0, tv3.getColds());
|
|
|
|
tv3.estimateSampleRate(a, b, r2);
|
|
EXPECT_EQ(0., a);
|
|
EXPECT_EQ(48000., b);
|
|
EXPECT_NEAR(1., r2, std::numeric_limits<double>::epsilon());
|
|
}
|
|
|
|
TEST(TimestampVerifier, discontinuity_zero)
|
|
{
|
|
android::TimestampVerifier<int64_t, int64_t> tv;
|
|
|
|
// Add timestamps advancing at normal rate over 2 seconds
|
|
tv.add(0, 0, 48000);
|
|
tv.add(48000, 1000000000, 48000);
|
|
tv.add(96000, 2000000000, 48000);
|
|
|
|
// Raise (mode zero) discontinuity at "3 seconds"
|
|
tv.discontinuity(tv.DISCONTINUITY_MODE_ZERO);
|
|
// Add timestamp where frame count has reset to zero (and not advancing)
|
|
tv.add(0, 3000000000, 48000);
|
|
|
|
// The last corrected timestamp after discontinuity (mode zero) should be zeroed
|
|
EXPECT_EQ(0., tv.getLastCorrectedTimestamp().mFrames);
|
|
EXPECT_EQ(3000000000., tv.getLastCorrectedTimestamp().mTimeNs);
|
|
|
|
// Add timestamp where frame count has not advanced from zero, but time has advanced 100 ms more
|
|
tv.add(0, 3100000000, 48000);
|
|
|
|
// The last corrected frame should be the raw timestamp if not advancing at normal rate
|
|
EXPECT_EQ(0., tv.getLastCorrectedTimestamp().mFrames);
|
|
EXPECT_EQ(3100000000., tv.getLastCorrectedTimestamp().mTimeNs);
|
|
|
|
// Add imperfect normal advancing timestamps
|
|
tv.add(48000*0.9, 4100000000*1.1, 48000);
|
|
tv.add(96000*1.1, 5100000000*0.9, 48000);
|
|
|
|
// Last corrected timestamp frame count should not be raw (or zero) as timestamps are now
|
|
// advancing at a (imperfect) normal rate (but the time should, as implementation uses frame
|
|
// rather than time correction).
|
|
EXPECT_NE(0, tv.getLastCorrectedTimestamp().mFrames);
|
|
EXPECT_NE(96000*1.1, tv.getLastCorrectedTimestamp().mFrames);
|
|
EXPECT_EQ(5100000000*0.9, tv.getLastCorrectedTimestamp().mTimeNs);
|
|
}
|