Adopting QuickTime X for Playback

QuickTime X is a high-performance media playback technology that you can use to power your applications. Adopting it is as simple as opting into and then verifying that you’re using only supported functionality.

This chapter describes how you can modify your existing QTKit code to take advantage of the QuickTime X media services provided in OS X v10.6. You gain access to the media playback services through the QTKit framework by opting into QuickTime X with a single method call.

QuickTime X Media Services

As a new media architecture developed by Apple and available in OS X v10.6, QuickTime X is specifically designed for efficient, high-performance playback of audio/video media, with optimized support for modern codecs such as H.264 and AAC. It provides support for the following:

Notably, QuickTime X media services do not require client cooperation or intervention in order to share processor time and to preserve responsiveness to user input.

In QuickTime 7, processor time is obtained cooperatively. This means that although QTKit takes care of the details, some applications may need to intervene via such methods as -[QTMovie setIdling:], and some operations are synchronous, especially I/O that occurs at initialization time.

By contrast, QuickTime X obtains processor time preemptively, according to OS X threading guidelines, and all operations are asynchronous. Media operations for initialization, playback, and tear-down, including I/O, decoding, and rendering, occur asynchronously to the operations of the client application. As a consequence, responsiveness to user input is always preserved.

Because QuickTime X does whatever is necessary in order to make extended media-processing operations occur on a background thread, your application avoids getting blocked for lengthy periods of time, for example, when you open a media file for playback.

For purposes of media playback, QTKit provides essentially one of two paths, either directly through QuickTime X or through QuickTime 7, as shown in Figure 3-1. These paths are transparent to your application, however, unless you choose to opt into QuickTime X.

Figure 3-1  QTKit media services provided through QuickTime X and QuickTime 7

In working with QTMovie objects generated by capture, the QTKit capture architecture uses QuickTime X transparently.

How it Works

Using the media services provided by QuickTime X, you can open a media file, gather information about the playback characteristics of the movie (such as its duration, the codecs used, and thumbnail images), display the movie in a view, and control the loading and playback of that movie.

QTKit will attempt to use QuickTime X if you tell it to open a media file either (a) asynchronously or (b) for playback only. However, if that file is not encoded using a modern codec, QTKit will automatically fall back to QuickTime 7. This happens silently, though, so you will need to test for error conditions yourself, as described Some Limitations.

Opting into QuickTime X

Two new movie attributes are defined in OS X v10.6 that enable you to opt into the more efficient media capabilities provided in QuickTime X. These are

While the default behavior of QTMovie is to open movies that can be made editable and exportable, you can create a dictionary of attributes, one of which specifies where the movie is, what the features of the movie are (optional), and specify that you want to open it for playback.

To initialize the attribute, as shown in Listing 3-1, do this:

Listing 3-1  Initializing the attribute

- (id)initWithAttributes:(NSDictionary *)attributes
                   error:(NSError **)errorPtr;

The code snippet (shown in Listing 3-2) illustrates how you pass this key with the value NSNumber numberWithBool:YES in the dictionary of attributes passed to initWithAttributes:error: to indicate that you are interested only in playing the movie. If editing or exporting services are not required, QTMovie may be able to select more efficient code paths.

Now to open a movie file using the more efficient playback path provided in QuickTime X, use this:

Listing 3-2  Opening a movie for playback using QuickTime X

QTMovie *movie = nil;
NSError *error = nil;
NSNumber *num = [NSNumber numberWithBool:YES];
NSDictionary *attributes =
          [NSDictionary dictionaryWithObjectsAndKeys:
              fileName, QTMovieFileNameAttribute,
              num, QTMovieLoopsAttribute,
              num, QTMovieOpenForPlaybackAttribute,
                 nil];
 
movie = [[QTMovie alloc] initWithAttributes:attributes
                                      error:&error];

Because the attributes dictionary contains a key-value pair with the QTMovieOpenForPlaybackAttribute key and the value YES, QTKit uses the new media services if possible to play back the media content in the selected file.

Some Limitations

By declaring that a QTMovie is initialized for purposes of playback, you intentionally and explicitly forfeit portions of the QTMovie contract previously established by the QTKit API in order to gain the best available optimizations for playback of the media resource represented by that instance of QTMovie.

When you opt-in, you declare that such operations as editing, saving, and export for instances of QTMovie are not needed.

Not all media files can be handled the same way. For example, you may specify a movie file and request that file to be opened for playback, but it may be the kind of file that QuickTime X cannot handle. In that case, QTKit simply falls back to the standard QuickTime 7 path for opening and playing movies.

Note that you cannot determine whether or not a movie has fallen back to the QuickTime 7 path. This happens transparently to the user. You are restricted to the same playback-only APIs whether or not QTKit falls back to QuickTime 7. Specifying QTMovieOpenForPlaybackAttribute means signing a contract that you will never do anything but play back the movie, no matter what state it happens to be in.

If you tell QTKit it can and should use QuickTime X, you will be restricted to only those APIs dedicated for use with movie playback and playback-related operations, and the codecs that are supported. These are documented in the QTKit Framework Reference, particularly in the QTMovie Class Reference.

If QTMovieOpenForPlaybackAttribute is set but the application attempts an operation that falls outside the scope of playback, an NSException with the name QTDisallowedForInitializationPurposeException will be raised.