Skip to content

Commit

Permalink
Videocodec implementation (#1484)
Browse files Browse the repository at this point in the history
* dummy videocodec

* filled videodec parameters

* vdec1 implementation

* clang format fix

* fixed codecType

* added crop offset info

* align output

* align all h/w

* some touchups

* small touch (last one)
  • Loading branch information
georgemoralis authored Nov 10, 2024
1 parent 4fd7f67 commit 7ab8515
Show file tree
Hide file tree
Showing 9 changed files with 539 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,10 @@ set(VDEC_LIB src/core/libraries/videodec/videodec2_impl.cpp
src/core/libraries/videodec/videodec2.cpp
src/core/libraries/videodec/videodec2.h
src/core/libraries/videodec/videodec2_avc.h
src/core/libraries/videodec/videodec.cpp
src/core/libraries/videodec/videodec.h
src/core/libraries/videodec/videodec_impl.cpp
src/core/libraries/videodec/videodec_impl.h
)

set(NP_LIBS src/core/libraries/np_manager/np_manager.cpp
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 @@ -120,6 +120,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
SUB(Lib, SharePlay) \
SUB(Lib, Fiber) \
SUB(Lib, Vdec2) \
SUB(Lib, Videodec) \
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 @@ -87,6 +87,7 @@ enum class Class : u8 {
Lib_SharePlay, ///< The LibSceSharePlay implemenation
Lib_Fiber, ///< The LibSceFiber implementation.
Lib_Vdec2, ///< The LibSceVideodec2 implementation.
Lib_Videodec, ///< The LibSceVideodec implementation.
Frontend, ///< Emulator UI
Render, ///< Video Core
Render_Vulkan, ///< Vulkan backend
Expand Down
27 changes: 26 additions & 1 deletion src/core/libraries/error_codes.h
Original file line number Diff line number Diff line change
Expand Up @@ -590,4 +590,29 @@ 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;
constexpr int ORBIS_VIDEODEC2_ERROR_FATAL_STREAM = 0x811D0304;

// Videodec library

constexpr int ORBIS_VIDEODEC_ERROR_API_FAIL = 0x80C10000;
constexpr int ORBIS_VIDEODEC_ERROR_CODEC_TYPE = 0x80C10001;
constexpr int ORBIS_VIDEODEC_ERROR_STRUCT_SIZE = 0x80C10002;
constexpr int ORBIS_VIDEODEC_ERROR_HANDLE = 0x80C10003;
constexpr int ORBIS_VIDEODEC_ERROR_CPU_MEMORY_SIZE = 0x80C10004;
constexpr int ORBIS_VIDEODEC_ERROR_CPU_MEMORY_POINTER = 0x80C10005;
constexpr int ORBIS_VIDEODEC_ERROR_CPU_GPU_MEMORY_SIZE = 0x80C10006;
constexpr int ORBIS_VIDEODEC_ERROR_CPU_GPU_MEMORY_POINTER = 0x80C10007;
constexpr int ORBIS_VIDEODEC_ERROR_SHADER_CONTEXT_POINTER = 0x80C10008;
constexpr int ORBIS_VIDEODEC_ERROR_AU_SIZE = 0x80C10009;
constexpr int ORBIS_VIDEODEC_ERROR_AU_POINTER = 0x80C1000A;
constexpr int ORBIS_VIDEODEC_ERROR_FRAME_BUFFER_SIZE = 0x80C1000B;
constexpr int ORBIS_VIDEODEC_ERROR_FRAME_BUFFER_POINTER = 0x80C1000C;
constexpr int ORBIS_VIDEODEC_ERROR_FRAME_BUFFER_ALIGNMENT = 0x80C1000D;
constexpr int ORBIS_VIDEODEC_ERROR_CONFIG_INFO = 0x80C1000E;
constexpr int ORBIS_VIDEODEC_ERROR_ARGUMENT_POINTER = 0x80C1000F;
constexpr int ORBIS_VIDEODEC_ERROR_NEW_SEQUENCE = 0x80C10010;
constexpr int ORBIS_VIDEODEC_ERROR_DECODE_AU = 0x80C10011;
constexpr int ORBIS_VIDEODEC_ERROR_MISMATCH_SPEC = 0x80C10012;
constexpr int ORBIS_VIDEODEC_ERROR_INVALID_SEQUENCE = 0x80C10013;
constexpr int ORBIS_VIDEODEC_ERROR_FATAL_STREAM = 0x80C10014;
constexpr int ORBIS_VIDEODEC_ERROR_FATAL_STATE = 0x80C10015;
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/videodec.h"
#include "core/libraries/videodec/videodec2.h"
#include "core/libraries/videoout/video_out.h"

Expand Down Expand Up @@ -87,6 +88,7 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) {
Libraries::GameLiveStreaming::RegisterlibSceGameLiveStreaming(sym);
Libraries::SharePlay::RegisterlibSceSharePlay(sym);
Libraries::Remoteplay::RegisterlibSceRemoteplay(sym);
Libraries::Videodec::RegisterlibSceVideodec(sym);
}

} // namespace Libraries
137 changes: 137 additions & 0 deletions src/core/libraries/videodec/videodec.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include "videodec.h"

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

namespace Libraries::Videodec {

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

int PS4_SYSV_ABI sceVideodecCreateDecoder(const OrbisVideodecConfigInfo* pCfgInfoIn,
const OrbisVideodecResourceInfo* pRsrcInfoIn,
OrbisVideodecCtrl* pCtrlOut) {
LOG_INFO(Lib_Videodec, "called");

if (!pCfgInfoIn || !pRsrcInfoIn || !pCtrlOut) {
return ORBIS_VIDEODEC_ERROR_ARGUMENT_POINTER;
}
if (pCfgInfoIn->thisSize != sizeof(OrbisVideodecConfigInfo) ||
pRsrcInfoIn->thisSize != sizeof(OrbisVideodecResourceInfo)) {
return ORBIS_VIDEODEC_ERROR_STRUCT_SIZE;
}

VdecDecoder* decoder = new VdecDecoder(*pCfgInfoIn, *pRsrcInfoIn);
pCtrlOut->thisSize = sizeof(OrbisVideodecCtrl);
pCtrlOut->handle = decoder;
pCtrlOut->version = 1; //???
return ORBIS_OK;
}

int PS4_SYSV_ABI sceVideodecDecode(OrbisVideodecCtrl* pCtrlIn,
const OrbisVideodecInputData* pInputDataIn,
OrbisVideodecFrameBuffer* pFrameBufferInOut,
OrbisVideodecPictureInfo* pPictureInfoOut) {
LOG_INFO(Lib_Videodec, "called");
if (!pCtrlIn || !pInputDataIn || !pPictureInfoOut) {
return ORBIS_VIDEODEC_ERROR_ARGUMENT_POINTER;
}
if (pCtrlIn->thisSize != sizeof(OrbisVideodecCtrl) ||
pFrameBufferInOut->thisSize != sizeof(OrbisVideodecFrameBuffer)) {
return ORBIS_VIDEODEC_ERROR_STRUCT_SIZE;
}

VdecDecoder* decoder = (VdecDecoder*)pCtrlIn->handle;
if (!decoder) {
return ORBIS_VIDEODEC_ERROR_HANDLE;
}
return decoder->Decode(*pInputDataIn, *pFrameBufferInOut, *pPictureInfoOut);
}

int PS4_SYSV_ABI sceVideodecDeleteDecoder(OrbisVideodecCtrl* pCtrlIn) {
LOG_INFO(Lib_Videodec, "(STUBBED) called");

VdecDecoder* decoder = (VdecDecoder*)pCtrlIn->handle;
if (!decoder) {
return ORBIS_VIDEODEC_ERROR_HANDLE;
}
delete decoder;
return ORBIS_OK;
}

int PS4_SYSV_ABI sceVideodecFlush(OrbisVideodecCtrl* pCtrlIn,
OrbisVideodecFrameBuffer* pFrameBufferInOut,
OrbisVideodecPictureInfo* pPictureInfoOut) {
LOG_INFO(Lib_Videodec, "called");

if (!pFrameBufferInOut || !pPictureInfoOut) {
return ORBIS_VIDEODEC_ERROR_ARGUMENT_POINTER;
}
if (pFrameBufferInOut->thisSize != sizeof(OrbisVideodecFrameBuffer) ||
pPictureInfoOut->thisSize != sizeof(OrbisVideodecPictureInfo)) {
return ORBIS_VIDEODEC_ERROR_STRUCT_SIZE;
}

VdecDecoder* decoder = (VdecDecoder*)pCtrlIn->handle;
if (!decoder) {
return ORBIS_VIDEODEC_ERROR_HANDLE;
}
return decoder->Flush(*pFrameBufferInOut, *pPictureInfoOut);
}

int PS4_SYSV_ABI sceVideodecMapMemory() {
LOG_ERROR(Lib_Videodec, "(STUBBED) called");
return ORBIS_OK;
}

int PS4_SYSV_ABI sceVideodecQueryResourceInfo(const OrbisVideodecConfigInfo* pCfgInfoIn,
OrbisVideodecResourceInfo* pRsrcInfoOut) {
LOG_INFO(Lib_Videodec, "called");

if (!pCfgInfoIn || !pRsrcInfoOut) {
return ORBIS_VIDEODEC_ERROR_ARGUMENT_POINTER;
}
if (pCfgInfoIn->thisSize != sizeof(OrbisVideodecConfigInfo) ||
pRsrcInfoOut->thisSize != sizeof(OrbisVideodecResourceInfo)) {
return ORBIS_VIDEODEC_ERROR_STRUCT_SIZE;
}

pRsrcInfoOut->thisSize = sizeof(OrbisVideodecResourceInfo);
pRsrcInfoOut->pCpuMemory = nullptr;
pRsrcInfoOut->pCpuGpuMemory = nullptr;

pRsrcInfoOut->cpuGpuMemorySize = kMinimumMemorySize;
pRsrcInfoOut->cpuMemorySize = kMinimumMemorySize;

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

return ORBIS_OK;
}

int PS4_SYSV_ABI sceVideodecReset(OrbisVideodecCtrl* pCtrlIn) {
LOG_INFO(Lib_Videodec, "(STUBBED) called");

VdecDecoder* decoder = (VdecDecoder*)pCtrlIn->handle;
decoder->Reset();
return ORBIS_OK;
}

void RegisterlibSceVideodec(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("qkgRiwHyheU", "libSceVideodec", 1, "libSceVideodec", 1, 1,
sceVideodecCreateDecoder);
LIB_FUNCTION("q0W5GJMovMs", "libSceVideodec", 1, "libSceVideodec", 1, 1, sceVideodecDecode);
LIB_FUNCTION("U0kpGF1cl90", "libSceVideodec", 1, "libSceVideodec", 1, 1,
sceVideodecDeleteDecoder);
LIB_FUNCTION("jeigLlKdp5I", "libSceVideodec", 1, "libSceVideodec", 1, 1, sceVideodecFlush);
LIB_FUNCTION("kg+lH0V61hM", "libSceVideodec", 1, "libSceVideodec", 1, 1, sceVideodecMapMemory);
LIB_FUNCTION("leCAscipfFY", "libSceVideodec", 1, "libSceVideodec", 1, 1,
sceVideodecQueryResourceInfo);
LIB_FUNCTION("f8AgDv-1X8A", "libSceVideodec", 1, "libSceVideodec", 1, 1, sceVideodecReset);
};

} // namespace Libraries::Videodec
108 changes: 108 additions & 0 deletions src/core/libraries/videodec/videodec.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include "common/types.h"

namespace Core::Loader {
class SymbolsResolver;
}

namespace Libraries::Videodec {

struct OrbisVideodecConfigInfo {
u64 thisSize;
u32 codecType;
u32 profile;
u32 maxLevel;
s32 maxFrameWidth;
s32 maxFrameHeight;
s32 maxDpbFrameCount;
u64 videodecFlags;
};

struct OrbisVideodecResourceInfo {
u64 thisSize;
u64 cpuMemorySize;
void* pCpuMemory;
u64 cpuGpuMemorySize;
void* pCpuGpuMemory;
u64 maxFrameBufferSize;
u32 frameBufferAlignment;
};

struct OrbisVideodecCtrl {
u64 thisSize;
void* handle;
u64 version;
};

struct OrbisVideodecFrameBuffer {
u64 thisSize;
void* pFrameBuffer;
u64 frameBufferSize;
};

struct OrbisVideodecAvcInfo {
u32 numUnitsInTick;
u32 timeScale;
u8 fixedFrameRateFlag;
u8 aspectRatioIdc;
u16 sarWidth;
u16 sarHeight;
u8 colourPrimaries;
u8 transferCharacteristics;
u8 matrixCoefficients;
u8 videoFullRangeFlag;
u32 frameCropLeftOffset;
u32 frameCropRightOffset;
u32 frameCropTopOffset;
u32 frameCropBottomOffset;
};

union OrbisVideodecCodecInfo {
u8 reserved[64];
OrbisVideodecAvcInfo avc;
};

struct OrbisVideodecPictureInfo {
u64 thisSize;
u32 isValid;
u32 codecType;
u32 frameWidth;
u32 framePitch;
u32 frameHeight;
u32 isErrorPic;
u64 ptsData;
u64 attachedData;
OrbisVideodecCodecInfo codec;
};

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

int PS4_SYSV_ABI sceVideodecCreateDecoder(const OrbisVideodecConfigInfo* pCfgInfoIn,
const OrbisVideodecResourceInfo* pRsrcInfoIn,
OrbisVideodecCtrl* pCtrlOut);
int PS4_SYSV_ABI sceVideodecDecode(OrbisVideodecCtrl* pCtrlIn,
const OrbisVideodecInputData* pInputDataIn,
OrbisVideodecFrameBuffer* pFrameBufferInOut,
OrbisVideodecPictureInfo* pPictureInfoOut);
int PS4_SYSV_ABI sceVideodecDeleteDecoder(OrbisVideodecCtrl* pCtrlIn);
int PS4_SYSV_ABI sceVideodecFlush(OrbisVideodecCtrl* pCtrlIn,
OrbisVideodecFrameBuffer* pFrameBufferInOut,
OrbisVideodecPictureInfo* pPictureInfoOut);
int PS4_SYSV_ABI sceVideodecMapMemory();
int PS4_SYSV_ABI sceVideodecQueryResourceInfo(const OrbisVideodecConfigInfo* pCfgInfoIn,
OrbisVideodecResourceInfo* pRsrcInfoOut);
int PS4_SYSV_ABI sceVideodecReset(OrbisVideodecCtrl* pCtrlIn);

void RegisterlibSceVideodec(Core::Loader::SymbolsResolver* sym);
} // namespace Libraries::Videodec
Loading

0 comments on commit 7ab8515

Please sign in to comment.