Setting Up Graphics and Audio Output

Before you open a QuickTime movie, you need to decide where the movie output should go. If you want to use the default audio and video outputs, this is very simple (just verify that the default graphics output port is valid). Otherwise, you need to specify a graphics destination, an audio output, or both.

A graphics destination specifies where the visual output of a QuickTime movie is rendered. By default, QuickTime renders to the current thread’s graphics port, which typically corresponds to a window, a view, or other control within a window. For simple playback, this default behavior is all you need; do not specify a graphics destination. Just verify that you have a valid graphics port and keep the graphics port valid for the life of the movie. For details, see Using a Graphics Port or GWorld.

QuickTime can also render to an offscreen buffer—either a GWorld buffer, a Core Video pixel buffer, or an OpenGL texture. Do this if you need to work with individual frames before, or instead of, presenting them to screen.

All versions of QuickTime can render to the default graphics device or a specified GWorld. QuickTime 7 and later can render to a Core Video pixel buffer or an OpenGL texture.

To work with individual video frames, you must specify a graphics destination by setting either a GWorld or a visual context. When you do this, you become responsible for final destination of the frames. You need to use a lower-level technology, such as QuickDraw, Core Image, or OpenGL, to transfer the images to the screen or other destination, and you are responsible for disposing of them when they are no longer needed.

To manipulate individual frames using a modern technology such as OpenGL, Core Video, or Core Image (Quartz), use a visual context to set the graphics destination by calling NewMovieFromProperties or SetMovieVisualContext. To manipulate video using older GWorld-based graphic systems such as QuickDraw, use SetMovieGWorld.

Mac OS X does not support direct rendering to screen. All rendering takes place to an offscreen buffer. If a GWorld or Core Video pixel buffer is specified, this is a buffer in main memory. If an OpenGL texture is specified, this is an image buffer in video memory. If no visual destination is specified, QuickTime attempts to use video memory to take advantage of graphics acceleration. The extent to which this is possible depends on such things as the media being rendered, the pixel formats, available transfer codecs, and the capabilities of the computer’s graphics card.

For maximum performance, use the default graphics port or an OpenGL texture. Rendering to a GWorld or Core Video pixel buffer copies the image to and from main memory before final rendering, which slows things down.

Creating a Visual Context

Create a visual context if you need to manipulate individual frames before, or instead of, rendering them to the screen.

You create a visual context by calling one of the QT...ContextCreate functions, such as QTPixelBufferContextCreate or QTOpenGLTextureContextCreate. These functions return a QTVisualContextRef, an opaque token that you can pass to NewMovieFromProperties as part of a properties array or apply to an existing movie using SetMovieVisualContext.

QTPixelBufferContextCreate creates a visual context that causes QuickTime to render each frame to a Core Video pixel buffer in main memory. You can inspect or modify the frame and pass the pixel buffer to Core Image or OpenGL for display.

The QTPixelBufferContextCreate function takes a dictionary of attributes as an argument. This is a CFDictionary, an array of key-value pairs. This dictionary contains attributes such as the target dimensions and pixel buffer description. Some of these attributes are themselves contained in dictionaries, so the attributes dictionary can contain references to other dictionaries. Create the dictionaries using CFDictionaryCreate. For additional details, see “Visual Context Types” in QuickTime 7 Update Guide.

To specify a particular pixel buffer format, create a dictionary with the desired attributes as described in “Pixel Buffer Attribute Keys” in Core Video Reference. If you do not specify a pixel buffer format, QuickTime uses the native pixel format of the video frame.

To render each frame as an OpenGL texture, create the context using QTOpenGLTextureContextCreate. You are responsible for passing the textures to OpenGL for display.

QTOpenGLTextureContextCreate takes an OpenGL context and a pixel format object as arguments, as well as a CFDictionary of attributes.

To disable visual rendering, pass NULL instead of a VisualContextRef, either to SetMovieVisualContext or as a visual context movie property. This also frees the context for reuse or disposal.

To render to an offscreen graphics world instead of to a Core Video pixel buffer, disable visual rendering by setting a NULL visual context, then call SetMovieGWorld after the movie is instantiated. Do this if you need to manipulate individual frames using an older technology, such as QuickDraw, that works with GWorlds.

When you render to a pixel buffer or GWorld, you render to main memory and typically lose the advantages of graphics acceleration. When you render to an OpenGL texture, you render directly to video memory. 

When you render to the default graphics port, QuickTime attempts to use video memory, but the actual rendering path depends on factors such as the media types, compressed pixel formats, and available transfer codecs. 

To render to the default graphics port, do not include a visual context in the properties array when calling NewMovieFromProperties. You are not responsible for rendering individual frames in this case; QuickTime renders them automatically as the movie plays. For more information, see Using a Graphics Port or GWorld.

Using a Graphics Port or GWorld

If you instantiate a movie without specifying a visual context, the movie’s graphics destination is set to your program’s current graphics port (the port for the active window or thread). This is always the case when using versions of QuickTime prior to QuickTime 7 or when using NewMovieFrom... functions that do not accept a visual context.

You are not responsible for displaying individual frames when rendering to the default graphics port; this is handled automatically.

You can use GetGWorld to check for a valid port, and use NewGWorld to create a port if needed, before instantiating a movie.

A graphics port is automatically created when you create a window in the Mac OS. Your movie output typically goes to a view within a window, and therefore to the window’s associated port; but if your application has not created a window, you may need to create a graphics port separately.

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 of your window.) Alternatively, you can create a GWorld that corresponds to your window’s current graphics device by calling GetNativeWindowPort.

Changing a Movie’s Graphics Destination

To change an existing movie’s graphics destination to a new visual context, call SetMovieVisualContext.

To change an existing movie’s graphics destination to a new GWorld, call SetMovieGWorld. If the movie is currently using a visual context, free the context by calling SetMovieVisualContext, passing in NULL instead of a VisualContextRef, before setting the GWorld.

To disable visual rendering, call SetMovieVisualContext, passing in NULL instead of a VisualContextRef.

To get a movie’s current graphics destination, call GetMovieVisualContext. If the movie’s destination is a GWorld instead of a visual context, this function returns an error (kQTVisualContextRequiredErr); you can then call GetMovieGworld to obtain the GWorld.

GetMovieGWorld does not return an error for movies that use a visual context instead of a GWorld. It gives a special GWorld value that represents the visual context. This provides backward compatibility with existing code that gets a movie GWorld and later restores it.

Switching to Full-Screen Mode

When rendering to a graphics port, you can switch between playing your movie in a window and playing your movie using the full screen by calling BeginFullScreen and EndFullScreen. When playing a movie using the full screen, you should respond to the Escape key by ending full-screen mode.

Setting an Audio Context

QuickTime normally sends audio to the default audio output for your system. Channels are automatically mixed-down as needed (when playing multichannel sound through a stereo output, for example).

To direct the audio output of a movie to a particular device, or to set up a channel configuration or assign individual sound tracks to particular channels, create an audio context.

To create an audio context, call QTAudioContextCreateForAudioDevice and pass in the UID of an output device. An audio context reference is returned. Pass that audio context ref either to NewMovieFromProperties, as you would pass in a visual context, or to SetMovieAudioContext, to redirect the output of an existing movie.

Audio contexts are not shareable. If you want to route the output of two or more movies to the same device, call QTAudioContextCreateForAudioDevice once for each movie, passing in the same device UID to get another audio context for the same device. Pass a separate audio context reference to each movie.

You can pass NULL as the UID to QTAudioContextCreateForAudioDevice to create an audio context for the default audio output.