Getting a Movie

To get a movie from a stored movie file or other data source, call one of the NewMovieFrom... functions, specifying the movie data source and any other new-movie properties, such as the graphics destination. The exact details of how you specify your graphics destination, movie data source, and other movie properties depends on which NewMovieFrom... function you call, which in turn depends on what version of QuickTime you are targeting.

Getting a Movie in QuickTime 7 or Later

In QuickTime 7 and later, recommended practice is to get movies using the NewMovieFromProperties function. All the properties of the movie—graphics destination, movie data source, instantiation flags, and so on—are stored as elements in an array of movie properties. The properties array is then passed to NewMovieFromProperties.

The Movie Properties Array

The movie properties array is an extensible array that describes how the movie should be instantiated. Unlike a typical C structure (struct), new parameters can be added without breaking compatibility with existing code, and older versions of the properties array can be used with future versions of code. Any property not specified in the array is set to a default value. This means future versions of QuickTime will simply use default values for properites that can’t be specified in code you write today. In addition, if a property is passed that QuickTime does not understand, or if the specified value cannot be set, an error is returned in the status field but the movie is still created. The calling application is free to determine whether this is a fatal error or an inconvenience. This will allow programs you write in the future to react appropriately if an earlier version of QuickTime does not recognize a new property that you set, regardless of what that new property is.

Each element in the movie properties array has a type field, identifying it as (for example) a movie data reference or a context. Each element also has a subtype ID field, identifying its data format, such as a CFURL or a QTVisualContextRef. These fields are followed by a data size field, indicating the number of bytes of data in the property value, and a pointer to the data. There is also a returned status field to indicate whether QuickTime was able to set the specified property value.

Field

Size

Type

4 bytes

ID

4 bytes

DataSize

4 bytes

ValueAddr

4 bytes

PropStatus

4 bytes

For example, you specify the graphics destination using a visual context,

In QuickTime 7 and later, you specify the graphics destination using a visual context, which has a movie property of type kQTPropertyClass_Context, and subtype ID of kQTContextPropertyID_VisualContext.

Similarly, you specify the movie data source as a movie property of type kQTPropertyClass_DataLocation. The subtype ID depends on the format of the data that specifies the movie source, such as a file specification, path, or URL.

NewMovieFromProperties also supports an audio context (kQTContextPropertyID_AudioContext). This allows you to specify an audio output device, set up a channel configuration, assign particular sound tracks to particular channels, and generally make use of the features of Core Audio, bypassing the limitations of the old Sound Manager. If no audio context is specified, the default output device and channel configuration are used.

Other settable movie properties include kQTPropertyClass_MovieResourceLocator, kQTPropertyClass_MovieInstantiation, and kQTPropertyClass_NewMovieProperty.

The MovieResourceLocator property lets you specify any special location of a stored movie data structure within a movie data source, such as a legacy Mac OS resource fork or an offset into a file containing multiple stored movies.

The MovieInstantiation property lets you control how QuickTime instantiates the movie. For example, you can tell QuickTime to ask the user for help if external data files can’t be found, or tell QuickTime not to even look for external data files. You can tell NewMovieFromProperties to operate asynchronously, returning almost immediately and getting the movie in the background, or to operate synchronously, blocking until the movie is complete or an error has occured.

The NewMovieProperty property lets you specify additional movie characteristics, such as whether the movie is active or if it has a special default data reference for movie storage (for example, if the movie is not stored in a file, where QuickTime should initially offer to save the movie when the user chooses Save).

For additional details, see Movie Property Constants.

Specifying a Visual Context Property

Specify the graphics destination using a visual context, a movie property of type kQTPropertyClass_Context, and subtype ID of kQTContextPropertyID_VisualContext.

If this property is not specified, QuickTime renders movie output to the default graphics port for the thread. If you want QuickTime to render to the default graphics port, simply omit the visual context from the properties array.

Listing 1-1 shows how to create a visual context element and store it in a movie properties array.

Listing 3-1  Creating a visual context

 
// Allocate variables and pointers
CFAllocatorRef myAllocator;
CFDictionaryRef myAttributes;
QTVisualContextRef myContext;
 
// Create a key-value array pair with the pixel buffer attributes
// Create a CFDictionary from the arrays
//   Use default allocator and callbacks
 
 
// Create a CVPixelBuffer context
err = QTPixelBufferContextCreate(myAllocator, myAttributes, &myContext);
 
// Define a property array for NewMovieFromProperties
QTNewMoviePropertyElement movieProps[10];
ItemCount moviePropCount = 0;
 
// Add the visual context to the property array
movieProps[moviePropCount].propClass = kQTPropertyClass_Context;
movieProps[moviePropCount].propID = kQTContextPropertyID_VisualContext;
movieProps[moviePropCount].propValueSize = sizeof(myContext);
movieProps[moviePropCount].propValueAddress = &myContext;
movieProps[moviePropCount].propStatus = 0;
moviePropCount++;
 
// Add other movie properties to the array...
// ...
// Pass properties array to NewMovieFromProperties...
// ...

Specifying a Movie Data Source Property

The property class of a movie data source is kQTPropertyClass_DataLocation. The type of data reference (file specification, URL, and so forth) is passed in the property ID. See Movie Property Constants for a complete list of data reference type IDs.

For example, a URL data source has the property ID kQTDataLocationPropertyID_CFURL ('cfur'), and its value is passed as a CFURL.

The code for passing a URL created from a literal string is shown in Listing 1-2.

Listing 3-2  Creating a URL from a string

// Define a property array for NewMovieFromProperties
QTNewMoviePropertyElement movieProps[10];
ItemCount moviePropCount = 0;
 
// Create a URL data reference of type CFURL
CFStringRefmyURLString = CFSTR("http://myserver.mydomain.com/myMovie.mov");
CFURLRef myURLRef = CFURLCreateWithString(kCFAllocatorDefault, myURLString, Null);
 
// Add the movie data location to the property array
movieProps[moviePropCount].propClass = kQTPropertyClass_DataLocation;
movieProps[moviePropCount].propID = kQTDataLocationPropertyID_CFURL;
movieProps[moviePropCount].propValueSize = sizeof(myURLRef);
movieProps[moviePropCount].propValueAddress = (void*)&myURLRef;
movieProps[moviePropCount].propStatus = 0;
moviePropCount++;
 
// Add other movie properties to the array...
// ...
// Pass properties array to NewMovieFromProperties...
// ...

To specify a pointer or handle as the data source, you first need to create a data reference, as described in Specifying a Movie Data Source Using a Data Reference. You then pass the data reference to NewMovieFromProperties in the movie property array in the same way the CFURLRef is passed in Listing 3-2.

Getting a Movie Using NewMovieFromProperties

To use NewMovieFromProperties, you first create an array of movie properties set to your chosen values. These include the movie data source, the graphics destination, movie instantiation flags, whether the movie is active, and whether the movie supports user interaction. See Movie Property Constants for a list of available movie properties.

You pass the array to NewMovieFromProperties and the movie is instantiated using the properties you specify. Unspecified properties are set to system defaults. To use the system default for a given property, simply omit that property from the array.

If no movie data source (kQTPropertyClass_DataLocation) is specified, the default is to create an empty movie.

If no audio or video context is specified (kQTPropertyClass_Context), the default is the current graphics port and audio output device.

If no resource locator is specified (kQTPropertyClass_MovieResourceLocator), the default is the first movie QuickTime finds in the source.

There are several movie instantiation flags implemented as properties of the class kQTPropertyClass_MovieInstantiation. The default behavior when these properties are omitted is as follows:

kQTMovieInstantiationPropertyID_DontResolveDataRefs—QuickTime attempts to resolve all data references.

kQTMovieInstantiationPropertyID_DontAskUnresolvedDataRefs—QuickTime asks the user to help if it cannot resolve references.

kQTMovieInstantiationPropertyID_DontAutoAlternates—Auto-alternates are automatically chosen (one alternate track is enabled; the other alternates are disabled).

kQTMovieInstantiationPropertyID_DontUpdateForeBackPointers

kQTMovieInstantiationPropertyID_AsyncOK—Loading is synchronous; NewMovieFromProperties blocks until either movie loading is complete or a fatal error is encountered.

kQTMovieInstantiationPropertyID_IdleImportOK—QuickTime may use a movie import component that operates asynchronously. See Monitoring the Load State

kQTMovieInstantiationPropertyID_DontAutoUpdateClock

kQTMovieInstantiationPropertyID_ResultDataLocationChanged—QuickTime does not update the output property array if the data location of the movie changes.

If none of new-movie properties (kQTPropertyClass_NewMovieProperty) are specified, QuickTime uses its default new-movie settings: it copies the first movie it finds in the specified movie data source, the movie is not active when it opens, movie loading is synchronous, and the movie is set to interact with users.

While most of the QuickTime defaults are fine for normal movie playback, there are a few you will typically want to override:

  • You typically want to specify a data source, not create an empty movie.

  • You typically want to specify DontAskUnresolvedDataRef so QuickTime dones not ask the user for help locating files.

  • You typically want to pass the AsyncOK property so the function does not block during a long file download.

  • You typically want to pass the Active property so the movie is immediately active.

For additional details, see Movie Property Constants.

Listing 1-3 illustrates creating a movie properties array and passing it to NewMovieFromProperties.

Listing 3-3  Getting a movie using NewMovieFromProperties

 
// Define a property array for NewMovieFromProperties
QTNewMoviePropertyElement movieProps[10];
ItemCount moviePropCount = 0;
 
// Store the movie properties in the array
 
movieProps[moviePropCount].propClass = kQTPropertyClass_DataLocation;
movieProps[moviePropCount].propID = kQTDataLocationPropertyID_CFStringNativePath;
movieProps[moviePropCount].propValueSize = sizeof(inputPath);
movieProps[moviePropCount].propValueAddress = (void*)&inputPath;
movieProps[moviePropCount].propStatus = 0;
moviePropCount++;
 
movieProps[moviePropCount].propClass = kQTPropertyClass_MovieInstantiation;
movieProps[moviePropCount].propID = kQTMovieInstantiationPropertyID_DontAskUnresolvedDataRefs;
movieProps[moviePropCount].propValueSize = sizeof(boolTrue);
movieProps[moviePropCount].propValueAddress = &boolTrue;
movieProps[moviePropCount].propStatus = 0;
moviePropCount++;
 
movieProps[moviePropCount].propClass = kQTPropertyClass_NewMovieProperty;
movieProps[moviePropCount].propID = kQTNewMoviePropertyID_Active;
movieProps[moviePropCount].propValueSize = sizeof(boolTrue);
movieProps[moviePropCount].propValueAddress = &boolTrue;
movieProps[moviePropCount].propStatus = 0;
moviePropCount++;
 
movieProps[moviePropCount].propClass = kQTPropertyClass_NewMovieProperty;
movieProps[moviePropCount].propID = kQTNewMoviePropertyID_DontInteractWithUser;
movieProps[moviePropCount].propValueSize = sizeof(boolTrue);
movieProps[moviePropCount].propValueAddress = &boolTrue;
movieProps[moviePropCount].propStatus = 0;
moviePropCount++;
 
movieProps[moviePropCount].propClass = kQTPropertyClass_Context;
movieProps[moviePropCount].propID = kQTContextPropertyID_VisualContext;
movieProps[moviePropCount].propValueSize = sizeof(visualContext);
movieProps[moviePropCount].propValueAddress = &visualContext;
movieProps[moviePropCount].propStatus = 0;
moviePropCount++;
 
movieProps[moviePropCount].propClass = kQTPropertyClass_Context;
movieProps[moviePropCount].propID = kQTContextPropertyID_AudioContext;
movieProps[moviePropCount].propValueSize = sizeof(audioContext);
movieProps[moviePropCount].propValueAddress = &audioContext;
movieProps[moviePropCount].propStatus = 0;
moviePropCount++;
 
if ((err = NewMovieFromProperties(moviePropCount, movieProps, 0, NULL, &movie)))
{
MyErrorHandlingRoutine;  // Your application's error handling routine
}
 
//  clean-up
DisposeMovie(movie); movie = NULL;
CFRelease(inputPath); inputPath = NULL;
QTVisualContextRelease(visualContext); visualContext = NULL;
CGLDestroyContext(cglContext); cglContext = NULL;
CGLDestroyPixelFormat(cglPixelFormat); cglPixelFormat = NULL;
QTAudioContextRelease(audioContext); audioContext = NULL;

To create an empty movie with no data source and default properties, pass in 0 and NULL as the movie properties count and movie properties array; for example:

// Create a blank movie using NewMovieFromProperties
movie myMovie;
err = NewMovieFromProperties(0, nil, 0, nil, &myMovie);

Getting a Movie in QuickTime 6

In QuickTime 6 neither the NewMoviesFromProperties function nor the audio and visual contexts are available. The graphics destination is the current graphics port, the audio output is the default output device, and recommended practice is to instantiate the movie using NewMovieFromDataRef.

Setting a Graphics Destination in QuickTime 6 and Earlier

In QuickTime 6 and earlier, a movie is always instantiated using the application’s current graphics port, or GWorld. If you want to render to a different GWorld, you must change it by calling SetMovieGWorld after the movie is instantiated.

Your program’s graphics port must be valid when the movie is created, even if the movie is sound-only. The graphics port must remain valid for the life of the movie (or until you set a different valid graphics port for the movie using SetMovieGWorld). To test for a valid graphics port, call GetGWorld.

A graphics port is automatically created and assigned when you create a window in the Mac OS.

In the Windows OS, you create a valid graphics port using NewGWorld and associate it with your window by calling CreatePortAssociation. (You also need to call DestroyPortAssociation before disposing your window.) You can create a GWorld that corresponds to your window’s current graphics device in the Windows OS by calling GetNativeWindowPort.

Specifying a Movie Data Source Using a Data Reference

In QuickTime 6, you create a data reference for your movie data source (file, URL, pointer, or handle) and pass the data reference to the function NewMovieFromDataRef.

To create a data reference for the movie data source, use one of the QTNewDataReferencers> functions:

There are functions you can use to create a data reference from a string representing a file system reference, a directory, a full path, or a URL. There are also functions for creating a data reference directly from a CFURL, FSRef, or FSSpec. Use the utility function that is most convenient for you. For example, if you have a C string that indicates a URL, convert the C string to a CFString and call QTNewDataReferenceFromURLCFString. Windows programmers with a native Windows pathname might find it more convenient to create a CFString and call QTNewDataReferenceFromFullPathCFString.

All of these functions take a pointer for a data reference and a pointer for a reference type. On return, these pointers indicate the location and type of data reference created; you pass these pointers to NewMovieFromDataRef.

The data reference can point to either a QuickTime movie or to media data in a non-QuickTime format that QuickTime can import in place. If the data source does not contain a stored movie, QuickTime attempts to create a movie by searching the list of available movie import components based on the file type, MIME type, or filename extension of the data source.

If the data source is a buffer in memory, and is not a QuickTime movie, an additional step is required. Because your data reference is a pointer or handle, there is no MIME type, file type, or extension associated with it. In this case, you need to “tag” your data reference by adding one or more datarefextensions, such as a filename, file type, or MIME type, so QuickTime knows what type of importer is needed. For details, see Technical Note TN1195 Tagging Handle and Pointer Data References in QuickTime.

Getting a Movie Using NewMovieFromDataRef

NewMovieFromDataRef is a generalized routine that can instantiate a movie from most data sources. If you are writing an application that needs to run in QuickTime 6, it is recommended that you use NewMovieFromDataRef to instantiate the movie.

To use NewMovieFromDataRef, you first create a data reference to the movie data source. For details, see Specifying a Movie Data Source Using a Data Reference.

NewMovieFromDataRef also accepts a set of movie instantiation flags, indicating such things as whether the movie is active immediately, whether to query the user if QuickTime is unable to locate data files specified in the movie, and so on. For additional details, see NewMovieFromDataRef.

Listing 1-4 shows an example of creating a data reference and passing it to NewMovieFromDataRef, along with the movie instantiation flags.

Listing 3-4  Creating a data reference and calling NewMovieFromDataRef

 
// This function takes a CFStringRef to a full path and
// attempts to get a movie from the specified file
Booolean OpenMovie(CFStringRef inPath)
{
    Movie    myMovie = NULL;
    OSType   myDataRefType;
    Handle   myDataRef = NULL;
    short    myResID = 0;
    OSErr    myErr = noErr;
 
    ...
 
    // create the data reference
    myErr = QTNewDataReferenceFromFullPathCFString(inPath, kQTNativeDefaultPathStyle,
                                                   0, &myDataRef, &myDataRefType);
    if (myErr != noErr) goto bail;
 
    // get the Movie
    myErr = NewMovieFromDataRef(&myMovie,
newMovieActive | newMovieAsyncOK,
                                &myResID, myDataRef, myDataRefType);
    if (myErr != noErr) goto bail;
 
    // dispose of the data reference handle - we no longer need it
    DisposeHandle(myDataRef);
 
    // remember to call DisposeMovie when done with the returned Movie
 
    ...
}

Getting a Movie in Older Versions of QuickTime

For versions of QuickTime prior to QuickTime 6, you need to use a specific NewMovieFrom... function for each type of data source: NewMovieFromFile for files, NewMovieFromHandle for handles, NewMovieFromScrap, and so on.

There is no general procedure for specifying a movie data source for these functions; every type of data source is a special case. Different functions require you to pass the data source in different ways. For example, to use NewMovieFromFile> you need to pass in an FSRef. This is commonly obtained by calling OpenMovieFile with an FSSpec. Windows users might first need to convert a native Windows pathname to a Mac OS FSSpec using the utility function FSMakeFSSpec, setting both the volume reference number and directory ID to 0 and passing the full pathname in place of a filename.

Details on the required format for the movie data source are provided in the documentation for the specific NewMoviers> functions.

The graphics destination for movies created using these functions is always the current graphics port for your program. For additional details, see Setting a Graphics Destination in QuickTime 6 and Earlier.

The QuickTime documentation is rich in code samples that use these functions. For implementation details, see the QuickTimeAPIReference for these functions: