Q: I've written a codec that uses the Base Image
Decompressor. My Decompressor should be able to run
asynchronously (the DrawBand function doesn't make any
un-safe calls), and I've made sure to set the canAsync flag
in the sub-codec capabilities record during
ImageCodecInitialize. However, the codec doesn't seem to be
running asynchronously. Am I missing something?
A: Asynchronous codecs derived from the Base Codec
must make sure to implement the ImageCodecQueueStarting and
ImageCodecQueueStopping routines in addition to setting the
canAsync flag. Your codec must implement these calls or the
Base Codec will fall back to synchronous playback.
If your codec doesn't need to do any work at these
times, simply return noErr.
Listing 1 demonstrates setting up a dispatch file
and implementing both selectors.
Listing 2 demonstrates how to let
ComponentDispatchHelper do the work for you if your codec
doesn't need to do any work in QueueStarting and
QueueStopping.
// MySubCodecDispatch.h
...
ComponentRangeBegin (3)
ComponentCall (Preflight)
ComponentCall (Initialize)
ComponentCall (BeginBand)
ComponentCall (DrawBand)
ComponentCall (EndBand)
ComponentCall (QueueStarting)
ComponentCall (QueueStopping)
ComponentDelegate (DroppingFrame)
ComponentDelegate (ScheduleFrame)
ComponentDelegate (CancelTrigger)
ComponentRangeEnd (3)
...
// MySubCodec.c
...
// ImageCodecQueueStarting
// The base image decompressor calls your image decompressor component's
// ImageCodecQueueStarting function before decompressing the frames in the
// queue. The base image decompressor never calls the ImageCodecQueueStarting
// function at interrupt time.
// If your codec supports asynchronous scheduled decompression you must
// implement this selector. If your codec does not need to do anything at
// this time simply return noErr.
pascal ComponentResult EI_ImageCodecQueueStarting(EI_Globals glob)
{
#pragma unused(glob)
return noErr;
}
// ImageCodecQueueStopping
// The base image decompressor calls your ImageCodecQueueStopping
// function to notify your codec that the frames in the queue have been
// decompressed. After your image decompressor component handles an
// ImageCodecQueueStopping call, it can perform any tasks that are required
// when decompression of the frames is finished, such as disposing of data
// structures that are no longer needed.
// If your codec supports asynchronous scheduled decompression you must
// implement this selector. If your codec does not need to do anything at
// this time simply return noErr.
// The base image decompressor never calls the ImageCodecQueueStopping
// function at interrupt time.
pascal ComponentResult EI_ImageCodecQueueStopping(EI_Globals glob)
{
#pragma unused(glob)
return noErr;
}
...
|
Listing 1. Implementing QueueStarting
& QueueStopping
|
// If your codec doesn't need to perform any work in QueueStarting
// and QueueStopping, you can use ComponentNoError in your dispatcher
// and let ComponentDispatchHelper do the work for you.
// ComponentDispatchHelper will return noErr for these two selectors and not
// badComponentSelector.
// MySubCodecDispatch.h
...
ComponentRangeBegin (3)
ComponentCall (Preflight)
ComponentCall (Initialize)
ComponentCall (BeginBand)
ComponentCall (DrawBand)
ComponentCall (EndBand)
ComponentNoError (QueueStarting)
ComponentNoError (QueueStopping)
ComponentDelegate (DroppingFrame)
ComponentDelegate (ScheduleFrame)
ComponentDelegate (CancelTrigger)
ComponentRangeEnd (3)
...
|
Listing 2. Using ComponentNoError to
implement QueueStarting & QueueStopping
|
References:
QuickTime
Codec Components
Base
Image Decompressor Functions
[Jul 09 2002]
|