One subtitle is one DVD subpicture unit (SPU), held in the packets of the .sub file and up to 53,220 bytes long. Each multi-byte value is big-endian. This page follows the public DVD subpicture reference.
Unit layout
The unit starts with a header. The other three areas are located through offsets and can in principle appear in any order; the usual order is top field, bottom field, then the control sequences.
| Offset | Size | Name | Meaning |
|---|---|---|---|
0 | 2 | SPDSZ | Total size of the unit, which may span packets. |
2 | 2 | SP_DCSQTA | Offset from the start of the unit to the first control sequence. |
| variable | PXDtf | Run-length pixels of the top field (odd lines). | |
| variable | PXDbf | Run-length pixels of the bottom field (even lines). | |
| variable | SP_DCSQT | The display control sequences. |
Pixel data
Each pixel has one of four 2-bit values: 0 background, 1
pattern, 2 emphasis 1, 3 emphasis 2. The code form depends on
the run length.
| Run length | Code size | Bits |
|---|---|---|
| 1–3 | 4 bits | n n c c |
| 4–15 | 8 bits | 0 0 n n n n c c |
| 16–63 | 12 bits | 0 0 0 0 n n n n n n c c |
| 64–255 | 16 bits | 0 0 0 0 0 0 n n n n n n n n c c |
| rest of line | 16 bits | The 16-bit form with a run of zero fills the rest of the line with colour c. |
If the bits of a line do not end on a byte boundary, four fill bits of 0 are appended.
Control sequences
The table is a chain of control sequences. Each starts with a 4-byte header.
| Offset | Size | Name | Meaning |
|---|---|---|---|
0 | 2 | SP_DCSQ_STM | Delay before the sequence runs, in units of the 90 kHz clock divided by 1024. To convert from seconds, multiply by 90000/1024, about 87.89, and truncate. |
2 | 2 | SP_NXT_DCSQ_SA | Offset of the next sequence from the start of the unit. The last sequence points to itself. |
Commands follow until CMD_END. The first sequence must set the colours,
contrast, display area and field addresses.
| Code | Name | Argument bytes | Meaning |
|---|---|---|---|
00 | FSTA_DSP | 0 | Forced start of display. |
01 | STA_DSP | 0 | Start display. |
02 | STP_DSP | 0 | Stop display. |
03 | SET_COLOR | 2 | Four 4-bit palette indexes, one nibble each: emphasis 2, emphasis 1, pattern, background. |
04 | SET_CONTR | 2 | Four 4-bit contrasts in the same order. 0 is transparent and F is opaque. |
05 | SET_DAREA | 6 | Display area: start X, end X, start Y, end Y, 12 bits each. |
06 | SET_DSPXA | 4 | Offsets of the top and bottom pixel data, 2 bytes each. |
07 | CHG_COLCON | variable | Changes colours and contrast within parts of the display; see below. |
FF | CMD_END | 0 | Ends this control sequence. |
CHG_COLCON
Its argument area starts with a 2-byte size that includes those two bytes, followed by bands.
| Item | Size | Layout |
|---|---|---|
LN_CTLI | 4 bytes | One nibble 0, then 12-bit csln (the first line of the band), one nibble n (1–15 entries follow), then 12-bit ctln (the last line). |
PX_CTLI | 6 bytes each | A 2-byte starting column, then 2 bytes in SET_COLOR form and 2 bytes in SET_CONTR form. Applies from this column to the next entry or the edge of the area. |
| Terminator | 4 bytes | 0F FF FF FF in place of an LN_CTLI. It is required. |
Worked example
04 ec 04 c8 SPDSZ = 0x04EC, SP_DCSQTA = 0x04C8
… pixel data …
00 00 04 c8 delay 0, next sequence points to itself (last)
03 01 23 SET_COLOR: emphasis 2 = 0, emphasis 1 = 1, pattern = 2, background = 3
04 ff f0 SET_CONTR: first three opaque, background transparent
05 00 02 cf 01 e0 3f SET_DAREA: x 0 to 719, y 480 to 575 (0x000 0x2CF 0x1E0 0x23F)
06 00 04 01 84 SET_DSPXA: top field at 4, bottom at 0x184
01 STA_DSP
ff CMD_END