Motion Decoder (MDEC)
Image decompression engine that performs the inverse DCT on macroblocks.
Overview
The MDEC (Motion DECoder) is the data expansion engine of the PlayStation. It executes the inverse DCT at high speed and therefore expands JPEG data and MPEG data that is compressed within the frame only.1 The MDEC takes compressed data from main memory and returns the expanded image to main memory, from where it is transferred to the display area of the frame buffer.2
The MDEC shares the main bus with the CPU and the other devices by time sharing. Decompression can therefore run in parallel with the program and with transfers to the frame buffer.3 Because the inverse DCT takes time, Sony gives it to this separate piece of hardware, while the CPU performs the VLC decoding of the bitstream into run-level data.4
The maximum decompression speed is 9,000 macroblocks per second. This is the equivalent of 30 images of 320 x 240 pixels. The speed does not depend on the compression ratio, so the resolution and the frame rate of a movie are inversely proportional:5
| Resolution | Frames per second |
|---|---|
| 320 x 240 | 30 |
| 640 x 240 | 15 |
| 640 x 480 | 7.5 |
The bitstream format and the STR movie container are described on the BS page. The MDEC itself decodes the run-level data that the CPU produces from the bitstream.4
Decoding Process
DCT compression works on a macroblock of 16 x 16 pixels in 24-bit direct color. The encoder converts the RGB macroblock to Y, Cb and Cr; Y is the brightness element and Cb and Cr are color difference elements.6 Y is divided into four 8 x 8 blocks and Cb and Cr are thinned out to one 8 x 8 block each, so a macroblock becomes six blocks. Each block is then transformed by DCT, quantized, listed in zig-zag order and run-length compressed into run level, and the run level is finally Huffman encoded (VLC) into the bitstream.6
Decompression performs these steps in reverse order and therefore has two passes: VLC decoding by the CPU and IDCT by the MDEC.6 The image data is 24-bit. However, the bitstream can be decompressed in either 16-bit or 24-bit mode, and the mode is selected when decompression is carried out. In 16-bit mode the STP bit of each pixel can also be selected.6
psx-spx gives the MDEC's order for one colored macroblock. It decodes Cr and Cb first, then decodes Y1 to Y4 one at a time and converts each with the matching quarter of Cr and Cb into RGB:7
rl_decode_block(Crblk,src,iq_uv) ;Cr (low resolution)
rl_decode_block(Cbblk,src,iq_uv) ;Cb (low resolution)
rl_decode_block(Yblk,src,iq_y), yuv_to_rgb(0,0) ;Y1 (and upper-left Cr,Cb)
rl_decode_block(Yblk,src,iq_y), yuv_to_rgb(8,0) ;Y2 (and upper-right Cr,Cb)
rl_decode_block(Yblk,src,iq_y), yuv_to_rgb(0,8) ;Y3 (and lower-left Cr,Cb)
rl_decode_block(Yblk,src,iq_y), yuv_to_rgb(8,8) ;Y4 (and lower-right Cr,Cb)
In 4-bit and 8-bit output depth a macroblock is a single 8 x 8 Y block, and the output is grayscale without conversion to RGB.7 8
I/O Ports
The MDEC has two 32-bit ports. Each address has a different function for reading and for writing:9
| Address | Name | Read | Write |
|---|---|---|---|
| 1F801820h | MDEC0 | Data/Response: decoded macroblock data | Command/Parameter |
| 1F801824h | MDEC1 | Status | Control/Reset |
A program normally writes only the command word to MDEC0 and lets DMA0 transfer the parameter words. Output is always read as 8 x 8 pixel blocks. For a colored 16 x 16 macroblock the four Y blocks must therefore be placed side by side in memory, which DMA1 does automatically and a program reading MDEC0 itself must do by hand.9
MDEC1 Status Register (Read)
| Bits | Name | Content |
|---|---|---|
| 31 | FIFO1 | Data-out FIFO empty (0 = no, 1 = empty) |
| 30 | FIFO0 | Data-in FIFO full (0 = no, 1 = full, or last word received) |
| 29 | BUSY | Command busy (0 = ready, 1 = busy receiving or processing parameters) |
| 28 | DREQ0 | Data-in request (set when DMA0 is enabled and ready to receive) |
| 27 | DREQ1 | Data-out request (set when DMA1 is enabled and ready to send) |
| 25 to 26 | Data output depth (0 = 4-bit, 1 = 8-bit, 2 = 24-bit, 3 = 15-bit), from command bits 27 to 28 | |
| 24 | Data output signed (0 = unsigned, 1 = signed), from command bit 26 | |
| 23 | STP | Data output bit 15 (0 = clear, 1 = set) for 15-bit depth, from command bit 25 |
| 19 to 22 | Not used, always zero | |
| 16 to 18 | Current block (0 to 3 = Y1 to Y4, 4 = Cr, 5 = Cb; 4 = Y for monochrome) | |
| 0 to 15 | Number of parameter words remaining minus 1 (FFFFh = none) |
While the output FIFO holds data, the current block field gives the block being output; DMA1 uses it to place the data. When the output FIFO is empty the field gives the block being received.9
MDEC1 Control Register (Write)
| Bits | Content |
|---|---|
| 31 | Reset MDEC (1 = abort any command and set status to 80040000h) |
| 30 | Enable data-in request (1 = enable DMA0 and status bit 28) |
| 29 | Enable data-out request (1 = enable DMA1 and status bit 27) |
| 0 to 28 | Not used, normally zero |
The data requests must be enabled before DMA is used, and also before a program can read the request flags. The data-out request is set when a block is ready but clears after the first words of the block are read. The rest of the block can still be read until the FIFO-empty flag is set.9
DMA
Playing a movie uses four DMA channels. DMA3 brings the compressed data from the CD-ROM to main memory, DMA0 sends it to the MDEC, DMA1 returns the decoded macroblocks to main memory and DMA2 sends them to the GPU.10
DMA0 and DMA1 are normally used with a block size of 20h words. The parameters of the decode command are therefore padded with FE00h halfwords to a multiple of 20h words (40h halfwords).10
Because the exchange between the MDEC and main memory is asynchronous, a whole 640 x 240 frame can be decompressed without a frame-sized buffer in main memory. libpress splits the image into slices of 16 x 240 pixels (15 macroblocks) and receives and transfers each slice separately.4 The DecDCTin() and DecDCTout() functions of libpress are non-blocking. A program detects the end of a transfer by polling DecDCTinSync() and DecDCToutSync() or by registering a callback with DecDCTinCallback() and DecDCToutCallback().4
Commands
Bits 29 to 31 of the command word select the command:11
| Command | Name | Parameters |
|---|---|---|
| 0 | No function | None |
| 1 | Decode macroblock(s) | The run-level data, length in bits 0 to 15 |
| 2 | Set quant table(s) | 64 bytes, or 128 bytes when bit 0 is set |
| 3 | Set scale table | 64 signed halfwords |
| 4 to 7 | Invalid | Act as command 0 |
In every command, bits 25 to 28 are copied to status bits 23 to 26.11
MDEC(1) - Decode Macroblock
| Bits | Content |
|---|---|
| 29 to 31 | Command (1) |
| 27 to 28 | Data output depth (0 = 4-bit, 1 = 8-bit, 2 = 24-bit, 3 = 15-bit) |
| 26 | Data output signed (0 = unsigned, 1 = signed) |
| 25 | Data output bit 15 (0 = clear, 1 = set), for 15-bit depth only |
| 16 to 24 | Not used, zero |
| 0 to 15 | Number of parameter words (size of the compressed data) |
The command is followed by the macroblock data. A program normally sends all the macroblocks of a whole image at once.11
MDEC(2) - Set Quant Table
Bit 0 of the command word selects the tables. The command is followed by 64 unsigned bytes for the luminance quant table, which is used for Y1 to Y4. When bit 0 is 1 they are followed by 64 more bytes for the color quant table, which is used for Cb and Cr.11
MDEC(3) - Set Scale Table
The command is followed by 64 signed halfwords with a 14-bit fraction that define the IDCT matrix. All known programs send the standard values:11 12
5A82 5A82 5A82 5A82 5A82 5A82 5A82 5A82
7D8A 6A6D 471C 18F8 E707 B8E3 9592 8275
7641 30FB CF04 89BE 89BE CF04 30FB 7641
6A6D E707 8275 B8E3 471C 7D8A 18F8 9592
5A82 A57D A57D 5A82 5A82 A57D A57D 5A82
471C 8275 18F8 6A6D 9592 E707 7D8A B8E3
30FB 89BE 7641 CF04 CF04 7641 89BE 30FB
18F8 B8E3 6A6D 8275 7D8A 9592 471C E707
psx-spx derives the entries from scalefactor[k] = cos(k x 90/8 degrees), which is multiplied by the square root of 2 for k = 1 to 7. Each table entry is a scalefactor multiplied again by the square root of 2 and by 4000h for the 14-bit fraction. psx-spx reports that the hardware uses only the upper 13 bits of each halfword.12
MDEC(0) - No Function
Command 0 does nothing. Its bits 0 to 15 are copied to status bits 0 to 15 without the minus 1 of MDEC(1), and no parameters follow.11
Run-Level Data
Each block in the decode parameters consists of one DC halfword followed by 0 to 63 run-level halfwords and one end code:8
| Halfword | Bits 10 to 15 | Bits 0 to 9 |
|---|---|---|
| First (DCT) | Q: quantization factor (unsigned) | DC: direct current value (signed) |
| Run level | LEN: number of zero AC values to insert (unsigned) | AC: AC value (signed) |
| End of block | FE00h |
The AC values "000h, 000h, 123h" therefore become the single halfword (2 shl 10) + 123h. The end code fills the rest of the block with zero values. Most games append it even to a block whose 64 values are already complete.8
FE00h also serves as padding. At the start of a block or after an end of block it is ignored; anywhere else it ends the block.8
psx-spx describes the decoding of one block. Each value is multiplied by its quant table entry and by Q, divided by 8 with rounding, clipped to -400h to 3FFh and stored in de-zig-zag order; with Q = 0 the value is doubled and stored in order without the quant table:13
for i=0 to 63, blk[i]=0, next i
@@skip:
n=[src], src=src+2, k=0
if n=FE00h then @@skip
q_scale=(n SHR 10) AND 3Fh
val=signed10bit(n AND 3FFh)*qt[k]
@@lop:
if q_scale=0 then val=signed10bit(n AND 3FFh)*2
val=minmax(val,-400h,+3FFh)
if q_scale>0 then blk[zagzig[k]]=val
if q_scale=0 then blk[k]=val
n=[src], src=src+2
k=k+((n SHR 10) AND 3Fh)+1
val=(signed10bit(n AND 3FFh)*qt[k]*q_scale+4)/8
if k<=63 then jump @@lop
idct_core(blk)
The zig-zag order is the following, where entry x + y*8 gives the position of pixel (x, y) in the coefficient list:14
0, 1, 5, 6,14,15,27,28,
2, 4, 7,13,16,26,29,42,
3, 8,12,17,25,30,41,43,
9,11,18,24,31,40,44,53,
10,19,23,32,39,45,52,54,
20,22,33,38,46,51,55,60,
21,34,37,47,50,56,59,61,
35,36,48,49,57,58,62,63
Color Conversion
psx-spx gives the YUV to RGB conversion as follows. Each Cr and Cb value covers 2 x 2 Y pixels, and for unsigned output 128 is added to each component:15
R=(1.402*Cr)
G=(-0.3437*Cb)+(-0.7143*Cr)
B=(1.772*Cb)
R=MinMax(-128,127,(Y+R))
G=MinMax(-128,127,(Y+G))
B=MinMax(-128,127,(Y+B))
if unsigned then BGR=BGR xor 808080h
The exact fixed-point precision of the hardware conversion is not known.15 In 4-bit and 8-bit depth the Y value is clipped to signed 9 bits and then to -128 to 127. For unsigned output 128 is then added.16
Output Format
A colored macroblock is 16 x 16 pixels. Native PlayStation files arrange the macroblocks vertically, so a column of macroblocks can be sent to the GPU as one 16 x 240 rectangle.8
A monochrome macroblock is 8 x 8 pixels and is not RGB. psx-spx suggests writing it to texture memory and drawing it with a 15-bit grayscale palette of 32 levels, or converting it to 24-bit by software for 256 levels.8
Images can reach the frame buffer in two ways. With direct transmission the decoded image goes straight to the drawing area. With texture transmission it goes to the texture area first and is then drawn as a texture, and in that case the texture is limited to 16-bit mode.17
References
-
^ Sony Computer Entertainment Inc. PlayStation Hardware. August 1998. Page 1-5.
-
^ Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 7-3.
-
^ Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 7-4, Figure 7-1.
-
^ a b c d Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 7-8.
-
^ Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 7-9, Table 7-2.
-
^ a b c d Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Pages 7-6 and 7-7.
-
^ a b psx-spx. Macroblock Decoder (MDEC), MDEC Decompression. https://psx-spx.consoledev.net/macroblockdecodermdec/
-
^ a b c d e f psx-spx. Macroblock Decoder (MDEC), MDEC Data Format. https://psx-spx.consoledev.net/macroblockdecodermdec/
-
^ a b c d psx-spx. Macroblock Decoder (MDEC), MDEC I/O Ports. https://psx-spx.consoledev.net/macroblockdecodermdec/
-
^ a b psx-spx. Macroblock Decoder (MDEC), DMA. https://psx-spx.consoledev.net/macroblockdecodermdec/
-
^ a b c d e f psx-spx. Macroblock Decoder (MDEC), MDEC Commands. https://psx-spx.consoledev.net/macroblockdecodermdec/
-
^ a b psx-spx. Macroblock Decoder (MDEC), set_scale_table and scalefactor. https://psx-spx.consoledev.net/macroblockdecodermdec/
-
^ psx-spx. Macroblock Decoder (MDEC), rl_decode_block. https://psx-spx.consoledev.net/macroblockdecodermdec/
-
^ psx-spx. Macroblock Decoder (MDEC), zigzag. https://psx-spx.consoledev.net/macroblockdecodermdec/
-
^ a b psx-spx. Macroblock Decoder (MDEC), yuv_to_rgb. https://psx-spx.consoledev.net/macroblockdecodermdec/
-
^ psx-spx. Macroblock Decoder (MDEC), y_to_mono. https://psx-spx.consoledev.net/macroblockdecodermdec/
-
^ Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 7-10.