This chapter discusses the true basis for the video format compiler: the details of the native language and what the pieces do.
In “Building a Video Frame”, you see the pieces that constitute a video frame.
In “Assignment Statements”, you can learn about the expressions permitted in the video format source files.
In “The General Parameters Section”, review the basic variables that describe the overall frame.
In “The Active Line Section”, you see the parameters that describe the active lines of the frame.
In “The Field Description”, you learn how to describe most of the detail of a frame in the transitions of sync in each field.
In writing a video format in the compiler's native language, you describe the pattern of the synchronization signal pulses. You also describe the durations of each of the components of the horizontal line. Given this information, the compiler can produce a video format with which you can program the video generation hardware.
You build the video frame from one or more video fields, and each field is built by describing a series of components; the components are discussed in Chapter 3, “Building Blocks of a Video Format.” Each field must be built independently because each field describes a contiguous stand of video lines surrounded by blanking.
Usually, there is no need to write a video format completely from scratch; instead, try copying or modifying an existing format source file. For block sync formats, the Silicon Graphics standard high-resolution format is a good start. See the example below.
/* ** 1280x1024_60.vfs - SGI standard format */ General { FieldsPerFrame = 1; FramesPerSecond = 60; TotalLinesPerFrame = 1065; TotalPixelsPerLine = 1680; ActiveLinesPerFrame = 1024; ActivePixelsPerLine = 1280; FormatName = "1280x1024_60"; } Active Line { HorizontalFrontPorch = 0.372 usec; HorizontalSync = 1.12 usec; HorizontalBackPorch = 2.23 usec; } Field { Vertical Sync = { { /* * Sync goes low here (at beginning of the * line, time = 0.0) but does not recover to the * high state until the first line of Vertical * Back Porch. */ Length = 1.0H; Low = 0.0 usec; } repeat 2 { /* Two lines with no transitions */ Length = 1.0H; } } Vertical Back Porch = { { /* * Only one transition: sync goes high at the * time 1.12 usec (HorizontalSync) into the * frame. */ Length = 1.0H; High = HorizontalSync; } repeat 34 { /* * Normal horizontal sync. Goes low at time=0.0, * at beginning of the line. */ Length = 1.0H; Low = 0.0 usec; High = HorizontalSync; } } Active = { repeat 1024 { /* Normal horizontal sync */ Length = 1.0H; Low = 0.0 usec; High = HorizontalSync; } } Vertical Front Porch = { repeat 3 { /* Normal horizontal sync */ Length = 1.0H; Low = 0.0 usec; High = HorizontalSync; } } } |
The language in Example 5-1 is standard; the format is that of the Silicon Graphics standard high-resolution monitor. The layout of the information in a format must follow a special sequence.
General { /* Overall Description */ } Active Line { /* The components of the horizontal blanking */ } Field { /* Description of sync pattern for a field */ } Field { /* Description of sync pattern for a field */ } |
Example 5-2 shows the standard layout of the source file.
The General section describes the overall geometry of the frame. For details on this section, see “Assignment Statements”.
The Active Line section describes the horizontal blanking section of an active line. You can read about this section in “The Active Line Section”.
The Field section describes the pattern of sync as it transitions between high and low. You can add as many field sections as needed to describe your format, one for each field. See “The Field Description”.
The compiler executes your video source program in the order as presented in Example 5-2:
The General section.
The Active Line section.
The Field sections, in the order found in the source file.
The compiler uses assignment statements to derive much of the simple parametric information in a video format.
You specify the values in the General section via a series of assignment statements using this form:
variable = value; |
The assignment statement is one form of an expression (the formal definition of the “expression:” is in Appendix A, “Native Language Grammar”). The name of the variable you are using depends on the section you are using, so you should refer to “The General Parameters Section”, “The Active Line Section”, and “The Field Description” for details on the variables required.
Many variables in the compiler deal with absolute or relative positions in the video frame or with quantities of time. The compiler has special time expressions to deal with specifying these values.
Number of pixels. You must use the pixels suffix when specifying this. For example:
35 pixels |
Number of seconds. You must use the sec suffix for seconds, the msec suffix for milliseconds (10e-3 seconds), or the usec suffix for microseconds (10e-6) seconds. For example:
0.3 sec 55.2 msec 4.75 usec |
Number of lines. You must use the lines or the H suffix for to specify lines, as in:
5 lines 0.5 H |
Number of clock ticks. This expression, not normally used except within Silicon Graphics, specifies the duration of hardware clock ticks. The duration of the clock is often related in some way to the pixel frequency; however, it is dependent completely upon the hardware on which your format will execute. An example of the syntax is:
38 clocks |
It makes no sense to specify a non-integer number of clocks; it will be quantized to the nearest clock.
The sum of two time elements:
(38 usec + 5 pixels) |
The difference of two time elements:
(2 lines - 3 usec) |
The product of time multiplied by a scalar:
(0.5H + 0.29 usec) * 5.5 |
The quotient of a division of time by a scalar:
(25 lines + 3 pixels) / 2.0 |
For a formal definition, see “constant-time:” in Appendix A, “Native Language Grammar.”
You will usually find it more satisfactory and more transportable to use expressions specifying durations in seconds rather than in pixels or lines. The video format compiler quantizes time expression in seconds to the nearest clock group multiple without complaining; however, when quantizing time units specified in pixels or lines, the compiler will report warnings if the exact position cannot be achieved.
For details on quantization of the pixel-to-clock ratio and quantization, see “The Pixel-to-Clock Ratio”.
You may use your own variables if you wish, to supplement the compiler's variables. User-defined variables sometimes make calculations easier; they also allow you to communicate information from one section to another.
You must always define a variable before you use it. The general form for variable definition is as follows:
[ storage-class ] data-type variable-name [ = value ] ; |
The items surrounded by square brackets ([ ]) are optional. For a formal definition, see “compound-statement:” in Appendix A, “Native Language Grammar.” If you define your own variables, the definition must come before any executable statements in the compound statement block.
You have your choice of one of the following data types when defining a variable:
double—a double similar to the double in the C language. The data type is double.
time—a specific time in the frame. You specify the data type as time. Time variables can be specified in the units as described in “Time Expressions”.
string—a variable-length string. You specify the data type as string. You assign to string variables with double-quoted strings, as in "High-Resolution Format".
The video format compiler has two storage classes of variables, each with its own scope and associated lifetime:
automatic variables—these have scope of the most tightly-enclosing compound statement, a set of curly brackets ({ }); the lifetime of the variable is the time in which the block is executed. This is the default storage class when you do not specify one explicitly. For example, the time variable thirdPoint is declared below as an automatic variable:
time thirdPoint; |
exported variables—these have scope across the entire source input file and lifetime that becomes valid when the variable is first assigned and continues until the end of the program. You must specify a storage class of exported, as in the declaration below of the integer variable syncCount:
exported int syncCount; |
You may treat user variables as you would any pre-defined system variable in the program.
The General section of the video format source file gives overall information about the format. The General section is executed first so that it provides information about the format to the rest of the compiler.
You provide the information in the General section in the general form shown in Example 5-3.
Example 5-3. Example of General Section Layout
General { /* Overall Description */ assignment statement assignment statement assignment statement ... } |
The assignment statements specify the values of several system-defined variables. If you are looking for detail on assignment statements, see “Assignment Statements”; the variables are listed in Table 5-1.
Table 5-1. Values Specified in the General Section
Variable Name | Meaning | Optional |
---|---|---|
Integer. The number of fields in the video format. A field is a contiguous set of active lines surrounded by a vertical blanking interval. If a format has active video lines that cease and restart later, the format has more than one field. | No | |
Double. The number of frames to be displayed per second, to the best resolution of the hardware. The video format defines one frame; thus, the entire video format repeats at the rate specified by this variable. This value is used to establish the pixel clock. | No | |
Integer. The number of lines in the video frame, including lines in vertical blanking. This value is used to establish the pixel clock. | No | |
Integer. The number of pixels in each line of video, including pixels in horizontal blanking. This value is used to establish the pixel clock. | No | |
Integer. The number of lines in the frame buffer used by the video format. Note that this may not be the same as the total number of active lines in the frame: for single-field formats, the number of active lines in the field is the same as that drawn from the frame buffer; for multiple-field formats that are interlaced, this is the total number of lines in all fields; for multiple-field formats which repetitively fetch from the same frame buffer space for each field (such as stereo or field sequential color formats), this is the number of lines in only one of the fields. In the case of formats that contain active lines that are only a portion of a line (such as that of the NTSC and PAL half-lines), you must round each half line up to the next whole-line size. Formally stated, set this variable to the whole number of lines from which pixels are extracted, regardless of whether a whole line or just a partial line of pixels is extracted. The mechanism you use to tell the compiler whether active lines are half lines is described in | No | |
Integer. The number of pixels in one line of the frame. If the format has fields that may begin or end with half lines, supply the length of the whole line. | No | |
A descriptive name for the video format. | Yes |
See Example 5-1 for an example of actual use of the General section.
The pixel rate of the video format is expressed in pixels per second, the aggregate bandwidth of all pixels flowing from an output port of the computer system. The formula is as follows:
TotalLinesPerFrame * TotalPixelsPerLine * FramesPerSecond |
The video output hardware of your computer system has a maximum pixel rate at which it can operate. Refer to documentation on your particular system to determine the maximum rate.
Within the compiler, the pixel rate is needed to perform conversions between time and pixels. Thus, the General section is executed before any other section so conversions can be computed.
You describe the composition of the horizontal blanking in the Active Line section. It is called Active Line because these parameters describe the behavior of the horizontal blanking region on lines that contain active pixels. If you need a review of the components of the horizontal blanking region, “The Horizontal Line” describes its different sections. The active line section allows you to describe it.
You specify the Active Line section as shown in Example 5-4.
Active Line { /* Active Line Component Description */ assignment statement assignment statement assignment statement ... } |
The assignment statements specify the system-defined variables that describe the length of the components of horizontal blanking. The variables are listed in Table 5-2.
Table 5-2. Values Specified in the Active Line Section
Variable Name | Meaning | Optional |
---|---|---|
Time. The length of time of the horizontal front porch of an active line. | No | |
Time. The duration of the horizontal back porch of an active line. | No | |
Time. The duration of the horizontal sync pulse. | No |
Specify the durations of each of the components in units of seconds, milliseconds, or microseconds if possible. Placement on a specified pixel can lead to quantization; see “Quantization”.
See Example 5-1 for an example of actual use of the Active Line section.
When writing a video format, you must describe each field individually. According to “The Field of the Format”, a field consists of contiguous lines of video surrounded by vertical blanking. Therefore, each time active lines cease and start again in a format, you must define a new field.
To define the field, specify each transition of sync in the frame. You need not specify the active section because it is implied by the values you specified earlier (as shown in “The Active Line Section”); however, you must individually describe the excursions between low, high, and tri-level of the sync signal (see “Level of Sync” for definitions of these levels).
For example, Figure 3-3 shows an excerpt of a few lines of a typical frame of video. If this figure were descriptive of the format you wish to write, you would need to describe sync going from its high position to low position, then the low-to-high transition; you would need to describe these two transitions for each of the blanking regions in the diagram—and for the rest of the frame.
A field contains these general classes of description:
The field components—the major vertical sections of the field, as described in “Field Components”.
The field attributes—additional information, not related to timing, that describes a field. These are described in “Field Attributes”.
The components of the field, as described in “The Vertical Interval”, are as follows:
You must define each of these components in each field in this order.
Field { Vertical Sync = { sync transition set sync transition set sync transition set ... } Vertical Back Porch = { sync transition set ... } Active = { sync transition set ... } Vertical Front Porch = { sync transition set ... } } |
Example 5-5 shows an example of the layout you might use. The grammar is formally described in “field-definition:” in Appendix A, “Native Language Grammar.” For a real example, see Example 5-1.
You may place only sync transition sets within each of the field components. You may use as many sync transition sets as needed to describe the format. For information on this part of the language, see “Sync Transition Set”.
Be especially careful to place the proper active lines in the Active section: only and all lines placed in the active component will have active pixels on them. If the first or last line in the Active section is not a whole line (such as with the NTSC and PAL half lines), only part of the output line will have active pixels.
The sync transition set defines a set of transitions of the video sync signal on a line or portion of a line. The length of the defined line portion is a required statement, the transitions are optional (that is, it is possible to define a line with no transitions of sync).
{ /* Normal horizontal sync, one repetition */ Length = 1.0H; Low = 0.0 usec; High = 1.19 usec; } repeat 3 { /* Normal horizontal sync, three rep. */ Length = 1.0H; Low = 0.0 usec; High = 1.19 usec; } |
Two simple sync transition sets appear in Example 5-6, each set delimited by curly brackets ({ }). All repetitions are concatenated to the previous set, so you must specify the sync transition sets in the order in which they are to appear in the frame.
repeat 6 { Length = 0.5H; Low = 0 usec; High = 27.1 usec; } |
A single simple transition set is in Example 5-7.
The first sync transition set in Example 5-6 is executed once, while the second sync transition set is repeated three times; otherwise they are identical. One could have shortened the text of the definition simply by omitting the first set and specifying the repeat value of the second set as repeat 4 instead of the two separate definitions.
The sync transition set shown in Example 5-7 also has a repetition factor—it is executed six times.
If you do not specify an explicit repetition count, a sync transition set is executed once.
The repetition count can be an integer expression. See the formal grammar of “sync-transition-multiplier:” for a formal treatment.
The length of the transition set is specified with an assignment to the length variable with a duration, as in this example:
length = 0.5 lines; |
The length of the two sync transition sets of Example 5-6 are both one line, so the total length of all the sets in that example is four lines (1 line + 3(1 line) = 4 lines).
The length of the set in Example 5-7 is one half line; when the compiler performs the six repetitions, its total length is three lines.
repeat 100 { Length = 1.0 H; sync transitions... } |
The sample source code in Example 5-8 shows 100 repetitions of a one-line set. Irrespective of the sync level transitions in the set—irrespective of what changes in the sync signal on the line—the source of this example creates 100 lines of video.
Thus, the length specified is not dependent on any of the sync-level transitions. In fact, it is possible to have a sync transition set with no transitions at all, just a length. For example, see the vertical sync pulse of Figure 3-8; the pulse is more than three lines long, so it has no transitions at all for two lines. The source file for this is shown in Example 5-1, where the Vertical Sync component has two transition sets: one in which the sync transition goes low; that set is followed by two repetitions of the set where no transitions occur at all—only the length.
The sync-level statements specify the time at which the sync transition changes level (sync levels are defined in “Level of Sync”). You use this form:
level = time-expression; |
The level can be high, low, or tri.
The time-expression is a time constant (see “Time Expressions”) or a time variable. When you use time variables, you can make your source program easier to read and less prone to error. In so doing, you document why sync is making a transition (by using a descriptive name) and make cut-and-paste errors less likely than explicitly using time values (because the text of variable names cannot be corrupted without the compiler reporting an error).
For an example of using variables, see Example 5-1: it uses the variable HorizontalSync, described in “The Active Line Section”. In that example, most of the sync transitions (all but those in the vertical sync) make a transition to low at the beginning of the line (0.0 usec). The sync transitions that define the point at which sync make the transition to the high state do not specify a time constant but instead refer to the HorizontalSync variable.
Each field can have attributes assigned individually to it. These attributes describe features of the frame not related to timing, such as how pixels should be fetched from the frame buffer.
Each attribute is set before any of the components of the field are specified. The components of the field are Vertical Sync, Vertical Back Porch, Vertical Active, Vertical Front Porch (see “Field Components”). The attributes are set via an assignment statement of this form:
attribute = value; |
You can assign the attributes directly, or not specify them and allow the compiler to use default values.