Besides video and sound, the tracks met in today’s MOV files are timecode, closed
captions, subtitles and timed metadata. Each uses the base media header
(gmhd) and its own sample description in
stsd. Sample description
offsets count from the start of the entry, whose first 16 bytes are the common header.
Timecode (tmcd)
Handler and data format tmcd. A video or sound track points to its timecode
track with a tmcd track reference.
| Offset | Size | Name | Meaning |
|---|---|---|---|
| 16 | 4 | reserved | 0. |
| 20 | 4 | flags | Bit flags, below. |
| 24 | 4 | time scale | Units per second for the frame duration. |
| 28 | 4 | frame duration | Length of one frame in those units (for 29.97 frame/s, time scale 30000 and duration 1001). |
| 32 | 1 | number of frames | Frames per second of the timecode (30 for 29.97); for a counter, frames per counter tick. |
| 33 | 1 | reserved | 0. |
| 34 | varies | source reference | Optional user data atom; its only used item is name, the name of the source tape. |
| Flag | Name | Meaning |
|---|---|---|
| 0x0001 | Drop frame | Drop-frame timecode. |
| 0x0002 | 24 hour max | The timecode wraps after 24 hours. |
| 0x0004 | Negative times OK | Negative times are allowed. |
| 0x0008 | Counter | Values are tape counter values, not timecode. |
Each sample is 4 bytes. With the counter flag, it is a uint32 that, divided by the number of frames, gives the counter value. Otherwise it is an int32 frame number from which the timecode record is worked out: hours (8 bits), a negative sign (1 bit), minutes (7 bits), seconds (8 bits) and frames (8 bits).
tcmi
The timecode media information atom, inside the track’s gmhd (writers place
it in a tmcd atom there), says how to draw the timecode as text:
| Offset | Size | Name | Meaning |
|---|---|---|---|
| 8 | 1 | version | 0. |
| 9 | 3 | flags | 0. |
| 12 | 2 | text font | Font number; 0 for the system font. Ignored if the font name is valid. |
| 14 | 2 | text face | Style bits: 0x0001 bold, 0x0002 italic, 0x0004 underline, 0x0008 outline, 0x0010 shadow, 0x0020 condense, 0x0040 extend; 0 for plain. |
| 16 | 2 | text size | Point size. |
| 18 | 2 | reserved | 0. |
| 20 | 6 | text colour | RGB, three uint16. |
| 26 | 6 | background colour | RGB. |
| 32 | varies | font name | Pascal string. |
Closed captions (clcp)
Handler clcp. The sample description adds no fields; its data format is
c608 (CEA-608) or c708 (CEA-708), one format per track. Other
formats are undefined and ignored. Each sample is a sequence of atoms, at least one being
cdat, whose data is one or more byte pairs for channel 1, field 1 (CC1) of a
CEA-608 stream, one pair per video frame. Unknown atoms in a sample are skipped. A video
track points to its caption track with a clcp track reference.
Subtitles (sbtl, tx3g)
Handler sbtl, one sample description per track, data format
tx3g. The description is based on the 3GPP timed text sample entry (TS 26.245),
and the layout below follows it; Apple marks several of these fields reserved.
| Offset | Size | Name | Meaning |
|---|---|---|---|
| 16 | 4 | display flags | Bit flags, below. |
| 20 | 1 | horizontal justification | Reserved in Apple’s subtitle media. |
| 21 | 1 | vertical justification | Reserved in Apple’s subtitle media. |
| 22 | 4 | background colour | RGBA; reserved in Apple’s subtitle media. |
| 26 | 8 | default text box | Top, left, bottom, right (int16 each). Must fill the track: 0, 0, track height, track width. |
| 34 | 2 | start character | Of the default style; reserved. |
| 36 | 2 | end character | Of the default style; reserved. |
| 38 | 2 | font ID | Must match the font in ftab. |
| 40 | 1 | font face | 0 plain; 0x01 bold, 0x02 italic, 0x04 underline. |
| 41 | 1 | font size | Points; should be 0.05 × the video track height (36 for 720). |
| 42 | 4 | foreground colour | RGBA, 8 bits each; (255, 255, 255, 255) is opaque white. |
| 46 | varies | ftab | Font table atom. |
| Display flag | Meaning |
|---|---|
| 0x20000000 | Vertical placement: place the text by the top of a sample’s tbox; otherwise subtitles sit at the bottom of the video. |
| 0x40000000 | Some samples are forced (contain frcd). |
| 0x80000000 | All samples are forced. Must be set with 0x40000000, giving 0xC0000000. |
ftab: entry count (uint16, must be 1), then for each font a font ID (uint16),
name length (uint8) and name, which must be Serif or
Sans-Serif.
Subtitle samples
A uint16 text length, the text (UTF-8, or UTF-16 starting with a byte-order mark in either byte order, not null-terminated), then optional atoms:
| Atom | Meaning |
|---|---|
frcd | No data. This sample is a forced subtitle, shown without the user choosing subtitles (for example foreign dialogue in a dubbed film). |
styl | Style runs: entry count (uint16), then records of start character (uint16), end character (uint16, the character after the run), font ID (uint16), font face (uint8), font size (uint8) and foreground RGBA (4 bytes). Apple’s description of the record leaves out the font ID, which 3GPP’s 12-byte record has. |
tbox | A text box (top, left, bottom, right) overriding the default, used only with display flag 0x20000000, and then only its top; it must span the track’s width. |
twrp | Text wrap, one byte: 0 none, 1 automatic soft wrap. |
A regular subtitle track refers to its forced companion with a forc track
reference. Apple’s older text media (handler text, with a text
atom holding an identity matrix in gmhd) is not described on this page.
Timed metadata (meta, mebx)
Handler meta, data format mebx. The sample description holds a
required key table keys and an optional bit rate atom btrt. Other
formats would use another data format code. A timed metadata track that describes other
tracks points to them with cdsc references; one that describes the whole movie
has none.
| Atom | Contents |
|---|---|
keys | One metadata key atom per key that samples may use. |
| key atom | Its type is the local_key_id, any 32-bit value (a mnemonic FourCC is recommended). 0 marks an unused key; 0xFFFFFFFF must not be used. It holds a required keyd, and optionally dtyp and loca. |
keyd | Key namespace (uint32) and key value (bytes to the end). For example namespace mdta with the reverse-DNS key com.apple.quicktime.location.ISO6709; see Metadata. |
dtyp | Datatype namespace (uint32) and datatype. Namespace 0: a uint32 well-known type (1 is UTF-8, 23 is float32). Namespace 1: a reverse-DNS UTF-8 type name, no terminator. Values of unknown types are ignored. |
loca | Null-terminated UTF-8 BCP 47 locale such as en-US. Absent means all locales. |
btrt | Buffer size, maximum bit rate and average bit rate, each uint32. |
Each sample is a run of atoms whose types are local_key_id values, each
holding one value for that key at that time. Type 0 is a placeholder with no set contents;
0xFFFFFFFF is reserved and ignored. A key with no atom in a sample has no value at that
time; values do not carry over from earlier samples. All metadata samples are sync samples,
and none may be empty, so a gap is filled with a sample holding no keyed atoms. For
example, key wher with value +27.5916+086.5640+8850/ gives an
ISO 6709 location.