mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-12 20:55:56 +00:00
avplayer: implemented sync modes
This commit is contained in:
parent
c39179a5f4
commit
8162bc2af1
7 changed files with 36 additions and 19 deletions
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue