Merge pull request #709 from merwie/fix/videoout-unsupported-output-mode

fix(videoout): report unavailable output modes instead of throwing
This commit is contained in:
Dean 2026-10-07 15:15:22 +13:00 committed by GitHub
commit e4048a0989
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 11 additions and 6 deletions

View File

@ -25,9 +25,6 @@ static int validateOutputConfig(int handle, uint64_t mode, const VideoOutOutputO
}
}
}
if (mode != VIDEO_OUT_OUTPUT_MODE_DEFAULT && mode != VIDEO_OUT_OUTPUT_MODE_119_88HZ) {
throw std::runtime_error(std::string(__func__) + ": VIDEO_OUT_ERROR_UNSUPPORTED_OUTPUT_MODE");
}
return 0;
}
@ -199,7 +196,7 @@ int APS5_VABI sceVideoOutIsOutputSupported(int handle, uint64_t mode, const Vide
if (result != 0) {
return result;
}
return (mode == VIDEO_OUT_OUTPUT_MODE_119_88HZ) ? 0 : 1;
return mode == VIDEO_OUT_OUTPUT_MODE_DEFAULT ? 1 : 0;
} catch (const ProcessShutdown&) {
LibcAwaitExit_nid_postfix();
}
@ -209,8 +206,8 @@ int APS5_VABI sceVideoOutConfigureOutput(int handle, uint64_t mode, const VideoO
if (supported < 0) {
return supported;
}
if (supported == 0 && mode == VIDEO_OUT_OUTPUT_MODE_119_88HZ) {
throw std::runtime_error(std::string(__func__) + ": VIDEO_OUT_ERROR_UNAVAILABLE_OUTPUT_MODE");
if (supported == 0) {
return VIDEO_OUT_ERROR_UNAVAILABLE_OUTPUT_MODE;
}
auto cfg = VideoOutDriver::Get().GetConfig(handle);
if (cfg == nullptr) {

View File

@ -12,6 +12,7 @@
#include <chrono>
#include <cstdint>
#include <cstdio>
#include <initializer_list>
#include <string>
#include <limits>
#include <thread>
@ -229,6 +230,12 @@ void testControls() {
const auto handle = sceVideoOutOpen(255, 0, 0, openParam.data());
check(handle >= 0, "open with the highest priority on every CPU failed");
const auto cfg = VideoOutDriver::Get().GetConfig(handle);
check(sceVideoOutIsOutputSupported(handle, VIDEO_OUT_OUTPUT_MODE_DEFAULT, nullptr, nullptr, 0) == 1, "default output mode is unsupported");
for (const uint64_t unsupported : std::initializer_list<uint64_t>{VIDEO_OUT_OUTPUT_MODE_119_88HZ, 0xd000000aull}) {
check(sceVideoOutIsOutputSupported(handle, unsupported, nullptr, nullptr, 0) == 0, "unavailable output mode is supported");
check(sceVideoOutConfigureOutput(handle, unsupported, nullptr, nullptr, 0) == VIDEO_OUT_ERROR_UNAVAILABLE_OUTPUT_MODE, "unavailable output mode was configured");
}
check(sceVideoOutConfigureOutput(handle, VIDEO_OUT_OUTPUT_MODE_DEFAULT, nullptr, nullptr, 0) == 0, "default output mode was rejected");
for (int rate = 0; rate <= 2; ++rate) {
check(sceVideoOutSetFlipRate(handle, rate) == 0 && cfg->flipRate == rate, "flip rate was not applied");
}

View File

@ -38,6 +38,7 @@ Throughout the project, every function at every stage either **does exactly what
- [sceAvPlayerAddSource](../../core/libs/prx/libSceAvPlayer/src/Source.cpp) (libSceAvPlayer) - requests up to 4 additional decode-ahead video framebuffers from the memory replacement beyond `num_output_video_framebuffers` when memory is available; the console's internal buffering behaviour is unknown
- [sceVideoOutRegisterBuffers2](../../core/libs/prx/libSceVideoOut/src/Buffer.cpp) (libSceVideoOut) - buffer option 8 (STRICT_COLORIMETRY) is presented as option 0, with the stored values unchanged; what the console changes for it is unknown. Only options 0 and 8 are accepted
- [sceVideoOutRegisterBuffers2](../../core/libs/prx/libSceVideoOut/src/Buffer.cpp) (libSceVideoOut) - DCC buffers (category 1): `dcc_control` is taken as the CB_DCC_CONTROL block layout, only bits 0x10026c are accepted; `dcc_cb_register_clear_color` as the register-clear texel, only 32-bit values are presented
- [sceVideoOutIsOutputSupported](../../core/libs/prx/libSceVideoOut/src/Output.cpp) (libSceVideoOut) - output mode encoding unknown: every mode except the default reports not supported (0), and `sceVideoOutConfigureOutput` returns `VIDEO_OUT_ERROR_UNAVAILABLE_OUTPUT_MODE` for it, instead of returning `VIDEO_OUT_ERROR_UNSUPPORTED_OUTPUT_MODE` for values the console does not define. PPSA12544 probes `0xd000000a` and selects 7680 pixels when it is supported, 3840 otherwise
- [sceVideoOutOpen](../../core/libs/prx/libSceVideoOut/src/Output.cpp) (libSceVideoOut) - the open param's first word is unknown (PPSA21564 passes 16; it is not the byte size, since the affinity mask is at offset 16); only 16 is accepted. Whether the param continues past offset 24 is also unknown
- [sceRtcParseDateTime](../../core/libs/prx/libSceRtc/Export.cpp) (libSceRtc) - accepted format assumed to be the ISO 8601 subset `YYYY-MM-DDTHH:MM:SS[.ffffff]` (T/t/space separator, optional fractional seconds) with the sibling RFC 3339 zone suffix (`Z` or `±HH:MM`), plus the RFC 2822 shape `Ddd, DD Mon YYYY HH:MM:SS[ GMT| ±HHMM]` and the asctime shape `Ddd Mon DD HH:MM:SS YYYY` (day zero- or space-padded) that shadPS4 parses at fixed positions; the weekday name is not checked against the date, a `±HHMM` offset is subtracted to get UTC like the RFC 3339 path (shadPS4 adds it), a string without a zone is taken as UTC, and anything outside these shapes throws instead of returning a parse error, unverified against hardware
- [sceAudio3dPortOpen](../../core/libs/prx/libSceAudio3d/Export.cpp) (libSceAudio3d) - buffer modes 0 and 1 (also selected by the 0x10 and 0x18 parameter sizes) and 3 beds depend on an SDK version check in the module ([prosper](https://github.com/mattias800/prosper)) and throw. A repeated `sceAudio3dInitialize` (`NOT_READY` in shadPS4, 0 in prosper) and `sceAudio3dPortAdvance` on a full queue (`NOT_READY` in shadPS4, unhandled in KytyPS5) throw too