Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core/libraries: Videodec2 implementation #1241

Merged
merged 1 commit into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,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 @@ -503,6 +510,7 @@ set(CORE src/core/aerolib/stubs.cpp
${MISC_LIBS}
${IME_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 @@ -552,4 +552,42 @@ constexpr int ORBIS_IME_ERROR_INVALID_PARAM = 0x80BC0030;
constexpr int ORBIS_IME_ERROR_INVALID_ADDRESS = 0x80BC0031;
constexpr int ORBIS_IME_ERROR_INVALID_RESERVED = 0x80BC0032;
constexpr int ORBIS_IME_ERROR_INVALID_TIMING = 0x80BC0033;
constexpr int ORBIS_IME_ERROR_INTERNAL = 0x80BC00FF;
constexpr int ORBIS_IME_ERROR_INTERNAL = 0x80BC00FF;

// 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
200 changes: 200 additions & 0 deletions src/core/libraries/videodec/videodec2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
// 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

s32 PS4_SYSV_ABI
sceVideodec2QueryComputeMemoryInfo(OrbisVideodec2ComputeMemoryInfo* computeMemInfo) {
LOG_INFO(Lib_Vdec2, "called");

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

computeMemInfo->cpuGpuMemory = nullptr;
computeMemInfo->cpuGpuMemorySize = kMinimumMemorySize;
return ORBIS_OK;
}

s32 PS4_SYSV_ABI
sceVideodec2AllocateComputeQueue(const OrbisVideodec2ComputeConfigInfo* computeCfgInfo,
const OrbisVideodec2ComputeMemoryInfo* computeMemInfo,
OrbisVideodec2ComputeQueue* computeQueue) {
LOG_INFO(Lib_Vdec2, "called");
return ORBIS_OK;
}

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

s32 PS4_SYSV_ABI
sceVideodec2QueryDecoderMemoryInfo(const OrbisVideodec2DecoderConfigInfo* decoderCfgInfo,
OrbisVideodec2DecoderMemoryInfo* decoderMemInfo) {
LOG_INFO(Lib_Vdec2, "called");

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

decoderMemInfo->cpuMemory = nullptr;
decoderMemInfo->gpuMemory = nullptr;
decoderMemInfo->cpuGpuMemory = nullptr;

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

decoderMemInfo->maxFrameBufferSize = kMinimumMemorySize;
decoderMemInfo->frameBufferAlignment = 0x100;

return ORBIS_OK;
}

s32 PS4_SYSV_ABI sceVideodec2CreateDecoder(const OrbisVideodec2DecoderConfigInfo* decoderCfgInfo,
const OrbisVideodec2DecoderMemoryInfo* decoderMemInfo,
OrbisVideodec2Decoder* decoder) {
LOG_INFO(Lib_Vdec2, "called");

if (!decoderCfgInfo || !decoderMemInfo || !decoder) {
return ORBIS_VIDEODEC2_ERROR_ARGUMENT_POINTER;
}
if (decoderCfgInfo->thisSize != sizeof(OrbisVideodec2DecoderConfigInfo) ||
decoderMemInfo->thisSize != sizeof(OrbisVideodec2DecoderMemoryInfo)) {
return ORBIS_VIDEODEC2_ERROR_STRUCT_SIZE;
}

*decoder = new VdecDecoder(*decoderCfgInfo, *decoderMemInfo);
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* inputData,
OrbisVideodec2FrameBuffer* frameBuffer,
OrbisVideodec2OutputInfo* outputInfo) {
LOG_TRACE(Lib_Vdec2, "called");

if (!decoder) {
return ORBIS_VIDEODEC2_ERROR_DECODER_INSTANCE;
}
if (!inputData || !frameBuffer || !outputInfo) {
return ORBIS_VIDEODEC2_ERROR_ARGUMENT_POINTER;
}
if (inputData->thisSize != sizeof(OrbisVideodec2InputData) ||
frameBuffer->thisSize != sizeof(OrbisVideodec2FrameBuffer)) {
return ORBIS_VIDEODEC2_ERROR_STRUCT_SIZE;
}

return decoder->Decode(*inputData, *frameBuffer, *outputInfo);
}

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

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

return decoder->Flush(*frameBuffer, *outputInfo);
}

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* outputInfo,
void* p1stPictureInfoOut, void* p2ndPictureInfoOut) {
LOG_TRACE(Lib_Vdec2, "called");

if (!outputInfo) {
return ORBIS_VIDEODEC2_ERROR_ARGUMENT_POINTER;
}
if (outputInfo->thisSize != sizeof(OrbisVideodec2OutputInfo)) {
return ORBIS_VIDEODEC2_ERROR_STRUCT_SIZE;
}
if (outputInfo->pictureCount == 0 || gPictureInfos.empty()) {
return ORBIS_OK;
}

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

if (outputInfo->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
Loading