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 13, 2024
1 parent 8776eba commit 3dc4857
Show file tree
Hide file tree
Showing 11 changed files with 613 additions and 3 deletions.
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,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 @@ -479,6 +486,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
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
165 changes: 165 additions & 0 deletions src/core/libraries/videodec/videodec2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include "videodec2.h"
#include "videodec2_impl.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->thisSize != sizeof(OrbisVideodec2ComputeMemoryInfo)) {
return 0x811d0101;
}

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->thisSize == 0x48) && (pMemInfoOut->thisSize == 0x48)) {
pMemInfoOut->pCpuMemory = nullptr;
pMemInfoOut->pGpuMemory = nullptr;
pMemInfoOut->pCpuGpuMemory = nullptr;

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

pMemInfoOut->maxFrameBufferSize = kMinimumMemorySize;
pMemInfoOut->frameBufferAlignment = kMinimumMemorySize;
} else {
return 0x811d0101;
}

return ORBIS_OK;
}

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

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

s32 PS4_SYSV_ABI sceVideodec2DeleteDecoder(OrbisVideodec2Decoder decoder) {
LOG_INFO(Lib_Vdec2, "called");
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 == nullptr) {
return 0x811D0103; // SCE_VIDEODEC2_ERROR_DECODER_INSTANCE;
}

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

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

if (decoder == nullptr) {
return 0x811D0103;
}

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

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

if (decoder == nullptr) {
return 0x811D0103;
}

return decoder->Reset();
}

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

if (p1stPictureInfoOut) {
OrbisVideodec2AvcPictureInfo* picInfo = (OrbisVideodec2AvcPictureInfo*)p1stPictureInfoOut;

memset(p1stPictureInfoOut, 0, sizeof(OrbisVideodec2AvcPictureInfo));
picInfo->isValid = 1;
picInfo->frameCropLeftOffset = 0; // frame->crop_left;
picInfo->frameCropRightOffset = 0; // frame->crop_right;
picInfo->frameCropTopOffset = 0; // frame->crop_top;
picInfo->frameCropBottomOffset = 0; // frame->crop_bottom;
}

if (pOutputInfoIn->pictureCount == 2 && p2ndPictureInfoOut) {
OrbisVideodec2AvcPictureInfo* picInfo = (OrbisVideodec2AvcPictureInfo*)p2ndPictureInfoOut;

memset(p2ndPictureInfoOut, 0, sizeof(OrbisVideodec2AvcPictureInfo));
picInfo->isValid = 1;
picInfo->frameCropLeftOffset = 0;
picInfo->frameCropRightOffset = 0;
picInfo->frameCropTopOffset = 0;
picInfo->frameCropBottomOffset = 0;
}

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
133 changes: 133 additions & 0 deletions src/core/libraries/videodec/videodec2.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include "common/types.h"

#include "videodec2_avc.h"

namespace Core::Loader {
class SymbolsResolver;
}
namespace Libraries::Vdec2 {

class VdecDecoder;

using OrbisVideodec2Decoder = VdecDecoder*;
typedef void* OrbisVideodec2ComputeQueue;

struct OrbisVideodec2DecoderConfigInfo {
u64 thisSize;
u32 resourceType;
u32 codecType;
u32 profile;
u32 maxLevel;
s32 maxFrameWidth;
s32 maxFrameHeight;
s32 maxDpbFrameCount;
u32 decodePipelineDepth;
OrbisVideodec2ComputeQueue computeQueue;
u64 cpuAffinityMask;
s32 cpuThreadPriority;
bool optimizeProgressiveVideo;
bool checkMemoryType;
u8 reserved0;
u8 reserved1;
void* extraConfigInfo;
};

struct OrbisVideodec2DecoderMemoryInfo {
u64 thisSize;
u64 cpuMemorySize;
void* pCpuMemory;
u64 gpuMemorySize;
void* pGpuMemory;
u64 cpuGpuMemorySize;
void* pCpuGpuMemory;
u64 maxFrameBufferSize;
u32 frameBufferAlignment;
u32 reserved0;
};

struct OrbisVideodec2InputData {
u64 thisSize;
void* pAuData;
u64 auSize;
u64 ptsData;
u64 dtsData;
u64 attachedData;
};

struct OrbisVideodec2OutputInfo {
u64 thisSize;
bool isValid;
bool isErrorFrame;
u8 pictureCount;
u32 codecType;
u32 frameWidth;
u32 framePitch;
u32 frameHeight;
void* pFrameBuffer;
u64 frameBufferSize;
};

struct OrbisVideodec2FrameBuffer {
u64 thisSize;
void* pFrameBuffer;
u64 frameBufferSize;
bool isAccepted;
};

struct OrbisVideodec2ComputeMemoryInfo {
u64 thisSize;
u64 cpuGpuMemorySize;
void* pCpuGpuMemory;
};

struct OrbisVideodec2ComputeConfigInfo {
u64 thisSize;
u16 computePipeId;
u16 computeQueueId;
bool checkMemoryType;
u8 reserved0;
u16 reserved1;
};

s32 PS4_SYSV_ABI
sceVideodec2QueryComputeMemoryInfo(OrbisVideodec2ComputeMemoryInfo* pComputeMemInfoOut);

s32 PS4_SYSV_ABI
sceVideodec2AllocateComputeQueue(const OrbisVideodec2ComputeConfigInfo* pComputeCfgInfoIn,
const OrbisVideodec2ComputeMemoryInfo* pComputeMemInfoIn,
OrbisVideodec2ComputeQueue* pComputeQueueOut);

s32 PS4_SYSV_ABI sceVideodec2ReleaseComputeQueue(OrbisVideodec2ComputeQueue computeQueueIn);

s32 PS4_SYSV_ABI
sceVideodec2QueryDecoderMemoryInfo(const OrbisVideodec2DecoderConfigInfo* pDecoderConfigInfoIn,
OrbisVideodec2DecoderMemoryInfo* pDecoderMemoryInfoOut);

s32 PS4_SYSV_ABI
sceVideodec2CreateDecoder(const OrbisVideodec2DecoderConfigInfo* pDecoderConfigInfoIn,
const OrbisVideodec2DecoderMemoryInfo* pDecoderMemoryInfoIn,
OrbisVideodec2Decoder* pDecoderInstanceOut);

s32 PS4_SYSV_ABI sceVideodec2DeleteDecoder(OrbisVideodec2Decoder decoder);

s32 PS4_SYSV_ABI sceVideodec2Decode(OrbisVideodec2Decoder decoder,
const OrbisVideodec2InputData* pInputDataInOut,
OrbisVideodec2FrameBuffer* pFrameBufferInOut,
OrbisVideodec2OutputInfo* pOutputInfoOut);

s32 PS4_SYSV_ABI sceVideodec2Flush(OrbisVideodec2Decoder decoder,
OrbisVideodec2FrameBuffer* pFrameBufferInOut,
OrbisVideodec2OutputInfo* pOutputInfoOut);

s32 PS4_SYSV_ABI sceVideodec2Reset(OrbisVideodec2Decoder decoder);

s32 PS4_SYSV_ABI sceVideodec2GetPictureInfo(const OrbisVideodec2OutputInfo* pOutputInfoIn,
void* p1stPictureInfoOut, void* p2ndPictureInfoOut);

void RegisterlibSceVdec2(Core::Loader::SymbolsResolver* sym);
} // namespace Libraries::Vdec2
Loading

0 comments on commit 3dc4857

Please sign in to comment.