Skip to content

Commit

Permalink
core/libraries: Videodec2 implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
polybiusproxy committed Oct 17, 2024
1 parent 88c3704 commit 0bbf917
Show file tree
Hide file tree
Showing 12 changed files with 717 additions and 4 deletions.
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,13 @@ set(FIBER_LIB src/core/libraries/fiber/fiber.cpp
src/core/libraries/fiber/fiber.h
)

set(VDEC_LIB src/core/libraries/videodec/videodec2_impl.cpp
src/core/libraries/videodec/videodec2_impl.h
src/core/libraries/videodec/videodec2.cpp
src/core/libraries/videodec/videodec2.h
src/core/libraries/videodec/videodec2_avc.h
)

set(NP_LIBS src/core/libraries/np_manager/np_manager.cpp
src/core/libraries/np_manager/np_manager.h
src/core/libraries/np_score/np_score.cpp
Expand Down Expand Up @@ -497,6 +504,7 @@ set(CORE src/core/aerolib/stubs.cpp
${MISC_LIBS}
${DIALOGS_LIB}
${FIBER_LIB}
${VDEC_LIB}
${DEV_TOOLS}
src/core/debug_state.cpp
src/core/debug_state.h
Expand Down
1 change: 1 addition & 0 deletions src/common/logging/filter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
SUB(Lib, Remoteplay) \
SUB(Lib, SharePlay) \
SUB(Lib, Fiber) \
SUB(Lib, Vdec2) \
CLS(Frontend) \
CLS(Render) \
SUB(Render, Vulkan) \
Expand Down
1 change: 1 addition & 0 deletions src/common/logging/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ enum class Class : u8 {
Lib_Remoteplay, ///< The LibSceRemotePlay implementation
Lib_SharePlay, ///< The LibSceSharePlay implemenation
Lib_Fiber, ///< The LibSceFiber implementation.
Lib_Vdec2, ///< The LibSceVideodec2 implementation.
Frontend, ///< Emulator UI
Render, ///< Video Core
Render_Vulkan, ///< Vulkan backend
Expand Down
40 changes: 39 additions & 1 deletion src/core/libraries/error_codes.h
Original file line number Diff line number Diff line change
Expand Up @@ -507,4 +507,42 @@ constexpr int ORBIS_FIBER_ERROR_ALIGNMENT = 0x80590002;
constexpr int ORBIS_FIBER_ERROR_RANGE = 0x80590003;
constexpr int ORBIS_FIBER_ERROR_INVALID = 0x80590004;
constexpr int ORBIS_FIBER_ERROR_PERMISSION = 0x80590005;
constexpr int ORBIS_FIBER_ERROR_STATE = 0x80590006;
constexpr int ORBIS_FIBER_ERROR_STATE = 0x80590006;

// Videodec2 library
constexpr int ORBIS_VIDEODEC2_ERROR_API_FAIL = 0x811D0100;
constexpr int ORBIS_VIDEODEC2_ERROR_STRUCT_SIZE = 0x811D0101;
constexpr int ORBIS_VIDEODEC2_ERROR_ARGUMENT_POINTER = 0x811D0102;
constexpr int ORBIS_VIDEODEC2_ERROR_DECODER_INSTANCE = 0x811D0103;
constexpr int ORBIS_VIDEODEC2_ERROR_MEMORY_SIZE = 0x811D0104;
constexpr int ORBIS_VIDEODEC2_ERROR_MEMORY_POINTER = 0x811D0105;
constexpr int ORBIS_VIDEODEC2_ERROR_FRAME_BUFFER_SIZE = 0x811D0106;
constexpr int ORBIS_VIDEODEC2_ERROR_FRAME_BUFFER_POINTER = 0x811D0107;
constexpr int ORBIS_VIDEODEC2_ERROR_FRAME_BUFFER_ALIGNMENT = 0x811D0108;
constexpr int ORBIS_VIDEODEC2_ERROR_NOT_ONION_MEMORY = 0x811D0109;
constexpr int ORBIS_VIDEODEC2_ERROR_NOT_GARLIC_MEMORY = 0x811D010A;
constexpr int ORBIS_VIDEODEC2_ERROR_NOT_DIRECT_MEMORY = 0x811D010B;
constexpr int ORBIS_VIDEODEC2_ERROR_MEMORY_INFO = 0x811D010C;
constexpr int ORBIS_VIDEODEC2_ERROR_ACCESS_UNIT_SIZE = 0x811D010D;
constexpr int ORBIS_VIDEODEC2_ERROR_ACCESS_UNIT_POINTER = 0x811D010E;
constexpr int ORBIS_VIDEODEC2_ERROR_OUTPUT_INFO = 0x811D010F;
constexpr int ORBIS_VIDEODEC2_ERROR_COMPUTE_QUEUE = 0x811D0110;
constexpr int ORBIS_VIDEODEC2_ERROR_FATAL_STATE = 0x811D0111;
constexpr int ORBIS_VIDEODEC2_ERROR_PRESET_VALUE = 0x811D0112;
constexpr int ORBIS_VIDEODEC2_ERROR_CONFIG_INFO = 0x811D0200;
constexpr int ORBIS_VIDEODEC2_ERROR_COMPUTE_PIPE_ID = 0x811D0201;
constexpr int ORBIS_VIDEODEC2_ERROR_COMPUTE_QUEUE_ID = 0x811D0202;
constexpr int ORBIS_VIDEODEC2_ERROR_RESOURCE_TYPE = 0x811D0203;
constexpr int ORBIS_VIDEODEC2_ERROR_CODEC_TYPE = 0x811D0204;
constexpr int ORBIS_VIDEODEC2_ERROR_PROFILE_LEVEL = 0x811D0205;
constexpr int ORBIS_VIDEODEC2_ERROR_PIPELINE_DEPTH = 0x811D0206;
constexpr int ORBIS_VIDEODEC2_ERROR_AFFINITY_MASK = 0x811D0207;
constexpr int ORBIS_VIDEODEC2_ERROR_THREAD_PRIORITY = 0x811D0208;
constexpr int ORBIS_VIDEODEC2_ERROR_DPB_FRAME_COUNT = 0x811D0209;
constexpr int ORBIS_VIDEODEC2_ERROR_FRAME_WIDTH_HEIGHT = 0x811D020A;
constexpr int ORBIS_VIDEODEC2_ERROR_EXTRA_CONFIG_INFO = 0x811D020B;
constexpr int ORBIS_VIDEODEC2_ERROR_NEW_SEQUENCE = 0x811D0300;
constexpr int ORBIS_VIDEODEC2_ERROR_ACCESS_UNIT = 0x811D0301;
constexpr int ORBIS_VIDEODEC2_ERROR_OVERSIZE_DECODE = 0x811D0302;
constexpr int ORBIS_VIDEODEC2_ERROR_INVALID_SEQUENCE = 0x811D0303;
constexpr int ORBIS_VIDEODEC2_ERROR_FATAL_STREAM = 0x811D0304;
2 changes: 1 addition & 1 deletion src/core/libraries/fiber/fiber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

namespace Libraries::Fiber {

constexpr static u64 kFiberSignature = 0x054ad954;
static constexpr u64 kFiberSignature = 0x054ad954;

thread_local SceFiber* gCurrentFiber = nullptr;
thread_local void* gFiberThread = nullptr;
Expand Down
2 changes: 2 additions & 0 deletions src/core/libraries/libs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include "core/libraries/system/systemservice.h"
#include "core/libraries/system/userservice.h"
#include "core/libraries/usbd/usbd.h"
#include "core/libraries/videodec/videodec2.h"
#include "core/libraries/videoout/video_out.h"

namespace Libraries {
Expand Down Expand Up @@ -80,6 +81,7 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) {
Libraries::ErrorDialog::RegisterlibSceErrorDialog(sym);
Libraries::ImeDialog::RegisterlibSceImeDialog(sym);
Libraries::AvPlayer::RegisterlibSceAvPlayer(sym);
Libraries::Vdec2::RegisterlibSceVdec2(sym);
Libraries::Audio3d::RegisterlibSceAudio3d(sym);
Libraries::Ime::RegisterlibSceIme(sym);
Libraries::GameLiveStreaming::RegisterlibSceGameLiveStreaming(sym);
Expand Down
201 changes: 201 additions & 0 deletions src/core/libraries/videodec/videodec2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include "videodec2.h"
#include "videodec2_impl.h"

#include "common/assert.h"
#include "common/logging/log.h"
#include "core/libraries/error_codes.h"
#include "core/libraries/libs.h"

namespace Libraries::Vdec2 {

static constexpr u64 kMinimumMemorySize = 32_MB; ///> Fake minimum memory size for querying

int PS4_SYSV_ABI sceVideodec2QueryComputeMemoryInfo(OrbisVideodec2ComputeMemoryInfo* pMemInfoOut) {
LOG_INFO(Lib_Vdec2, "called");

if (!pMemInfoOut) {
return ORBIS_VIDEODEC2_ERROR_ARGUMENT_POINTER;
}
if (pMemInfoOut->thisSize != sizeof(OrbisVideodec2ComputeMemoryInfo)) {
return ORBIS_VIDEODEC2_ERROR_STRUCT_SIZE;
}

pMemInfoOut->pCpuGpuMemory = nullptr;
pMemInfoOut->cpuGpuMemorySize = kMinimumMemorySize;
return ORBIS_OK;
}

s32 PS4_SYSV_ABI
sceVideodec2AllocateComputeQueue(const OrbisVideodec2ComputeConfigInfo* pComputeCfgInfoIn,
const OrbisVideodec2ComputeMemoryInfo* pComputeMemInfoIn,
OrbisVideodec2ComputeQueue* pComputeQueueOut) {
LOG_INFO(Lib_Vdec2, "called");
return ORBIS_OK;
}

s32 PS4_SYSV_ABI sceVideodec2ReleaseComputeQueue(OrbisVideodec2ComputeQueue computeQueueIn) {
LOG_INFO(Lib_Vdec2, "called");
return ORBIS_OK;
}

int PS4_SYSV_ABI
sceVideodec2QueryDecoderMemoryInfo(const OrbisVideodec2DecoderConfigInfo* pCfgInfoIn,
OrbisVideodec2DecoderMemoryInfo* pMemInfoOut) {
LOG_INFO(Lib_Vdec2, "called");

if (!pCfgInfoIn || !pMemInfoOut) {
return ORBIS_VIDEODEC2_ERROR_ARGUMENT_POINTER;
}
if (pCfgInfoIn->thisSize != sizeof(OrbisVideodec2DecoderConfigInfo) ||
pMemInfoOut->thisSize != sizeof(OrbisVideodec2DecoderMemoryInfo)) {
return ORBIS_VIDEODEC2_ERROR_STRUCT_SIZE;
}

pMemInfoOut->pCpuMemory = nullptr;
pMemInfoOut->pGpuMemory = nullptr;
pMemInfoOut->pCpuGpuMemory = nullptr;

pMemInfoOut->cpuGpuMemorySize = kMinimumMemorySize;
pMemInfoOut->cpuMemorySize = kMinimumMemorySize;
pMemInfoOut->gpuMemorySize = kMinimumMemorySize;

pMemInfoOut->maxFrameBufferSize = kMinimumMemorySize;
pMemInfoOut->frameBufferAlignment = kMinimumMemorySize;

return ORBIS_OK;
}

s32 PS4_SYSV_ABI
sceVideodec2CreateDecoder(const OrbisVideodec2DecoderConfigInfo* pDecoderConfigInfoIn,
const OrbisVideodec2DecoderMemoryInfo* pDecoderMemoryInfoIn,
OrbisVideodec2Decoder* pDecoderInstanceOut) {
LOG_INFO(Lib_Vdec2, "called");

if (!pDecoderConfigInfoIn || !pDecoderMemoryInfoIn || !pDecoderInstanceOut) {
return ORBIS_VIDEODEC2_ERROR_ARGUMENT_POINTER;
}
if (pDecoderConfigInfoIn->thisSize != sizeof(OrbisVideodec2DecoderConfigInfo) ||
pDecoderMemoryInfoIn->thisSize != sizeof(OrbisVideodec2DecoderMemoryInfo)) {
return ORBIS_VIDEODEC2_ERROR_STRUCT_SIZE;
}

*pDecoderInstanceOut = new VdecDecoder(*pDecoderConfigInfoIn, *pDecoderMemoryInfoIn);
return ORBIS_OK;
}

s32 PS4_SYSV_ABI sceVideodec2DeleteDecoder(OrbisVideodec2Decoder decoder) {
LOG_INFO(Lib_Vdec2, "called");

if (!decoder) {
return ORBIS_VIDEODEC2_ERROR_DECODER_INSTANCE;
}

delete decoder;
return ORBIS_OK;
}

s32 PS4_SYSV_ABI sceVideodec2Decode(OrbisVideodec2Decoder decoder,
const OrbisVideodec2InputData* pInputDataInOut,
OrbisVideodec2FrameBuffer* pFrameBufferInOut,
OrbisVideodec2OutputInfo* pOutputInfoOut) {
LOG_TRACE(Lib_Vdec2, "called");

if (!decoder) {
return ORBIS_VIDEODEC2_ERROR_DECODER_INSTANCE;
}
if (!pInputDataInOut || !pFrameBufferInOut || !pOutputInfoOut) {
return ORBIS_VIDEODEC2_ERROR_ARGUMENT_POINTER;
}
if (pInputDataInOut->thisSize != sizeof(OrbisVideodec2InputData) ||
pFrameBufferInOut->thisSize != sizeof(OrbisVideodec2FrameBuffer)) {
return ORBIS_VIDEODEC2_ERROR_STRUCT_SIZE;
}

return decoder->Decode(*pInputDataInOut, *pFrameBufferInOut, *pOutputInfoOut);
}

s32 PS4_SYSV_ABI sceVideodec2Flush(OrbisVideodec2Decoder decoder,
OrbisVideodec2FrameBuffer* pFrameBufferInOut,
OrbisVideodec2OutputInfo* pOutputInfoOut) {
LOG_INFO(Lib_Vdec2, "called");

if (!decoder) {
return ORBIS_VIDEODEC2_ERROR_DECODER_INSTANCE;
}
if (!pFrameBufferInOut || !pOutputInfoOut) {
return ORBIS_VIDEODEC2_ERROR_ARGUMENT_POINTER;
}
if (pFrameBufferInOut->thisSize != sizeof(OrbisVideodec2FrameBuffer) ||
pOutputInfoOut->thisSize != sizeof(OrbisVideodec2OutputInfo)) {
return ORBIS_VIDEODEC2_ERROR_STRUCT_SIZE;
}

return decoder->Flush(*pFrameBufferInOut, *pOutputInfoOut);
}

s32 PS4_SYSV_ABI sceVideodec2Reset(OrbisVideodec2Decoder decoder) {
LOG_INFO(Lib_Vdec2, "called");

if (!decoder) {
return ORBIS_VIDEODEC2_ERROR_DECODER_INSTANCE;
}

return decoder->Reset();
}

s32 PS4_SYSV_ABI sceVideodec2GetPictureInfo(const OrbisVideodec2OutputInfo* pOutputInfoIn,
void* p1stPictureInfoOut, void* p2ndPictureInfoOut) {
LOG_TRACE(Lib_Vdec2, "called");

if (!pOutputInfoIn) {
return ORBIS_VIDEODEC2_ERROR_ARGUMENT_POINTER;
}
if (pOutputInfoIn->thisSize != sizeof(OrbisVideodec2OutputInfo)) {
return ORBIS_VIDEODEC2_ERROR_STRUCT_SIZE;
}

if (pOutputInfoIn->pictureCount == 0 || gPictureInfos.empty()) {
return 0;
}

if (p1stPictureInfoOut) {
OrbisVideodec2AvcPictureInfo* picInfo =
static_cast<OrbisVideodec2AvcPictureInfo*>(p1stPictureInfoOut);
if (picInfo->thisSize != sizeof(OrbisVideodec2AvcPictureInfo)) {
return ORBIS_VIDEODEC2_ERROR_STRUCT_SIZE;
}
*picInfo = gPictureInfos.back();
}

if (pOutputInfoIn->pictureCount > 1) {
UNREACHABLE();
}

return ORBIS_OK;
}

void RegisterlibSceVdec2(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("RnDibcGCPKw", "libSceVideodec2", 1, "libSceVideodec2", 1, 1,
sceVideodec2QueryComputeMemoryInfo);
LIB_FUNCTION("eD+X2SmxUt4", "libSceVideodec2", 1, "libSceVideodec2", 1, 1,
sceVideodec2AllocateComputeQueue);
LIB_FUNCTION("UvtA3FAiF4Y", "libSceVideodec2", 1, "libSceVideodec2", 1, 1,
sceVideodec2ReleaseComputeQueue);

LIB_FUNCTION("qqMCwlULR+E", "libSceVideodec2", 1, "libSceVideodec2", 1, 1,
sceVideodec2QueryDecoderMemoryInfo);
LIB_FUNCTION("CNNRoRYd8XI", "libSceVideodec2", 1, "libSceVideodec2", 1, 1,
sceVideodec2CreateDecoder);
LIB_FUNCTION("jwImxXRGSKA", "libSceVideodec2", 1, "libSceVideodec2", 1, 1,
sceVideodec2DeleteDecoder);
LIB_FUNCTION("852F5+q6+iM", "libSceVideodec2", 1, "libSceVideodec2", 1, 1, sceVideodec2Decode);
LIB_FUNCTION("l1hXwscLuCY", "libSceVideodec2", 1, "libSceVideodec2", 1, 1, sceVideodec2Flush);
LIB_FUNCTION("wJXikG6QFN8", "libSceVideodec2", 1, "libSceVideodec2", 1, 1, sceVideodec2Reset);
LIB_FUNCTION("NtXRa3dRzU0", "libSceVideodec2", 1, "libSceVideodec2", 1, 1,
sceVideodec2GetPictureInfo);
}

} // namespace Libraries::Vdec2
Loading

0 comments on commit 0bbf917

Please sign in to comment.