Sequence Grabber Components

Relationships among your application, a sequence grabber component, and channel components

Sequence grabber components allow applications to obtain digitized data from sources that are external to a Macintosh computer. For example, you can use a sequence grabber component to record video data from a video digitizer. Your application can then request that the sequence grabber store the captured video data in a QuickTime movie. In this manner, you can acquire movie data from various sources that can augment the movie data you create by other means, such as computer animation. You can also use sequence grabber components to obtain and display data from external sources, without saving the captured data in a movie.

The sequence grabber component provided by Apple allows applications to capture both audio and video data easily, without concern for the details of how the data is acquired. When capturing video data, this sequence grabber uses a video digitizer component to supply the digitized video images (see About Video Digitizer Components for more information about video digitizer components). When working with audio data, Apple’s sequence grabber component retrieves its sound data from a sound input device.

Sequence grabber components use sequence grabber channel components (or, simply, channel components) to obtain data from the audio- or video-digitizing equipment. These components isolate the sequence grabber from the details of working with the various types of data that can be collected. The features that a sequence grabber component supplies are dependent on the services provided by sequence grabber channel components. The channel components, in turn, may use other components to interact with the digitizing equipment. For example, the video channel component supplied by Apple uses a video digitizer component. Figure 2-1 shows the relationship between these components and your application.

Sequence grabber panel components augment the capabilities of sequence grabber components and sequence grabber channel components by allowing sequence grabbers to obtain configuration information from the user for a particular digitizing source. Sequence grabbers present a settings dialog box to the user whenever an application calls the SGSettingsDialog function (see Working With Sequence Grabber Settings for more information about this sequence grabber function). Applications never call sequence grabber panel components directly; application developers use panel components only by calling the sequence grabber component. See the chapter Sequence Grabber Panel Components for more information about the sequence grabber configuration dialog box and the relationships of sequence grabbers, sequence grabber channels, and sequence grabber panels.

If you are developing digitizing equipment and you want to allow applications to use the services of your equipment with a sequence grabber component, you should create an appropriate video digitizer component or sound input device driver.

If you are developing equipment that provides a new type of data to QuickTime, you should develop a new sequence grabber channel component. See Sequence Grabber Channel Components for a description of sequence grabber channel components.

Working With Sequence Grabber Settings

Sequence grabber components can work with channel components and panel components to collect configuration settings from the user. The functions discussed in this section allow you to direct the sequence grabber to display its settings dialog box to the user and to work with the configuration of each of the grabber’s channels.

Use the SGSettingsDialog function to instruct the sequence grabber to display its settings dialog box to the user.

The SGSetSettings and SGGetSettings functions allow you to retrieve or set the sequence grabber’s configuration.

The SGSetChannelSettings and SGGetChannelSettings functions work with the configuration of an individual channel.

Features of Sequence Grabber Components

Sequence grabber components allow you to assign a specific file to each channel. This allows you to collect data into more than one file at a time, which can result in improved performance by defining the files for different channels on different devices. These destination containers are referred to as sequence grabber outputs. See Working with Sequence Grabber Outputs for a complete discussion.

Sequence grabber components use data handler components when writing movie data. This provides greater flexibility, especially when working with special storage devices such as networks.

A sequence grabber automatically creates a timecode track if the video digitizer component contains timecode information. To support timecode tracks, the sequence grabber also provides two functions that let you identify the source information associated with video data that contains timecode information.

Working with Sequence Grabber Outputs

In order to allow sequence grabber components to capture to more than one data reference at a time, QuickTime supports the concept of a sequence grabber output. A sequence grabber output ties a sequence grabber channel to a specified data reference for the output of captured data.

If you are capturing to a single movie file, you can continue to use the SGSetDataOutput function (or the SGSetDataRef function) to specify the sequence grabber’s destination. However, if you want to capture movie data into several different files or data references, you must use sequence grabber outputs to do so. Even if you are using outputs, you must still use the SGSetDataOutput function or the SGSetDataRef function to identify where the sequence grabber should create the movie resource.

You are responsible for creating outputs, assigning them to sequence grabber channels, and disposing of them when you are done. Sequence grabber components provide a number of functions for managing outputs:

Storing Captured Data in Multiple Files

In QuickTime, the sequence grabber allows a single capture session to store the captured data across multiple files. Each channel of a capture can be placed in a separate file. In this way, sound and video can be captured to separate files, even on separate devices. It is also possible to have a single capture session place its data on several different devices in sequence. As a result, several different devices can be used in a single capture session. This enables data capture to exceed any file size limitation imposed by a file system.

Application Examples

The first step in implementing multiple sequence grabber outputs during a single capture session is to create all the sequence grabber outputs. Once the outputs have been created, they must be linked together. This is done using the new SGSetOutputNextOutput routine. The linked outputs are used in link order. An example of creating and linking two sequence grabber outputs is shown in Listing 2-1.

Listing 2-1  Creating and linking sequence grabber outputs

 
OSErr FSSpecToSGOutput(SeqGrabComponent theSG, FSSpec *fss,
    SGOutput *output)
{
    OSErr err;
    AliasHandle alias = nil;
    err = QTNewAlias(&fss, &alias, true);
    err = SGNewOutput(theSG, (Handle)alias, rAliasType,
        seqGrabToDisk, output);
    FSSpec fss;
    SGOutput output1, output2;
    // create an FSSpec for the first file
    FSMakeFSSpec(0, 0, "\pMacintosh HD:Movie 1", &fss);
    // create the output for the first file
    FSSpecToSGOutput(theSG, &fss, &output1)
    // create an FSSpec for the second file
    FSMakeFSSpec(0, 0, "\pMacintosh HD:Movie 2", &fss);
    //create the output for the second file
    FSSpecToSGOutput(theSG, &fss, &output2)
    // direct the movie resource to the first file
    err = SGSetDataOutput(theSG, fss, seqGrabToDisk);
    if (err) goto exit;
    // finally, link the outputs
    SGSetOutputNextOutput(theSG, output1, output2);
}

In this example two separate outputs are created. Once these outputs are created, they are linked together using SGSetOutputNextOutput. The output output1 is used first. Once that output is full, output2 is used.

Once outputs are created, they must be associated with the sequence grabber channels that write data to these outputs. Listing 2-2 shows how this can be accomplished. This example shows how to associate the outputs created in Listing 2-1 with both a sound and a video channel.

Listing 2-2  Associating outputs with channels

 
//associate both sound and video channels with all linked outputs
SGSetChannelOutput(theSG, soundChannel, output1);
SGSetChannelOutput(theSG, videoChannel, output1);

You can limit output files to a particular size by specifying the maximum number of bytes to be written to a given sequence grabber output. Listing 1-3 shows an example of setting a maximum offset of 64 KB for data written to an output.

Listing 2-3  Specifying maximum data offset for an output

 
wide maxOffset;
maxOffset.hi = 0;
//set the offset to 64K
maxOffset.lo = 64 * 1024;
SGSetOutputMaximumOffset(theSG, output1, &maxOffset);

Using Sequence Grabber Components

Sequence grabber components are standard components that are managed by the Component Manager.

The sequence grabber component provides functions that give your application precise control over the display of the captured data. This section describes how to use the basic sequence grabber component functions as well as the functions that allow you to configure video and sound channels.

Apple has defined a component type value for sequence grabber components; that type value is 'barg'. You can use the following constant to specify this type value.

#define SeqGrabComponentType 'barg'/* sequence grabber component type */

Apple has defined a functional interface for basic sequence grabber components. For information about the functions a sequence grabber component may support, see Sequence Grabber Component Functions.

You can use the following constants to refer to the request codes for each of the functions that a sequence grabber component may support.

enum {
    /* selectors for basic sequence grabber component functions */
    kSGInitializeSelect                         = 0x1;
    kSGSetDataOutputSelect                      = 0x2;
    kSGGetDataOutputSelect                      = 0x3;
    kSGSetGWorldSelect                          = 0x4;
    kSGGetGWorldSelect                          = 0x5;
    kSGNewChannelSelect                         = 0x6;
    kSGDisposeChannelSelect                     = 0x7;
    kSGStartPreviewSelect                       = 0x10;
    kSGStartRecordSelect                        = 0x11;
    kSGIdleSelect                               = 0x12;
    kSGStopSelect                               = 0x13;
    kSGPauseSelect                              = 0x14;
    kSGPrepareSelect                            = 0x15;
    kSGReleaseSelect                            = 0x16;
    kSGGetMovieSelect                           = 0x17;
    kSGSetMaximumRecordTimeSelect               = 0x18;
    kSGGetMaximumRecordTimeSelect               = 0x19;
    kSGGetStorageSpaceRemainingSelect           = 0x1a;
    kSGGetTimeRemainingSelect                   = 0x1b;
    kSGGrabPictSelect                           = 0x1c;
    kSGGetLastMovieResIDSelect                  = 0x1d;
    kSGSetFlagsSelect                           = 0x1e;
    kSGGetFlagsSelect                           = 0x1f;
    kSGSetDataProcSelect                        = 0x20;
    kSGNewChannelFromComponentSelect            = 0x21;
    kSGDisposeDeviceListSelect                  = 0x22;
    kSGAppendDeviceListToMenuSelect             = 0x23;
    kSGSetSettingsSelect                        = 0x24;
    kSGGetSettingsSelect                        = 0x25;
    kSGGetIndChannelSelect                      = 0x26;
    kSGUpdateSelect                             = 0x27;
    kSGGetPauseSelect                           = 0x28;
    kSGSettingsDialogSelect                     = 0x29;
    kSGGetAlignmentProcSelect                   = 0x2A;
    kSGSetChannelSettingsSelect                 = 0x2B;
    kSGGetChannelSettingsSelect                 = 0x2C;
 
    /* selectors for common channel configuration functions */
    kSGCSetChannelUsageSelect                   = 0x80;
    kSGCGetChannelUsageSelect                   = 0x81;
    kSGCSetChannelBoundsSelect                  = 0x82;
    kSGCGetChannelBoundsSelect                  = 0x83;
    kSGCSetChannelVolumeSelect                  = 0x84;
    kSGCGetChannelVolumeSelect                  = 0x85;
    kSGCGetChannelInfoSelect                    = 0x86;
    kSGCSetChannelPlayFlagsSelect               = 0x87;
    kSGCGetChannelPlayFlagsSelect               = 0x88;
    kSGCSetChannelMaxFramesSelect               = 0x89;
    kSGCGetChannelMaxFramesSelect               = 0x8a;
    kSGCSetChannelRefConSelect                  = 0x8b;
    kSGCSetChannelClipSelect                    = 0x8C;
    kSGCGetChannelClipSelect                    = 0x8D;
    kSGCGetChannelSampleDescriptionSelect       = 0x8E;
    kSGCGetChannelDeviceListSelect              = 0x8F;
    kSGCSetChannelDeviceSelect                  = 0x90;
    kSGCSetChannelMatrixSelect                  = 0x91;
    kSGCGetChannelMatrixSelect                  = 0x92;
    kSGCGetChannelTimeScaleSelect               = 0x93;
 
    /* selectors for video channel configuration functions */
    kSGCGetSrcVideoBoundsSelect                 = 0x100;
    kSGCSetVideoRectSelect                      = 0x101;
    kSGCGetVideoRectSelect                      = 0x102;
    kSGCGetVideoCompressorTypeSelect            = 0x103;
    kSGCSetVideoCompressorTypeSelect            = 0x104;
    kSGCSetVideoCompressorSelect                = 0x105;
    kSGCGetVideoCompressorSelect                = 0x106;
    kSGCGetVideoDigitizerComponentSelect        = 0x107;
    kSGCSetVideoDigitizerComponentSelect        = 0x108;
    kSGCVideoDigitizerChangedSelect             = 0x109;
    kSGCSetVideoBottlenecksSelect               = 0x10a;
    kSGCGetVideoBottlenecksSelect               = 0x10b;
    kSGCGrabFrameSelect                         = 0x10c;
    kSGCGrabFrameCompleteSelect                 = 0x10d;
    kSGCDisplayFrameSelect                      = 0x10e;
    kSGCCompressFrameSelect                     = 0x10f;
    kSGCCompressFrameCompleteSelect             = 0x110;
    kSGCAddFrameSelect                          = 0x111;
    kSGCTransferFrameForCompressSelect          = 0x112;
    kSGCSetCompressBufferSelect                 = 0x113;
    kSGCGetCompressBufferSelect                 = 0x114;
    kSGCGetBufferInfoSelect                     = 0x115;
    kSGCSetUseScreenBufferSelect                = 0x116;
    kSGCGetUseScreenBufferSelect                = 0x117;
    kSGCGrabCompressCompleteSelect              = 0x118;
    kSGCDisplayCompressSelect                   = 0x119;
    kSGCSetFrameRateSelect                      = 0x11A;
    kSGCGetFrameRateSelect                      = 0x11B;
 
    /* selectors for sound channel configuration functions */
    kSGCSetSoundInputDriverSelect               = 0x100;
    kSGCGetSoundInputDriverSelect               = 0x101;
    kSGCSoundInputDriverChangedSelect           = 0x102;
    kSGCSetSoundRecordChunkSizeSelect           = 0x103;
    kSGCGetSoundRecordChunkSizeSelect           = 0x104;
    kSGCSetSoundInputRateSelect                 = 0x105;
    kSGCGetSoundInputRateSelect                 = 0x106;
    kSGCSetSoundInputParametersSelect           = 0x107;
    kSGCGetSoundInputParametersSelect           = 0x108;
 
    /* selectors for utility functions provided to channel components */
    kSGWriteMovieData                           = 0x100;
    kSGAddFrameReferenceSelect                  = 0x101;
    kSGGetNextFrameReferenceSelect              = 0x102;
    kSGGetTimeBaseSelect                        = 0x103;
    kSGSortDeviceListSelect                     = 0x104;
    kSGAddMovieDataSelect                       = 0x105;
    kSGChangedSourceSelect                      = 0x106;
};