Files
AnyPS5/docs/dev/debt/libSceVorbisDec.md
T
zaryabzip a542a13f00 feat(libSceVorbisDec): decode Ogg Vorbis with libvorbisfile 1.3.7
Add libogg 1.3.6 and libvorbis 1.3.7 as submodules, built from source as
hidden static libraries, and implement the 31 libvorbisfile exports on top
of them. Decoder state lives in a host table keyed by the guest
OggVorbis_File, guest callbacks are trampolined, and vorbis_info is
returned in its LP64 layout.
2026-10-22 09:51:31 +05:00

3.0 KiB

libSceVorbisDec technical debt

Unknown function info

  • sceVorbisDecOpenCallbacks, sceVorbisDecRead and the other libvorbisfile exports (libSceVorbisDec) - the 31 exports named after libvorbisfile functions are taken to be the libvorbisfile API with a sceVorbisDec prefix (Read is ov_read, CrossLap is ov_crosslap, HalfrateP is ov_halfrate_p). ReadFilter, ReadFloat and Halfrate exist in libvorbis (ov_read_filter since 1.2.2, with the same vorbisfile.h signatures through 1.3.7 apart from const) but not in Tremor, so times are double and ov_read takes bigendianp, word and sgned. Guest long arguments and results are 64-bit. They run the bundled libvorbis 1.3.7 and libogg 1.3.6; the console's libvorbis version, any Sony changes to its behaviour or error codes, and the signatures themselves are unverified on a PS5.
  • sceVorbisDecGetDecodePriority (libSceVorbisDec) - declared without parameters, signature unknown; name from the NID database
  • sceVorbisDecGetLastDecodeError (libSceVorbisDec) - declared without parameters, signature unknown; name from the NID database
  • sceVorbisDecSetDecodePriority (libSceVorbisDec) - declared without parameters, signature unknown; name from the NID database

Functional

  • libSceVorbisDec (libSceVorbisDec) - the guest OggVorbis_File is never written: the decoder state lives on the host, keyed by the struct's address, so fields a title reads directly keep what it stored, and a struct never opened, cleared or failed to open behaves as libvorbisfile's zeroed struct. sceVorbisDecInfo returns a copy of each link's vorbis_info with 64-bit long fields, refreshed after every call on the struct and valid until sceVorbisDecClear. Reopening a struct that is still open frees its old state without calling its close callback; libvorbisfile leaks it.
  • sceVorbisDecClear and sceVorbisDecCrossLap (libSceVorbisDec) - a null vf throws, as libvorbisfile dereferences it, except that sceVorbisDecClear and sceVorbisDecCrossLap with the same pointer twice return 0, and sceVorbisDecCrossLap with a null second pointer after a first that is not open returns OV_EINVAL, as libvorbisfile does. sceVorbisDecClear frees the state before it calls the close callback, as ov_clear does, so when that callback throws the struct is already cleared, where libvorbisfile leaves it freed but not zeroed.
  • sceVorbisDecOpenCallbacks and sceVorbisDecBitrate (libSceVorbisDec) - on Windows the host long is 32-bit: a tell result outside it, or an initial byte count outside it with a non-null initial, throws; a sample rate of 2^31 Hz or more is rejected as a bad header; and sceVorbisDecBitrate rounds halves up instead of to even.