Using Video Output Components

This section explains how to use video output components in your software.

Video output components are standard components that are managed by the Component Manager. Their component type is QTVideoOutputComponentType.

Apple has defined a functional interface for video output components. For each function of a video output component, there is a selector constant. These constants are listed in the next section.

Selectors for Video Output Component Functions

The following constants are the selectors for functions of a video output component.

enum {
    kQTVideoOutputGetDisplayModeListSelect = 0x0001,
    kQTVideoOutputGetCurrentClientNameSelect = 0x0002,
    kQTVideoOutputSetClientNameSelect = 0x0003,
    kQTVideoOutputGetClientNameSelect = 0x0004,
    kQTVideoOutputBeginSelect = 0x0005,
    kQTVideoOutputEndSelect = 0x0006,
    kQTVideoOutputSetDisplayModeSelect = 0x0007,
    kQTVideoOutputGetDisplayModeSelect = 0x0008,
    kQTVideoOutputCustomConfigureDisplaySelect = 0x0009,
    kQTVideoOutputSaveStateSelect = 0x000A,
    kQTVideoOutputRestoreStateSelect = 0x000B,
    kQTVideoOutputGetGWorldSelect = 0x000C,
    kQTVideoOutputGetGWorldParametersSelect = 0x000D,
    kQTVideoOutputGetIndSoundOutputSelect = 0x000E,
    kQTVideoOutputGetClockSelect = 0x000F,
    kQTVideoOutputSetEchoPortSelect = 0x0010
};

Selecting a Video Output Component

Listing 4-1 shows how to assemble a list of available video output components using the FindNextComponent function. This list can then be presented to the user.

The base video output component is a special component that provides services to other video output components. It is never connected to a display, and it has a component flag, kQTVideoOutputDontDisplayToUser, that indicates that it should not be included in a list of available video output components. The sample code shows how to check for this flag.

Listing 4-1  Displaying available video output components

ComponentDescription cd;
Component c = 0;
cd.componentType = QTVideoOutputComponentType;
cd.componentSubType = 0;
cd.componentManufacturer = 0;
cd.componentFlags = 0;
cd.componentFlagsMask = kQTVideoOutputDontDisplayToUser;
while (c = FindNextComponent (c, &cd)) {
    Handle nameHandle = NewHandle (0);
    GetComponentInfo (c, &cd, nameHandle, nil, nil);
    // add name to list
    DisposeHandle (nameHandle);
}

Choosing a Display Mode

After a video output component is chosen, the next step is to choose one of the component’s available display modes. Your software does this by getting the QT atom container that contains descriptions of the available modes by calling the QTVideoOutputGetDisplayModeList function, traversing the atom container’s contents using the QTFindChildByIndex function, examining the characteristics of each mode and setting aside any modes that are not appropriate for your software, and then optionally presenting a list of modes to the user to select from.

If your software does present a list of display modes to the user, it can obtain a string that describes each mode from the mode’s kQTVOName atom with an ID of 1. The string doesn’t include a leading length byte or a trailing null. Your software can determine the length of the string from the size of the atom.

When the mode has been chosen, your software calls the QTVideoOutputSetDisplayMode function to set the display mode.

Of display mode’s characteristics, the most important is whether the mode can display the video data. This is determined by the availability of a decompressor component that takes the video data as input and converts it to the type of data, specified by the kQTVOPixelType atom, required by the video output device. If a video output device can directly display one of the supported QuickTime pixel formats, the necessary decompressor component is included in QuickTime. If special decompressor components are required for the video output device, such as JPEG or other decompressors that deliver data directly to the video output hardware without creating a new pixel format, these decompressor components are described in kQTVODecompressors atoms.

Contents of the Display Mode QT Atom Container

To obtain descriptions of the display modes, your software must traverse QT atom containers. At the root of the QT atom container returned by the QTVideoOutputGetDisplayModeList function are one or more atoms of type kQTVODisplayModeItem, each containing a definition of a display mode. Your software can traverse the display mode atoms by calling the QTFindChildByIndex function.

Within each kQTVODisplayModeItem atom are the following atoms:

By storing resolutions rather than an aspect ratio, QuickTime makes it easy for your software to compare values with values in QuickTime ImageDescription records. Your software can calculate the aspect ratio for the display mode by dividing the value for the horizontal resolution by the value for the vertical resolution.

Because kQTVODecompressors atoms are not required to have consecutive IDs, your software must use the QTFindChildByIndex function to iterate through the decompressors.

Within each kQTVODecompressors atom are one or more atoms:

Drawing to an Echo Port

Some video output devices can display video simultaneously on an external video display and in a window on a computer’s desktop. To use this feature, your software draws to a graphics port for the window on the computer’s desktop, known as the echo port, rather than the port that is normally used for the video output device. The video then appears on both displays, although in some cases the video on the desktop is displayed at a smaller size or lower frame rate.

To draw to both outputs at the same time, do the following:

This process is shown in Listing 4-2.

Listing 4-2  Drawing to an echo port

Movie               aMovie;
ComponentInstance   ci;
CGrafPtr            thePort;
/* instantiation of the video output component here */
/* creation of the graphics port here */
if (ComponentFunctionImplemented(ci, kQTVideoOutputSetEchoPortSelect)) {
    result = QTVideoOutputSetEchoPort(ci, thePort);
    SetMovieGWorld (aMovie, thePort, nil);
    StartMovie (aMovie);
}

The video then appears on both displays. Note that you bypass the graphics world that is normally used for the video output device; your software draws only to the echo port you specify with the QTVideoOutputSetEchoPort function.