Apple Developer Connection
Member Login Log In | Not a Member? Contact ADC

< Previous PageNext Page > Hide TOC

Threaded Programming and QuickTime

QuickTime 6.4 introduces several new features that support execution of background tasks on multiple threads in a preemptive multitasking environment. This makes it possible to offload many tasks from your program's main thread to forestall blocking the user interface. Typical thread-safe tasks include importing still images or image sequences, exporting movies, and rendering to the offscreen graphics world a movie that is not currently being played.

The new threading features allow a degree of concurrent tasking in QuickTime that was not previously possible. In the past, QuickTime could be used on separate threads only by serializing access to the QuickTime API, either by the application itself or through the use of a cooperative threading manager such as the Carbon Thread Manager. While serializing allowed QuickTime to be used safely on multiple threads, it did not support concurrent QuickTime operations; if one thread was executing a QuickTime function, other threads needing to call QuickTime were blocked.

In this section:

Getting Ready to Use QuickTime from a Thread
User Interface Limited to the Main Thread
Error Handling
Using QuickTime From a Thread
Cleaning Up
Backward Compatibility
Thread Safety Issues


Getting Ready to Use QuickTime from a Thread

To use QuickTime in the background on a preemptive thread, make a call to EnterMoviesOnThread from the thread before calling any other QuickTime functions from that thread. It is important that you call EnterMovies on your main thread before spawning any threads that call EnterMoviesOnThread.

EnterMoviesOnThread initializes QuickTime with an environment that is private to the thread. Calls to GetMoviesError or MoviesTask(null), for example, will not obtain errors or task movies in other threads.

User Interface Limited to the Main Thread

Currently, only the main thread can access the user interface. You can play movies or open user dialogs only from the main thread.

To perform an export operation that requires a user dialog, for example, you need to first execute the dialog on the main thread. You can then perform the actual export operation on a separate thread without tying up the user interface. You can pass the information returned by the dialog to another thread by passing an atom container, using functions that get settings as atom containers and set settings from atom containers.

Error Handling

Calling EnterMoviesOnThread indicates that QuickTime should perform additional thread-safety checks on components opened and operations performed on the thread. If you call a function that requires use of a non-thread-safe component, or requires access to the user interface, or performs another thread-unsafe operation, QuickTime returns a distinguished error (componentNotThreadSafeErr = -2098).

Not all QuickTime components are thread-safe, so your code should be designed to detect threading error messages and transfer necessary tasks to the main thread. For example, you might spawn a thread to import a list of image files. The thread would import all the image files that have thread-safe importer components and return a list of any unhandled cases to the main thread, which could then import any remaining image files in the foreground.

From the main thread, your application can call CSSetComponentsThreadMode, passing it kCSAcceptThreadSafeComponentsOnlyMode, to see if opening a movie or other QuickTime object will succeed when attempted from a preemptive thread. You can do this only with Mac OS X version 10.3 or later.

Using QuickTime From a Thread

It is important that you use multiple threads to perform tasks on different movies. Do not use multiple threads to act on the same movie concurrently.

You can work on a given movie in separate threads sequentially, for example to perform an export in the background after playing a movie in the foreground, by passing a data reference from one thread to another when you are through operating on the movie in the first thread.

QuickTime 6.4 includes the following functions that you can use to associate movies and time bases with threads:

You can open movies in separate threads from the same source file, but each thread creates its own movie from the file. You can, however, play one movie while exporting the other, for example, which allows your application to behave as if it could concurrently process the same movie on different threads. This currently works with movies whose data is accessed from files, but not with movies accessed from a URL. The URL data handler is not currently thread-safe, so it is not possible to work with separate movies from the same URL in different threads.

Similarly, a thread-safe component type can be used by multiple threads at the same time, but each thread must instantiate its own instance of the component. Do not call a single component instance from multiple threads.

Many QuickTime functions that expect a component instance as a parameter also accept a component in that parameter. This ambiguity should generally be avoided when using different instances of the same component from multiple threads.

Cleaning Up

When your thread is done working with QuickTime, call ExitMoviesOnThread prior to closing the thread. Failure to do so may cause a memory leak, because resources allocated by EnterMoviesOnThread for the private QuickTime environment may fail to be released.

You may call EnterMoviesOnThread multiple times, which allows libraries to use this function without needing to know if their host thread has already done so. Subsequent calls do little more than increment a counter. To prevent memory leaks, one call to ExitMoviesOnThread should be made for each call to EnterMoviesOnThread.

Never call ExitMoviesOnThread without a prior call to EnterMoviesOnThread. Calls may be nested, but each instance of ExitMoviesOnThread must be balanced by a prior call to EnterMoviesOnThread.

Backward Compatibility

Because QuickTime did not previously support concurrent use from multiple threads, programs that already use QuickTime in preemptive threads may, accidentally or intentionally, make use of formerly global QuickTime states and data structures. For example, in older versions of QuickTime a call to MoviesTask(null) gives processor time to all movies in any thread. Similarly, an error handling routine in one thread might successfully detect errors in another.

While this kind of cross-thread interaction is more likely to do harm than good, the possibility exists that existing applications may rely on it. Consequently, if a thread makes calls to QuickTime without calling EnterMoviesOnThread, the thread shares QuickTime’s state and data structures on the main thread and any other threads that have not called EnterMoviesOnThread.

It is strongly recomended that you transition existing code away from any dependance on QuickTime states and data structures across threads as quickly as possible. When writing new code, threads that call QuickTime should use EnterMoviesOnThread to create private, thread-specific versions of the QuickTime environment.

Thread Safety Issues

For developers who are not familiar with QuickTime’s existing API, it’s possible to assume––largely because Mac OS X is multithreaded––that QuickTime is thread-safe. This is not the case. Your application can’t call QuickTime from arbitrary threads.

However, in some cases and with great care, in QuickTime 6.4 you are able to perform a few operations on secondary threads. The key point is that you can’t do it willy-nilly. If you need to use QuickTime on secondary threads, in limited cases, it is now possible.

The rules for new threads that call QuickTime are as follows:

Component developers should make their components thread-safe and set the new component flag cmThreadSafe.

The following parts of Mac OS X are newly thread-safe:

The following are not thread-safe:

In summary, you should unblock your user interface by moving slow QuickTime processing to other threads, cope with dynamic discovery of non-thread-safe media, and make your components thread-safe.



< Previous PageNext Page > Hide TOC


Last updated: 2003-09-01




Did this document help you?
Yes: Tell us what works for you.

It’s good, but: Report typos, inaccuracies, and so forth.

It wasn’t helpful: Tell us what would have helped.
Get information on Apple products.
Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Copyright © 2007 Apple Inc.
All rights reserved. | Terms of use | Privacy Notice