Files
AnyPS5/docs/dev/debt/libSceVideodec2.md
T
Dean 8ebd28b1c6 Merge pull request #10913 from thuanquang/fix/videodec2-discarded-frame
fix(libSceVideodec2): mark returned pictures as not discarded
2026-10-27 10:56:04 +13:00

9.1 KiB

libSceVideodec2 technical debt

Unknown function info

  • sceVideodec2InitLibrary (libSceVideodec2) throws: the FFmpeg decoders this module creates need no library-level initialisation, and neither SharpProspero nor EVO-PLAYER-PS5 declares this call, so its arguments and result are unknown. A title imports it from this module

  • sceVideodec2GetAvcPictureInfo (libSceVideodec2) - runs the sceVideodec2GetPictureInfo body (KytyPS5 binds both NIDs to one function; SharpProspero gives both the same outputInfo, first, second signature); the second (bottom field) picture info is never written, since only progressive H.264 output is modelled. prosper calls the AVC layout unestablished (no title observed calling it)

  • sceVideodec2TermLibrary and twelve other exports (libSceVideodec2) - report that they are not implemented; what they do on the console is not known. The others are QueryLibraryInfo, QueryDecoderInfo, MapMemory, MapDirectMemory, PresetDecoderConfigInfo (plain, Avc, Hevc, Vp9), CreateDecoderBid, CreateHevcDecoder, QueryHevcDecoderMemoryInfo and GetHevcPictureInfo. They are exported so that a title which imports them with sceVideodec2InitLibrary and calls none of them directly loads. Only sceVideodec2MapDirectMemory has a known parameter list, (decoder, memory), from EVO-PLAYER-PS5's sce_videodec2.h; the others take none here

Functional

  • AVC parameter-set units (libSceVideodec2) - an H.264 access unit with no slice NAL (types 1 to 5), such as the sequence and picture parameter sets Twispero (PPSA99474) submits on their own before a stream's first slices, is kept and put in front of the next unit that has a slice, and sceVideodec2Decode returns 0 with no picture for it, since libavcodec refuses a packet without a slice. What the console returns for such a unit is not known. HEVC units of parameter sets alone are still passed to libavcodec as they are

  • sceVideodec2CreateDecoder (libSceVideodec2) decodes HEVC (codec type 974921) and VP9 (2382845) through FFmpeg, besides H.264. The tags come from SharpProspero's Videodec2CodecType and EVO-PLAYER-PS5's sce_videodec2.h, which records them from hardware runs. HEVC input is converted from length-prefixed NAL units to Annex B as for H.264, and VP9 frames are passed through. Output is NV12 for 8-bit pictures. A 10-bit picture is written as 16-bit little-endian words with the sample in the low 10 bits, Y rows then interleaved UV rows at framePitchInBytes times the picture height, with framePitch in samples and framePitchInBytes in bytes (twice the width, aligned to 256), and QueryDecoderMemoryInfo sizes a frame of an HEVC or VP9 profile 2 configuration with two bytes per sample. Evidence is from EVO-PLAYER-PS5, which decodes and presents 1080p HEVC Main10 on hardware through this path (docs/evo-pro/on-demand-decoder-handoff.md): it takes a picture as 10-bit when pitch_bytes >= pitch * 2, puts UV at pitch_bytes times the height and samples with a low-bit factor (projects/evoplayer/media/src/evo_vdec_native.c, ro_harvest), and its hardware logs give 6128 KB and 24496 KB frame buffers for 1920x1088 and 3840x2176 Main10 decoders after rounding to 16 KiB. The 1080p size is what this formula gives; at 3840x2176 it gives 16 KiB less, so the console's size there has another term that is not known. Unverified: frameFormat (still 0; no consumer found reads it), VP9 profile 2 output (no hardware evidence), and the layout of 12-bit pictures and of decoded formats other than yuv420p10le, which throw. sceVideodec2GetPictureInfo and sceVideodec2GetAvcPictureInfo throw for HEVC pictures (SceVideodec2HevcPictureInfo is not filled), and sceVideodec2GetHevcPictureInfo reports that it is not implemented. One title (PPSA02225) disassembled for this entry calls it once (arguments set up at 0x8b5095-0x8b50a6) with three pointers: a structure built on its stack, a structure inside its decoder object and the address of a field of the same object. A nonzero result makes it leave the decoder setup; on one path (a flag byte set and two 32-bit fields equal to values it computed before) it passes that field to the next Videodec2 call. The codec type it requests and the meaning of the structure fields are not shown.

  • sceVideodec2GetVp9PictureInfo uses the 88-byte layout and two-pointer signature from SharpProspero Videodec2.cs. Frame metadata follows the VP9 specification, sections 5.26 and 6.2: profile, key/intra-only flags, bit depth, color space/range, coded/render dimensions and superframe count are retained per emitted buffer. Level is 0 because the elementary stream does not signal a level; the console value is unverified. Null pointers, undersized structures and querying another codec throw; console error codes and support for other structure sizes are unknown. Pictures deeper than 10 bits are rejected. Superframes are submitted as individual coded frames to keep each output associated with its input metadata. sceVideodec2GetPictureInfo writes this layout for a VP9 picture, as shadPS4's videodec2.cpp writes the decoder's own layout; Mortal Shell 2 (PPSA34008) calls it with thisSize 88.

  • sceVideodec2Decode after sceVideodec2Flush (libSceVideodec2) without sceVideodec2Reset restarts FFmpeg's decoder (avcodec_flush_buffers) and decodes the unit, where it threw before. TEKKEN DARK RESURRECTION (PPSA31371), which runs in Sony's PSP emulator, decodes after a flush without a reset (#7118), so the console accepts the call. Pictures the flush decoded but has not returned yet are returned before the new ones. A flush with no picture pending (each decoded unit has returned its picture) leaves the decoder and its reference pictures as they are, so a stream that continues without a new IDR picture keeps decoding: Daxter (PPSA09695), also in the PSP emulator, flushes after every access unit of its H.264 movies, and restarting the decoder there lost every P picture until the next keyframe. What the console returns for pending pictures, and for a stream that continues across a flush that had pictures pending, is not measured.

  • sceVideodec2Decode (libSceVideodec2) and sceVideodec2Flush output the coded picture, with the chroma plane after its luma rows, as the console does for 1080p H.264 and HEVC streams coded at 1920x1088. An HEVC or VP9 picture whose size is not a multiple of 16, such as HEVC coded at 1920x1080, is output at that size; whether the console pads it is unverified. sceVideodec2GetPictureInfo reports no frame cropping

  • sceVideodec2Decode of an empty access unit (libSceVideodec2) returns 0x811D010E for a null auData and 0x811D010D for an auSize of 0, with no picture, where it threw before. The values are ACCESS_UNIT_POINTER and ACCESS_UNIT_SIZE in the error table of shadPS4's videodec_error.h, whose libSceVdecsw codes this repository already uses; they are not measured on a PS5, and neither is whether the console leaves the decoder's state alone on that call, as this does. Media Player Classic PS5 (PPSA99015) submits empty units: its own converter reads a 4-byte length prefix of 00 00 01 xx as a start code and drops the rest as a non-base HEVC layer. It goes on after the error.

  • sceVideodec2Decode and sceVideodec2Flush (libSceVideodec2): the decoder core's discarded flag is not modelled: a returned picture always has OutputInfo.isDiscardedFrame (byte 0xb) at 0, and an unshown VP9 frame returns no picture. Per a #10913 review reading firmware 13.42's module (not reproduced here), the byte is written only with a returned picture and is left as the caller set it otherwise, as here. Name and offset: SharpProspero and KytyPS5; shadPS4 leaves it as padding. PPSA05110 sets only thisSize before its VP9 Decode (0x13728dd) and Flush (0x1371f7e) and takes a picture only when the byte is 0