// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "avplayer_common.h" #include "avplayer_file_streamer.h" #include "avplayer_impl.h" #include "common/logging/log.h" #include "core/libraries/error_codes.h" #include "core/libraries/kernel/libkernel.h" using namespace Libraries::Kernel; namespace Libraries::AvPlayer { void* PS4_SYSV_ABI AvPlayer::Allocate(void* handle, u32 alignment, u32 size) { const auto* const self = reinterpret_cast(handle); const auto allocate = self->m_init_data_original.memory_replacement.allocate; const auto ptr = self->m_init_data_original.memory_replacement.object_ptr; return allocate(ptr, alignment, size); } void PS4_SYSV_ABI AvPlayer::Deallocate(void* handle, void* memory) { const auto* const self = reinterpret_cast(handle); const auto deallocate = self->m_init_data_original.memory_replacement.deallocate; const auto ptr = self->m_init_data_original.memory_replacement.object_ptr; return deallocate(ptr, memory); } void* PS4_SYSV_ABI AvPlayer::AllocateTexture(void* handle, u32 alignment, u32 size) { const auto* const self = reinterpret_cast(handle); const auto allocate = self->m_init_data_original.memory_replacement.allocate_texture; const auto ptr = self->m_init_data_original.memory_replacement.object_ptr; return allocate(ptr, alignment, size); } void PS4_SYSV_ABI AvPlayer::DeallocateTexture(void* handle, void* memory) { const auto* const self = reinterpret_cast(handle); const auto deallocate = self->m_init_data_original.memory_replacement.deallocate_texture; const auto ptr = self->m_init_data_original.memory_replacement.object_ptr; return deallocate(ptr, memory); } int PS4_SYSV_ABI AvPlayer::OpenFile(void* handle, const char* filename) { auto const self = reinterpret_cast(handle); std::lock_guard guard(self->m_file_io_mutex); const auto open = self->m_init_data_original.file_replacement.open; const auto ptr = self->m_init_data_original.file_replacement.object_ptr; return open(ptr, filename); } int PS4_SYSV_ABI AvPlayer::CloseFile(void* handle) { auto const self = reinterpret_cast(handle); std::lock_guard guard(self->m_file_io_mutex); const auto close = self->m_init_data_original.file_replacement.close; const auto ptr = self->m_init_data_original.file_replacement.object_ptr; return close(ptr); } int PS4_SYSV_ABI AvPlayer::ReadOffsetFile(void* handle, u8* buffer, u64 position, u32 length) { auto const self = reinterpret_cast(handle); std::lock_guard guard(self->m_file_io_mutex); const auto read_offset = self->m_init_data_original.file_replacement.readOffset; const auto ptr = self->m_init_data_original.file_replacement.object_ptr; return read_offset(ptr, buffer, position, length); } u64 PS4_SYSV_ABI AvPlayer::SizeFile(void* handle) { auto const self = reinterpret_cast(handle); std::lock_guard guard(self->m_file_io_mutex); const auto size = self->m_init_data_original.file_replacement.size; const auto ptr = self->m_init_data_original.file_replacement.object_ptr; return size(ptr); } SceAvPlayerInitData AvPlayer::StubInitData(const SceAvPlayerInitData& data) { SceAvPlayerInitData result = data; result.memory_replacement.object_ptr = this; result.memory_replacement.allocate = &AvPlayer::Allocate; result.memory_replacement.deallocate = &AvPlayer::Deallocate; result.memory_replacement.allocate_texture = &AvPlayer::AllocateTexture; result.memory_replacement.deallocate_texture = &AvPlayer::DeallocateTexture; if (data.file_replacement.open == nullptr || data.file_replacement.close == nullptr || data.file_replacement.readOffset == nullptr || data.file_replacement.size == nullptr) { result.file_replacement = {}; } else { result.file_replacement.object_ptr = this; result.file_replacement.open = &AvPlayer::OpenFile; result.file_replacement.close = &AvPlayer::CloseFile; result.file_replacement.readOffset = &AvPlayer::ReadOffsetFile; result.file_replacement.size = &AvPlayer::SizeFile; } return result; } AvPlayer::AvPlayer(const SceAvPlayerInitData& data) : m_init_data(StubInitData(data)), m_init_data_original(data), m_state(std::make_unique(m_init_data)) {} s32 AvPlayer::PostInit(const SceAvPlayerPostInitData& data) { m_post_init_data = data; return ORBIS_OK; } s32 AvPlayer::AddSource(std::string_view path) { if (path.empty()) { return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS; } if (!m_state->AddSource(path, GetSourceType(path))) { return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED; } return ORBIS_OK; } s32 AvPlayer::GetStreamCount() { if (m_state == nullptr) { return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED; } const auto res = m_state->GetStreamCount(); if (AVPLAYER_IS_ERROR(res)) { return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED; } return res; } s32 AvPlayer::GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info) { if (!m_state->GetStreamInfo(stream_index, info)) { return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED; } return ORBIS_OK; } s32 AvPlayer::EnableStream(u32 stream_index) { if (m_state == nullptr) { return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED; } if (!m_state->EnableStream(stream_index)) { return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED; } return ORBIS_OK; } s32 AvPlayer::Start() { if (!m_state->Start()) { return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED; } return ORBIS_OK; } bool AvPlayer::GetVideoData(SceAvPlayerFrameInfo& video_info) { if (m_state == nullptr) { return false; } return m_state->GetVideoData(video_info); } bool AvPlayer::GetVideoData(SceAvPlayerFrameInfoEx& video_info) { if (m_state == nullptr) { return false; } return m_state->GetVideoData(video_info); } bool AvPlayer::GetAudioData(SceAvPlayerFrameInfo& audio_info) { if (m_state == nullptr) { return false; } return m_state->GetAudioData(audio_info); } bool AvPlayer::IsActive() { if (m_state == nullptr) { return false; } return m_state->IsActive(); } u64 AvPlayer::CurrentTime() { if (m_state == nullptr) { return 0; } return m_state->CurrentTime(); } s32 AvPlayer::Stop() { if (m_state == nullptr || !m_state->Stop()) { return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED; } return ORBIS_OK; } bool AvPlayer::SetLooping(bool is_looping) { if (m_state == nullptr) { return false; } return m_state->SetLooping(is_looping); } } // namespace Libraries::AvPlayer