avplayer: implement pause and resume

This commit is contained in:
polyproxy 2025-01-02 22:30:52 +01:00
parent 4e1733222f
commit bb250c7f9d
No known key found for this signature in database
GPG key ID: B8ADC8F57BA18DBA
7 changed files with 81 additions and 12 deletions

View file

@ -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,

View file

@ -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;

View file

@ -33,6 +33,8 @@ public:
bool IsActive();
u64 CurrentTime();
s32 Stop();
s32 Pause();
s32 Resume();
bool SetLooping(bool is_looping);
private:

View file

@ -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();

View file

@ -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<bool> 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<IDataStreamer> m_up_data_streamer;

View file

@ -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) {

View file

@ -33,6 +33,8 @@ public:
bool GetVideoData(SceAvPlayerFrameInfoEx& video_info);
bool IsActive();
u64 CurrentTime();
bool Pause();
bool Resume();
bool SetLooping(bool is_looping);
private: