mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-01-27 08:51:47 +00:00
avplayer: implement pause and resume
This commit is contained in:
parent
4e1733222f
commit
bb250c7f9d
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -33,6 +33,8 @@ public:
|
|||
bool IsActive();
|
||||
u64 CurrentTime();
|
||||
s32 Stop();
|
||||
s32 Pause();
|
||||
s32 Resume();
|
||||
bool SetLooping(bool is_looping);
|
||||
|
||||
private:
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -33,6 +33,8 @@ public:
|
|||
bool GetVideoData(SceAvPlayerFrameInfoEx& video_info);
|
||||
bool IsActive();
|
||||
u64 CurrentTime();
|
||||
bool Pause();
|
||||
bool Resume();
|
||||
bool SetLooping(bool is_looping);
|
||||
|
||||
private:
|
||||
|
|
Loading…
Reference in a new issue