sceAudiocodec: Match hardware setup, framing, errors and timing; fix Atrac3 polarity

Checked against pspautotests audio/audiocodec, recorded on a PSP.

- Atrac3+: at3Related selects headered (mpeg.prx) or raw (libatrac3plus)
  frames, instead of sniffing for the sync word. The header's size field
  is 10 bits, as the context's. Header errors 0x211/0x213, bad frames
  0x20a, all returning SCE_AVCODEC_ERROR_INVALID_DATA with nothing read.
- The first successfully decoded Atrac3+ frame, and the first two AAC
  frames, produce no output. Checked sample-for-sample against hardware.
- Atrac3: the parameter at 0x28 selects the frame layout, as
  libatrac3plus.prx's table maps it. We used to read its low bit as a
  joint-stereo flag, which decoded mono (0x0F) streams as stereo garbage.
  AtracCtx2 had the table's fields swapped the same way.
- at3_standalone's Atrac3 output was inverted relative to the PSP's
  (sceAtrac too). Negate the IMDCT scale.
- CheckNeedMem sizes (AAC is 0x658c), codec 0x1004/0x1005, Init
  validation (AAC sample rate, Atrac3 parameter, Atrac3+ channels), and
  ReleaseEDRAM clearing edramAddr.
- Every call that reaches the ME now blocks for its measured time, and
  decode time is modelled per codec and frame size.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-09-28 16:57:41 -06:00
1 parent fb17e58fe3
commit c162eb3d74
5 files changed
+272 -137

No files matched your search

+3 -1
View File
@@ -902,7 +902,9 @@ ATRAC3Context *atrac3_alloc(int channels, int *block_align, const uint8_t *extra
q->decoded_bytes_buffer = (uint8_t *)av_mallocz(FFALIGN(q->block_align, 4) + AV_INPUT_BUFFER_PADDING_SIZE);
/* initialize the MDCT transform */
if ((ret = ff_mdct_init(&q->mdct_ctx, 9, 1, 1.0 / 32768)) < 0) {
/* Negative scale: the PSP's decoder outputs the opposite polarity to ffmpeg's, in mono,
* stereo and joint stereo alike (compared on hardware through sceAudiocodec). */
if ((ret = ff_mdct_init(&q->mdct_ctx, 9, 1, -1.0 / 32768)) < 0) {
av_log(AV_LOG_ERROR, "Error initializing MDCT");
av_freep(&q->decoded_bytes_buffer);