Vertical Blanking Interval (VBI) Information
Laserdiscs have things like frame numbers and stop codes encoded in the VBI portion of the NTSC (or PAL) signal. This info is available in the official laserdisc standard documents (IEC 60856 and 60857) and is summarized here.
From LD-V6000 technical info manual (a little vague), for NTSC: http://www.daphne-emu.com/graphics/laserdisc-philips-codes.png
24-bit biphase coded signal
A 24-bit value can be stored on one line, and laserdiscs have various 24-bit values stored that represent various things. Each 24-bit value must have the most significant bit set to 1 by definition. The first four bits of each value is the "key", and the first bit after the first nibble is the 'stop bit' (see more about this below). From the official laserdisc standard, Each 'bit cell' is 2 microseconds long with the digital level between 0 and 100 IRE. This means that the 24 bits will take 48 micro seconds. An IRE of 0 basically means as black (dark) as possible, and an IRE of 100 means as white (bright) as possible. You can read more about it here: http://en.wikipedia.org/wiki/IRE_(unit)
The bits for each 24-bit value are encoded using a scheme known as Manchester code, which you can read about here: http://en.wikipedia.org/wiki/Manchester_code . Manchester code is a clever scheme for encoding both bits and a clock pulse in one medium (in this case, the medium would be a line on the laserdisc). Each bit must contain a transition from low to high or from high to low. Knowing this, one can look at a line and see where each bit starts and stops fairly easily, especially if drawing red lines like I do below.
This screenshot represents line 17 of frame 587 from the Dragon's Lair NTSC laserdisc. It has been stretched vertically to make is easier to see. It resolves to a value of F80578. The red lines (not present on the video signal) show where the boundary of each bit cell is. Notice that there is black space before and after the bit cells. This is one reason why the first bit must always be a 1, so that the first bit cell can be reliably found.
24-bit values (NTSC)
|Description||24-bit value||Lines NTSC||Lines PAL|
|Lead-In||88FFFF||17, 18, 280, and 281||17, 18, 330, and 331|
|Lead-Out||80EEEE||17, 18, 280, and 281||17, 18, 330, and 331|
|Picture Number (frame number)||NTSC: A BCD-encoded number OR'd with (0xF00000 OR (bNoStop << 19)), where bNoStop is 1 if we don't want to stop or 0 if we do. For example, picture number of 10 with bNoStop set, would be 0xF80010. Maximum picture number is 79999. NOTE : I have yet to find a laserdisc player that honors bit 19 (ie they all seem to ignore it). See IEC 60857, section 10.1.4 for more info about this bit.
PAL: A BCD-encoded number OR'd with (0xF00000). Max picture number is 99999.
|(17 and 18) or (280 and 281) depending on which field is the first field for the picture.||(17 and 18) or (330 and 331) depending on which field is the first field for the picture.|
|Picture Stop Code||0x82CFFF. Must come one field after a picture number code, to enable stopping on that picture.||(16 and 17) or (279 and 280).||(16 and 17) or (329 and 330).|
|Chapter Number||A BCD-encoded number shifted left by 12 bits and OR'd with (0x800DDD OR (bNoStop << 19)), where bNoStop is 0 for the first 400 tracks of a chapter and 1 thereafter (so that it's easy for the laserdisc player to find chapter boundaries while searching). For example, a chapter number of 1, with bNoStop set would be 0x881DDD. Maximum chapter number is 79. See IEC 60857, section 10.1.5 for more info about the chapter number encoding.||17, 18, 280, and 281 of active fields that do not have picture numbers. Stop codes also take precedence for lines 17 and 280.||17, 18, 330, and 331 of active fields that do not have picture numbers. Stop codes also take precedence for lines 17 and 330.|
VBI File Format
Here is a basic file format for storing VBI information.
24-bit value convention
Much of the VBI information is stored as 24-bit values. For our purposes, we will store these values in big-endian format (to make it easy to read from a hex editor). Also, a black line will be stored as 0. A non-black line which could not be parsed (for example, due to an error on the disc) will be stored as 0x7FFFFF which should not conflict with any valid data (because all valid data must have the most significant bit set).
|0-3||The bytes "1VBI" as a version header.|
|4+N||Bit 0 is set if this field contains a white flag (line 11 or 274 depending on the field). Only applies to NTSC and is always 0 for PAL. All other bits are reserved and should be 0.|
|5+N to 7+N||This field's 24-bit value for line 16/279|
|8+N to 10+N||This field's 24-bit value for line 17/280|
|11+N to 13+N||This field's 24-bit value for line 18/281|
N is defined as the field index (starting with 0) multiplied by the size of one VBI entry (10 bytes in this case). So the first set of VBI data starts at 4 because (0*10) is 0, and the header's size is 4. The second set (index 1) would start at offset 14 beceause (1*10) is 10, and the header's size is 4.
Should the 'most plausible' value for line 17 and 18 be stored?
MAME's code stores the most plausible value for line 17/18 because lines 17 and 18 are used to store picture numbers, and they are both supposed to contain the same data. If one of them can't be parsed, the other one can hopefully be used to obtain the required data. At first, I decided to follow this convention and store the most plausible value for lines 17 and 18. But then I started thinking about how stop codes are stored on lines 16 and 17 and the chapter codes can be mingled with stop codes, and I started realizing that three lines must be looked at for each field, not just two. Therefore, the benefit of storing the best value for lines 17/18 (which was always about performance in my mind) was lost. So my new solution is to just store the parsed VBI data and to compute the actual frame numbers and stop codes at run-time when the VBI data is first loaded.