Skip to content

Commit 7ab8515

Browse files
Videocodec implementation (#1484)
* 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)
1 parent 4fd7f67 commit 7ab8515

File tree

9 files changed

+539
-1
lines changed

9 files changed

+539
-1
lines changed

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,10 @@ set(VDEC_LIB src/core/libraries/videodec/videodec2_impl.cpp
366366
src/core/libraries/videodec/videodec2.cpp
367367
src/core/libraries/videodec/videodec2.h
368368
src/core/libraries/videodec/videodec2_avc.h
369+
src/core/libraries/videodec/videodec.cpp
370+
src/core/libraries/videodec/videodec.h
371+
src/core/libraries/videodec/videodec_impl.cpp
372+
src/core/libraries/videodec/videodec_impl.h
369373
)
370374

371375
set(NP_LIBS src/core/libraries/np_manager/np_manager.cpp

src/common/logging/filter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
120120
SUB(Lib, SharePlay) \
121121
SUB(Lib, Fiber) \
122122
SUB(Lib, Vdec2) \
123+
SUB(Lib, Videodec) \
123124
CLS(Frontend) \
124125
CLS(Render) \
125126
SUB(Render, Vulkan) \

src/common/logging/types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ enum class Class : u8 {
8787
Lib_SharePlay, ///< The LibSceSharePlay implemenation
8888
Lib_Fiber, ///< The LibSceFiber implementation.
8989
Lib_Vdec2, ///< The LibSceVideodec2 implementation.
90+
Lib_Videodec, ///< The LibSceVideodec implementation.
9091
Frontend, ///< Emulator UI
9192
Render, ///< Video Core
9293
Render_Vulkan, ///< Vulkan backend

src/core/libraries/error_codes.h

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -590,4 +590,29 @@ constexpr int ORBIS_VIDEODEC2_ERROR_NEW_SEQUENCE = 0x811D0300;
590590
constexpr int ORBIS_VIDEODEC2_ERROR_ACCESS_UNIT = 0x811D0301;
591591
constexpr int ORBIS_VIDEODEC2_ERROR_OVERSIZE_DECODE = 0x811D0302;
592592
constexpr int ORBIS_VIDEODEC2_ERROR_INVALID_SEQUENCE = 0x811D0303;
593-
constexpr int ORBIS_VIDEODEC2_ERROR_FATAL_STREAM = 0x811D0304;
593+
constexpr int ORBIS_VIDEODEC2_ERROR_FATAL_STREAM = 0x811D0304;
594+
595+
// Videodec library
596+
597+
constexpr int ORBIS_VIDEODEC_ERROR_API_FAIL = 0x80C10000;
598+
constexpr int ORBIS_VIDEODEC_ERROR_CODEC_TYPE = 0x80C10001;
599+
constexpr int ORBIS_VIDEODEC_ERROR_STRUCT_SIZE = 0x80C10002;
600+
constexpr int ORBIS_VIDEODEC_ERROR_HANDLE = 0x80C10003;
601+
constexpr int ORBIS_VIDEODEC_ERROR_CPU_MEMORY_SIZE = 0x80C10004;
602+
constexpr int ORBIS_VIDEODEC_ERROR_CPU_MEMORY_POINTER = 0x80C10005;
603+
constexpr int ORBIS_VIDEODEC_ERROR_CPU_GPU_MEMORY_SIZE = 0x80C10006;
604+
constexpr int ORBIS_VIDEODEC_ERROR_CPU_GPU_MEMORY_POINTER = 0x80C10007;
605+
constexpr int ORBIS_VIDEODEC_ERROR_SHADER_CONTEXT_POINTER = 0x80C10008;
606+
constexpr int ORBIS_VIDEODEC_ERROR_AU_SIZE = 0x80C10009;
607+
constexpr int ORBIS_VIDEODEC_ERROR_AU_POINTER = 0x80C1000A;
608+
constexpr int ORBIS_VIDEODEC_ERROR_FRAME_BUFFER_SIZE = 0x80C1000B;
609+
constexpr int ORBIS_VIDEODEC_ERROR_FRAME_BUFFER_POINTER = 0x80C1000C;
610+
constexpr int ORBIS_VIDEODEC_ERROR_FRAME_BUFFER_ALIGNMENT = 0x80C1000D;
611+
constexpr int ORBIS_VIDEODEC_ERROR_CONFIG_INFO = 0x80C1000E;
612+
constexpr int ORBIS_VIDEODEC_ERROR_ARGUMENT_POINTER = 0x80C1000F;
613+
constexpr int ORBIS_VIDEODEC_ERROR_NEW_SEQUENCE = 0x80C10010;
614+
constexpr int ORBIS_VIDEODEC_ERROR_DECODE_AU = 0x80C10011;
615+
constexpr int ORBIS_VIDEODEC_ERROR_MISMATCH_SPEC = 0x80C10012;
616+
constexpr int ORBIS_VIDEODEC_ERROR_INVALID_SEQUENCE = 0x80C10013;
617+
constexpr int ORBIS_VIDEODEC_ERROR_FATAL_STREAM = 0x80C10014;
618+
constexpr int ORBIS_VIDEODEC_ERROR_FATAL_STATE = 0x80C10015;

src/core/libraries/libs.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "core/libraries/system/systemservice.h"
4242
#include "core/libraries/system/userservice.h"
4343
#include "core/libraries/usbd/usbd.h"
44+
#include "core/libraries/videodec/videodec.h"
4445
#include "core/libraries/videodec/videodec2.h"
4546
#include "core/libraries/videoout/video_out.h"
4647

@@ -87,6 +88,7 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) {
8788
Libraries::GameLiveStreaming::RegisterlibSceGameLiveStreaming(sym);
8889
Libraries::SharePlay::RegisterlibSceSharePlay(sym);
8990
Libraries::Remoteplay::RegisterlibSceRemoteplay(sym);
91+
Libraries::Videodec::RegisterlibSceVideodec(sym);
9092
}
9193

9294
} // namespace Libraries
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
2+
// SPDX-License-Identifier: GPL-2.0-or-later
3+
4+
#include "videodec.h"
5+
6+
#include "common/logging/log.h"
7+
#include "core/libraries/error_codes.h"
8+
#include "core/libraries/libs.h"
9+
#include "videodec_impl.h"
10+
11+
namespace Libraries::Videodec {
12+
13+
static constexpr u64 kMinimumMemorySize = 32_MB; ///> Fake minimum memory size for querying
14+
15+
int PS4_SYSV_ABI sceVideodecCreateDecoder(const OrbisVideodecConfigInfo* pCfgInfoIn,
16+
const OrbisVideodecResourceInfo* pRsrcInfoIn,
17+
OrbisVideodecCtrl* pCtrlOut) {
18+
LOG_INFO(Lib_Videodec, "called");
19+
20+
if (!pCfgInfoIn || !pRsrcInfoIn || !pCtrlOut) {
21+
return ORBIS_VIDEODEC_ERROR_ARGUMENT_POINTER;
22+
}
23+
if (pCfgInfoIn->thisSize != sizeof(OrbisVideodecConfigInfo) ||
24+
pRsrcInfoIn->thisSize != sizeof(OrbisVideodecResourceInfo)) {
25+
return ORBIS_VIDEODEC_ERROR_STRUCT_SIZE;
26+
}
27+
28+
VdecDecoder* decoder = new VdecDecoder(*pCfgInfoIn, *pRsrcInfoIn);
29+
pCtrlOut->thisSize = sizeof(OrbisVideodecCtrl);
30+
pCtrlOut->handle = decoder;
31+
pCtrlOut->version = 1; //???
32+
return ORBIS_OK;
33+
}
34+
35+
int PS4_SYSV_ABI sceVideodecDecode(OrbisVideodecCtrl* pCtrlIn,
36+
const OrbisVideodecInputData* pInputDataIn,
37+
OrbisVideodecFrameBuffer* pFrameBufferInOut,
38+
OrbisVideodecPictureInfo* pPictureInfoOut) {
39+
LOG_INFO(Lib_Videodec, "called");
40+
if (!pCtrlIn || !pInputDataIn || !pPictureInfoOut) {
41+
return ORBIS_VIDEODEC_ERROR_ARGUMENT_POINTER;
42+
}
43+
if (pCtrlIn->thisSize != sizeof(OrbisVideodecCtrl) ||
44+
pFrameBufferInOut->thisSize != sizeof(OrbisVideodecFrameBuffer)) {
45+
return ORBIS_VIDEODEC_ERROR_STRUCT_SIZE;
46+
}
47+
48+
VdecDecoder* decoder = (VdecDecoder*)pCtrlIn->handle;
49+
if (!decoder) {
50+
return ORBIS_VIDEODEC_ERROR_HANDLE;
51+
}
52+
return decoder->Decode(*pInputDataIn, *pFrameBufferInOut, *pPictureInfoOut);
53+
}
54+
55+
int PS4_SYSV_ABI sceVideodecDeleteDecoder(OrbisVideodecCtrl* pCtrlIn) {
56+
LOG_INFO(Lib_Videodec, "(STUBBED) called");
57+
58+
VdecDecoder* decoder = (VdecDecoder*)pCtrlIn->handle;
59+
if (!decoder) {
60+
return ORBIS_VIDEODEC_ERROR_HANDLE;
61+
}
62+
delete decoder;
63+
return ORBIS_OK;
64+
}
65+
66+
int PS4_SYSV_ABI sceVideodecFlush(OrbisVideodecCtrl* pCtrlIn,
67+
OrbisVideodecFrameBuffer* pFrameBufferInOut,
68+
OrbisVideodecPictureInfo* pPictureInfoOut) {
69+
LOG_INFO(Lib_Videodec, "called");
70+
71+
if (!pFrameBufferInOut || !pPictureInfoOut) {
72+
return ORBIS_VIDEODEC_ERROR_ARGUMENT_POINTER;
73+
}
74+
if (pFrameBufferInOut->thisSize != sizeof(OrbisVideodecFrameBuffer) ||
75+
pPictureInfoOut->thisSize != sizeof(OrbisVideodecPictureInfo)) {
76+
return ORBIS_VIDEODEC_ERROR_STRUCT_SIZE;
77+
}
78+
79+
VdecDecoder* decoder = (VdecDecoder*)pCtrlIn->handle;
80+
if (!decoder) {
81+
return ORBIS_VIDEODEC_ERROR_HANDLE;
82+
}
83+
return decoder->Flush(*pFrameBufferInOut, *pPictureInfoOut);
84+
}
85+
86+
int PS4_SYSV_ABI sceVideodecMapMemory() {
87+
LOG_ERROR(Lib_Videodec, "(STUBBED) called");
88+
return ORBIS_OK;
89+
}
90+
91+
int PS4_SYSV_ABI sceVideodecQueryResourceInfo(const OrbisVideodecConfigInfo* pCfgInfoIn,
92+
OrbisVideodecResourceInfo* pRsrcInfoOut) {
93+
LOG_INFO(Lib_Videodec, "called");
94+
95+
if (!pCfgInfoIn || !pRsrcInfoOut) {
96+
return ORBIS_VIDEODEC_ERROR_ARGUMENT_POINTER;
97+
}
98+
if (pCfgInfoIn->thisSize != sizeof(OrbisVideodecConfigInfo) ||
99+
pRsrcInfoOut->thisSize != sizeof(OrbisVideodecResourceInfo)) {
100+
return ORBIS_VIDEODEC_ERROR_STRUCT_SIZE;
101+
}
102+
103+
pRsrcInfoOut->thisSize = sizeof(OrbisVideodecResourceInfo);
104+
pRsrcInfoOut->pCpuMemory = nullptr;
105+
pRsrcInfoOut->pCpuGpuMemory = nullptr;
106+
107+
pRsrcInfoOut->cpuGpuMemorySize = kMinimumMemorySize;
108+
pRsrcInfoOut->cpuMemorySize = kMinimumMemorySize;
109+
110+
pRsrcInfoOut->maxFrameBufferSize = kMinimumMemorySize;
111+
pRsrcInfoOut->frameBufferAlignment = 0x100;
112+
113+
return ORBIS_OK;
114+
}
115+
116+
int PS4_SYSV_ABI sceVideodecReset(OrbisVideodecCtrl* pCtrlIn) {
117+
LOG_INFO(Lib_Videodec, "(STUBBED) called");
118+
119+
VdecDecoder* decoder = (VdecDecoder*)pCtrlIn->handle;
120+
decoder->Reset();
121+
return ORBIS_OK;
122+
}
123+
124+
void RegisterlibSceVideodec(Core::Loader::SymbolsResolver* sym) {
125+
LIB_FUNCTION("qkgRiwHyheU", "libSceVideodec", 1, "libSceVideodec", 1, 1,
126+
sceVideodecCreateDecoder);
127+
LIB_FUNCTION("q0W5GJMovMs", "libSceVideodec", 1, "libSceVideodec", 1, 1, sceVideodecDecode);
128+
LIB_FUNCTION("U0kpGF1cl90", "libSceVideodec", 1, "libSceVideodec", 1, 1,
129+
sceVideodecDeleteDecoder);
130+
LIB_FUNCTION("jeigLlKdp5I", "libSceVideodec", 1, "libSceVideodec", 1, 1, sceVideodecFlush);
131+
LIB_FUNCTION("kg+lH0V61hM", "libSceVideodec", 1, "libSceVideodec", 1, 1, sceVideodecMapMemory);
132+
LIB_FUNCTION("leCAscipfFY", "libSceVideodec", 1, "libSceVideodec", 1, 1,
133+
sceVideodecQueryResourceInfo);
134+
LIB_FUNCTION("f8AgDv-1X8A", "libSceVideodec", 1, "libSceVideodec", 1, 1, sceVideodecReset);
135+
};
136+
137+
} // namespace Libraries::Videodec
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
2+
// SPDX-License-Identifier: GPL-2.0-or-later
3+
4+
#pragma once
5+
6+
#include "common/types.h"
7+
8+
namespace Core::Loader {
9+
class SymbolsResolver;
10+
}
11+
12+
namespace Libraries::Videodec {
13+
14+
struct OrbisVideodecConfigInfo {
15+
u64 thisSize;
16+
u32 codecType;
17+
u32 profile;
18+
u32 maxLevel;
19+
s32 maxFrameWidth;
20+
s32 maxFrameHeight;
21+
s32 maxDpbFrameCount;
22+
u64 videodecFlags;
23+
};
24+
25+
struct OrbisVideodecResourceInfo {
26+
u64 thisSize;
27+
u64 cpuMemorySize;
28+
void* pCpuMemory;
29+
u64 cpuGpuMemorySize;
30+
void* pCpuGpuMemory;
31+
u64 maxFrameBufferSize;
32+
u32 frameBufferAlignment;
33+
};
34+
35+
struct OrbisVideodecCtrl {
36+
u64 thisSize;
37+
void* handle;
38+
u64 version;
39+
};
40+
41+
struct OrbisVideodecFrameBuffer {
42+
u64 thisSize;
43+
void* pFrameBuffer;
44+
u64 frameBufferSize;
45+
};
46+
47+
struct OrbisVideodecAvcInfo {
48+
u32 numUnitsInTick;
49+
u32 timeScale;
50+
u8 fixedFrameRateFlag;
51+
u8 aspectRatioIdc;
52+
u16 sarWidth;
53+
u16 sarHeight;
54+
u8 colourPrimaries;
55+
u8 transferCharacteristics;
56+
u8 matrixCoefficients;
57+
u8 videoFullRangeFlag;
58+
u32 frameCropLeftOffset;
59+
u32 frameCropRightOffset;
60+
u32 frameCropTopOffset;
61+
u32 frameCropBottomOffset;
62+
};
63+
64+
union OrbisVideodecCodecInfo {
65+
u8 reserved[64];
66+
OrbisVideodecAvcInfo avc;
67+
};
68+
69+
struct OrbisVideodecPictureInfo {
70+
u64 thisSize;
71+
u32 isValid;
72+
u32 codecType;
73+
u32 frameWidth;
74+
u32 framePitch;
75+
u32 frameHeight;
76+
u32 isErrorPic;
77+
u64 ptsData;
78+
u64 attachedData;
79+
OrbisVideodecCodecInfo codec;
80+
};
81+
82+
struct OrbisVideodecInputData {
83+
u64 thisSize;
84+
void* pAuData;
85+
u64 auSize;
86+
u64 ptsData;
87+
u64 dtsData;
88+
u64 attachedData;
89+
};
90+
91+
int PS4_SYSV_ABI sceVideodecCreateDecoder(const OrbisVideodecConfigInfo* pCfgInfoIn,
92+
const OrbisVideodecResourceInfo* pRsrcInfoIn,
93+
OrbisVideodecCtrl* pCtrlOut);
94+
int PS4_SYSV_ABI sceVideodecDecode(OrbisVideodecCtrl* pCtrlIn,
95+
const OrbisVideodecInputData* pInputDataIn,
96+
OrbisVideodecFrameBuffer* pFrameBufferInOut,
97+
OrbisVideodecPictureInfo* pPictureInfoOut);
98+
int PS4_SYSV_ABI sceVideodecDeleteDecoder(OrbisVideodecCtrl* pCtrlIn);
99+
int PS4_SYSV_ABI sceVideodecFlush(OrbisVideodecCtrl* pCtrlIn,
100+
OrbisVideodecFrameBuffer* pFrameBufferInOut,
101+
OrbisVideodecPictureInfo* pPictureInfoOut);
102+
int PS4_SYSV_ABI sceVideodecMapMemory();
103+
int PS4_SYSV_ABI sceVideodecQueryResourceInfo(const OrbisVideodecConfigInfo* pCfgInfoIn,
104+
OrbisVideodecResourceInfo* pRsrcInfoOut);
105+
int PS4_SYSV_ABI sceVideodecReset(OrbisVideodecCtrl* pCtrlIn);
106+
107+
void RegisterlibSceVideodec(Core::Loader::SymbolsResolver* sym);
108+
} // namespace Libraries::Videodec

0 commit comments

Comments
 (0)