blob: fefcce231171d28965bfb669e2ef6a66f2bdc44a [file] [log] [blame]
// Copyright 2024 The Cobalt Authors. All Rights Reserved.
//
// 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.
#include "starboard/nplb/player_test_fixture.h"
#include "starboard/string.h"
#include "starboard/testing/fake_graphics_context_provider.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace starboard {
namespace nplb {
namespace {
using ::testing::ValuesIn;
typedef SbPlayerTestFixture::GroupedSamples GroupedSamples;
typedef testing::FakeGraphicsContextProvider FakeGraphicsContextProvider;
class SbPlayerGetMediaTimeTest
: public ::testing::TestWithParam<SbPlayerTestConfig> {
protected:
FakeGraphicsContextProvider fake_graphics_context_provider_;
};
TEST_P(SbPlayerGetMediaTimeTest, SunnyDay) {
const int64_t kDurationToPlay = 1'000'000; // 1 second
SbPlayerTestFixture player_fixture(GetParam(),
&fake_graphics_context_provider_);
if (HasFatalFailure()) {
return;
}
int64_t media_time_before_write = player_fixture.GetCurrentMediaTime();
ASSERT_EQ(media_time_before_write, 0);
GroupedSamples samples;
if (player_fixture.HasAudio()) {
samples.AddAudioSamples(
0, player_fixture.ConvertDurationToAudioBufferCount(kDurationToPlay));
samples.AddAudioEOS();
}
if (player_fixture.HasVideo()) {
samples.AddVideoSamples(
0, player_fixture.ConvertDurationToVideoBufferCount(kDurationToPlay));
samples.AddVideoEOS();
}
ASSERT_NO_FATAL_FAILURE(player_fixture.Write(samples));
ASSERT_NO_FATAL_FAILURE(player_fixture.WaitForPlayerPresenting());
int64_t start_system_time = CurrentMonotonicTime();
int64_t start_media_time = player_fixture.GetCurrentMediaTime();
ASSERT_NO_FATAL_FAILURE(player_fixture.WaitForPlayerEndOfStream());
int64_t end_system_time = CurrentMonotonicTime();
int64_t end_media_time = player_fixture.GetCurrentMediaTime();
const int64_t kDurationDifferenceAllowance = 500'000; // 500 ms
EXPECT_NEAR(end_media_time, kDurationToPlay, kDurationDifferenceAllowance);
EXPECT_NEAR(end_system_time - start_system_time + start_media_time,
kDurationToPlay, kDurationDifferenceAllowance);
SB_DLOG(INFO) << "The expected media time should be " << kDurationToPlay
<< ", the actual media time is " << end_media_time
<< ", with difference "
<< std::abs(end_media_time - kDurationToPlay) << ".";
SB_DLOG(INFO) << "The expected total playing time should be "
<< kDurationToPlay << ", the actual playing time is "
<< end_system_time - start_system_time + start_media_time
<< ", with difference "
<< std::abs(end_system_time - start_system_time +
start_media_time - kDurationToPlay)
<< ".";
}
TEST_P(SbPlayerGetMediaTimeTest, TimeAfterSeek) {
const int kSamplesToWrite = 8;
SbPlayerTestFixture player_fixture(GetParam(),
&fake_graphics_context_provider_);
if (HasFatalFailure()) {
return;
}
GroupedSamples samples;
if (player_fixture.HasAudio()) {
samples.AddAudioSamples(0, kSamplesToWrite);
samples.AddAudioEOS();
}
if (player_fixture.HasVideo()) {
samples.AddVideoSamples(0, kSamplesToWrite);
samples.AddVideoEOS();
}
ASSERT_NO_FATAL_FAILURE(player_fixture.Write(samples));
ASSERT_NO_FATAL_FAILURE(player_fixture.WaitForPlayerPresenting());
const int64_t seek_to_time = 1'000'000; // 1 second
ASSERT_NO_FATAL_FAILURE(player_fixture.Seek(seek_to_time));
const int64_t kDurationToPlay = 1'000'000; // 1 second
samples = GroupedSamples();
if (player_fixture.HasAudio()) {
samples.AddAudioSamples(
0,
player_fixture.ConvertDurationToAudioBufferCount(seek_to_time) +
player_fixture.ConvertDurationToAudioBufferCount(kDurationToPlay));
samples.AddAudioEOS();
}
if (player_fixture.HasVideo()) {
samples.AddVideoSamples(
0,
player_fixture.ConvertDurationToVideoBufferCount(seek_to_time) +
player_fixture.ConvertDurationToVideoBufferCount(kDurationToPlay));
samples.AddVideoEOS();
}
ASSERT_NO_FATAL_FAILURE(player_fixture.Write(samples));
ASSERT_NO_FATAL_FAILURE(player_fixture.WaitForPlayerPresenting());
int64_t start_system_time = CurrentMonotonicTime();
int64_t start_media_time = player_fixture.GetCurrentMediaTime();
ASSERT_NO_FATAL_FAILURE(player_fixture.WaitForPlayerEndOfStream());
int64_t end_system_time = CurrentMonotonicTime();
int64_t end_media_time = player_fixture.GetCurrentMediaTime();
const int64_t kDurationDifferenceAllowance = 500'000; // 500 ms
EXPECT_NEAR(end_media_time, kDurationToPlay + seek_to_time,
kDurationDifferenceAllowance);
EXPECT_NEAR(
end_system_time - start_system_time + start_media_time - seek_to_time,
kDurationToPlay, kDurationDifferenceAllowance);
SB_DLOG(INFO) << "The expected media time should be "
<< kDurationToPlay + seek_to_time
<< ", the actual media time is " << end_media_time
<< ", with difference "
<< std::abs(end_media_time - kDurationToPlay - seek_to_time)
<< ".";
SB_DLOG(INFO) << "The expected total playing time should be "
<< kDurationToPlay << ", the actual playing time is "
<< end_system_time - start_system_time + start_media_time -
seek_to_time
<< ", with difference "
<< std::abs(end_system_time - start_system_time +
start_media_time - seek_to_time - kDurationToPlay)
<< ".";
}
std::vector<SbPlayerTestConfig> GetSupportedTestConfigs() {
static std::vector<SbPlayerTestConfig> supported_configs;
if (supported_configs.size() > 0) {
return supported_configs;
}
const std::vector<const char*>& key_systems = GetKeySystems();
for (auto key_system : key_systems) {
std::vector<SbPlayerTestConfig> configs =
GetSupportedSbPlayerTestConfigs(key_system);
supported_configs.insert(supported_configs.end(), configs.begin(),
configs.end());
}
return supported_configs;
}
INSTANTIATE_TEST_CASE_P(SbPlayerGetMediaTimeTests,
SbPlayerGetMediaTimeTest,
ValuesIn(GetSupportedTestConfigs()),
GetSbPlayerTestConfigName);
} // namespace
} // namespace nplb
} // namespace starboard