Files
AnyPS5/docs/dev/debt/libSceAudiodec.md
T
Dean bf1d324add Merge pull request #12785 from hypermoist/fix/audiodec-m4aac-unopenable-layout
fix(libSceAudiodec): report a decode error when FFmpeg cannot open an M4AAC layout
2026-11-03 11:35:18 +13:00

4.0 KiB

libSceAudiodec technical debt

Unknown function info

  • M4AAC extended parameters: 28-byte and 32-byte parameter variants add fields at offsets 24 and 28, named by their range errors (0x807F0305 SCE_AUDIODEC_ERROR_M4AAC_INVALID_ENABLE_NONDELAY_OUTPUT, 0x807F0306 SCE_AUDIODEC_ERROR_M4AAC_INVALID_SURROUND_CHANNEL_INTERLEAVE_ORDER, in fpPS4's ps4_libsceaudiodec.pas). Non-delay output 1 decodes every access unit to its own PCM from the first one on, as shadPS4's AJM AAC decoder does with EnableNondelayOutput; without that flag shadPS4 holds back the first 2 frames. Non-delay output 0 still decodes the same way, with no frame held back: no measurement shows whether the console delays it. Interleave orders 1 and 2 leave mono and stereo output unchanged, having no surround channels to place (PPSA21607 decodes stereo with order 2); with more channels they throw: no source says which value selects shadPS4's ExtlExtrLsRs or LsRsExtlExtr AJM order, or which order 0 is.

  • sceAudiodecDecode (libSceAudiodec) - a raw M4AAC stream carries no channel configuration, so the decoder tries the mono/stereo configuration and then configurations 3 to 7 within ui_max_channels until one decodes the first access unit, and keeps that one. No reference documents how the library picks the layout (shadPS4 maps the channel count straight to the configuration; SharpProspero only describes the maximum). With the stereo configuration a mono raw stream decodes as 2 channels, so 2 is reported, not 1

  • sceAudiodecDecode (libSceAudiodec) - the HE-AAC handling follows one console measurement of an HE-AAC v2 ADTS stream: SBR output at 48 kHz in one channel with ui_enable_heaac 1, the 24 kHz mono core with 0. Not measured: whether the console, like FFmpeg, decodes a stream without SBR data in its first access unit as AAC-LC with ui_enable_heaac 1, and what it reports in ui_sampling_freq and ui_heaac with ui_enable_heaac 0 (here the rate of the returned PCM and 0)

  • sceAudiodecDecode (libSceAudiodec) - the console's answer to an M4AAC layout its decoder cannot use is not measured. An ADTS header whose layout FFmpeg cannot open (for example the reserved sampling index 13) is answered with M4AAC_RESULT_DECODE_ERROR (-4) and ERROR_API_FAIL with sizes 0, as an access unit FFmpeg cannot decode is. The decoder then has no FFmpeg context and answers the same for every access unit until a header names a layout that opens; the raw layout search skips a layout FFmpeg refuses

Functional

  • sceAudiodecDecode (libSceAudiodec) - an ADTS stream with channel configuration 0 (layout in a program config element) is still parsed by FFmpeg, so ui_enable_heaac 0 does not remove its SBR and a mono one with Parametric Stereo comes out as stereo.
  • libSceAudiodec accepts only 16-bit PCM, and float PCM for ATRAC9 and M4AAC, as sceAudiodecCreateDecoder did in a payload process on a PS5 (firmware 13.60), which returned ERROR_INVALID_WORD_LENGTH for iBwPcm 0, 3 and -1 with each codec and for float with MP3; other word sizes are assumed to fail the same way. Separately measured on PS4 (firmware 10.71) for MP3 and M4AAC over iBwPcm -1 to 3: MP3 accepts only 16-bit (1), M4AAC accepts 16-bit and float (1 and 2), and every other value returns ERROR_INVALID_WORD_LENGTH. ATRAC9's word length is not reached there: with invalid config data the console returns ERROR_AT9_INVALID_CONFIG_DATA for every word length, so it validates the config before the word size. This is a PS4 10.71 measurement; the PS5 behaviour for these cases is still the 13.60 one above, not re-confirmed on current PS5 firmware. ATRAC9 decoding is covered only by configuration and error tests, as no ATRAC9 encoder is available for a fixture.