Skip to content
RetrogamingDeep Dive Published Updated 7 min readViews unavailable

PlayStation MDEC: Command FIFOs, Macroblocks, and DMA Output

Trace the PlayStation MDEC decode pipeline from command and quantization tables through macroblock conversion, FIFO flow, and DMA completion.

The original PlayStation’s Motion Decoder (MDEC) is a fixed-function coprocessor for decompressing image and video data. Games use it for full-motion video, image sequences, and related visual effects. The MDEC is not the PlayStation GPU: the MDEC transforms compressed macroblock data into pixel output, while the GPU handles drawing commands and display composition. Confusing those stages leads to wrong diagnoses when a movie decodes with corrupted blocks, stalls mid-frame, or displays with unexpected color depth.

MDEC behavior is coordinated through command and data registers and DMA channels. Software supplies a command and compressed input; MDEC consumes the stream, applies quantization and inverse-transform processing, converts decoded color components, and makes output words available. The CPU or DMA controller must respect readiness and transfer direction. A decoder that computes an entire frame synchronously while ignoring input starvation and output backpressure may play common content yet fail at timing-sensitive handoffs.

Separate commands, compressed input, and output

MDEC software configures decoding through command words and associated tables. The PlayStation documentation describes commands for decoding macroblock data and loading quantization or scale tables. The decode command also carries mode information, including output depth and signedness behavior. The exact bit fields should be taken from the MDEC command specification or tested implementation, not inferred from the file format or a game-specific packet.

The MDEC has a compressed-input path and a decoded-output path. On the system DMA controller, MDEC input and output use distinct channels; common documentation identifies DMA channel 0 for MDEC input and channel 1 for MDEC output. Direction matters: sending output words to the input FIFO or reading output before it is ready corrupts the transfer sequence. Capture DMA channel registers and MDEC status together when debugging.

Treat a decode operation as a state machine rather than one function call that consumes an entire frame. A command establishes mode and expected work; input data arrives through the input path; output becomes available as blocks are decoded; and the DMA controller moves words according to its channel configuration. The CPU may observe status between these phases. Preserve the distinction between input accepted, decode work pending, output available, and DMA transfer complete. They are not interchangeable completion events.

Software may load the quantization tables and scale matrix before decoding. Those tables affect conversion, and initialization state should not be assumed to survive reset unless the hardware contract says it does. A decoder that silently reuses stale tables can appear to work for one title and fail after a soft reset or when a game changes video content format.

The macroblock decode pipeline

Compressed coefficients are represented with variable-length run/level data. MDEC reconstructs coefficient blocks using quantization information, performs an inverse discrete cosine transform, and converts the component data to the requested pixel representation. In color modes, luminance and chroma components must be combined with the specified range, signedness, and channel order. Rounding and saturation behavior matter; a mathematically similar floating-point transform can produce visible drift from the fixed-point hardware results.

Macroblock boundaries are important. The decoder consumes input in a defined sequence and emits output in packed words. A malformed run/level sequence, unsupported command, or incomplete data can leave the stream parser in a different state than the next block expects. Treat command boundaries and DMA block boundaries according to hardware semantics, not as interchangeable “video packet” markers.

Output pixel layouts depend on command mode. Fifteen-bit and twenty-four-bit output modes have different packing and alignment implications. For 24-bit output, the final word of a line or block may contain fewer valid pixel bytes than a 32-bit-aligned transfer; the DMA transfer count and MDEC output status must be interpreted together. Do not simply reinterpret an output buffer as a native host RGB struct, because host endianness, row pitch, and packing may differ.

Model readiness and DMA progress

DMA allows transfers to proceed without the CPU copying each word, but it does not eliminate synchronization. The MDEC input side can become full, output can become available incrementally, and the DMA controller has its own transfer mode and completion/interrupt behavior. A robust emulator advances the coprocessor and DMA state according to the shared timeline. It should expose partial progress when software polls status or waits for an interrupt.

When a game hangs during video playback, determine which side stopped making progress. Is the DMA channel still active? Is MDEC waiting for compressed input, or is output blocked because the consumer did not drain the FIFO? Did the transfer count or block boundary match the programmed request? Did an interrupt become pending but not asserted? An emulator that marks DMA complete immediately after queuing a decode job can break software that polls completion before consuming the data.

For deterministic output, keep the compressed stream state, tables, coefficient state, and FIFO state serializable if save states can be taken mid-decode. If a save state cannot preserve a partially completed command, document the limitation and either synchronize save-state capture to safe boundaries or serialize enough state to resume. Replaying only the visible image is not equivalent to restoring an in-progress DMA decode.

Diagnose artifacts by stage

Block corruption often points to input parsing, coefficient decoding, or table state. Incorrect colors may indicate signedness, YCbCr conversion, output mode, or palette/display handling after MDEC. A frozen movie may indicate FIFO handoff, DMA count, interrupt, or timing behavior. Wrong positioning or scaling may be downstream in the GPU display path rather than MDEC itself.

Use a known video sequence and capture the command word, table load order, input bytes consumed, output words produced, DMA channel state, and final GPU upload. Compare a single macroblock first, then a complete frame. A pixel comparison should account for documented output depth and conversion; do not apply a shader or display color correction during a decoder validation test.

Test signed and unsigned modes, output depth, quantization table initialization, reset between clips, short or truncated input, and save/restore during decode if supported. Keep proprietary game data private in public bug reports; synthetic test streams or small hashes and register traces are usually sufficient for reporting implementation defects.

When a decode pipeline is asynchronous in the emulator, make cancellation and reset behavior explicit. If software resets the machine while a transfer is pending, queued host work must not write pixels into a new game’s state. Tag pending work with the emulated device generation or cancel it at reset, and ensure saved state restores decoder and DMA progress as one coherent snapshot. A host worker thread that races the emulated scheduler can otherwise create nondeterministic results that cannot occur on the console.

A useful test report includes one command, compressed input length, decoded output length, expected hash, observed hash, and status transitions. A frame screenshot is a companion, not a substitute for the byte-level check. Record whether the comparison is against hardware capture, a documented test vector, or another emulator so readers understand confidence in the reference.

Accuracy limits and acceptance criteria

Documentation and emulator implementations can disagree in edge cases. Treat each assumption as a testable hypothesis and cite the exact command semantics being implemented. Avoid claiming cycle-perfect MDEC behavior unless input/output timing and backpressure have been validated against hardware or a trustworthy test suite. A correct decoded frame produced at the wrong time can still cause DMA or CPU-visible differences.

An acceptance suite should verify table initialization, command decoding, macroblock output bytes, both relevant DMA directions, transfer completion, status flags, reset behavior, and mid-command recovery if supported. Compare pixel output and register/interrupt traces. Run at least one title with video data and a synthetic or homebrew test that stresses output modes and transfer boundaries.

MDEC is a stateful video decompressor in the PlayStation’s DMA-driven system. Reconstruct its data pipeline and synchronization separately from the GPU, then validate byte packing, FIFO readiness, and completion. That decomposition makes black or corrupted video a tractable hardware-emulation problem rather than a vague rendering issue.

Related:

Sources:

Comments