After Effects Plugins
Volume Number: 15
Issue Number: 9
Column Tag: Programming Techniques
How to Write Plug-Ins for Adobe After Effects
by Kas Thomas
Creating custom video f/x for Adobe's bestselling
video-compositing program is surprisingly easy
If you've ever marveled at the stunning visuals in those 15-second bumpers for shows
on the Discovery Channel, A&E, or MTV, it may surprise you to know that many of
them were created on the Mac, using off-the-shelf software - namely, Adobe After
Effects.
After Effects is the Swiss Army knife of video post-production, offering a powerful,
intuitive, layer-based approach to compositing in which variable-opacity masks and
keyframe-based motion control can be used to create stunning video effects.
As with Photoshop (Adobe's 2D graphics editor), much of the power of After Effects
comes from its extensive use of plug-ins - external code resources that augment the
functionality of the core program. Plug-ins for After Effects are similar to plug-ins
for Photoshop in that most are image filters that batch-process pixels to achieve
effects like blurring, sharpening, contrast enhancement, etc. The big difference, of
course, is that plug-ins for After Effects operate not only in the image domain but the
time domain as well. An After Effects filter may be invoked dozens, hundreds, or even
thousands of times, sequentially, as frames of video are processed into final footage. An
effect may last a split-second, or several minutes. During that time, individual filter
parameters may ramp up or down or undergo any number of changes (or no change at
all).
Since After Effects filtering occurs entirely offline, the effect can be as simple - or as
computationally intense - as the programmer wants it to be; the calculations don't
have to occur in real time. (This is in contrast to QuickTime-API effects, which are
implemented as image decompressors and must occur in real time.) This means an
After Effects filter can tackle some fairly lofty tasks, such as:
• Synthesis of complex, animated textures for use as backgrounds. (This is
a so-called zero-source type of effect.)
• Traditional single-source image filtering. (Blurring, sharpening,
contrast enhancement, gamma adjustment, color-shifting, addition or removal
of noise, etc.)
• Dual-source image filtering. (Wipes, fades, dissolves; complex matte
effects.)
• Warping, morphing, and distortion-mapping effects.
• 3D effects.
• Particle systems and physics simulations.
• Audio processing. (New in version 4.0.)
As with Photoshop plug-ins, writing plug-ins for After Effects offers a number of
advantages for the graphics programmer, including rapid development time, a stable
host-program environment, freedom from having to worry about file I/O or format
conversions, automatic Undo, automatic data buffering, and good code portability
(thanks to a cross-platform API in which device and OS dependencies have been
abstracted out). In addition, the After Effects plug-in API lets you build a solid,
cross-platform user interface in minimal time, with minimal code. And you don't have
to know a thing about QuickTime. The net result is that you're free to concentrate on
special effects programming instead of worrying about event-loop code, file I/O, and
other non-graphics issues.
But beyond all that, writing After Effects plug-ins is just plain fun. Creating
Photoshop filters can be a blast, but the first time you see a custom video effect of
your own design come alive on the screen, you'll be transfixed, like a deer in
headlights. In fact, you may never look at video the same way again.
The After Effects SDK
To develop plug-ins for After Effects, you'll need a copy of the After Effects plug-in
SDK, which is available from Adobe's web site (see
); or you can get it on CD-ROM
by joining the Adobe Solutions Network Developer Program (formerly the Adobe
Developers Association). Joining the ASN Developer Program is worth considering,
because for $195/yr. you not only get CD-ROM updates for all the current Graphics &
Publishing SDKs (i.e., SDKs for Photoshop, Premiere, After Effects, Illustrator,
InDesign, etc.), but you also qualify to obtain a full version of any Adobe product for
just $99 - including After Effects itself.
If you can't get the SDK on CD, plan on downloading several megabytes of material from
Adobe's web site. You'll end up with around four megs of quite useful .pdf
documentation, plus an equal amount of C/C++ sample code and headers. Most of what
you need to know is covered in the 82-page AE 4.0 SDK Guide, updated in January '99
to reflect the changes that occurred with After Effects 4.0. Additional docfiles talk
about Adobe's Plug-In Component Architecture (PICA), 'PiPL' resources, and sundry
other matters.
Compared to the Photoshop plug-in specification (which has become quite complex; see
my two-part article in the April and May 1999 issues of MacTech), the After Effects
API is lean and mean - a Porsche 911 in a world of London double-decker buses. "But
don't Photoshop and After Effects use the same basic plug-in API?" you may be asking.
Actually, the two programs have entirely different plug-in architectures. After
Effects does emulate the Photoshop 3.0 plug-in API, but native After Effects plug-ins
use a dedicated API which is not recognized by Photoshop. (This shouldn't come as a
surprise, since video effects have a time domain and respond to keyframe and track
data - things a Photoshop plug-in wouldn't know anything about.) Technically, it is
possible to make a Photoshop plug-in respond to After Effects keyframes, using a kluge
called the 'ANIM' resource. The 'ANIM' resource spec is described on pages 21-24 of
Adobe's Plug-In Resource Guide (see the SDK), if you're interested. The advantage of
the 'ANIM' resource is that if you've already written and debugged a Photoshop filter,
you can convert it to a video filter by merely crafting a resource rather than writing
more code. But in most cases you should write to the After Effects API, which allows
access to standard AE user controls and a variety of callbacks that aren't present in the
Photoshop API.
Two Basic Components
There are two basic components to an After Effects plug-in: a 'PiPL' resource, and
executable code. The 'PiPL' (or plug-in property list) resource, as you may recall
from my article on Photoshop plug-ins (MacTech, April '99), is an extensible
structure for representing a plug-in's metadata - information about the plug-in's
version, mode of operation, menu and submenu names, image modes supported (RGB,
CMYK, etc.), how the host program should interpret alpha channel data, etc. The
detailed specification is given in Adobe's Plug-In Resource Guide. In addition, the SDK
contains Rez scripts and compiled resources for the example projects. Resorcerer
recognizes 'PiPL' resources and will be a help in editing them. ResEdit is no help at all.
The reason the 'PiPL' resource is so important is that this is the first thing the host
(After Effects) examines when it scans available plug-ins. It's how the host locates the
plug-in's entry point and also how it determines whether the file is a legitimate
plug-in at all (and if so, which menu it belongs in). Years ago, the plug-in's filetype
was the determining factor in identifying plug-ins, but that's not how it works any
more. For a plug-in to work right, the 'PiPL' has to be correct.
After Effects now supports three main plug-in types: Filter, Input/Output, and (with
version 4.0) Foreign Project File plug-ins. (The latter was created so that After
Effects could import Premiere projects.) The 'PiPL' tells After Effects what kind of
plug-in it is dealing with, which menu or submenu it should appear in, and what name
to give it in the submenu.
In terms of filetypes, a native After Effects plug-in will have a filetype of 'eFKT' (and
a creator type of 'FXTC'), but this is merely a convention, not a requirement. In terms
of code, an After Effects plug-in is compiled as a Shared Library module on the Mac or
a DLL under Windows, with an entry point of main; and as a practical matter all After
Effects filters for the Mac are now compiled as PPC-native, since the After Effects
SDK no longer supports 68K code (as of version 4.0).
How a Plug-in Works
When After Effects is launched, it looks for plug-ins in all subdirectories of its path,
recursively descending up to 10 levels deep. MacOS aliases are resolved and all folders
are checked except any with names surrounded in parentheses, such as "(Old
Plug-ins)". Note that no executables are actually loaded at this point; rather, After
Effects caches a list of available plug-ins and loads them dynamically as the
needarises. Unlike Photoshop, however, After Effects doesn't unload a plug-in after it
is used. That's because in a piece of video footage, a plug-in might have to be invoked
hundreds or even thousands of times, sequentially, and to unload and reload it
thousands of times would be inefficient. (Tip: During development, if you need to flush
After Effects' plug-in cache so that you can load a new version of your plug-in at
program run time, without having to quit and relaunch After Effects, hold down the
Control and Clear keys.)
All After Effects plug-ins have a single entry point, main(), which is called
repeatedly with selectors indicating the desired action. The prototype for main() looks
like this:
PF_Err main (PF_Cmd cmd,
PF_InData *in_data,
PF_OutData *out_data,
PF_ParamList params,
PF_LayerDef *output,
void *extra);
The first argument is a selector whose value represents the stage of execution that the
plug-in is about to enter.
The second argument to main is a pointer to a large data structure containing
host-application state information and hooks to callbacks.
The third parameter is a pointer to a structure that serves as a way for the plug-in to
communicate its needs to the host. For example, error messages can be passed back to
the host via the return_msg field. (See AE_Effect.h for the complete typedef.)
The params argument is where the plug-in gets access to its user-specified parameter
values - for example, the value of sliders or controls in the Effects Control Window
(ECW). In other words, all of your user interface info is cached here. We'll have more
to say about this is a minute.
The output parameter points to a PF_LayerDef struct, which contains information
about the output image (including a pointer to its data): its dimensions, its rowbytes
value, and the extent_hint, which is a Rect giving the bounds of the area that actually
needs rendering. (This is often just a subset of the overall image.) Don't confuse the
PF_InData and PF_OutData structs with pointers to pixel data; images are represented
by the PF_LayerDef, also sometimes called a PF_World.
Finally, the extra pointer is a special-use parameter that went largely unused prior
to After Effects 4.0. It points to different data structures at different times (and
garbage, at other times). You'll only deal with this parameter if you decide to
implement custom user interface elements and/or complex custom data types.
The possible selector values for cmd are:
enum {
PF_Cmd_ABOUT = 0,
PF_Cmd_GLOBAL_SETUP,
PF_Cmd_UNUSED_0,
PF_Cmd_GLOBAL_SETDOWN,
PF_Cmd_PARAMS_SETUP,
PF_Cmd_SEQUENCE_SETUP,
PF_Cmd_SEQUENCE_RESETUP,
PF_Cmd_SEQUENCE_FLATTEN,
PF_Cmd_SEQUENCE_SETDOWN,
PF_Cmd_DO_DIALOG,
PF_Cmd_FRAME_SETUP,