diff --git a/src/core/libraries/avplayer/avplayer.cpp b/src/core/libraries/avplayer/avplayer.cpp index 176fda137..aa84178db 100644 --- a/src/core/libraries/avplayer/avplayer.cpp +++ b/src/core/libraries/avplayer/avplayer.cpp @@ -179,11 +179,11 @@ s32 PS4_SYSV_ABI sceAvPlayerJumpToTime(SceAvPlayerHandle handle, uint64_t time) } s32 PS4_SYSV_ABI sceAvPlayerPause(SceAvPlayerHandle handle) { - LOG_ERROR(Lib_AvPlayer, "(STUBBED) called"); + LOG_TRACE(Lib_AvPlayer, "called"); if (handle == nullptr) { return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS; } - return ORBIS_OK; + return handle->Pause(); } s32 PS4_SYSV_ABI sceAvPlayerPostInit(SceAvPlayerHandle handle, SceAvPlayerPostInitData* data) { @@ -202,11 +202,11 @@ s32 PS4_SYSV_ABI sceAvPlayerPrintf(const char* format, ...) { } s32 PS4_SYSV_ABI sceAvPlayerResume(SceAvPlayerHandle handle) { - LOG_ERROR(Lib_AvPlayer, "(STUBBED) called"); + LOG_TRACE(Lib_AvPlayer, "called"); if (handle == nullptr) { return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS; } - return ORBIS_OK; + return handle->Resume(); } s32 PS4_SYSV_ABI sceAvPlayerSetAvSyncMode(SceAvPlayerHandle handle, diff --git a/src/core/libraries/avplayer/avplayer_impl.cpp b/src/core/libraries/avplayer/avplayer_impl.cpp index d9a67134c..2a8d7bc95 100644 --- a/src/core/libraries/avplayer/avplayer_impl.cpp +++ b/src/core/libraries/avplayer/avplayer_impl.cpp @@ -188,6 +188,20 @@ s32 AvPlayer::Stop() { return ORBIS_OK; } +s32 AvPlayer::Pause() { + if (m_state == nullptr || !m_state->Pause()) { + return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED; + } + return ORBIS_OK; +} + +s32 AvPlayer::Resume() { + if (m_state == nullptr || !m_state->Resume()) { + return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED; + } + return ORBIS_OK; +} + bool AvPlayer::SetLooping(bool is_looping) { if (m_state == nullptr) { return false; diff --git a/src/core/libraries/avplayer/avplayer_impl.h b/src/core/libraries/avplayer/avplayer_impl.h index 984d81499..e13b60d0a 100644 --- a/src/core/libraries/avplayer/avplayer_impl.h +++ b/src/core/libraries/avplayer/avplayer_impl.h @@ -33,6 +33,8 @@ public: bool IsActive(); u64 CurrentTime(); s32 Stop(); + s32 Pause(); + s32 Resume(); bool SetLooping(bool is_looping); private: diff --git a/src/core/libraries/avplayer/avplayer_source.cpp b/src/core/libraries/avplayer/avplayer_source.cpp index cf783403c..33004ea9a 100644 --- a/src/core/libraries/avplayer/avplayer_source.cpp +++ b/src/core/libraries/avplayer/avplayer_source.cpp @@ -72,7 +72,7 @@ s32 AvPlayerSource::GetStreamCount() { LOG_ERROR(Lib_AvPlayer, "Could not get stream count. NULL context."); return -1; } - LOG_INFO(Lib_AvPlayer, "Stream Count: {}", m_avformat_context->nb_streams); + LOG_TRACE(Lib_AvPlayer, "Stream Count: {}", m_avformat_context->nb_streams); return m_avformat_context->nb_streams; } @@ -110,13 +110,13 @@ bool AvPlayerSource::GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info info.duration = p_stream->duration; const auto p_lang_node = av_dict_get(p_stream->metadata, "language", nullptr, 0); if (p_lang_node != nullptr) { - LOG_INFO(Lib_AvPlayer, "Stream {} language = {}", stream_index, p_lang_node->value); + LOG_TRACE(Lib_AvPlayer, "Stream {} language = {}", stream_index, p_lang_node->value); } else { LOG_WARNING(Lib_AvPlayer, "Stream {} language is unknown", stream_index); } switch (info.type) { case SceAvPlayerStreamType::Video: { - LOG_INFO(Lib_AvPlayer, "Stream {} is a video stream.", stream_index); + LOG_TRACE(Lib_AvPlayer, "Stream {} is a video stream.", stream_index); info.details.video.aspect_ratio = f32(p_stream->codecpar->width) / p_stream->codecpar->height; auto width = u32(p_stream->codecpar->width); @@ -134,7 +134,7 @@ bool AvPlayerSource::GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info break; } case SceAvPlayerStreamType::Audio: { - LOG_INFO(Lib_AvPlayer, "Stream {} is an audio stream.", stream_index); + LOG_TRACE(Lib_AvPlayer, "Stream {} is an audio stream.", stream_index); info.details.audio.channel_count = p_stream->codecpar->ch_layout.nb_channels; info.details.audio.sample_rate = p_stream->codecpar->sample_rate; info.details.audio.size = 0; // sceAvPlayerGetStreamInfo() is expected to set this to 0 @@ -229,6 +229,24 @@ bool AvPlayerSource::EnableStream(u32 stream_index) { return true; } +bool AvPlayerSource::Pause() { + if (m_is_paused) { + return false; + } + m_is_paused = true; + return true; +} + +bool AvPlayerSource::Resume() { + if (!m_is_paused) { + return false; + } + m_is_paused = false; + m_video_packets_cv.Notify(); + m_audio_packets_cv.Notify(); + return true; +} + void AvPlayerSource::SetLooping(bool is_looping) { m_is_looping = is_looping; } @@ -601,8 +619,9 @@ void AvPlayerSource::VideoDecoderThread(std::stop_token stop) { LOG_INFO(Lib_AvPlayer, "Video Decoder Thread started"); while ((!m_is_eof || m_video_packets.Size() != 0) && !stop.stop_requested()) { - if (!m_video_packets_cv.Wait(stop, - [this] { return m_video_packets.Size() != 0 || m_is_eof; })) { + if (!m_video_packets_cv.Wait(stop, [this] { + return !m_is_paused && (m_video_packets.Size() != 0 || m_is_eof); + })) { continue; } const auto packet = m_video_packets.Pop(); @@ -723,8 +742,9 @@ void AvPlayerSource::AudioDecoderThread(std::stop_token stop) { LOG_INFO(Lib_AvPlayer, "Audio Decoder Thread started"); while ((!m_is_eof || m_audio_packets.Size() != 0) && !stop.stop_requested()) { - if (!m_audio_packets_cv.Wait(stop, - [this] { return m_audio_packets.Size() != 0 || m_is_eof; })) { + if (!m_audio_packets_cv.Wait(stop, [this] { + return !m_is_paused && (m_audio_packets.Size() != 0 || m_is_eof); + })) { continue; } const auto packet = m_audio_packets.Pop(); diff --git a/src/core/libraries/avplayer/avplayer_source.h b/src/core/libraries/avplayer/avplayer_source.h index 7e199c457..5c7dff9d8 100644 --- a/src/core/libraries/avplayer/avplayer_source.h +++ b/src/core/libraries/avplayer/avplayer_source.h @@ -126,6 +126,8 @@ public: s32 GetStreamCount(); bool GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info); bool EnableStream(u32 stream_index); + bool Pause(); + bool Resume(); void SetLooping(bool is_looping); std::optional HasFrames(u32 num_frames); bool Start(); @@ -171,6 +173,7 @@ private: std::atomic_bool m_is_looping = false; std::atomic_bool m_is_eof = false; + std::atomic_bool m_is_paused = false; std::unique_ptr m_up_data_streamer; diff --git a/src/core/libraries/avplayer/avplayer_state.cpp b/src/core/libraries/avplayer/avplayer_state.cpp index 143df749c..129a200f7 100644 --- a/src/core/libraries/avplayer/avplayer_state.cpp +++ b/src/core/libraries/avplayer/avplayer_state.cpp @@ -289,6 +289,34 @@ u64 AvPlayerState::CurrentTime() { return m_up_source->CurrentTime(); } +bool AvPlayerState::Pause() { + std::shared_lock lock(m_source_mutex); + if (m_up_source == nullptr) { + LOG_ERROR(Lib_AvPlayer, "Could not pause. No source."); + return false; + } + if (!m_up_source->Pause()) { + return false; + } + SetState(AvState::Pause); + OnPlaybackStateChanged(AvState::Pause); + return true; +} + +bool AvPlayerState::Resume() { + std::shared_lock lock(m_source_mutex); + if (m_up_source == nullptr) { + LOG_ERROR(Lib_AvPlayer, "Could not resume. No source."); + return false; + } + if (!m_up_source->Resume()) { + return false; + } + SetState(AvState::Play); + OnPlaybackStateChanged(AvState::Play); + return true; +} + bool AvPlayerState::SetLooping(bool is_looping) { std::shared_lock lock(m_source_mutex); if (m_up_source == nullptr) { diff --git a/src/core/libraries/avplayer/avplayer_state.h b/src/core/libraries/avplayer/avplayer_state.h index 48cd17bf2..48c4b6e0c 100644 --- a/src/core/libraries/avplayer/avplayer_state.h +++ b/src/core/libraries/avplayer/avplayer_state.h @@ -33,6 +33,8 @@ public: bool GetVideoData(SceAvPlayerFrameInfoEx& video_info); bool IsActive(); u64 CurrentTime(); + bool Pause(); + bool Resume(); bool SetLooping(bool is_looping); private: