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
Specifying a Visual Context Property
Specifying a Movie Data Source Property
Getting a Movie Using NewMovieFromProperties
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 |
| 4 bytes |
| 4 bytes |
| 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.”
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... |
// ... |
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.
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.DontAskUnresolvedDataRef so QuickTime dones not ask the user for help locating files.AsyncOK property so the function does not block during a long file download.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); |
Last updated: 2005-08-11