mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-18 23:07:07 -05:00
feat(libSceVdecsw): block on SyncDecodeInput/Output like TrySync
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
e9a3343a22
commit
cb6c305038
3 files changed
+57
-1
No files matched your search
@@ -7,6 +7,7 @@
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <stdexcept>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include "SceTypes.hpp"
|
||||
#include "prx/libc/include/General.hpp"
|
||||
@@ -311,6 +312,14 @@ int APS5_VABI sceVdecswTrySyncDecodeInput(std::uint64_t handle, InputResult* res
|
||||
return decoder->inputs.empty() ? VdecswErrorInputQueueEmpty : VdecswErrorDecodePending;
|
||||
}
|
||||
|
||||
int APS5_VABI sceVdecswSyncDecodeInput(std::uint64_t handle, InputResult* result) {
|
||||
for (;;) {
|
||||
const auto status = sceVdecswTrySyncDecodeInput(handle, result);
|
||||
if (status != VdecswErrorDecodePending) return status;
|
||||
std::this_thread::yield();
|
||||
}
|
||||
}
|
||||
|
||||
int APS5_VABI sceVdecswSetDecodeOutput(std::uint64_t handle, const FrameBuffer* frame) {
|
||||
if (frame == nullptr || frame->thisSize < sizeof(FrameBuffer) || frame->frameBuffer == nullptr) throw std::runtime_error("Vdecsw: invalid decode output");
|
||||
const auto decoder = findDecoder(handle);
|
||||
@@ -356,6 +365,14 @@ int APS5_VABI sceVdecswTrySyncDecodeOutput(std::uint64_t handle, OutputInfo* out
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceVdecswSyncDecodeOutput(std::uint64_t handle, OutputInfo* output) {
|
||||
for (;;) {
|
||||
const auto status = sceVdecswTrySyncDecodeOutput(handle, output);
|
||||
if (status != VdecswErrorOutputPending) return status;
|
||||
std::this_thread::yield();
|
||||
}
|
||||
}
|
||||
|
||||
int APS5_VABI sceVdecswGetAvcPictureInfo(const OutputInfo* output, AvcPictureInfo* first, AvcPictureInfo* second) {
|
||||
if (output == nullptr || first == nullptr || first->thisSize < sizeof(std::uint64_t)) throw std::runtime_error("Vdecsw: invalid argument pointer");
|
||||
if (output->pictureCount > 1) throw std::runtime_error("Vdecsw: second field picture info is not implemented");
|
||||
@@ -377,6 +394,13 @@ int APS5_VABI sceVdecswGetAvcPictureInfo(const OutputInfo* output, AvcPictureInf
|
||||
throw std::runtime_error("Vdecsw: picture info requested for a frame buffer no decoder returned");
|
||||
}
|
||||
|
||||
int APS5_VABI sceVdecswGetHevcPictureInfo(const OutputInfo* output, void* picture) {
|
||||
(void)output;
|
||||
(void)picture;
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceVdecswFinalizeDecodeSequence(std::uint64_t handle) {
|
||||
const auto decoder = findDecoder(handle);
|
||||
std::lock_guard lock(decoder->mutex);
|
||||
|
||||
@@ -120,9 +120,12 @@ int APS5_VABI sceVdecswCreateDecoder(const DecoderConfigInfo*, const DecoderMemo
|
||||
int APS5_VABI sceVdecswDeleteDecoder(std::uint64_t);
|
||||
int APS5_VABI sceVdecswSetDecodeInput(std::uint64_t, const InputData*);
|
||||
int APS5_VABI sceVdecswTrySyncDecodeInput(std::uint64_t, InputResult*);
|
||||
int APS5_VABI sceVdecswSyncDecodeInput(std::uint64_t, InputResult*);
|
||||
int APS5_VABI sceVdecswSetDecodeOutput(std::uint64_t, const FrameBuffer*);
|
||||
int APS5_VABI sceVdecswTrySyncDecodeOutput(std::uint64_t, OutputInfo*);
|
||||
int APS5_VABI sceVdecswSyncDecodeOutput(std::uint64_t, OutputInfo*);
|
||||
int APS5_VABI sceVdecswGetAvcPictureInfo(const OutputInfo*, AvcPictureInfo*, AvcPictureInfo*);
|
||||
int APS5_VABI sceVdecswGetHevcPictureInfo(const OutputInfo*, void*);
|
||||
int APS5_VABI sceVdecswFinalizeDecodeSequence(std::uint64_t);
|
||||
int APS5_VABI sceVdecswResetDecoder(std::uint64_t);
|
||||
}
|
||||
@@ -233,12 +236,37 @@ void testWithoutOutput() {
|
||||
check(sceVdecswTrySyncDecodeInput(session.decoder, &result) == InputQueueEmpty, "a reset decoder kept its inputs");
|
||||
}
|
||||
|
||||
void testSyncWrappers() {
|
||||
Session session;
|
||||
InputResult idle{sizeof(InputResult)};
|
||||
check(sceVdecswSyncDecodeInput(session.decoder, &idle) == InputQueueEmpty, "sync input on an idle decoder did not report an empty queue");
|
||||
const auto units = accessUnits(false);
|
||||
const InputData input{sizeof(InputData), units[0].data(), units[0].size(), 1000, 0, 0xa0};
|
||||
check(sceVdecswSetDecodeInput(session.decoder, &input) == 0, "decode input was rejected");
|
||||
InputResult result{sizeof(InputResult)};
|
||||
check(sceVdecswSyncDecodeInput(session.decoder, &result) == 0 && result.decodedAu == units[0].data(), "sync input did not consume the access unit");
|
||||
std::vector<std::uint8_t> buffer(session.memory.maxFrameBufferSize);
|
||||
const FrameBuffer frame{sizeof(FrameBuffer), buffer.data(), buffer.size()};
|
||||
check(sceVdecswSetDecodeOutput(session.decoder, &frame) == 0, "output buffer was rejected");
|
||||
check(sceVdecswFinalizeDecodeSequence(session.decoder) == 0, "finalize failed");
|
||||
OutputInfo output{sizeof(OutputInfo)};
|
||||
check(sceVdecswSyncDecodeOutput(session.decoder, &output) == 0 && output.isValid && output.isLastFrame, "sync output did not return the finalized picture");
|
||||
bool hevcThrows = false;
|
||||
try {
|
||||
sceVdecswGetHevcPictureInfo(&output, &result);
|
||||
} catch (const std::exception&) {
|
||||
hevcThrows = true;
|
||||
}
|
||||
check(hevcThrows, "GetHevcPictureInfo must still throw");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main() {
|
||||
try {
|
||||
testDecode();
|
||||
testWithoutOutput();
|
||||
testSyncWrappers();
|
||||
std::puts("Vdecsw tests passed");
|
||||
return 0;
|
||||
} catch (const std::exception& error) {
|
||||
|
||||
@@ -2,4 +2,8 @@
|
||||
|
||||
### Unknown function info
|
||||
|
||||
- [libSceVdecsw](../../../core/libs/prx/libSceVdecsw/Export.cpp) (libSceVdecsw) - structure layouts follow shadPS4's `vdecsw.h` and were checked against PPSA05684's movie decoder (`movie-decoder-vdecsw.cpp`), which asserts `pictureCount == 1` at offset 0xb of `OutputInfo` and reads `InputResult` offset 0x10 as the number of frames an access unit produced. The compute, decoder memory and decode input structures and the first 0x28 bytes of the 0x50-byte decoder config are those of libSceVideodec2, and decoding goes through it. The 0x78-byte AVC picture info is filled with Videodec2's leading fields and the cropping fields only. OUTPUT_PENDING (0x81510115), INPUT_QUEUE_EMPTY (0x81510116) and DECODE_PENDING (0x81510117) follow from the codes each call's assert accepts. At most four decoded pictures are queued and the last one is held until `sceVdecswFinalizeDecodeSequence`; the console's queue depth is unknown
|
||||
- [libSceVdecsw](../../../core/libs/prx/libSceVdecsw/Export.cpp) (libSceVdecsw) - structure layouts follow shadPS4's `vdecsw.h` and were checked against PPSA05684's movie decoder (`movie-decoder-vdecsw.cpp`), which asserts `pictureCount == 1` at offset 0xb of `OutputInfo` and reads `InputResult` offset 0x10 as the number of frames an access unit produced. The compute, decoder memory and decode input structures and the first 0x28 bytes of the 0x50-byte decoder config are those of libSceVideodec2, and decoding goes through it. The 0x78-byte AVC picture info is filled with Videodec2's leading fields and the cropping fields only. OUTPUT_PENDING (0x81510115), INPUT_QUEUE_EMPTY (0x81510116) and DECODE_PENDING (0x81510117) follow from the codes each call's assert accepts. At most four decoded pictures are queued and the last one is held until `sceVdecswFinalizeDecodeSequence`; the console's queue depth is unknown. `sceVdecswSyncDecodeInput` / `sceVdecswSyncDecodeOutput` retry the TrySync variants until they stop returning DECODE_PENDING / OUTPUT_PENDING; they do not sleep beyond a yield, so another thread must drain outputs when the picture queue is full. `sceVdecswGetHevcPictureInfo` still throws: the 0xb8-byte HEVC picture layout is in shadPS4's `vdecsw.h`, but this wrapper only keeps AVC picture info from Videodec2
|
||||
|
||||
### Unimplemented paths
|
||||
|
||||
- [sceVdecswGetHevcPictureInfo](../../../core/libs/prx/libSceVdecsw/Export.cpp) (libSceVdecsw) - throws until HEVC picture info is filled from the decoder
|
||||
Reference in new issue
Block a user