Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

avplayer: implement pause and resume #2026

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/core/libraries/avplayer/avplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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,
Expand Down
14 changes: 14 additions & 0 deletions src/core/libraries/avplayer/avplayer_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions src/core/libraries/avplayer/avplayer_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class AvPlayer {
bool IsActive();
u64 CurrentTime();
s32 Stop();
s32 Pause();
s32 Resume();
bool SetLooping(bool is_looping);

private:
Expand Down
36 changes: 28 additions & 8 deletions src/core/libraries/avplayer/avplayer_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down
3 changes: 3 additions & 0 deletions src/core/libraries/avplayer/avplayer_source.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ class AvPlayerSource {
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<bool> HasFrames(u32 num_frames);
bool Start();
Expand Down Expand Up @@ -171,6 +173,7 @@ class AvPlayerSource {

std::atomic_bool m_is_looping = false;
std::atomic_bool m_is_eof = false;
std::atomic_bool m_is_paused = false;

std::unique_ptr<IDataStreamer> m_up_data_streamer;

Expand Down
28 changes: 28 additions & 0 deletions src/core/libraries/avplayer/avplayer_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 2 additions & 0 deletions src/core/libraries/avplayer/avplayer_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class AvPlayerState : public AvPlayerStateCallback {
bool GetVideoData(SceAvPlayerFrameInfoEx& video_info);
bool IsActive();
u64 CurrentTime();
bool Pause();
bool Resume();
bool SetLooping(bool is_looping);

private:
Expand Down
Loading