avplayer: implemented sync modes

This commit is contained in:
Vladislav Mikhalin 2025-02-16 16:52:20 +03:00
parent c39179a5f4
commit 8162bc2af1
7 changed files with 36 additions and 19 deletions

View file

@ -188,11 +188,11 @@ s32 PS4_SYSV_ABI sceAvPlayerResume(AvPlayerHandle handle) {
}
s32 PS4_SYSV_ABI sceAvPlayerSetAvSyncMode(AvPlayerHandle handle, AvPlayerAvSyncMode sync_mode) {
LOG_ERROR(Lib_AvPlayer, "(STUBBED) called");
LOG_TRACE(Lib_AvPlayer, "(STUBBED) called");
if (handle == nullptr) {
return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS;
}
return ORBIS_OK;
return handle->SetAvSyncMode(sync_mode);
}
s32 PS4_SYSV_ABI sceAvPlayerSetLogCallback(AvPlayerLogCallback log_cb, void* user_data) {

View file

@ -168,6 +168,14 @@ s32 AvPlayer::Resume() {
return ORBIS_OK;
}
s32 AvPlayer::SetAvSyncMode(AvPlayerAvSyncMode sync_mode) {
if (m_state == nullptr) {
return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED;
}
m_state->SetAvSyncMode(sync_mode);
return ORBIS_OK;
}
bool AvPlayer::GetVideoData(AvPlayerFrameInfo& video_info) {
if (m_state == nullptr) {
return false;

View file

@ -30,6 +30,7 @@ public:
s32 Start();
s32 Pause();
s32 Resume();
s32 SetAvSyncMode(AvPlayerAvSyncMode sync_mode);
bool GetAudioData(AvPlayerFrameInfo& audio_info);
bool GetVideoData(AvPlayerFrameInfo& video_info);
bool GetVideoData(AvPlayerFrameInfoEx& video_info);

View file

@ -321,12 +321,16 @@ bool AvPlayerSource::GetVideoData(AvPlayerFrameInfoEx& video_info) {
return false;
}
{
using namespace std::chrono;
auto elapsed_time = CurrentTime();
if (elapsed_time < frame->info.timestamp) {
if (m_stop_cv.WaitFor(milliseconds(frame->info.timestamp - elapsed_time),
[&] { return elapsed_time >= frame->info.timestamp; })) {
if (m_state.GetSyncMode() == AvPlayerAvSyncMode::Default && m_audio_stream_index.has_value()) {
const auto audio_ts = m_last_audio_packet_time;
if (audio_ts < frame->info.timestamp) {
using namespace std::chrono;
const auto start = high_resolution_clock::now();
if (!m_stop_cv.WaitFor(milliseconds(frame->info.timestamp - audio_ts), [&] {
const auto passed =
duration_cast<milliseconds>(high_resolution_clock::now() - start).count();
return (audio_ts + passed) >= frame->info.timestamp;
})) {
return false;
}
}
@ -355,23 +359,13 @@ bool AvPlayerSource::GetAudioData(AvPlayerFrameInfo& audio_info) {
return false;
}
{
using namespace std::chrono;
auto elapsed_time = CurrentTime();
if (elapsed_time < frame->info.timestamp) {
if (m_stop_cv.WaitFor(milliseconds(frame->info.timestamp - elapsed_time),
[&] { return elapsed_time >= frame->info.timestamp; })) {
return false;
}
}
}
// return the buffer to the queue
if (m_current_audio_frame.has_value()) {
m_audio_buffers.Push(std::move(m_current_audio_frame.value()));
m_audio_buffers_cv.Notify();
}
m_current_audio_frame = std::move(frame->buffer);
m_last_audio_packet_time = frame->info.timestamp;
audio_info = {};
audio_info.timestamp = frame->info.timestamp;

View file

@ -30,6 +30,8 @@ class AvPlayerStateCallback {
public:
virtual ~AvPlayerStateCallback() = default;
virtual AvPlayerAvSyncMode GetSyncMode() = 0;
virtual void OnWarning(u32 id) = 0;
virtual void OnError() = 0;
virtual void OnEOF() = 0;
@ -216,6 +218,7 @@ private:
std::chrono::high_resolution_clock::time_point m_start_time{};
std::chrono::high_resolution_clock::time_point m_last_paused_time{};
std::chrono::high_resolution_clock::duration m_stalled_time{};
u64 m_last_audio_packet_time{};
};
} // namespace Libraries::AvPlayer

View file

@ -217,6 +217,10 @@ bool AvPlayerState::Resume() {
return true;
}
void AvPlayerState::SetAvSyncMode(AvPlayerAvSyncMode sync_mode) {
m_sync_mode = sync_mode;
}
void AvPlayerState::AvControllerThread(std::stop_token stop) {
using std::chrono::milliseconds;
Common::SetCurrentThreadName("shadPS4:AvController");
@ -337,6 +341,10 @@ void AvPlayerState::OnWarning(u32 id) {
WarningEvent(id);
}
AvPlayerAvSyncMode AvPlayerState::GetSyncMode() {
return m_sync_mode;
}
void AvPlayerState::OnError() {
SetState(AvState::Error);
OnPlaybackStateChanged(AvState::Error);

View file

@ -30,6 +30,7 @@ public:
bool Stop();
bool Pause();
bool Resume();
void SetAvSyncMode(AvPlayerAvSyncMode sync_mode);
bool GetAudioData(AvPlayerFrameInfo& audio_info);
bool GetVideoData(AvPlayerFrameInfo& video_info);
bool GetVideoData(AvPlayerFrameInfoEx& video_info);
@ -45,6 +46,7 @@ private:
static void PS4_SYSV_ABI DefaultEventCallback(void* handle, AvPlayerEvents event_id,
s32 source_id, void* event_data);
AvPlayerAvSyncMode GetSyncMode() override;
void OnWarning(u32 id) override;
void OnError() override;
void OnEOF() override;
@ -72,6 +74,7 @@ private:
AvPlayerEventReplacement m_event_replacement{};
bool m_auto_start{};
char m_default_language[4]{};
AvPlayerAvSyncMode m_sync_mode = AvPlayerAvSyncMode::Default;
std::atomic<AvState> m_current_state;
std::atomic<AvState> m_previous_state;